Browse Source

pr93253: lazytjp the default

tags/V1_5_0RC1
aclement 18 years ago
parent
commit
bb9d2de08e

+ 3
- 1
org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java View File

public void parseOption(String arg, LinkedList args) { // XXX use ListIterator.remove() public void parseOption(String arg, LinkedList args) { // XXX use ListIterator.remove()
int nextArgIndex = args.indexOf(arg)+1; // XXX assumes unique int nextArgIndex = args.indexOf(arg)+1; // XXX assumes unique
// trim arg? // trim arg?
buildConfig.setXlazyTjp(true); // now default - MINOR could be pushed down and made default at a lower level
if (LangUtil.isEmpty(arg)) { if (LangUtil.isEmpty(arg)) {
showWarning("empty arg found"); showWarning("empty arg found");
} else if (arg.equals("-inpath")) {; } else if (arg.equals("-inpath")) {;
} else if (arg.equals("-XserializableAspects")) { } else if (arg.equals("-XserializableAspects")) {
buildConfig.setXserializableAspects(true); buildConfig.setXserializableAspects(true);
} else if (arg.equals("-XlazyTjp")) { } else if (arg.equals("-XlazyTjp")) {
buildConfig.setXlazyTjp(true);
// do nothing as this is now on by default
showWarning("-XlazyTjp should no longer be used, build tjps lazily is now the default");
} else if (arg.startsWith("-Xreweavable")) { } else if (arg.startsWith("-Xreweavable")) {
showWarning("-Xreweavable is on by default"); showWarning("-Xreweavable is on by default");
if (arg.endsWith(":compress")) { if (arg.endsWith(":compress")) {

+ 2
- 1
org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/PerformanceTestCase.java View File

// joinpoint method-execution(int LazyTjp.doit3(int)) because around advice is used [Xlint:canNotImplementLazyTjp]' // joinpoint method-execution(int LazyTjp.doit3(int)) because around advice is used [Xlint:canNotImplementLazyTjp]'
// into an error so that we can use checkCompiles() ability to check errors occur. // into an error so that we can use checkCompiles() ability to check errors occur.
// Pass -proceedOnError to ensure even though we get that message, we still get the class file on disk // Pass -proceedOnError to ensure even though we get that message, we still get the class file on disk
checkCompile("src1/LazyTjp.aj", new String[] {"-XlazyTjp","-Xlint:error","-proceedOnError"}, new int[] {96});
checkCompile("src1/LazyTjp.aj", new String[] {"-Xlint:error","-proceedOnError"}, new int[] {96});
TestUtil.runMain("out", "LazyTjp"); TestUtil.runMain("out", "LazyTjp");
} }
} }

+ 4
- 0
tests/bugs/lazyTjpXLintWarning/LazyTjpTest4.java View File

before() : execution(public void LazyTjpTest4.test1()) { before() : execution(public void LazyTjpTest4.test1()) {
System.out.println(thisJoinPoint); System.out.println(thisJoinPoint);
} }

before() : execution(public void LazyTjpTest4.test1()) {
System.out.println(thisJoinPoint);
}
} }


} }

+ 22
- 0
tests/bugs/lazyTjpXLintWarning/LazyTjpTest5.java View File

public class LazyTjpTest5 {

public void test1 () { }
private static aspect Aspect1 {

private static boolean enabled = true;
after () : if(enabled) && execution(public void LazyTjpTest5.test1()) {
System.out.println(thisJoinPoint);
}

before() : execution(public void LazyTjpTest5.test1()) {
System.out.println(thisJoinPoint);
}

void around() : execution(public void LazyTjpTest5.test1()) {
System.out.println(thisJoinPoint);
}
}

}

+ 1
- 1
tests/bugs/lazyTjpXLintWarning/Scenario3.aj View File

pointcut toBeTraced() : execution(* main(..)); pointcut toBeTraced() : execution(* main(..));


Object around() : toBeTraced() { Object around() : toBeTraced() {
// Object[] args = thisJoinPoint.getArgs();
//Object[] args = thisJoinPoint.getArgs();
return proceed(); return proceed();
} }

