]> source.dussan.org Git - aspectj.git/commitdiff
finished implementation of around inlining
authorjhugunin <jhugunin>
Wed, 1 Jan 2003 00:07:33 +0000 (00:07 +0000)
committerjhugunin <jhugunin>
Wed, 1 Jan 2003 00:07:33 +0000 (00:07 +0000)
24 files changed:
org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AccessForInlineVisitor.java [new file with mode: 0644]
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/MakeDeclsPublicVisitor.java [new file with mode: 0644]
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/ProceedVisitor.java [new file with mode: 0644]
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java
org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/WorkingTestMain.java
weaver/src/org/aspectj/weaver/Advice.java
weaver/src/org/aspectj/weaver/ConcreteTypeMunger.java
weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java
weaver/src/org/aspectj/weaver/ResolvedTypeX.java
weaver/src/org/aspectj/weaver/World.java
weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
weaver/src/org/aspectj/weaver/bcel/BcelWorld.java
weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java
weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java
weaver/testdata/AfterFancyHelloWorld.txt
weaver/testdata/AfterThrowingFancyHelloWorld.txt
weaver/testdata/AfterThrowingParamFancyHelloWorld.txt
weaver/testdata/TraceJarHello.txt

index 81cabdb69a6e7028cd72acabdba468c26a68179a..9cbc17afb553e429979fcf26f74f91d3b1660017 100644 (file)
@@ -359,6 +359,8 @@ public class BuildArgParser extends org.eclipse.jdt.internal.compiler.batch.Main
                                buildConfig.setNoWeave(true);
                        } else if (arg.equals("-XserializableAspects")) {
                                buildConfig.setXserializableAspects(true);
+                       } else if (arg.equals("-XnoInline")) {
+                               buildConfig.setXnoInline(true);
                        } else if (arg.equals("-Xlintfile")) { 
                                if (args.size() > nextArgIndex) {
                                        File lintSpecFile = makeFile(((ConfigParser.Arg)args.get(nextArgIndex)).getValue());
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AccessForInlineVisitor.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AccessForInlineVisitor.java
new file mode 100644 (file)
index 0000000..411ae4d
--- /dev/null
@@ -0,0 +1,114 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import java.util.Arrays;
+
+import org.aspectj.ajdt.internal.compiler.lookup.*;
+import org.aspectj.ajdt.internal.compiler.lookup.PrivilegedHandler;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.ShadowMunger;
+import org.eclipse.jdt.internal.compiler.AbstractSyntaxTreeVisitorAdapter;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+/**
+ * Takes a method that already has the three extra parameters
+ * thisJoinPointStaticPart, thisJoinPoint and thisEnclosingJoinPointStaticPart
+ */
+
+public class AccessForInlineVisitor extends AbstractSyntaxTreeVisitorAdapter {
+       PrivilegedHandler handler;
+       EclipseWorld world;
+       public AccessForInlineVisitor(EclipseWorld world, PrivilegedHandler handler) {
+               this.world = world;
+               this.handler = handler;
+       }
+       
+       public void endVisit(SingleNameReference ref, BlockScope scope) {
+               if (ref.binding instanceof FieldBinding) {
+                       FieldBinding fieldBinding = (FieldBinding)ref.binding;
+                       makePublic(fieldBinding.declaringClass);
+                       if (isPublic(fieldBinding)) return;
+                       ref.binding = handler.getPrivilegedAccessField(fieldBinding);
+               }
+       }
+
+       public void endVisit(QualifiedNameReference ref, BlockScope scope) {
+               if (ref.binding instanceof FieldBinding) {
+                       FieldBinding fieldBinding = (FieldBinding)ref.binding;
+                       makePublic(fieldBinding.declaringClass);
+                       if (isPublic(fieldBinding)) return;
+                       ref.binding = handler.getPrivilegedAccessField(fieldBinding);
+               }
+       }
+
+       public void endVisit(FieldReference ref, BlockScope scope) {
+               if (ref.binding instanceof FieldBinding) {
+                       FieldBinding fieldBinding = (FieldBinding)ref.binding;
+                       makePublic(fieldBinding.declaringClass);
+                       if (isPublic(fieldBinding)) return;
+                       ref.binding = handler.getPrivilegedAccessField(fieldBinding);
+               }
+       }
+       public void endVisit(MessageSend send, BlockScope scope) {
+               if (send instanceof Proceed) return;
+               if (send.binding == null) return;
+               if (isPublic(send.binding)) return;
+               makePublic(send.binding.declaringClass);
+               send.binding = send.codegenBinding = handler.getPrivilegedAccessMethod(send.binding);
+       }
+       public void endVisit(AllocationExpression send, BlockScope scope) {
+               if (send.binding == null) return;
+               if (isPublic(send.binding)) return;
+               makePublic(send.binding.declaringClass);
+               send.binding = handler.getPrivilegedAccessMethod(send.binding);
+       }       
+       public void endVisit(
+               QualifiedTypeReference ref,
+               BlockScope scope)
+       {
+               makePublic(ref.binding);
+       }
+       
+       public void endVisit(
+               SingleTypeReference ref,
+               BlockScope scope)
+       {
+               makePublic(ref.binding);
+       }
+       
+       private boolean isPublic(FieldBinding fieldBinding) {
+               // these are always effectively public to the inliner
+               if (fieldBinding instanceof InterTypeFieldBinding) return true;
+               return fieldBinding.isPublic();
+       }
+
+       private boolean isPublic(MethodBinding methodBinding) {
+               // these are always effectively public to the inliner
+               if (methodBinding instanceof InterTypeMethodBinding) return true;
+               return methodBinding.isPublic();
+       }
+
+       private void makePublic(TypeBinding binding) {
+               if (binding instanceof ReferenceBinding) {
+                       ReferenceBinding rb = (ReferenceBinding)binding;
+                       if (!rb.isPublic()) handler.notePrivilegedTypeAccess(rb);
+               } else if (binding instanceof ArrayBinding) {
+                       makePublic( ((ArrayBinding)binding).leafComponentType );
+               } else {
+                       return;
+               }
+       }
+}
index 15e28461f78100f1232cc621de9458940ec0fbf8..9b783cb117da8a2784388b008f7107205930652f 100644 (file)
@@ -47,6 +47,8 @@ public class AdviceDeclaration extends MethodDeclaration {
        
        public MethodBinding proceedMethodBinding;
        
+       
+       public List proceedCalls = new ArrayList(2);
        public boolean proceedInInners;
        public ResolvedMember[] proceedCallSignatures;
        public boolean[] formalsUnchangedToProceed;
@@ -98,15 +100,9 @@ public class AdviceDeclaration extends MethodDeclaration {
                pointcutDesignator.finishResolveTypes(this, this.binding, 
                        baseArgumentCount, upperScope.referenceContext.binding);
                
+               if (binding == null || ignoreFurtherInvestigation) return;
                
-               if (kind == AdviceKind.Around && binding != null) {
-                       //XXX set these correctly
-                       proceedInInners = false;
-                       proceedCallSignatures = new ResolvedMember[0];
-                       formalsUnchangedToProceed = new boolean[baseArgumentCount];
-                       declaredExceptions = new TypeX[0];
-                       
-                       
+               if (kind == AdviceKind.Around) {
                        ReferenceBinding[] exceptions = 
                                new ReferenceBinding[] { upperScope.getJavaLangThrowable() };
                        proceedMethodBinding = new MethodBinding(Modifier.STATIC,
@@ -119,6 +115,44 @@ public class AdviceDeclaration extends MethodDeclaration {
                
                super.resolveStatements(upperScope);
                if (binding != null) determineExtraArgumentFlags();
+               
+               if (kind == AdviceKind.Around) {
+                       int n = proceedCalls.size();
+                       EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(upperScope);
+                                               
+                       //System.err.println("access to: " + Arrays.asList(handler.getMembers()));
+                       
+                       //XXX set these correctly
+                       formalsUnchangedToProceed = new boolean[baseArgumentCount];
+                       proceedCallSignatures = new ResolvedMember[0];
+                       proceedInInners = false;
+                       declaredExceptions = new TypeX[0];
+                       
+                       for (int i=0; i < n; i++) {
+                               Proceed call = (Proceed)proceedCalls.get(i);
+                               if (call.inInner) {
+                                       //System.err.println("proceed in inner: " + call);
+                                       proceedInInners = true;
+                                       //XXX wrong
+                                       //proceedCallSignatures[i] = world.makeResolvedMember(call.binding);
+                               }
+                       }
+                       
+                       // if we have proceed in inners we won't ever be inlined so the code below is unneeded
+                       if (!proceedInInners) {
+                               PrivilegedHandler handler = (PrivilegedHandler)upperScope.referenceContext.binding.privilegedHandler;
+                               //XXX timings is odd here
+                               if (handler == null) {
+                                       handler = new PrivilegedHandler((AspectDeclaration)upperScope.referenceContext);
+                                       upperScope.referenceContext.binding.privilegedHandler = handler;
+                               }
+                               
+                               this.traverse(new MakeDeclsPublicVisitor(), (ClassScope)null);
+                               
+                               AccessForInlineVisitor v = new AccessForInlineVisitor(world, handler);
+                               this.traverse(v, (ClassScope) null);
+                       }
+               }
        }
 
 
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/MakeDeclsPublicVisitor.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/MakeDeclsPublicVisitor.java
new file mode 100644 (file)
index 0000000..84ed18b
--- /dev/null
@@ -0,0 +1,57 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import java.util.Arrays;
+
+import org.aspectj.ajdt.internal.compiler.lookup.*;
+import org.aspectj.ajdt.internal.compiler.lookup.PrivilegedHandler;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.ShadowMunger;
+import org.eclipse.jdt.internal.compiler.AbstractSyntaxTreeVisitorAdapter;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+/**
+ * Takes a method that already has the three extra parameters
+ * thisJoinPointStaticPart, thisJoinPoint and thisEnclosingJoinPointStaticPart
+ */
+
+public class MakeDeclsPublicVisitor extends AbstractSyntaxTreeVisitorAdapter {
+       
+       public void endVisit(
+               AnonymousLocalTypeDeclaration decl,
+               BlockScope scope) {
+               decl.binding.modifiers = AstUtil.makePublic(decl.binding.modifiers);
+       }
+       
+       public void endVisit(LocalTypeDeclaration decl, BlockScope scope) {
+               decl.binding.modifiers = AstUtil.makePublic(decl.binding.modifiers);
+       }
+
+
+       public void endVisit(ConstructorDeclaration decl, ClassScope scope) {
+               decl.binding.modifiers = AstUtil.makePublic(decl.binding.modifiers);
+       }
+
+       public void endVisit(FieldDeclaration decl, MethodScope scope) {
+               decl.binding.modifiers = AstUtil.makePublic(decl.binding.modifiers);
+       }
+
+
+       public void endVisit(MethodDeclaration decl, ClassScope scope) {
+               decl.binding.modifiers = AstUtil.makePublic(decl.binding.modifiers);
+       }
+
+}
index 541184931b0a09e4b778ac7dd07c6166f7a86110..5cb328da5a3599855afb60bb22e81505f451ce89 100644 (file)
@@ -22,6 +22,8 @@ import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
 
 
 public class Proceed extends MessageSend {
+       public boolean inInner = false;
+       
        public Proceed(MessageSend parent) {
                super();
                
@@ -108,11 +110,14 @@ public class Proceed extends MessageSend {
                        if (context instanceof AdviceDeclaration) {
                                AdviceDeclaration adviceDecl = (AdviceDeclaration)context;
                                if (adviceDecl.kind == AdviceKind.Around) {
+                                       adviceDecl.proceedCalls.add(this);
                                        return adviceDecl;
                                } else {
                                        return null;
                                }
                        }
+               } else if (scope instanceof ClassScope) {
+                       inInner = true;
                }
                
                return findEnclosingAround(scope.parent);
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/ProceedVisitor.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/ProceedVisitor.java
new file mode 100644 (file)
index 0000000..355ed09
--- /dev/null
@@ -0,0 +1,224 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Xerox/PARC     initial implementation 
+ * ******************************************************************/
+
+
+package org.aspectj.ajdt.internal.compiler.ast;
+
+import java.util.Arrays;
+
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.ShadowMunger;
+import org.eclipse.jdt.internal.compiler.AbstractSyntaxTreeVisitorAdapter;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+/**
+ * Takes a method that already has the three extra parameters
+ * thisJoinPointStaticPart, thisJoinPoint and thisEnclosingJoinPointStaticPart
+ */
+
+public class ProceedVisitor extends AbstractSyntaxTreeVisitorAdapter {
+       boolean needsDynamic = false;
+       boolean needsStatic = false;
+       boolean needsStaticEnclosing = false;
+       boolean hasEffectivelyStaticRef = false;
+
+       LocalVariableBinding thisJoinPointDec;
+       LocalVariableBinding thisJoinPointStaticPartDec;
+       LocalVariableBinding thisEnclosingJoinPointStaticPartDec;
+       
+       LocalVariableBinding thisJoinPointDecLocal;
+       LocalVariableBinding thisJoinPointStaticPartDecLocal;
+       LocalVariableBinding thisEnclosingJoinPointStaticPartDecLocal;
+
+       boolean replaceEffectivelyStaticRefs = false;
+       
+       AbstractMethodDeclaration method;
+
+       ProceedVisitor(AbstractMethodDeclaration method) {
+               this.method = method;
+               int index = method.arguments.length - 3;
+               
+               thisJoinPointStaticPartDecLocal = method.scope.locals[index];
+               thisJoinPointStaticPartDec = method.arguments[index++].binding;
+               thisJoinPointDecLocal = method.scope.locals[index];
+               thisJoinPointDec = method.arguments[index++].binding;
+               thisEnclosingJoinPointStaticPartDecLocal = method.scope.locals[index];
+               thisEnclosingJoinPointStaticPartDec = method.arguments[index++].binding;
+       }
+
+       public void computeJoinPointParams() {
+               // walk my body to see what is needed
+               method.traverse(this, (ClassScope) null);
+
+               //??? add support for option to disable this optimization
+               //System.err.println("check:  "+ hasEffectivelyStaticRef + ", " + needsDynamic);
+               if (hasEffectivelyStaticRef && !needsDynamic) {
+                       // replace effectively static refs with thisJoinPointStaticPart
+                       replaceEffectivelyStaticRefs = true;
+                       needsStatic = true;
+                       method.traverse(this, (ClassScope) null);
+               }
+       }
+
+       boolean isRef(NameReference ref, Binding binding) {
+               return ref.binding == binding;
+       }
+
+       boolean isRef(Expression expr, Binding binding) {
+               //System.err.println("isRef: " + expr + ", " + binding);
+               return expr != null
+                       && expr instanceof NameReference
+                       && isRef((NameReference) expr, binding);
+       }
+
+       public void endVisit(SingleNameReference ref, BlockScope scope) {
+               if (isRef(ref, thisJoinPointDec))
+                       needsDynamic = true;
+               else if (isRef(ref, thisJoinPointStaticPartDec))
+                       needsStatic = true;
+               else if (isRef(ref, thisEnclosingJoinPointStaticPartDec))
+                       needsStaticEnclosing = true;
+       }
+
+       //        public void checkAndFix(ASTObject body) {
+       //            this.process(body);
+       //            if (needsFakeStatic && !needsDynamic) {
+       //                if (!this.getCompiler().getOptions().noMetaJoinPointOptimization) {
+       //                    makeFakeStatics = true;
+       //                    needsStatic = true;
+       //                    this.process(body);
+       //                } else {
+       //                    needsDynamic = true;
+       //                }
+       //            }
+       //        }
+
+       boolean canTreatAsStatic(String id) {
+               return id.equals("toString")
+                       || id.equals("toShortString")
+                       || id.equals("toLongString")
+                       || id.equals("getKind")
+                       || id.equals("getSignature")
+                       || id.equals("getSourceLocation")
+                       || id.equals("getStaticPart");
+       }
+
+       //        boolean canTreatAsStatic(VarExpr varExpr) {
+       //            ASTObject parent = varExpr.getParent();
+       //            if (parent instanceof CallExpr) {
+       //                Method calledMethod = ((CallExpr)parent).getMethod();
+       //                return canTreatAsStatic(calledMethod);
+       //
+       //                //??? should add a case here to catch
+       //                //??? tjp.getEnclosingExecutionJoinPoint().STATIC_METHOD()
+       //            } else if (parent instanceof BinopExpr) {
+       //                BinopExpr binop = (BinopExpr)parent;
+       //                if (binop.getType().isEquivalent(this.getTypeManager().getStringType())) {
+       //                    return true;
+       //                } else {
+       //                    return false;
+       //                }
+       //            } else {
+       //                return false;
+       //            }
+       //        }
+
+       boolean inBlockThatCantRun = false;
+
+       public boolean visit(MessageSend call, BlockScope scope) {
+               Expression receiver = call.receiver;
+               if (isRef(receiver, thisJoinPointDec)) {
+                       if (canTreatAsStatic(new String(call.selector))) {
+                               if (replaceEffectivelyStaticRefs) {
+                                       replaceEffectivelyStaticRef(call);
+                               } else {
+                                       //System.err.println("has static reg");
+                                       hasEffectivelyStaticRef = true;
+                                       if (call.arguments != null) {
+                                               int argumentsLength = call.arguments.length;
+                                               for (int i = 0; i < argumentsLength; i++)
+                                                       call.arguments[i].traverse(this, scope);
+                                       }
+                                       return false;
+                               }
+                       }
+               }
+
+               return super.visit(call, scope);
+       }
+
+       private void replaceEffectivelyStaticRef(MessageSend call) {
+               //System.err.println("replace static ref");
+               NameReference receiver = (NameReference) call.receiver;
+               receiver.binding = thisJoinPointStaticPartDecLocal; //thisJoinPointStaticPartDec;
+               receiver.codegenBinding = thisJoinPointStaticPartDecLocal;
+
+               call.binding.declaringClass =
+                       (ReferenceBinding) thisJoinPointStaticPartDec.type;
+       }
+
+       public int removeUnusedExtraArguments() {
+               int extraArgumentFlags = 0;
+               
+               this.computeJoinPointParams();
+               MethodBinding binding = method.binding;
+               
+               
+               int index = binding.parameters.length - 3;
+               if (needsStaticEnclosing) {
+                       extraArgumentFlags |= Advice.ThisEnclosingJoinPointStaticPart;
+               } else {
+                       removeParameter(index+2);
+               }
+               
+               if (needsDynamic) {
+                       extraArgumentFlags |= Advice.ThisJoinPoint;
+               } else {
+                       removeParameter(index+1);
+               }
+               
+               if (needsStatic) {
+                       extraArgumentFlags |= Advice.ThisJoinPointStaticPart;
+               } else {
+                       removeParameter(index+0);
+               }
+               
+               return extraArgumentFlags;
+       }
+
+       private void removeParameter(int indexToRemove) {
+               TypeBinding[] parameters = method.binding.parameters;
+               method.scope.locals = removeLocalBinding(indexToRemove, method.scope.locals);
+               method.binding.parameters = removeParameter(indexToRemove, method.binding.parameters);
+       }
+
+       
+       private static TypeBinding[] removeParameter(int index, TypeBinding[] bindings) {
+               int len = bindings.length;
+               TypeBinding[] ret = new TypeBinding[len-1];
+               System.arraycopy(bindings, 0, ret, 0, index);
+               System.arraycopy(bindings, index+1, ret, index, len-index-1);
+               return ret;
+       }
+
+       private static LocalVariableBinding[] removeLocalBinding(int index, LocalVariableBinding[] bindings) {
+               int len = bindings.length;
+               //??? for performance we should do this in-place
+               LocalVariableBinding[] ret = new LocalVariableBinding[len-1];
+               System.arraycopy(bindings, 0, ret, 0, index);
+               System.arraycopy(bindings, index+1, ret, index, len-index-1);
+               return ret;
+       }
+
+
+}
index 8a43cfa33b59bbdeea1cd5b63220844da7b696d1..93e0ebad93ce9f8188081626435b494f12c34ce5 100644 (file)
@@ -40,6 +40,7 @@ public class AjBuildConfig {
        private boolean emacsSymMode = false;
        private boolean noWeave = false;
        private boolean XserializableAspects = false;
+       private boolean XnoInline = false;
        private String lintMode = AJLINT_DEFAULT;
        private File lintSpecFile = null;
 
@@ -202,4 +203,12 @@ public class AjBuildConfig {
                XserializableAspects = xserializableAspects;
        }
 
+       public boolean isXnoInline() {
+               return XnoInline;
+       }
+
+       public void setXnoInline(boolean xnoInline) {
+               XnoInline = xnoInline;
+       }
+
 }
index 6fa941d8273dcdbe68b934f6689e6f6d86c112d2..a5f19ca94c1534385898d545c5ae1aff79564a61 100644 (file)
@@ -239,6 +239,7 @@ public class AjBuildManager {
                
        private void initBcelWorld(IMessageHandler handler) throws IOException {
                bcelWorld = new BcelWorld(buildConfig.getClasspath(), handler);
+               bcelWorld.setXnoInline(buildConfig.isXnoInline());
                bcelWeaver = new BcelWeaver(bcelWorld);
                
                for (Iterator i = buildConfig.getAspectpath().iterator(); i.hasNext();) {
@@ -504,6 +505,7 @@ public class AjBuildManager {
                                                                        pr, nameEnvironment);
                EclipseWorld ew = new EclipseWorld(le, handler);
                ew.setLint(bcelWorld.getLint());
+               ew.setXnoInline(buildConfig.isXnoInline());
                le.world = ew;
                pr.world = ew;
                le.world.buildManager = this;
index f2273f1b316c7d38ca2c510e3b6b259754b3b718..f1c1b67f8cf68496f2b3dcde8ee913a6a123b06f 100644 (file)
@@ -21,8 +21,8 @@ import org.aspectj.testing.util.TestUtil;
 public class WorkingTestMain {
 
        public static void main(String[] args1) throws IOException {
-               testExamples();
-               //testOne();
+               //testExamples();
+               testOne();
        }
        
        public static void testOne() throws IOException {
@@ -50,7 +50,8 @@ public class WorkingTestMain {
                //args.add("../weaver/testdata/megatrace.jar");
                
                args.add("testdata/src1/AroundA1.java");
-               //args.add("../tests/new/AroundInnerCalls.java");
+               args.add("-XnoInline");
+               //args.add("../tests/new/Counting1.java");
                //args.add("-Xlint:error");
                //args.add("testdata/src1/InterType.java");
                //args.add("@" + examplesDir + "tjp/files.lst");
@@ -59,12 +60,11 @@ public class WorkingTestMain {
                CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS);
                //CommandTestCase.runCompiler(args, new int[] {11, 14, 18, 32, 43});
                
-//             CommandTestCase.printGenerated("../out", "AdviceOnInheritedMethod");
+               CommandTestCase.printGenerated("../out", "AroundA1");
 //             CommandTestCase.printGenerated("../out", "SuperC");
 //             CommandTestCase.printGenerated("../out", "SubC");
 
-               //TestUtil.runMain("out;../bcweaver/testdata/megatrace.jar", "Privileged");
-               //TestUtil.runMain("out;../lib/test/testing-client.jar", "AroundInnerCalls");
+               TestUtil.runMain("out;../lib/test/testing-client.jar", "AroundA1");
        }
        
        private static String examplesDir = "../docs/dist/doc/examples/";
index b6714333ff04aa53296d98f754232dce5e421d47..cb6a4d5bc80579d3270c80a238edf2256f3681f0 100644 (file)
@@ -21,7 +21,7 @@ import org.aspectj.weaver.patterns.*;
 
 public abstract class Advice extends ShadowMunger {
 
-       AjAttribute.AdviceAttribute attribute; // the pointcut field is ignored
+       protected AjAttribute.AdviceAttribute attribute; // the pointcut field is ignored
 
     protected AdviceKind kind; // alias of attribute.getKind()
     protected Member signature;
index 9f55b28e9a2627c44da9fba7e08ad201da3191b2..3102bd24f6cd80cfadf7fa6d7f29443f39871eb4 100644 (file)
@@ -27,6 +27,10 @@ public abstract class ConcreteTypeMunger implements PartialOrder.PartialComparab
 
        //public abstract boolean munge(LazyClassGen gen);
 
+
+       /** returns null for mungers that are used internally, but were not part of a declared
+        * thing in source code.
+        */
        public ResolvedTypeMunger getMunger() {
                return munger;
        }
index e04c923cba72b2ddf6205878725e9b34c233b5c0..2b943ede1df327278f1b59a0a972ae0a1c007989 100644 (file)
@@ -45,7 +45,9 @@ public abstract class ResolvedTypeMunger {
     
     public boolean matches(ResolvedTypeX matchType) {
        ResolvedTypeX onType = matchType.getWorld().resolve(signature.getDeclaringType());
+       //System.err.println("matching: " + this + " to " + matchType + " onType = " + onType);
                if (matchType.equals(onType)) return true;
+               //System.err.println("NO MATCH DIRECT");
                
        if (onType.isInterface()) {
                return matchType.isTopmostImplementor(onType);
index a2c14f27a636e0ddc59823513a29cfb66933d980..e8a76d99a0f4b43b810fcd43780aac3a57a70d53 100644 (file)
@@ -33,7 +33,6 @@ public abstract class ResolvedTypeX extends TypeX {
 
     // ---- things that don't require a world
 
-
        /** returns Iterator&lt;ResolvedTypeX&gt;
         */
     public final Iterator getDirectSupertypes() {
@@ -808,7 +807,9 @@ public abstract class ResolvedTypeX extends TypeX {
        
        public void addInterTypeMunger(ConcreteTypeMunger munger) {
                ResolvedMember sig = munger.getSignature();
-               if (sig == null) {
+               if (sig == null || munger.getMunger() == null || 
+                               munger.getMunger().getKind() == ResolvedTypeMunger.PrivilegedAccess)
+               {
                        interTypeMungers.add(munger);
                        return;
                }
index 4ed8abb49222e38cd642dd538116e784a02c33f2..b1d150c6896f2231487574140ba419bcd31d9ebf 100644 (file)
@@ -31,6 +31,8 @@ public abstract class World {
     protected StructureModel model = null;
     
     protected Lint lint = new Lint(this);
+    
+    protected boolean XnoInline;
        
     protected World() {
         super();
@@ -337,4 +339,12 @@ public abstract class World {
                this.lint = lint;
        }
 
+       public boolean isXnoInline() {
+               return XnoInline;
+       }
+
+       public void setXnoInline(boolean xnoInline) {
+               XnoInline = xnoInline;
+       }
+
 }
index e27102cfaf24a7a085eb9053ff71150f41056fc7..77842f3cd161f11ecde590ff666a352e651d6a82 100644 (file)
@@ -85,6 +85,17 @@ public class BcelAdvice extends Advice {
         }
     }   
        
+    private boolean canInline(Shadow s) {
+       if (attribute.isProceedInInners()) return false;
+       //XXX this guard seems to only be needed for bad test cases
+       if (concreteAspect == null || concreteAspect == ResolvedTypeX.MISSING) return false;
+
+               if (concreteAspect.getWorld().isXnoInline()) return false;
+       //System.err.println("isWoven? " + ((BcelObjectType)concreteAspect).getLazyClassGen().getWeaverState());
+       return ((BcelObjectType)concreteAspect).getLazyClassGen().getWeaverState() 
+                       == WeaverStateKind.Woven;
+    }
+
     public void implementOn(Shadow s) {
         BcelShadow shadow = (BcelShadow) s;       
         if (getKind() == AdviceKind.Before) {
@@ -100,8 +111,11 @@ public class BcelAdvice extends Advice {
         } else if (getKind() == AdviceKind.After) {   
             shadow.weaveAfter(this);
         } else if (getKind() == AdviceKind.Around) {
-            shadow.weaveAroundClosure(this, hasDynamicTests());
-            //shadow.weaveAroundInline(this, hasDynamicTests());
+               if (!canInline(s)) {
+                       shadow.weaveAroundClosure(this, hasDynamicTests());
+               } else {
+               shadow.weaveAroundInline(this, hasDynamicTests());
+               }
         } else if (getKind() == AdviceKind.InterInitializer) {
                 shadow.weaveAfterReturning(this);
         } else if (getKind().isCflow()) {
index 8ceda85e38e15a6bf2b2668e0c849e4f615184cb..415098ba0fb7e090341d9384ed4241009974a805 100644 (file)
@@ -33,6 +33,7 @@ class BcelClassWeaver implements IClassWeaver {
                List typeMungers) 
        {
                boolean b =  new BcelClassWeaver(world, clazz, shadowMungers, typeMungers).weave();
+               //System.err.println(clazz.getClassName() + ", " + clazz.getWeaverState());
                //clazz.print();
                return b;
        }
index 9f4d8d28a9d0a8f9f7e9ea6529861bd96efa047c..6937d9bacdc5d799420faf6756e8ad8a55bcc12c 100644 (file)
@@ -1134,6 +1134,20 @@ public class BcelShadow extends Shadow {
                 * If only one call to proceed is made, we can re-inline the original shadow.
                 * We are not doing that presently.
                 */
+                
+               // !!! THIS BLOCK OF CODE SHOULD BE IN A METHOD CALLED weaveAround(...);
+        Member mungerSig = munger.getSignature();
+        ResolvedTypeX declaringType = world.resolve(mungerSig.getDeclaringType());
+        //??? might want some checks here to give better errors
+        BcelObjectType ot = (BcelObjectType)declaringType;
+        
+               LazyMethodGen adviceMethod = ot.getLazyClassGen().getLazyMethodGen(mungerSig);
+               if (!adviceMethod.getCanInline()) {
+                       weaveAroundClosure(munger, hasDynamicTest);
+                       return;
+               }
+               
+               
                
                // start by exposing various useful things into the frame
                final InstructionFactory fact = getFactory();
@@ -1174,22 +1188,22 @@ public class BcelShadow extends Shadow {
         if (! hasDynamicTest) {
             range.append(advice);
         } else {
+               InstructionList afterThingie = new InstructionList(fact.NOP);
             InstructionList callback = makeCallToCallback(extractedMethod);
             if (terminatesWithReturn()) {
                 callback.append(fact.createReturn(extractedMethod.getReturnType()));
             } else {
-                advice.append(fact.createBranchInstruction(Constants.GOTO, range.getEnd()));
+               //InstructionHandle endNop = range.insert(fact.NOP, Range.InsideAfter);
+                advice.append(fact.createBranchInstruction(Constants.GOTO, afterThingie.getStart()));
             }
             range.append(munger.getTestInstructions(this, advice.getStart(), callback.getStart(), advice.getStart()));
             range.append(advice);
-            range.append(callback);          
+            range.append(callback);
+            range.append(afterThingie);          
         }        
         
         // now the range contains everything we need.  We now inline the advice method.
-               LazyMethodGen adviceMethod =
-                       ((BcelObjectType) munger.getConcreteAspect())
-                               .getLazyClassGen()
-                               .getLazyMethodGen(munger.getSignature());
+
                                
         BcelClassWeaver.inlineMethod(adviceMethod, enclosingMethod, adviceMethodInvocation);
 
@@ -1296,6 +1310,8 @@ public class BcelShadow extends Shadow {
     {
        InstructionFactory fact = getFactory();
 
+               enclosingMethod.setCanInline(false);
+
         // MOVE OUT ALL THE INSTRUCTIONS IN MY SHADOW INTO ANOTHER METHOD!
         LazyMethodGen callbackMethod = 
                extractMethod(
index 6b6987e163f416d07c84505f939ad3025c03baba..97d8a09a476a64d661bc6cb4d09ebdc9de45d71b 100644 (file)
@@ -156,7 +156,7 @@ public class BcelWorld extends World {
     }       
 
     // ---- fluf
-       public  ResolvedTypeX resolveObjectType(TypeX ty) {
+       protected ResolvedTypeX resolveObjectType(TypeX ty) {
         String name = ty.getName();
         JavaClass jc = null;
         //UnwovenClassFile classFile = (UnwovenClassFile)sourceJavaClasses.get(name);
index 110ec064d97f557bff38faa0c286ef3b2a5ce998..e4135cbcba70658e9e310ad3d5d0f8f6a522c903 100644 (file)
@@ -295,6 +295,7 @@ public final class LazyClassGen {
                myGen.addAttribute(BcelAttributes.bcelAttribute(
                        new AjAttribute.WeaverState(s), 
                        getConstantPoolGen()));
+               myType.setWeaverState(s);
        }
 
     public InstructionFactory getFactory() {
@@ -484,6 +485,7 @@ public final class LazyClassGen {
                        if (gen.getName().equals(name) && gen.getSignature().equals(signature))
                                return gen;
                }
+               
                throw new BCException("Class " + this.getName() + " does not have a method "    
                        + name + " with signature " + signature);
        }
index 326f5426b51f582ffc47179706dfc63a531d32f0..5a6afccae995adfdb3bf71bf21678ddc7ee8b4ff 100644 (file)
@@ -51,6 +51,8 @@ public final class LazyMethodGen {
 
     private int             maxLocals; 
     
+    private boolean canInline = true;
+    
     /**
      * only used by {@link BcelClassWeaver}
      */
@@ -434,7 +436,9 @@ public final class LazyMethodGen {
         String getRangeString(Range r, Map labelMap) {
             if (r instanceof ExceptionRange) {
                 ExceptionRange er = (ExceptionRange) r;
-                return er.toString() + " -> " + labelMap.get(er.getHandler());
+                return er.toString() + " -> " + labelMap.get(er.getHandler()); 
+//                
+//                + " PRI " + er.getPriority();
             } else {
                 return r.toString();
             }
@@ -813,7 +817,11 @@ public final class LazyMethodGen {
         }
     }
 
-    // exception ordering
+    // exception ordering.
+    // What we should be doing is dealing with priority inversions way earlier than we are
+    // and counting on the tree structure.  In which case, the below code is in fact right.
+    
+    // XXX THIS COMMENT BELOW IS CURRENTLY WRONG. 
     // An exception A preceeds an exception B in the exception table iff:
     
     // * A and B were in the original method, and A preceeded B in the original exception table
@@ -824,15 +832,15 @@ public final class LazyMethodGen {
     // but I don't trust the only implementation, TreeSet, to do the right thing.
     
     private static void insertHandler(ExceptionRange fresh, LinkedList l) {
-        for (ListIterator iter = l.listIterator(); iter.hasNext();) {
-            ExceptionRange r = (ExceptionRange) iter.next();
-            if (fresh.getPriority() >= r.getPriority()) {
-                iter.previous();
-                iter.add(fresh);
-                return;
-            }            
-        }
-        l.add(fresh);        
+//        for (ListIterator iter = l.listIterator(); iter.hasNext();) {
+//            ExceptionRange r = (ExceptionRange) iter.next();
+//            if (fresh.getPriority() >= r.getPriority()) {
+//                iter.previous();
+//                iter.add(fresh);
+//                return;
+//            }            
+//        }
+        l.add(0, fresh);        
     }    
 
 
@@ -1064,4 +1072,12 @@ public final class LazyMethodGen {
                accessFlags = Utility.makePublic(accessFlags);
        }
 
+       public boolean getCanInline() {
+               return canInline;
+       }
+
+       public void setCanInline(boolean canInline) {
+               this.canInline = canInline;
+       }
+
 }
index 16b04e4b1d6228d0adc52d6e864bbb3a14cf70ab..b693040afb1f812fb70edbd8a90a7941fd28ce86 100644 (file)
@@ -19,11 +19,11 @@ public abstract class FancyHelloWorld extends java.lang.Object:
     method-execution(void FancyHelloWorld.main(java.lang.String[]))
     | catch java.lang.Throwable -> E6
     | | field-get(java.io.PrintStream java.lang.System.out)
-    | | | catch java.lang.Throwable -> E3
+    | | | catch java.lang.Throwable -> E5
     | | | |         GETSTATIC java.lang.System.out Ljava/io/PrintStream;   (line 9)
-    | | | catch java.lang.Throwable -> E3
+    | | | catch java.lang.Throwable -> E5
     | | |           GOTO L0
-    | | |       E3: ASTORE 5
+    | | |       E5: ASTORE 5
     | | |           INVOKESTATIC Aspect.ajc_after_field_get ()V
     | | |           ALOAD 5
     | | |           ATHROW
@@ -32,8 +32,8 @@ public abstract class FancyHelloWorld extends java.lang.Object:
     | | |           NOP
     | | field-get(java.io.PrintStream java.lang.System.out)
     | |             ASTORE_1
-    | | finally -> E5
-    | | | catch java.lang.Exception -> E4
+    | | finally -> E4
+    | | | catch java.lang.Exception -> E3
     | | | |         ALOAD_1     // java.io.PrintStream out   (line 11)
     | | | |         LDC "bye"
     | | | | method-call(void java.io.PrintStream.println(java.lang.String))
@@ -50,8 +50,8 @@ public abstract class FancyHelloWorld extends java.lang.Object:
     | | | | |       NOP
     | | | | method-call(void java.io.PrintStream.println(java.lang.String))
     | | | |         GOTO L3
-    | | | catch java.lang.Exception -> E4
-    | | |       E4: ASTORE_2   (line 12)
+    | | | catch java.lang.Exception -> E3
+    | | |       E3: ASTORE_2   (line 12)
     | | |           ALOAD_1     // java.io.PrintStream out   (line 13)
     | | |           ALOAD_2     // java.lang.Exception e
     | | | method-call(void java.io.PrintStream.println(java.lang.Object))
@@ -67,9 +67,9 @@ public abstract class FancyHelloWorld extends java.lang.Object:
     | | | |         INVOKESTATIC Aspect.ajc_after_method_call ()V
     | | | |         NOP
     | | | method-call(void java.io.PrintStream.println(java.lang.Object))
-    | | finally -> E5
+    | | finally -> E4
     | |             GOTO L3
-    | |         E5: ASTORE 4   (line 14)
+    | |         E4: ASTORE 4   (line 14)
     | |             JSR L4
     | |             ALOAD 4
     | |             ATHROW
@@ -180,4 +180,5 @@ public abstract class FancyHelloWorld extends java.lang.Object:
     |               ARETURN
     method-execution(java.lang.String FancyHelloWorld.getName())
   end public static String getName()
+
 end public abstract class FancyHelloWorld
index ed9e89bfdd75be6aa35f725094ab447bcd7f5add..3323beea64055f0ea7de107d21d686399b296ea7 100644 (file)
@@ -17,19 +17,19 @@ public abstract class FancyHelloWorld extends java.lang.Object:
     method-execution(void FancyHelloWorld.main(java.lang.String[]))
     | catch java.lang.Throwable -> E6
     | | field-get(java.io.PrintStream java.lang.System.out)
-    | | | catch java.lang.Throwable -> E3
+    | | | catch java.lang.Throwable -> E5
     | | | |         GETSTATIC java.lang.System.out Ljava/io/PrintStream;   (line 9)
-    | | | catch java.lang.Throwable -> E3
+    | | | catch java.lang.Throwable -> E5
     | | |           GOTO L0
-    | | |       E3: ASTORE 5
+    | | |       E5: ASTORE 5
     | | |           INVOKESTATIC Aspect.ajc_afterThrowing_field_get ()V
     | | |           ALOAD 5
     | | |           ATHROW
     | | |       L0: NOP
     | | field-get(java.io.PrintStream java.lang.System.out)
     | |             ASTORE_1
-    | | finally -> E5
-    | | | catch java.lang.Exception -> E4
+    | | finally -> E4
+    | | | catch java.lang.Exception -> E3
     | | | |         ALOAD_1     // java.io.PrintStream out   (line 11)
     | | | |         LDC "bye"
     | | | | method-call(void java.io.PrintStream.println(java.lang.String))
@@ -44,8 +44,8 @@ public abstract class FancyHelloWorld extends java.lang.Object:
     | | | | |   L1: NOP
     | | | | method-call(void java.io.PrintStream.println(java.lang.String))
     | | | |         GOTO L3
-    | | | catch java.lang.Exception -> E4
-    | | |       E4: ASTORE_2   (line 12)
+    | | | catch java.lang.Exception -> E3
+    | | |       E3: ASTORE_2   (line 12)
     | | |           ALOAD_1     // java.io.PrintStream out   (line 13)
     | | |           ALOAD_2     // java.lang.Exception e
     | | | method-call(void java.io.PrintStream.println(java.lang.Object))
@@ -59,9 +59,9 @@ public abstract class FancyHelloWorld extends java.lang.Object:
     | | | |         ATHROW
     | | | |     L2: NOP
     | | | method-call(void java.io.PrintStream.println(java.lang.Object))
-    | | finally -> E5
+    | | finally -> E4
     | |             GOTO L3
-    | |         E5: ASTORE 4   (line 14)
+    | |         E4: ASTORE 4   (line 14)
     | |             JSR L4
     | |             ALOAD 4
     | |             ATHROW
@@ -158,4 +158,5 @@ public abstract class FancyHelloWorld extends java.lang.Object:
     |               ATHROW
     method-execution(java.lang.String FancyHelloWorld.getName())
   end public static String getName()
+
 end public abstract class FancyHelloWorld
index 351d3564934baad601655270756db01dbaa92030..0e995aaff7eeb844e32e9321b0fe2b686e75b85c 100644 (file)
@@ -10,11 +10,11 @@ public abstract class FancyHelloWorld extends java.lang.Object:
   public static void main(String[]):
     method-execution(void FancyHelloWorld.main(java.lang.String[]))
     | field-get(java.io.PrintStream java.lang.System.out)
-    | | catch java.lang.Throwable -> E0
+    | | catch java.lang.Throwable -> E2
     | | |           GETSTATIC java.lang.System.out Ljava/io/PrintStream;   (line 9)
-    | | catch java.lang.Throwable -> E0
+    | | catch java.lang.Throwable -> E2
     | |             GOTO L0
-    | |         E0: ASTORE 5
+    | |         E2: ASTORE 5
     | |             ALOAD 5
     | |             INVOKESTATIC Aspect.ajc_afterThrowing_field_get (Ljava/lang/Throwable;)V
     | |             ALOAD 5
@@ -22,24 +22,24 @@ public abstract class FancyHelloWorld extends java.lang.Object:
     | |         L0: NOP
     | field-get(java.io.PrintStream java.lang.System.out)
     |               ASTORE_1
-    | finally -> E2
-    | | catch java.lang.Exception -> E1
+    | finally -> E1
+    | | catch java.lang.Exception -> E0
     | | |           ALOAD_1     // java.io.PrintStream out   (line 11)
     | | |           LDC "bye"
     | | | method-call(void java.io.PrintStream.println(java.lang.String))
     | | | |         INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V
     | | | method-call(void java.io.PrintStream.println(java.lang.String))
     | | |           GOTO L1
-    | | catch java.lang.Exception -> E1
-    | |         E1: ASTORE_2   (line 12)
+    | | catch java.lang.Exception -> E0
+    | |         E0: ASTORE_2   (line 12)
     | |             ALOAD_1     // java.io.PrintStream out   (line 13)
     | |             ALOAD_2     // java.lang.Exception e
     | | method-call(void java.io.PrintStream.println(java.lang.Object))
     | | |           INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/Object;)V
     | | method-call(void java.io.PrintStream.println(java.lang.Object))
-    | finally -> E2
+    | finally -> E1
     |               GOTO L1
-    |           E2: ASTORE 4   (line 14)
+    |           E1: ASTORE 4   (line 14)
     |               JSR L2
     |               ALOAD 4
     |               ATHROW
@@ -83,4 +83,5 @@ public abstract class FancyHelloWorld extends java.lang.Object:
     |               ARETURN
     method-execution(java.lang.String FancyHelloWorld.getName())
   end public static String getName()
+
 end public abstract class FancyHelloWorld
index 6d96a90259a39dd4b374377695e99ed211785069..19fa930a59337f6f92d2394cac49088207d70a3c 100644 (file)
@@ -66,33 +66,46 @@ public class DynamicHelloWorld extends java.lang.Object implements java.io.Seria
     |               ALOAD_0
     |               INVOKEVIRTUAL Trace.ajc$before$Trace$51 (Ljava/lang/Object;)V
     |               INVOKESTATIC MyTrace.aspectOf ()LMyTrace;
-    |               BIPUSH 3
-    |               ANEWARRAY java.lang.Object
-    |               ASTORE 6
-    |               ALOAD 6
-    |               BIPUSH 0
+    |               ACONST_NULL
+    |               ASTORE 13
+    |               ASTORE 12
+    |               LDC "Hi"   (line 9)
+    |               ASTORE 14
+    |               GETSTATIC java.lang.System.out Ljava/io/PrintStream;   (line 10)
+    |               NEW java.lang.StringBuffer
+    |               DUP
+    |               LDC "start around: "
+    |               INVOKESPECIAL java.lang.StringBuffer.<init> (Ljava/lang/String;)V
+    |               ALOAD 14
+    |               INVOKEVIRTUAL java.lang.StringBuffer.append (Ljava/lang/Object;)Ljava/lang/StringBuffer;
+    |               INVOKEVIRTUAL java.lang.StringBuffer.toString ()Ljava/lang/String;
+    |               INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V
+    |               ALOAD 13   (line 11)
+    |               ASTORE 18
     |               ALOAD_0
-    |               AASTORE
-    |               ALOAD 6
-    |               BIPUSH 1
     |               ALOAD_3
-    |               AASTORE
-    |               ALOAD 6
-    |               BIPUSH 2
     |               ALOAD 4
-    |               AASTORE
-    |               NEW DynamicHelloWorld$AjcClosure3
+    |               INVOKESTATIC DynamicHelloWorld.doit_aroundBody1 (LDynamicHelloWorld;Ljava/lang/String;Ljava/util/List;)Ljava/lang/String;
+    |               ASTORE 16
+    |               GETSTATIC java.lang.System.out Ljava/io/PrintStream;   (line 12)
+    |               NEW java.lang.StringBuffer
     |               DUP
-    |               ALOAD 6
-    |               INVOKESPECIAL DynamicHelloWorld$AjcClosure3.<init> ([Ljava/lang/Object;)V
-    |               INVOKEVIRTUAL Trace.ajc$around$Trace$cc (Lorg/aspectj/runtime/internal/AroundClosure;)Ljava/lang/Object;
-    |               CHECKCAST java.lang.String
+    |               LDC "exiting around with: "
+    |               INVOKESPECIAL java.lang.StringBuffer.<init> (Ljava/lang/String;)V
+    |               ALOAD 16
+    |               INVOKEVIRTUAL java.lang.StringBuffer.append (Ljava/lang/Object;)Ljava/lang/StringBuffer;
+    |               INVOKEVIRTUAL java.lang.StringBuffer.toString ()Ljava/lang/String;
+    |               INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V
+    |               ALOAD 16   (line 13)
     |               GOTO L0
-    |           L0: DUP
-    |               ASTORE 7
+    |           L0: NOP
+    |               CHECKCAST java.lang.String
+    |               GOTO L1
+    |           L1: DUP
+    |               ASTORE 19
     |               INVOKESTATIC MyTrace.aspectOf ()LMyTrace;
     |               ALOAD_0
-    |               ALOAD 7
+    |               ALOAD 19
     |               INVOKEVIRTUAL MyTrace.ajc$afterReturning$MyTrace$6e (Ljava/lang/Object;Ljava/lang/Object;)V
     |               ARETURN
     method-execution(java.lang.String DynamicHelloWorld.doit(java.lang.String, java.util.List))
@@ -112,88 +125,45 @@ public class DynamicHelloWorld extends java.lang.Object implements java.io.Seria
                     ARETURN
   end static final String doit_aroundBody0(DynamicHelloWorld, String, java.util.List)
 
-  static final String doit_aroundBody2(DynamicHelloWorld, String, java.util.List):
+  static final String doit_aroundBody1(DynamicHelloWorld, String, java.util.List):
                     INVOKESTATIC MyTrace.aspectOf ()LMyTrace;
                     ALOAD_0
-                    BIPUSH 3
-                    ANEWARRAY java.lang.Object
+                    ACONST_NULL
                     ASTORE_3
-                    ALOAD_3
-                    BIPUSH 0
-                    ALOAD_0
-                    AASTORE
-                    ALOAD_3
-                    BIPUSH 1
-                    ALOAD_1
-                    AASTORE
-                    ALOAD_3
-                    BIPUSH 2
-                    ALOAD_2
-                    AASTORE
-                    NEW DynamicHelloWorld$AjcClosure1
+                    ASTORE 5
+                    ASTORE 7
+                    GETSTATIC java.lang.System.out Ljava/io/PrintStream;   (line 17)
+                    NEW java.lang.StringBuffer
                     DUP
+                    LDC "start around(2): "
+                    INVOKESPECIAL java.lang.StringBuffer.<init> (Ljava/lang/String;)V
+                    ALOAD 5
+                    INVOKEVIRTUAL java.lang.StringBuffer.append (Ljava/lang/Object;)Ljava/lang/StringBuffer;
+                    INVOKEVIRTUAL java.lang.StringBuffer.toString ()Ljava/lang/String;
+                    INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V
+                    ALOAD 5   (line 18)
                     ALOAD_3
-                    INVOKESPECIAL DynamicHelloWorld$AjcClosure1.<init> ([Ljava/lang/Object;)V
-                    INVOKEVIRTUAL Trace.ajc$around$Trace$1bc (Ljava/lang/Object;Lorg/aspectj/runtime/internal/AroundClosure;)Ljava/lang/Object;
-                    CHECKCAST java.lang.String
-                    ARETURN
-  end static final String doit_aroundBody2(DynamicHelloWorld, String, java.util.List)
-end public class DynamicHelloWorld
-
-public class DynamicHelloWorld$AjcClosure1 extends org.aspectj.runtime.internal.AroundClosure:
-  public void <init>(Object[]):
-                    ALOAD_0
-                    ALOAD_1
-                    INVOKESPECIAL org.aspectj.runtime.internal.AroundClosure.<init> ([Ljava/lang/Object;)V
-                    RETURN
-  end public void <init>(Object[])
-
-  public Object run(Object[]):
-                    ALOAD_0
-                    GETFIELD org.aspectj.runtime.internal.AroundClosure.state [Ljava/lang/Object;
-                    ASTORE_2
-                    ALOAD_1
-                    BIPUSH 0
-                    AALOAD
+                    ASTORE 9
+                    ASTORE 11
+                    ALOAD 11
                     CHECKCAST DynamicHelloWorld
-                    ALOAD_2
-                    BIPUSH 1
-                    AALOAD
-                    CHECKCAST java.lang.String
-                    ALOAD_2
-                    BIPUSH 2
-                    AALOAD
-                    CHECKCAST java.util.List
-                    INVOKESTATIC DynamicHelloWorld.doit_aroundBody0 (LDynamicHelloWorld;Ljava/lang/String;Ljava/util/List;)Ljava/lang/String;
-                    ARETURN
-  end public Object run(Object[])
-end public class DynamicHelloWorld$AjcClosure1
-
-public class DynamicHelloWorld$AjcClosure3 extends org.aspectj.runtime.internal.AroundClosure:
-  public void <init>(Object[]):
-                    ALOAD_0
                     ALOAD_1
-                    INVOKESPECIAL org.aspectj.runtime.internal.AroundClosure.<init> ([Ljava/lang/Object;)V
-                    RETURN
-  end public void <init>(Object[])
-
-  public Object run(Object[]):
-                    ALOAD_0
-                    GETFIELD org.aspectj.runtime.internal.AroundClosure.state [Ljava/lang/Object;
-                    ASTORE_2
-                    ALOAD_2
-                    BIPUSH 0
-                    AALOAD
-                    CHECKCAST DynamicHelloWorld
                     ALOAD_2
-                    BIPUSH 1
-                    AALOAD
+                    INVOKESTATIC DynamicHelloWorld.doit_aroundBody0 (LDynamicHelloWorld;Ljava/lang/String;Ljava/util/List;)Ljava/lang/String;
+                    ASTORE 13
+                    GETSTATIC java.lang.System.out Ljava/io/PrintStream;   (line 19)
+                    NEW java.lang.StringBuffer
+                    DUP
+                    LDC "exiting around with(2): "
+                    INVOKESPECIAL java.lang.StringBuffer.<init> (Ljava/lang/String;)V
+                    ALOAD 13
+                    INVOKEVIRTUAL java.lang.StringBuffer.append (Ljava/lang/Object;)Ljava/lang/StringBuffer;
+                    INVOKEVIRTUAL java.lang.StringBuffer.toString ()Ljava/lang/String;
+                    INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V
+                    ALOAD 13   (line 20)
+                    GOTO L0
+                L0: NOP
                     CHECKCAST java.lang.String
-                    ALOAD_2
-                    BIPUSH 2
-                    AALOAD
-                    CHECKCAST java.util.List
-                    INVOKESTATIC DynamicHelloWorld.doit_aroundBody2 (LDynamicHelloWorld;Ljava/lang/String;Ljava/util/List;)Ljava/lang/String;
                     ARETURN
-  end public Object run(Object[])
-end public class DynamicHelloWorld$AjcClosure3
+  end static final String doit_aroundBody1(DynamicHelloWorld, String, java.util.List)
+end public class DynamicHelloWorld