From: jhugunin Date: Wed, 1 Jan 2003 00:07:33 +0000 (+0000) Subject: finished implementation of around inlining X-Git-Tag: V_1_1_b5~184 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=28f09b17d4991c6754d0a2b701a6f6eb4abdbed0;p=aspectj.git finished implementation of around inlining --- diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java index 81cabdb69..9cbc17afb 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java @@ -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 index 000000000..411ae4df5 --- /dev/null +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AccessForInlineVisitor.java @@ -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; + } + } +} diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java index 15e28461f..9b783cb11 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/AdviceDeclaration.java @@ -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 index 000000000..84ed18b75 --- /dev/null +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/MakeDeclsPublicVisitor.java @@ -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); + } + +} diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java index 541184931..5cb328da5 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java @@ -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 index 000000000..355ed098c --- /dev/null +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/ProceedVisitor.java @@ -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; + } + + +} diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java index 8a43cfa33..93e0ebad9 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java @@ -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; + } + } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java index 6fa941d82..a5f19ca94 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java @@ -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; diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/WorkingTestMain.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/WorkingTestMain.java index f2273f1b3..f1c1b67f8 100644 --- a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/WorkingTestMain.java +++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/WorkingTestMain.java @@ -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/"; diff --git a/weaver/src/org/aspectj/weaver/Advice.java b/weaver/src/org/aspectj/weaver/Advice.java index b6714333f..cb6a4d5bc 100644 --- a/weaver/src/org/aspectj/weaver/Advice.java +++ b/weaver/src/org/aspectj/weaver/Advice.java @@ -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; diff --git a/weaver/src/org/aspectj/weaver/ConcreteTypeMunger.java b/weaver/src/org/aspectj/weaver/ConcreteTypeMunger.java index 9f55b28e9..3102bd24f 100644 --- a/weaver/src/org/aspectj/weaver/ConcreteTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/ConcreteTypeMunger.java @@ -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; } diff --git a/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java b/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java index e04c923cb..2b943ede1 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java @@ -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); diff --git a/weaver/src/org/aspectj/weaver/ResolvedTypeX.java b/weaver/src/org/aspectj/weaver/ResolvedTypeX.java index a2c14f27a..e8a76d99a 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedTypeX.java +++ b/weaver/src/org/aspectj/weaver/ResolvedTypeX.java @@ -33,7 +33,6 @@ public abstract class ResolvedTypeX extends TypeX { // ---- things that don't require a world - /** returns Iterator<ResolvedTypeX> */ 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; } diff --git a/weaver/src/org/aspectj/weaver/World.java b/weaver/src/org/aspectj/weaver/World.java index 4ed8abb49..b1d150c68 100644 --- a/weaver/src/org/aspectj/weaver/World.java +++ b/weaver/src/org/aspectj/weaver/World.java @@ -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; + } + } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java b/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java index e27102cfa..77842f3cd 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java @@ -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()) { diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java index 8ceda85e3..415098ba0 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java @@ -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; } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java index 9f4d8d28a..6937d9bac 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java @@ -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( diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java b/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java index 6b6987e16..97d8a09a4 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java @@ -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); diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java index 110ec064d..e4135cbcb 100644 --- a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java +++ b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java @@ -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); } diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java index 326f5426b..5a6afccae 100644 --- a/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java +++ b/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java @@ -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; + } + } diff --git a/weaver/testdata/AfterFancyHelloWorld.txt b/weaver/testdata/AfterFancyHelloWorld.txt index 16b04e4b1..b693040af 100644 --- a/weaver/testdata/AfterFancyHelloWorld.txt +++ b/weaver/testdata/AfterFancyHelloWorld.txt @@ -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 diff --git a/weaver/testdata/AfterThrowingFancyHelloWorld.txt b/weaver/testdata/AfterThrowingFancyHelloWorld.txt index ed9e89bfd..3323beea6 100644 --- a/weaver/testdata/AfterThrowingFancyHelloWorld.txt +++ b/weaver/testdata/AfterThrowingFancyHelloWorld.txt @@ -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 diff --git a/weaver/testdata/AfterThrowingParamFancyHelloWorld.txt b/weaver/testdata/AfterThrowingParamFancyHelloWorld.txt index 351d35649..0e995aaff 100644 --- a/weaver/testdata/AfterThrowingParamFancyHelloWorld.txt +++ b/weaver/testdata/AfterThrowingParamFancyHelloWorld.txt @@ -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 diff --git a/weaver/testdata/TraceJarHello.txt b/weaver/testdata/TraceJarHello.txt index 6d96a9025..19fa930a5 100644 --- a/weaver/testdata/TraceJarHello.txt +++ b/weaver/testdata/TraceJarHello.txt @@ -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. (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. ([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. (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. (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. ([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 (Object[]): - ALOAD_0 - ALOAD_1 - INVOKESPECIAL org.aspectj.runtime.internal.AroundClosure. ([Ljava/lang/Object;)V - RETURN - end public void (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 (Object[]): - ALOAD_0 ALOAD_1 - INVOKESPECIAL org.aspectj.runtime.internal.AroundClosure. ([Ljava/lang/Object;)V - RETURN - end public void (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. (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