+ 58
- 1
tests/src/org/aspectj/systemtest/xlint/XLintTests.java View File

import java.io.File; import java.io.File;
import junit.framework.Test; import junit.framework.Test;
import org.aspectj.testing.XMLBasedAjcTestCase; import org.aspectj.testing.XMLBasedAjcTestCase;
import org.aspectj.weaver.bcel.BcelShadow;


public class XLintTests extends org.aspectj.testing.XMLBasedAjcTestCase { public class XLintTests extends org.aspectj.testing.XMLBasedAjcTestCase {


runTest("XLint warning for call PCD's using subtype of defining type (-1.3 -Xlint:ignore)"); runTest("XLint warning for call PCD's using subtype of defining type (-1.3 -Xlint:ignore)");
} }

// the following five tests check various scenarios around the lazyTjp XLint message
public void test020(){
runTest("no XLint warning: thisJoinPoint potentially lazy and nothing stopping it");
assertTrue("Something prevented the lazytjp optimization from working??",BcelShadow.appliedLazyTjpOptimization);
}
public void test021(){
runTest("XLint warning: thisJoinPoint potentially lazy but stopped by around advice which doesn't use tjp");
assertFalse("lazytjp optimization should have failed to be applied because of around advice at the jp",
BcelShadow.appliedLazyTjpOptimization);
}
public void test022(){
runTest("no XLint warning: thisJoinPoint not lazy (no if PCD) but would have been stopped anyway by around advice");
assertFalse("lazytjp optimization should have failed to be applied because of around advice *and* before advice has no if() at the jp",
BcelShadow.appliedLazyTjpOptimization);
}
public void test023(){
runTest("no XLint warning: thisJoinPoint cannot be built lazily");
assertFalse("lazytjp optimization should have failed to be applied because before advice has no if() at the jp",
BcelShadow.appliedLazyTjpOptimization);
}
public void test024(){
runTest("XLint warning: thisJoinPoint potentially lazy but stopped by around advice which uses tjp");
assertFalse("lazytjp optimization should have failed to be applied because around advice uses tjp",
BcelShadow.appliedLazyTjpOptimization);
}
public void test025(){
runTest("check for xlazytjp warning if actually supplied");
assertTrue("Something prevented the lazytjp optimization from working??",BcelShadow.appliedLazyTjpOptimization);
}
public void test026(){
runTest("lazytjp: warning when around advice uses tjp");
}
public void test027() {
runTest("lazytjp: warning when if missing on before advice");
}
public void test028() {
runTest("lazytjp: warning when if missing on after advice");
}
public void test029() {
runTest("lazytjp: multiple clashing advice preventing lazytjp");
}
public void test030() {
runTest("lazytjp: interfering before and around");
}
// FIXME asc put this back in ! // FIXME asc put this back in !
// public void test020() {
// public void test031() {
// if (is15VMOrGreater) // if (is15VMOrGreater)
// runTest("7 lint warnings"); // runTest("7 lint warnings");
// } // }

+ 78
- 0
tests/src/org/aspectj/systemtest/xlint/xlint-tests.xml View File



