diff options
author | aclement <aclement> | 2006-08-08 07:59:54 +0000 |
---|---|---|
committer | aclement <aclement> | 2006-08-08 07:59:54 +0000 |
commit | f239f2a2ac6a887fd46e6d95e8fb4ec93e2e159d (patch) | |
tree | 743a6c0065bbfe01d7a32427b90cd1414be3c8b2 /weaver | |
parent | 6dca4cc41d0af83c9baeb1aa1734b48cec11b1b0 (diff) | |
download | aspectj-f239f2a2ac6a887fd46e6d95e8fb4ec93e2e159d.tar.gz aspectj-f239f2a2ac6a887fd46e6d95e8fb4ec93e2e159d.zip |
tests (?) and fixes for 152873 - optimized check for @AJ aspects in LTW
Diffstat (limited to 'weaver')
3 files changed, 195 insertions, 23 deletions
diff --git a/weaver/src/org/aspectj/weaver/World.java b/weaver/src/org/aspectj/weaver/World.java index e1e663db0..fb17ab9d3 100644 --- a/weaver/src/org/aspectj/weaver/World.java +++ b/weaver/src/org/aspectj/weaver/World.java @@ -1202,4 +1202,8 @@ public abstract class World implements Dump.INode { if (trace.isTraceEnabled()) trace.exit("setSynchronizationPointcutsInUse"); } public boolean areSynchronizationPointcutsInUse() {return synchronizationPointcutsInUse;} + + public boolean isASMAround() { + return isASMAround; + } } diff --git a/weaver/src/org/aspectj/weaver/tools/IsAtAspectAnnotationVisitor.java b/weaver/src/org/aspectj/weaver/tools/IsAtAspectAnnotationVisitor.java new file mode 100644 index 000000000..d15c2f8d8 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/tools/IsAtAspectAnnotationVisitor.java @@ -0,0 +1,148 @@ +/* ******************************************************************* + * Copyright (c) 2006 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eugene Kuleshov, Ron Bodkin initial implementation + * ******************************************************************/ +package org.aspectj.weaver.tools; + +import org.aspectj.org.objectweb.asm.AnnotationVisitor; +import org.aspectj.org.objectweb.asm.Attribute; +import org.aspectj.org.objectweb.asm.ClassVisitor; +import org.aspectj.org.objectweb.asm.FieldVisitor; +import org.aspectj.org.objectweb.asm.Label; +import org.aspectj.org.objectweb.asm.MethodVisitor; + +// should extend EmptyVisitor but it's not currently included with AspectJ's ASM... +public class IsAtAspectAnnotationVisitor implements ClassVisitor, FieldVisitor, + MethodVisitor, AnnotationVisitor { + private boolean isAspect = false; + + public AnnotationVisitor visitAnnotation(String desc, boolean visible) { + if ("Lorg/aspectj/lang/annotation/Aspect;".equals(desc)) { + isAspect = true; + } + return this; + } + + public FieldVisitor visitField(int access, String name, String desc, + String signature, Object value) { + return null; + } + + public MethodVisitor visitMethod(int access, String name, String desc, + String signature, String[] exceptions) { + return null; + } + + public boolean isAspect() { + return isAspect; + } + + public void visit(int version, int access, String name, String signature, + String superName, String[] interfaces) { + } + + public void visitSource(String source, String debug) { + } + + public void visitOuterClass(String owner, String name, String desc) { + } + + public void visitAttribute(Attribute attr) { + } + + public void visitInnerClass(String name, String outerName, + String innerName, int access) { + } + + public void visitEnd() { + } + + public AnnotationVisitor visitAnnotationDefault() { + return this; + } + + public AnnotationVisitor visitParameterAnnotation(int parameter, + String desc, boolean visible) { + return this; + } + + public void visitCode() { + } + + public void visitInsn(int opcode) { + } + + public void visitIntInsn(int opcode, int operand) { + } + + public void visitVarInsn(int opcode, int var) { + } + + public void visitTypeInsn(int opcode, String desc) { + } + + public void visitFieldInsn(int opcode, String owner, String name, + String desc) { + } + + public void visitMethodInsn(int opcode, String owner, String name, + String desc) { + } + + public void visitJumpInsn(int opcode, Label label) { + } + + public void visitLabel(Label label) { + } + + public void visitLdcInsn(Object cst) { + } + + public void visitIincInsn(int var, int increment) { + } + + public void visitTableSwitchInsn(int min, int max, Label dflt, + Label labels[]) { + } + + public void visitLookupSwitchInsn(Label dflt, int keys[], Label labels[]) { + } + + public void visitMultiANewArrayInsn(String desc, int dims) { + } + + public void visitTryCatchBlock(Label start, Label end, Label handler, + String type) { + } + + public void visitLocalVariable(String name, String desc, String signature, + Label start, Label end, int index) { + } + + public void visitLineNumber(int line, Label start) { + } + + public void visitMaxs(int maxStack, int maxLocals) { + } + + public void visit(String name, Object value) { + } + + public void visitEnum(String name, String desc, String value) { + } + + public AnnotationVisitor visitAnnotation(String name, String desc) { + return this; + } + + public AnnotationVisitor visitArray(String name) { + return this; + } +} diff --git a/weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java b/weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java index 55265ca3e..dc7cb73fa 100644 --- a/weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java +++ b/weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java @@ -37,6 +37,7 @@ import org.aspectj.bridge.MessageUtil; import org.aspectj.bridge.MessageWriter; import org.aspectj.bridge.Version; import org.aspectj.bridge.IMessage.Kind; +import org.aspectj.org.objectweb.asm.ClassReader; import org.aspectj.util.FileUtil; import org.aspectj.util.LangUtil; import org.aspectj.weaver.IClassFileProvider; @@ -212,16 +213,25 @@ public class WeavingAdaptor { try { delegateForCurrentClass=null; if (trace.isTraceEnabled()) trace.enter("weaveClass",this,new Object[] {name,bytes}); - if (shouldWeave(name, bytes)) { - info("weaving '" + name + "'"); - bytes = getWovenBytes(name, bytes); - } else if (shouldWeaveAnnotationStyleAspect(name, bytes)) { - // an @AspectJ aspect needs to be at least munged by the aspectOf munger - info("weaving '" + name + "'"); - bytes = getAtAspectJAspectBytes(name, bytes); - } - else { - info("not weaving '" + name + "'"); + name = name.replace('/','.'); + if (couldWeave(name, bytes)) { + if (accept(name, bytes)) { + // TODO @AspectJ problem + // Annotation style aspects need to be included regardless in order to get + // a valid aspectOf()/hasAspect() generated in them. However - if they are excluded + // (via include/exclude in aop.xml) they really should only get aspectOf()/hasAspect() + // and not be included in the full set of aspects being applied by 'this' weaver + info("weaving '" + name + "'"); + bytes = getWovenBytes(name, bytes); + } else if (shouldWeaveAnnotationStyleAspect(name, bytes)) { + // an @AspectJ aspect needs to be at least munged by the aspectOf munger + info("weaving '" + name + "'"); + bytes = getAtAspectJAspectBytes(name, bytes); + } else { + info("not weaving '" + name + "'"); + } + } else { + info("cannot weave '" + name + "'"); } if (trace.isTraceEnabled()) trace.exit("weaveClass",bytes); @@ -235,17 +245,10 @@ public class WeavingAdaptor { /** * @param name - * @return true if should weave (but maybe we still need to munge it for @AspectJ aspectof support) + * @return true if even valid to weave: either with an accept check or to munge it for @AspectJ aspectof support */ - private boolean shouldWeave (String name, byte[] bytes) { - name = name.replace('/','.'); - boolean b = !generatedClasses.containsKey(name) && shouldWeaveName(name); - return b && accept(name, bytes); -// && shouldWeaveAnnotationStyleAspect(name); -// // we recall shouldWeaveAnnotationStyleAspect as we need to add aspectOf methods for @Aspect anyway -// //FIXME AV - this is half ok as the aspect will be weaved by others. In theory if the aspect -// // is excluded from include/exclude config we should only weave late type mungers for aspectof -// return b && (accept(name) || shouldWeaveAnnotationStyleAspect(name)); + private boolean couldWeave (String name, byte[] bytes) { + return !generatedClasses.containsKey(name) && shouldWeaveName(name); } //ATAJ @@ -276,12 +279,29 @@ public class WeavingAdaptor { * @return true if @Aspect */ private boolean shouldWeaveAnnotationStyleAspect(String name, byte[] bytes) { - // AV: instead of doing resolve that would lookup stuff on disk thru BCEL ClassLoaderRepository - // we reuse bytes[] here to do a fast lookup for @Aspect annotation - ensureDelegateInitialized(name,bytes); + if (delegateForCurrentClass==null) { + if (weaver.getWorld().isASMAround()) return asmCheckAnnotationStyleAspect(bytes); + else ensureDelegateInitialized(name, bytes); + } return (delegateForCurrentClass.isAnnotationStyleAspect()); } + private boolean asmCheckAnnotationStyleAspect(byte[] bytes) { + IsAtAspectAnnotationVisitor detector = new IsAtAspectAnnotationVisitor(); + + ClassReader cr = new ClassReader(bytes); + try { + cr.accept(detector, true);//, ClassReader.SKIP_DEBUG | ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES); + } catch (Exception spe) { + // if anything goes wrong, e.g., an NPE, then assume it's NOT an @AspectJ aspect... + System.err.println("Unexpected problem parsing bytes to discover @Aspect annotation"); + spe.printStackTrace(); + return false; + } + + return detector.isAspect(); + } + protected void ensureDelegateInitialized(String name,byte[] bytes) { if (delegateForCurrentClass==null) delegateForCurrentClass = ((BcelWorld)weaver.getWorld()).addSourceObjectType(Utility.makeJavaClass(name, bytes)); |