<!-- .................................... -Xlint tests --> <!-- .................................... -Xlint tests -->
<!-- ............... positive -Xlint tests --> <!-- ............... positive -Xlint tests -->
<ajc-test dir="bugs/lazyTjpXLintWarning"
title="no XLint warning: thisJoinPoint potentially lazy and nothing stopping it">
<compile options="-Xlint:warning" files="Scenario1.aj"/>
</ajc-test>
<ajc-test dir="bugs/lazyTjpXLintWarning"
title="XLint warning: thisJoinPoint potentially lazy but stopped by around advice which doesn't use tjp">
<compile options="-Xlint:warning" files="Scenario2.aj">
<message kind="warning" line="21" text="can not implement lazyTjp on this joinpoint method-execution(void Test.main(java.lang.String[])) because around advice is used [Xlint:canNotImplementLazyTjp]"/>
</compile>
</ajc-test>
<ajc-test dir="bugs/lazyTjpXLintWarning"
title="no XLint warning: thisJoinPoint not lazy (no if PCD) but would have been stopped anyway by around advice">
<compile options="-Xlint:warning" files="Scenario3.aj">
<message kind="warning" line="14" text="can not build thisJoinPoint lazily for this advice since it has no suitable guard. The advice applies at method-execution(void Test.main(java.lang.String[])) [Xlint:noGuardForLazyTjp]"/>
</compile>
</ajc-test>
<ajc-test dir="bugs/lazyTjpXLintWarning" title="no XLint warning: thisJoinPoint cannot be built lazily">
<compile options="-Xlint:warning" files="Scenario4.aj">
<message kind="warning" line="9" text="can not build thisJoinPoint lazily for this advice since it has no suitable guard. The advice applies at method-execution(void Test.main(java.lang.String[]))"/>
</compile>
</ajc-test>
<ajc-test dir="bugs/lazyTjpXLintWarning"
title="XLint warning: thisJoinPoint potentially lazy but stopped by around advice which uses tjp">
<compile options="-Xlint:warning" files="Scenario5.aj">
<message kind="warning" line="22" text="can not implement lazyTjp on this joinpoint method-execution(void Test.main(java.lang.String[])) because around advice is used [Xlint:canNotImplementLazyTjp]"/>
</compile>
</ajc-test>
<ajc-test dir="bugs/lazyTjpXLintWarning"
title="check for xlazytjp warning if actually supplied">
<compile options="-XlazyTjp -Xlint:warning" files="Scenario1.aj">
<message kind="warning" text="-XlazyTjp should no longer be used, build tjps lazily is now the default"/>
</compile>
</ajc-test>
<ajc-test dir="bugs/lazyTjpXLintWarning"
title="lazytjp: warning when around advice uses tjp">
<compile options="-Xlint:warning" files="LazyTjpTest1.java">
<message kind="warning" line="4" text="can not implement lazyTjp on this joinpoint method-execution(void LazyTjpTest1.test2()) because around advice is used [Xlint:canNotImplementLazyTjp]"/>
</compile>
</ajc-test>
<ajc-test dir="bugs/lazyTjpXLintWarning"
title="lazytjp: warning when if missing on before advice">
<compile options="-Xlint:warning" files="LazyTjpTest2.java">
<message kind="warning" line="16" text="can not build thisJoinPoint lazily for this advice since it has no suitable guard. The advice applies at method-execution(void LazyTjpTest2.test2())"/>
</compile>
</ajc-test>
<ajc-test dir="bugs/lazyTjpXLintWarning"
title="lazytjp: warning when if missing on after advice">
<compile options="-Xlint:warning" files="LazyTjpTest3.java">
<message kind="warning" line="17" text="can not build thisJoinPoint lazily for this advice since it has no suitable guard. The advice applies at method-execution(void LazyTjpTest3.test2())"/>
</compile>
</ajc-test>
<ajc-test dir="bugs/lazyTjpXLintWarning"
title="lazytjp: multiple clashing advice preventing lazytjp">
<compile options="-Xlint:warning" files="LazyTjpTest4.java">
<message kind="warning" line="13" text="can not build thisJoinPoint lazily for this advice since it has no suitable guard. The advice applies at method-execution(void LazyTjpTest4.test1())"/>
<message kind="warning" line="3" text="can not implement lazyTjp at joinpoint method-execution(void LazyTjpTest4.test1()) because of advice conflicts, see secondary locations to find conflicting advice"/>
<message kind="warning" line="17" text="can not build thisJoinPoint lazily for this advice since it has no suitable guard. The advice applies at method-execution(void LazyTjpTest4.test1())"/>
</compile>
</ajc-test>
<ajc-test dir="bugs/lazyTjpXLintWarning"
title="lazytjp: interfering before and around">
<compile options="-Xlint:warning" files="LazyTjpTest5.java">
<message kind="warning" line="3" text="can not implement lazyTjp at joinpoint method-execution(void LazyTjpTest5.test1()) because of advice conflicts, see secondary locations to find conflicting advice"/>
<message kind="warning" line="13" text="can not build thisJoinPoint lazily for this advice since it has no suitable guard. The advice applies at method-execution(void LazyTjpTest5.test1())"/>
</compile>
</ajc-test>
<ajc-test dir="options" <ajc-test dir="options"
title="options -Xlint args()" title="options -Xlint args()"
keywords="lint"> keywords="lint">

+ 7
- 1
weaver/src/org/aspectj/weaver/Lint.java View File

public final Kind canNotImplementLazyTjp = public final Kind canNotImplementLazyTjp =
new Kind("canNotImplementLazyTjp", "can not implement lazyTjp on this joinpoint {0} because around advice is used"); new Kind("canNotImplementLazyTjp", "can not implement lazyTjp on this joinpoint {0} because around advice is used");


public final Kind multipleAdviceStoppingLazyTjp =
new Kind("multipleAdviceStoppingLazyTjp", "can not implement lazyTjp at joinpoint {0} because of advice conflicts, see secondary locations to find conflicting advice");

public final Kind needsSerialVersionUIDField = public final Kind needsSerialVersionUIDField =
new Kind("needsSerialVersionUIDField", "serialVersionUID of type {0} needs to be set because of {1}"); new Kind("needsSerialVersionUIDField", "serialVersionUID of type {0} needs to be set because of {1}");


public final Kind uncheckedAdviceConversion = public final Kind uncheckedAdviceConversion =
new Kind("uncheckedAdviceConversion","unchecked conversion when advice applied at shadow {0}, expected {1} but advice uses {2}"); new Kind("uncheckedAdviceConversion","unchecked conversion when advice applied at shadow {0}, expected {1} but advice uses {2}");
public final Kind noGuardForLazyTjp =
new Kind("noGuardForLazyTjp","can not build thisJoinPoint lazily for this advice since it has no suitable guard. The advice applies at {0}");

public Lint(World world) { public Lint(World world) {
this.world = world; this.world = world;
} }

+ 3
- 1
weaver/src/org/aspectj/weaver/XlintDefault.properties View File



unmatchedSuperTypeInCall = warning unmatchedSuperTypeInCall = warning


canNotImplementLazyTjp = warning
canNotImplementLazyTjp = ignore
multipleAdviceStoppingLazyTjp=ignore
noGuardForLazyTjp=ignore


uncheckedAdviceConversion = warning uncheckedAdviceConversion = warning



+ 17
- 2
weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java View File

import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;


import org.aspectj.apache.bcel.generic.InstructionConstants;
import org.aspectj.apache.bcel.generic.InstructionFactory; import org.aspectj.apache.bcel.generic.InstructionFactory;
import org.aspectj.apache.bcel.generic.InstructionHandle; import org.aspectj.apache.bcel.generic.InstructionHandle;
import org.aspectj.apache.bcel.generic.InstructionList; import org.aspectj.apache.bcel.generic.InstructionList;
import org.aspectj.apache.bcel.generic.InstructionConstants;
import org.aspectj.bridge.IMessage; import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.Message; import org.aspectj.bridge.Message;
import org.aspectj.weaver.Advice; import org.aspectj.weaver.Advice;
import org.aspectj.weaver.AdviceKind; import org.aspectj.weaver.AdviceKind;
} }


if ((getExtraParameterFlags() & ThisJoinPoint) != 0) { if ((getExtraParameterFlags() & ThisJoinPoint) != 0) {
((BcelShadow)shadow).requireThisJoinPoint(pointcutTest != Literal.TRUE && getKind() != AdviceKind.Around);
boolean hasGuardTest = pointcutTest != Literal.TRUE && getKind() != AdviceKind.Around;
boolean isAround = getKind() == AdviceKind.Around;
((BcelShadow)shadow).requireThisJoinPoint(hasGuardTest,isAround);
((BcelShadow)shadow).getEnclosingClass().warnOnAddedStaticInitializer(shadow,getSourceLocation()); ((BcelShadow)shadow).getEnclosingClass().warnOnAddedStaticInitializer(shadow,getSourceLocation());
if (!hasGuardTest && world.getLint().multipleAdviceStoppingLazyTjp.isEnabled()) {
// collect up the problematic advice
((BcelShadow)shadow).addAdvicePreventingLazyTjp(this);
}
if (!isAround && !hasGuardTest && world.getLint().noGuardForLazyTjp.isEnabled()) {
// can't build tjp lazily, no suitable test...
world.getLint().noGuardForLazyTjp.signal(
new String[] {shadow.toString()},
getSourceLocation(),
new ISourceLocation[] { ((BcelShadow)shadow).getSourceLocation() }
);
}
} }
if ((getExtraParameterFlags() & ThisEnclosingJoinPointStaticPart) != 0) { if ((getExtraParameterFlags() & ThisEnclosingJoinPointStaticPart) != 0) {

+ 68
- 15
weaver/src/org/aspectj/weaver/bcel/BcelShadow.java View File

private final LazyMethodGen enclosingMethod; private final LazyMethodGen enclosingMethod;
private boolean fallsThrough; //XXX not used anymore private boolean fallsThrough; //XXX not used anymore
// SECRETAPI - for testing, this will tell us if the optimization succeeded *on the last shadow processed*
public static boolean appliedLazyTjpOptimization;
// Some instructions have a target type that will vary // Some instructions have a target type that will vary
// from the signature (pr109728) (1.4 declaring type issue) // from the signature (pr109728) (1.4 declaring type issue)
private String actualInstructionTargetType; private String actualInstructionTargetType;
} }
} }
// records advice that is stopping us doing the lazyTjp optimization
private List badAdvice = null;
public void addAdvicePreventingLazyTjp(BcelAdvice advice) {
if (badAdvice == null) badAdvice = new ArrayList();
badAdvice.add(advice);
}
protected void prepareForMungers() { protected void prepareForMungers() {
// if we're a constructor call, we need to remove the new:dup or the new:dup_x1:swap, // if we're a constructor call, we need to remove the new:dup or the new:dup_x1:swap,
// and store all our // and store all our
} }


// now we ask each munger to request our state // now we ask each munger to request our state
isThisJoinPointLazy = world.isXlazyTjp();
isThisJoinPointLazy = true;//world.isXlazyTjp(); // lazy is default now

badAdvice = null;
for (Iterator iter = mungers.iterator(); iter.hasNext();) { for (Iterator iter = mungers.iterator(); iter.hasNext();) {
ShadowMunger munger = (ShadowMunger) iter.next(); ShadowMunger munger = (ShadowMunger) iter.next();
munger.specializeOn(this); munger.specializeOn(this);
} }
initializeThisJoinPoint(); initializeThisJoinPoint();


if (thisJoinPointVar!=null && !isThisJoinPointLazy && badAdvice!=null && badAdvice.size()>1) {
// something stopped us making it a lazy tjp
// can't build tjp lazily, no suitable test...
int valid = 0;
for (Iterator iter = badAdvice.iterator(); iter.hasNext();) {
BcelAdvice element = (BcelAdvice) iter.next();
ISourceLocation sLoc = element.getSourceLocation();
if (sLoc!=null && sLoc.getLine()>0) valid++;
}
if (valid!=0) {
ISourceLocation[] badLocs = new ISourceLocation[valid];
int i = 0;
for (Iterator iter = badAdvice.iterator(); iter.hasNext();) {
BcelAdvice element = (BcelAdvice) iter.next();
ISourceLocation sLoc = element.getSourceLocation();
if (sLoc!=null) badLocs[i++]=sLoc;
}
world.getLint().multipleAdviceStoppingLazyTjp.signal(
new String[] {this.toString()},
getSourceLocation(),badLocs
);
}
}
badAdvice=null;
// If we are an expression kind, we require our target/arguments on the stack // If we are an expression kind, we require our target/arguments on the stack
// before we do our actual thing. However, they may have been removed // before we do our actual thing. However, they may have been removed
// from the stack as the shadowMungers have requested state. // from the stack as the shadowMungers have requested state.
public final Var getThisEnclosingJoinPointStaticPartVar() { public final Var getThisEnclosingJoinPointStaticPartVar() {
return getThisEnclosingJoinPointStaticPartBcelVar(); return getThisEnclosingJoinPointStaticPartBcelVar();
} }
public void requireThisJoinPoint(boolean hasGuardTest) {
if (!hasGuardTest) {
isThisJoinPointLazy = false;
} else {
lazyTjpConsumers++;
}
public void requireThisJoinPoint(boolean hasGuardTest, boolean isAround) {
if (!isAround){
if (!hasGuardTest) {
isThisJoinPointLazy = false;
} else {
lazyTjpConsumers++;
}
}
// if (!hasGuardTest) {
// isThisJoinPointLazy = false;
// } else {
// lazyTjpConsumers++;
// }
if (thisJoinPointVar == null) { if (thisJoinPointVar == null) {
thisJoinPointVar = genTempVar(UnresolvedType.forName("org.aspectj.lang.JoinPoint")); thisJoinPointVar = genTempVar(UnresolvedType.forName("org.aspectj.lang.JoinPoint"));
} }
public Var getThisJoinPointVar() { public Var getThisJoinPointVar() {
requireThisJoinPoint(false);
requireThisJoinPoint(false,false);
return thisJoinPointVar; return thisJoinPointVar;
} }
} }
if (isThisJoinPointLazy) { if (isThisJoinPointLazy) {
appliedLazyTjpOptimization = true;
createThisJoinPoint(); // make sure any state needed is initialized, but throw the instructions out createThisJoinPoint(); // make sure any state needed is initialized, but throw the instructions out
if (lazyTjpConsumers == 1) return; // special case only one lazyTjpUser if (lazyTjpConsumers == 1) return; // special case only one lazyTjpUser
il.append(thisJoinPointVar.createStore(fact)); il.append(thisJoinPointVar.createStore(fact));
range.insert(il, Range.OutsideBefore); range.insert(il, Range.OutsideBefore);
} else { } else {
appliedLazyTjpOptimization = false;
InstructionFactory fact = getFactory(); InstructionFactory fact = getFactory();
InstructionList il = createThisJoinPoint(); InstructionList il = createThisJoinPoint();
il.append(thisJoinPointVar.createStore(fact)); il.append(thisJoinPointVar.createStore(fact));
ShadowMunger munger = (ShadowMunger) i.next(); ShadowMunger munger = (ShadowMunger) i.next();
if (munger instanceof Advice) { if (munger instanceof Advice) {
if ( ((Advice)munger).getKind() == AdviceKind.Around) { if ( ((Advice)munger).getKind() == AdviceKind.Around) {
world.getLint().canNotImplementLazyTjp.signal(
new String[] {toString()},
getSourceLocation(),
new ISourceLocation[] { munger.getSourceLocation() }
);
if (munger.getSourceLocation()!=null) { // do we know enough to bother reporting?
world.getLint().canNotImplementLazyTjp.signal(
new String[] {toString()},
getSourceLocation(),
new ISourceLocation[] { munger.getSourceLocation() }
);
}
return false; return false;
} }
} }
InstructionList il = new InstructionList(); InstructionList il = new InstructionList();


if (isThisJoinPointLazy) { if (isThisJoinPointLazy) {
// If we're lazy, build the join point right here.
il.append(createThisJoinPoint()); il.append(createThisJoinPoint());
// Does someone else need it? If so, store it for later retrieval
if (lazyTjpConsumers > 1) { if (lazyTjpConsumers > 1) {
il.append(thisJoinPointVar.createStore(fact)); il.append(thisJoinPointVar.createStore(fact));
il.insert(thisJoinPointVar.createLoad(fact)); il.insert(thisJoinPointVar.createLoad(fact));
} }
} else { } else {
// If not lazy, its already been built and stored, just retrieve it
thisJoinPointVar.appendLoad(il, fact); thisJoinPointVar.appendLoad(il, fact);
} }

Loading…
Cancel
Save