Browse Source

Bug#531694: generate more optional thisJoinPoint construction code

This commit introduces some new methods into the
runtime Factory class and modifies code generation
to use them (and to use the form of the LDC bytecode
that loads class constants).
tags/V1_9_0
Andy Clement 6 years ago
parent
commit
7d47cba010
34 changed files with 1104 additions and 34 deletions
  1. 1
    0
      bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionFactory.java
  2. 4
    3
      bcel-builder/src/org/aspectj/apache/bcel/generic/Type.java
  3. BIN
      build/products/tools/dist/lib/aspectjrt.jar
  4. 3
    0
      build/updateAspectjrt.sh
  5. BIN
      lib/aspectj/lib/aspectjrt.jar
  6. BIN
      lib/bcel/bcel-src.zip
  7. BIN
      lib/bcel/bcel-verifier.jar
  8. BIN
      lib/bcel/bcel.jar
  9. BIN
      lib/test/aspectjrt.jar
  10. 3
    1
      org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java
  11. 20
    0
      org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/ConfigParser.java
  12. 1
    0
      org.aspectj.matcher/src/org/aspectj/weaver/Constants.java
  13. 47
    0
      org.aspectj.matcher/src/org/aspectj/weaver/RuntimeVersion.java
  14. 8
    8
      org.aspectj.matcher/src/org/aspectj/weaver/World.java
  15. 116
    9
      runtime/src/org/aspectj/runtime/reflect/Factory.java
  16. 19
    0
      tests/features190/efficientTJP/Advice.java
  17. 16
    0
      tests/features190/efficientTJP/Clinit.java
  18. 16
    0
      tests/features190/efficientTJP/ClinitE.java
  19. 46
    0
      tests/features190/efficientTJP/Fields.java
  20. 40
    0
      tests/features190/efficientTJP/Fields2.java
  21. 46
    0
      tests/features190/efficientTJP/FieldsE.java
  22. 21
    0
      tests/features190/efficientTJP/Four.java
  23. 21
    0
      tests/features190/efficientTJP/FourA.java
  24. 24
    0
      tests/features190/efficientTJP/Init.java
  25. 12
    0
      tests/features190/efficientTJP/One.java
  26. 19
    0
      tests/features190/efficientTJP/Three.java
  27. 19
    0
      tests/features190/efficientTJP/ThreeA.java
  28. 12
    0
      tests/features190/efficientTJP/Two.java
  29. 14
    4
      tests/src/org/aspectj/systemtest/ajc151/NewarrayJoinpointTests.java
  30. 1
    1
      tests/src/org/aspectj/systemtest/ajc190/AllTestsAspectJ190.java
  31. 126
    0
      tests/src/org/aspectj/systemtest/ajc190/EfficientTJPTests.java
  32. 172
    0
      tests/src/org/aspectj/systemtest/ajc190/features190.xml
  33. 9
    0
      weaver/src/org/aspectj/weaver/bcel/BcelWorld.java
  34. 268
    8
      weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java

+ 1
- 0
bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionFactory.java View File

@@ -761,6 +761,7 @@ public class InstructionFactory implements InstructionConstants {
iList.append(new InstructionCP(Instruction.LDC_W, classIndex));
}
} else {
className = className.replace('/', '.');
iList.append(InstructionFactory.PUSH(cp, className));
iList.append(this.createInvoke("java.lang.Class", "forName", ObjectType.CLASS, Type.STRINGARRAY1,
Constants.INVOKESTATIC));

+ 4
- 3
bcel-builder/src/org/aspectj/apache/bcel/generic/Type.java View File

@@ -89,9 +89,9 @@ public abstract class Type {
public static final BasicType CHAR = new BasicType(Constants.T_CHAR);
public static final ObjectType OBJECT = new ObjectType("java.lang.Object");
public static final ObjectType STRING = new ObjectType("java.lang.String");
public static final ObjectType OBJECT_ARRAY = new ObjectType("java.lang.Object[]");
public static final ObjectType STRING_ARRAY = new ObjectType("java.lang.String[]");
public static final ObjectType CLASS_ARRAY = new ObjectType("java.lang.Class[]");
public static final ArrayType OBJECT_ARRAY = new ArrayType("java.lang.Object",1);
public static final ArrayType STRING_ARRAY = new ArrayType("java.lang.String",1);
public static final ArrayType CLASS_ARRAY = new ArrayType("java.lang.Class",1);
public static final ObjectType STRINGBUFFER = new ObjectType("java.lang.StringBuffer");
public static final ObjectType STRINGBUILDER = new ObjectType("java.lang.StringBuilder");
public static final ObjectType THROWABLE = new ObjectType("java.lang.Throwable");
@@ -130,6 +130,7 @@ public abstract class Type {
commonTypes.put(CLASS.getSignature(), CLASS);
commonTypes.put(OBJECT.getSignature(), OBJECT);
commonTypes.put(STRING_ARRAY.getSignature(), STRING_ARRAY);
commonTypes.put(CLASS_ARRAY.getSignature(), CLASS_ARRAY);
commonTypes.put(OBJECT_ARRAY.getSignature(), OBJECT_ARRAY);
commonTypes.put(INTEGER.getSignature(), INTEGER);
commonTypes.put(EXCEPTION.getSignature(), EXCEPTION);

BIN
build/products/tools/dist/lib/aspectjrt.jar View File


+ 3
- 0
build/updateAspectjrt.sh View File

@@ -0,0 +1,3 @@
cp ../aj-build/dist/tools/lib/aspectjrt.jar ../lib/test/aspectjrt.jar
cp ../aj-build/dist/tools/lib/aspectjrt.jar ../lib/aspectj/lib/aspectjrt.jar
cp ../aj-build/dist/tools/lib/aspectjrt.jar ../build/products/tools/dist/lib/aspectjrt.jar

BIN
lib/aspectj/lib/aspectjrt.jar View File


BIN
lib/bcel/bcel-src.zip View File


BIN
lib/bcel/bcel-verifier.jar View File


BIN
lib/bcel/bcel.jar View File


BIN
lib/test/aspectjrt.jar View File


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

@@ -807,8 +807,10 @@ public class BuildArgParser extends Main {
buildConfig.setTargetAspectjRuntimeLevel(Constants.RUNTIME_LEVEL_12);
} else if (arg.endsWith(":1.5")) {
buildConfig.setTargetAspectjRuntimeLevel(Constants.RUNTIME_LEVEL_15);
} else if (arg.endsWith(":1.9")) {
buildConfig.setTargetAspectjRuntimeLevel(Constants.RUNTIME_LEVEL_19);
} else {
showError("-Xajruntimetarget:<level> only supports a target level of 1.2 or 1.5");
showError("-Xajruntimetarget:<level> supports a target level of 1.2, 1.5, 1.9");
}
} else if (arg.equals("-timers")) {
buildConfig.setTiming(true);

+ 20
- 0
org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/ConfigParser.java View File

@@ -21,6 +21,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;

public class ConfigParser {
Location location;
@@ -44,6 +45,13 @@ public class ConfigParser {
for (int i = 0; i < argsArray.length; i++) {
args.add(new Arg(argsArray[i], location));
}
String aspectjOptions = System.getProperty("ASPECTJ_OPTS");
if (aspectjOptions != null) {
StringTokenizer st = new StringTokenizer(aspectjOptions);
while (st.hasMoreElements()) {
args.add(new Arg(st.nextToken(),location));
}
}
parseArgs(args);
}

@@ -138,12 +146,14 @@ public class ConfigParser {
if (sourceFile.getName().charAt(0) == '*') {
if (sourceFile.getName().equals("*.java")) {
addFiles(sourceFile.getParentFile(), new FileFilter() {
@Override
public boolean accept(File f) {
return f != null && f.getName().endsWith(".java");
}
});
} else if (sourceFile.getName().equals("*.aj")) {
addFiles(sourceFile.getParentFile(), new FileFilter() {
@Override
public boolean accept(File f) {
return f != null && f.getName().endsWith(".aj");
}
@@ -287,6 +297,7 @@ public class ConfigParser {
private Location location;
private String value;

@Override
public String toString() {
return "Arg[location="+location+" value="+value+"]";
}
@@ -320,6 +331,7 @@ public class ConfigParser {

public abstract int getLine();

@Override
public abstract String toString();
}

@@ -332,36 +344,44 @@ public class ConfigParser {
this.file = file;
}

@Override
public File getFile() {
return file;
}

@Override
public File getDirectory() {
return file.getParentFile();
}

@Override
public int getLine() {
return line;
}

@Override
public String toString() {
return file.getPath() + ":" + line;
}
}

static class CommandLineLocation extends Location {
@Override
public File getFile() {
return new File(System.getProperty("user.dir"));
}

@Override
public File getDirectory() {
return new File(System.getProperty("user.dir"));
}

@Override
public int getLine() {
return -1;
}

@Override
public String toString() {
return "command-line";
}

+ 1
- 0
org.aspectj.matcher/src/org/aspectj/weaver/Constants.java View File

@@ -22,6 +22,7 @@ public interface Constants {

public final static String RUNTIME_LEVEL_12 = "1.2";
public final static String RUNTIME_LEVEL_15 = "1.5";
public final static String RUNTIME_LEVEL_19 = "1.9";

// Default for 1.5.0
public final static String RUNTIME_LEVEL_DEFAULT = RUNTIME_LEVEL_15;

+ 47
- 0
org.aspectj.matcher/src/org/aspectj/weaver/RuntimeVersion.java View File

@@ -0,0 +1,47 @@
/* *******************************************************************
* Copyright (c) 2018 Contributors
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
* ******************************************************************/
package org.aspectj.weaver;

/**
* Captures important runtime versions. Typically new versions are added here if something
* changes in the runtime and the code generation may be able to do something different
* (more optimal) for a later runtime.
*
* @author Andy Clement
*/
public enum RuntimeVersion {
V1_2("1.2"), V1_5("1.5"), V1_6_10("1.6.10"), V1_9("1.9");
private String[] aliases = null;

RuntimeVersion(String... aliases) {
this.aliases = aliases;
}
public static RuntimeVersion getVersionFor(String version) {
for (RuntimeVersion candidateVersion: values()) {
if (candidateVersion.name().equals(version)) {
return candidateVersion;
}
if (candidateVersion.aliases != null) {
for (String alias: candidateVersion.aliases) {
if (alias.equals(version)) {
return candidateVersion;
}
}
}
}
return null;
}

public boolean isThisVersionOrLater(RuntimeVersion version) {
return this.compareTo(version) >= 0;
}
}

+ 8
- 8
org.aspectj.matcher/src/org/aspectj/weaver/World.java View File

@@ -110,8 +110,9 @@ public abstract class World implements Dump.INode {
private boolean incrementalCompileCouldFollow = false;

/** The level of the aspectjrt.jar the code we generate needs to run on */
private String targetAspectjRuntimeLevel = Constants.RUNTIME_LEVEL_DEFAULT;

public static final RuntimeVersion RUNTIME_LEVEL_DEFAULT = RuntimeVersion.V1_5;
private RuntimeVersion targetAspectjRuntimeLevel = RUNTIME_LEVEL_DEFAULT;
/** Flags for the new joinpoints that are 'optional': -Xjoinpoints:arrayconstruction -Xjoinpoints:synchronization */
private boolean optionalJoinpoint_ArrayConstruction = false;
private boolean optionalJoinpoint_Synchronization = false;
@@ -202,6 +203,7 @@ public abstract class World implements Dump.INode {
/**
* Dump processing when a fatal error occurs
*/
@Override
public void accept(Dump.IVisitor visitor) {
// visitor.visitObject("Extra configuration:");
// visitor.visitList(extraConfiguration.);
@@ -982,7 +984,7 @@ public abstract class World implements Dump.INode {
}

public void setTargetAspectjRuntimeLevel(String s) {
targetAspectjRuntimeLevel = s;
targetAspectjRuntimeLevel = RuntimeVersion.getVersionFor(s);
}

public void setOptionalJoinpoints(String jps) {
@@ -1005,20 +1007,18 @@ public abstract class World implements Dump.INode {
return optionalJoinpoint_Synchronization;
}

public String getTargetAspectjRuntimeLevel() {
public RuntimeVersion getTargetAspectjRuntimeLevel() {
return targetAspectjRuntimeLevel;
}

// OPTIMIZE are users falling foul of not supplying -1.5 and so targetting
// the old runtime?
// OPTIMIZE are users falling foul of not supplying -1.5 and so targetting the old runtime?
public boolean isTargettingAspectJRuntime12() {
boolean b = false; // pr116679
if (!isInJava5Mode()) {
b = true;
} else {
b = getTargetAspectjRuntimeLevel().equals(org.aspectj.weaver.Constants.RUNTIME_LEVEL_12);
b = (getTargetAspectjRuntimeLevel() == RuntimeVersion.V1_2);
}
// System.err.println("Asked if targetting runtime 1.2 , returning: "+b);
return b;
}


+ 116
- 9
runtime/src/org/aspectj/runtime/reflect/Factory.java View File

@@ -1,6 +1,6 @@
/* *******************************************************************
* Copyright (c) 1999-2001 Xerox Corporation,
* 2002 Palo Alto Research Center, Incorporated (PARC).
* 2002-2018 Palo Alto Research Center, Incorporated (PARC), Contributors
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
@@ -8,9 +8,10 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Xerox/PARC initial implementation
* Xerox/PARC initial implementation
* Alex Vasseur new factory methods for variants of JP
* Abraham Nevado new factory methods for collapsed SJPs
* Abraham Nevado new factory methods for collapsed SJPs
* Andy Clement new factory methods that rely on LDC <class>
* ******************************************************************/

package org.aspectj.runtime.reflect;
@@ -38,6 +39,9 @@ public final class Factory {
ClassLoader lookupClassLoader;
String filename;
int count;
private static final Class[] NO_TYPES = new Class[0];
private static final String[] NO_STRINGS = new String[0];

static Hashtable prims = new Hashtable();
static {
@@ -55,7 +59,7 @@ public final class Factory {
static Class makeClass(String s, ClassLoader loader) {
if (s.equals("*"))
return null;
Class ret = (Class) prims.get(s);
Class ret = (Class)prims.get(s);
if (ret != null)
return ret;
try {
@@ -113,6 +117,105 @@ public final class Factory {
Signature sig = this.makeMethodSig(modifiers, methodName, declaringType, paramTypes, paramNames, "", returnType);
return new JoinPointImpl.StaticPartImpl(count++, kind, sig, makeSourceLoc(l, -1));
}
// These are direct routes to creating thisJoinPoint and thisEnclosingJoinPoint objects
// added in 1.9.1
public JoinPoint.StaticPart makeMethodSJP(String kind, int modifiers, String methodName, Class declaringType, Class[] paramTypes, String[] paramNames, Class[] exceptionTypes, Class returnType, int line) {
Signature sig = this.makeMethodSig(modifiers, methodName, declaringType, paramTypes==null?NO_TYPES:paramTypes,
paramNames==null?NO_STRINGS:paramNames, exceptionTypes==null?NO_TYPES:exceptionTypes, returnType == null?Void.TYPE:returnType);
return new JoinPointImpl.StaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1));
}

public JoinPoint.EnclosingStaticPart makeMethodESJP(String kind, int modifiers, String methodName, Class declaringType, Class[] paramTypes, String[] paramNames, Class[] exceptionTypes, Class returnType, int line) {
Signature sig = this.makeMethodSig(modifiers, methodName, declaringType, paramTypes==null?NO_TYPES:paramTypes,
paramNames==null?NO_STRINGS:paramNames, exceptionTypes==null?NO_TYPES:exceptionTypes, returnType == null?Void.TYPE:returnType);
return new JoinPointImpl.EnclosingStaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1));
}

public JoinPoint.StaticPart makeConstructorSJP(String kind, int modifiers, Class declaringType, Class[] parameterTypes, String[] parameterNames, Class[] exceptionTypes, int line) {
ConstructorSignatureImpl sig = new ConstructorSignatureImpl(modifiers, declaringType, parameterTypes==null?NO_TYPES:parameterTypes, parameterNames==null?NO_STRINGS:parameterNames,
exceptionTypes==null?NO_TYPES:exceptionTypes);
return new JoinPointImpl.StaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1));
}

public JoinPoint.EnclosingStaticPart makeConstructorESJP(String kind, int modifiers, Class declaringType, Class[] parameterTypes, String[] parameterNames, Class[] exceptionTypes, int line) {
ConstructorSignatureImpl sig = new ConstructorSignatureImpl(modifiers, declaringType, parameterTypes==null?NO_TYPES:parameterTypes, parameterNames==null?NO_STRINGS:parameterNames,
exceptionTypes==null?NO_TYPES:exceptionTypes);
return new JoinPointImpl.EnclosingStaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1));
}

public JoinPoint.StaticPart makeCatchClauseSJP(String kind, Class declaringType, Class parameterType, String parameterName, int line) {
CatchClauseSignatureImpl sig = new CatchClauseSignatureImpl(declaringType, parameterType, parameterName==null?"":parameterName);
return new JoinPointImpl.StaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1));
}

public JoinPoint.EnclosingStaticPart makeCatchClauseESJP(String kind, Class declaringType, Class parameterType, String parameterName, int line) {
CatchClauseSignatureImpl sig = new CatchClauseSignatureImpl(declaringType, parameterType, parameterName==null?"":parameterName);
return new JoinPointImpl.EnclosingStaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1));
}

public JoinPoint.StaticPart makeFieldSJP(String kind, int modifiers, String name, Class declaringType, Class fieldType, int line) {
FieldSignatureImpl sig = new FieldSignatureImpl(modifiers, name, declaringType, fieldType);
return new JoinPointImpl.StaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1));
}

public JoinPoint.EnclosingStaticPart makeFieldESJP(String kind, int modifiers, String name, Class declaringType, Class fieldType, int line) {
FieldSignatureImpl sig = new FieldSignatureImpl(modifiers, name, declaringType, fieldType);
return new JoinPointImpl.EnclosingStaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1));
}
public JoinPoint.StaticPart makeInitializerSJP(String kind, int modifiers, Class declaringType, int line) {
InitializerSignatureImpl sig = new InitializerSignatureImpl(modifiers, declaringType);
return new JoinPointImpl.StaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1));
}

public JoinPoint.EnclosingStaticPart makeInitializerESJP(String kind, int modifiers, Class declaringType, int line) {
InitializerSignatureImpl sig = new InitializerSignatureImpl(modifiers, declaringType);
return new JoinPointImpl.EnclosingStaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1));
}
public JoinPoint.StaticPart makeLockSJP(String kind, Class declaringType, int line) {
LockSignatureImpl sig = new LockSignatureImpl(declaringType);
return new JoinPointImpl.StaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1));
}

public JoinPoint.EnclosingStaticPart makeLockESJP(String kind, Class declaringType, int line) {
LockSignatureImpl sig = new LockSignatureImpl(declaringType);
return new JoinPointImpl.EnclosingStaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1));
}

public JoinPoint.StaticPart makeUnlockSJP(String kind, Class declaringType, int line) {
UnlockSignatureImpl sig = new UnlockSignatureImpl(declaringType);
return new JoinPointImpl.StaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1));
}

public JoinPoint.EnclosingStaticPart makeUnlockESJP(String kind, Class declaringType, int line) {
UnlockSignatureImpl sig = new UnlockSignatureImpl(declaringType);
return new JoinPointImpl.EnclosingStaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1));
}

public JoinPoint.StaticPart makeAdviceSJP(String kind, int modifiers, String name, Class declaringType, Class[] parameterTypes,
String[] parameterNames, Class[] exceptionTypes, Class returnType, int line) {
AdviceSignatureImpl sig = new AdviceSignatureImpl(modifiers, name, declaringType,
parameterTypes==null?NO_TYPES:parameterTypes,
parameterNames==null?NO_STRINGS:parameterNames,
exceptionTypes==null?NO_TYPES:exceptionTypes,
returnType==null?Void.TYPE:returnType);
return new JoinPointImpl.StaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1));
}

public JoinPoint.EnclosingStaticPart makeAdviceESJP(String kind, int modifiers, String name, Class declaringType, Class[] parameterTypes,
String[] parameterNames, Class[] exceptionTypes, Class returnType, int line) {
AdviceSignatureImpl sig = new AdviceSignatureImpl(modifiers, name, declaringType,
parameterTypes==null?NO_TYPES:parameterTypes,
parameterNames==null?NO_STRINGS:parameterNames,
exceptionTypes==null?NO_TYPES:exceptionTypes,
returnType==null?Void.TYPE:returnType);
return new JoinPointImpl.EnclosingStaticPartImpl(count++, kind, sig, makeSourceLoc(line, -1));
}
// ---

public JoinPoint.StaticPart makeSJP(String kind, Signature sig, SourceLocation loc) {
return new JoinPointImpl.StaticPartImpl(count++, kind, sig, loc);
@@ -181,12 +284,16 @@ public final class Factory {
ret.setLookupClassLoader(lookupClassLoader);
return ret;
}
public MethodSignature makeMethodSig(String modifiers, String methodName, String declaringType, String paramTypes,
String paramNames, String exceptionTypes, String returnType) {
int modifiersAsInt = Integer.parseInt(modifiers, 16);

Class declaringTypeClass = makeClass(declaringType, lookupClassLoader);
return makeMethodSig(modifiers, methodName, declaringTypeClass, paramTypes, paramNames, exceptionTypes, returnType);
}
public MethodSignature makeMethodSig(String modifiers, String methodName, Class declaringTypeClass, String paramTypes,
String paramNames, String exceptionTypes, String returnType) {
int modifiersAsInt = Integer.parseInt(modifiers, 16);

StringTokenizer st = new StringTokenizer(paramTypes, ":");
int numParams = st.countTokens();
@@ -216,8 +323,8 @@ public final class Factory {

public MethodSignature makeMethodSig(int modifiers, String name, Class declaringType, Class[] parameterTypes,
String[] parameterNames, Class[] exceptionTypes, Class returnType) {
MethodSignatureImpl ret = new MethodSignatureImpl(modifiers, name, declaringType, parameterTypes, parameterNames,
exceptionTypes, returnType);
MethodSignatureImpl ret = new MethodSignatureImpl(modifiers, name, declaringType, parameterTypes==null?NO_TYPES:parameterTypes, parameterNames,
exceptionTypes == null?NO_TYPES:exceptionTypes, returnType);
ret.setLookupClassLoader(lookupClassLoader);
return ret;
}

+ 19
- 0
tests/features190/efficientTJP/Advice.java View File

@@ -0,0 +1,19 @@
public class Advice {
public static void main(String []argv) {
}
}

aspect X {
before(): execution(* main(..)) {}
}

aspect Y {
before(): adviceexecution() && within(X) {
System.out.println("tjp:"+thisJoinPointStaticPart.getSignature());
}

before(): adviceexecution() && within(X) {
System.out.println("tejp:"+thisEnclosingJoinPointStaticPart.getSignature());
}

}

+ 16
- 0
tests/features190/efficientTJP/Clinit.java View File

@@ -0,0 +1,16 @@
public class Clinit {
public static void main(String []argv) {
new Inner();
}

static class Inner {}
}

aspect X {
before(): staticinitialization(Clinit.Inner) {
System.out.println(thisJoinPointStaticPart.getSignature());
}
before(): staticinitialization(Clinit) {
System.out.println(thisJoinPointStaticPart.getSignature());
}
}

+ 16
- 0
tests/features190/efficientTJP/ClinitE.java View File

@@ -0,0 +1,16 @@
public class ClinitE {
public static void main(String []argv) {
new Inner();
}

static class Inner {}
}

aspect X {
before(): staticinitialization(ClinitE.Inner) {
System.out.println(thisEnclosingJoinPointStaticPart.getSignature());
}
before(): staticinitialization(ClinitE) {
System.out.println(thisEnclosingJoinPointStaticPart.getSignature());
}
}

+ 46
- 0
tests/features190/efficientTJP/Fields.java View File

@@ -0,0 +1,46 @@
public class Fields {
int a = 1;
String s = "hello";
double d = 1.0d;
boolean b = true;

short ps = (short)1;
float fs = 1.0f;
long ls = 1L;
byte bs = (byte)3;
char cs = 'a';


Inner obj = new Inner();
static int as = 1;
static String ss = "hello";
static double ds = 1.0d;
static Inner objs = new Inner();

public static void main(String []argv) {
Fields f = new Fields();
int a2 = f.a;
String s2 = f.s;
double d2 = f.d;
Inner obj2 = f.obj;

short ps2 = f.ps;
float fs2 = f.fs;
long ls2 = f.ls;
byte bs2 = f.bs;
char cs2 = f.cs;

int a3 = as;
String s3 = ss;
double d3 = ds;
Inner obj3 = objs;
}

static class Inner {}
}

aspect X {
before(): within(Fields) && get(* *) {
System.out.println(thisJoinPointStaticPart.getSignature());
}
}

+ 40
- 0
tests/features190/efficientTJP/Fields2.java View File

@@ -0,0 +1,40 @@
public class Fields2 {
int a = 1;
String s = "hello";
double d = 1.0d;
boolean b = true;

short ps = (short)1;
float fs = 1.0f;
long ls = 1L;
byte bs = (byte)3;
char cs = 'a';


Inner obj = new Inner();
static int as = 1;
static String ss = "hello";
static double ds = 1.0d;
static Inner objs = new Inner();

public static void main(String []argv) {
Fields2 f = new Fields2();
f.a = 2;
f.ps = (short)3;
f.d = 2.0d;
f.obj = new Inner();
f.s = "helo";
f.fs = 4f;
f.ls = 3L;
f.bs = (byte)23;
f.cs = 'a';
}

static class Inner {}
}

aspect X {
before(): within(Fields2) && set(* *) && withincode(* main(..)){
System.out.println(thisJoinPointStaticPart.getSignature());
}
}

+ 46
- 0
tests/features190/efficientTJP/FieldsE.java View File

@@ -0,0 +1,46 @@
public class FieldsE {
int a = 1;
String s = "hello";
double d = 1.0d;
boolean b = true;

short ps = (short)1;
float fs = 1.0f;
long ls = 1L;
byte bs = (byte)3;
char cs = 'a';


Inner obj = new Inner();
static int as = 1;
static String ss = "hello";
static double ds = 1.0d;
static Inner objs = new Inner();

public static void main(String []argv) {
FieldsE f = new FieldsE();
int a2 = f.a;
String s2 = f.s;
double d2 = f.d;
Inner obj2 = f.obj;

short ps2 = f.ps;
float fs2 = f.fs;
long ls2 = f.ls;
byte bs2 = f.bs;
char cs2 = f.cs;

int a3 = as;
String s3 = ss;
double d3 = ds;
Inner obj3 = objs;
}

static class Inner {}
}

aspect X {
before(): within(FieldsE) && get(* *) {
System.out.println(thisEnclosingJoinPointStaticPart.getSignature());
}
}

+ 21
- 0
tests/features190/efficientTJP/Four.java View File

@@ -0,0 +1,21 @@
public class Four {
public static void main(String []argv) {
new Four().run();
}

public void run() {
try {
System.out.println("run() running");
throw new IllegalStateException();
} catch (Throwable t) {
System.out.println("caught something");
}
}

}

aspect X {
before(Throwable t): handler(Throwable) && args(t) {
System.out.println(thisJoinPointStaticPart.getSignature());
}
}

+ 21
- 0
tests/features190/efficientTJP/FourA.java View File

@@ -0,0 +1,21 @@
public class FourA {
public static void main(String []argv) {
new FourA().run();
}

public void run() {
try {
System.out.println("run() running");
throw new IllegalStateException();
} catch (Throwable t) {
System.out.println("caught something");
}
}

}

aspect X {
before(Throwable t): handler(Throwable) && args(t) {
System.out.println(thisEnclosingJoinPointStaticPart.getSignature());
}
}

+ 24
- 0
tests/features190/efficientTJP/Init.java View File

@@ -0,0 +1,24 @@
public class Init {
public static void main(String []argv) {
new A();
new B();
}
}

class A {}
class B {}

aspect X {
before(): preinitialization(A.new(..)) && !within(X) {
System.out.println(thisJoinPointStaticPart.getSignature());
}
before(): preinitialization(A.new(..)) && !within(X) {
System.out.println(thisEnclosingJoinPointStaticPart.getSignature());
}
before(): initialization(B.new(..)) && !within(X) {
System.out.println(thisJoinPointStaticPart.getSignature());
}
before(): initialization(B.new(..)) && !within(X) {
System.out.println(thisEnclosingJoinPointStaticPart.getSignature());
}
}

+ 12
- 0
tests/features190/efficientTJP/One.java View File

@@ -0,0 +1,12 @@
public class One {
public static void main(String []argv) {
System.out.println("One running");
}
}

aspect X {
void around(): execution(* main(..)) {
System.out.println(thisJoinPoint.getSignature());
proceed();
}
}

+ 19
- 0
tests/features190/efficientTJP/Three.java View File

@@ -0,0 +1,19 @@
public class Three {
public static void main(String []argv) {
System.out.println("Three running");
new Three();
new Three("abc");
new Three(1,"abc");
}

Three() {}
Three(String s) {}
Three(int i, String s) {}
}

aspect X {
void around(): execution(new(..)) && !within(X) {
System.out.println(thisJoinPointStaticPart.getSignature());
proceed();
}
}

+ 19
- 0
tests/features190/efficientTJP/ThreeA.java View File

@@ -0,0 +1,19 @@
public class ThreeA {
public static void main(String []argv) {
System.out.println("ThreeA running");
new ThreeA();
new ThreeA("abc");
new ThreeA(1,"abc");
}

ThreeA() {}
ThreeA(String s) {}
ThreeA(int i, String s) {}
}

aspect X {
void around(): execution(new(..)) && !within(X) {
System.out.println(thisEnclosingJoinPointStaticPart.getSignature());
proceed();
}
}

+ 12
- 0
tests/features190/efficientTJP/Two.java View File

@@ -0,0 +1,12 @@
public class Two {
public static void main(String []argv) {
System.out.println("Two running");
}
}

aspect X {
void around(): execution(* main(..)) {
System.out.println(thisEnclosingJoinPointStaticPart.getSignature());
proceed();
}
}

+ 14
- 4
tests/src/org/aspectj/systemtest/ajc151/NewarrayJoinpointTests.java View File

@@ -13,13 +13,13 @@ package org.aspectj.systemtest.ajc151;
import java.io.File;
import java.util.List;

import junit.framework.Test;

import org.aspectj.asm.AsmManager;
import org.aspectj.asm.IProgramElement;
import org.aspectj.asm.IRelationship;
import org.aspectj.testing.XMLBasedAjcTestCase;

import junit.framework.Test;

/*
* The design:
*
@@ -59,6 +59,15 @@ public class NewarrayJoinpointTests extends XMLBasedAjcTestCase {
runTest("thisjoinpoint");
}

public void testThisJoinPoint19() {
try {
System.setProperty("ASPECTJ_OPTS", "-Xajruntimetarget:1.9");
runTest("thisjoinpoint");
} finally {
System.setProperty("ASPECTJ_OPTS", "");
}
}

public void testDifferentAdviceKinds() {
runTest("different advice kinds");
}
@@ -105,9 +114,9 @@ public class NewarrayJoinpointTests extends XMLBasedAjcTestCase {
assertTrue("Couldnt find 'Five' type in the model", ipe != null);
List<IProgramElement> kids = ipe.getChildren();
assertTrue("Couldn't find 'main' method in the 'Five' type", kids != null && kids.size() == 1);
List<IProgramElement> codenodes = ((IProgramElement) kids.get(0)).getChildren();
List<IProgramElement> codenodes = kids.get(0).getChildren();
assertTrue("Couldn't find nodes below 'main' method", codenodes != null && codenodes.size() == 1);
IProgramElement arrayCtorCallNode = (IProgramElement) codenodes.get(0);
IProgramElement arrayCtorCallNode = codenodes.get(0);
String exp = "constructor-call(void java.lang.Integer[].<init>(int))";
assertTrue("Expected '" + exp + "' but found " + arrayCtorCallNode.toString(), arrayCtorCallNode.toString().equals(exp));
List<IRelationship> rels = AsmManager.lastActiveStructureModel.getRelationshipMap().get(arrayCtorCallNode);
@@ -119,6 +128,7 @@ public class NewarrayJoinpointTests extends XMLBasedAjcTestCase {
return XMLBasedAjcTestCase.loadSuite(NewarrayJoinpointTests.class);
}

@Override
protected File getSpecFile() {
return getClassResource("newarray_joinpoint.xml");
}

+ 1
- 1
tests/src/org/aspectj/systemtest/ajc190/AllTestsAspectJ190.java View File

@@ -20,7 +20,7 @@ public class AllTestsAspectJ190 {
// $JUnit-BEGIN$
suite.addTest(Ajc190Tests.suite());
suite.addTest(SanityTests19.suite());
// suite.addTest(EfficientTJPTests.suite());
suite.addTest(EfficientTJPTests.suite());
suite.addTest(ModuleTests.suite());
suite.addTest(Annotations.suite());
// $JUnit-END$

+ 126
- 0
tests/src/org/aspectj/systemtest/ajc190/EfficientTJPTests.java View File

@@ -0,0 +1,126 @@
/*******************************************************************************
* Copyright (c) 2018 Contributors
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.aspectj.systemtest.ajc190;

import java.io.File;

import org.aspectj.apache.bcel.classfile.JavaClass;
import org.aspectj.apache.bcel.classfile.Method;
import org.aspectj.testing.XMLBasedAjcTestCase;

import junit.framework.Assert;
import junit.framework.Test;

/**
*
* @author Andy Clement
*/
public class EfficientTJPTests extends XMLBasedAjcTestCase {

public void testThisJoinPointMethodExecution() {
// Test setting it via sys props rather than passing the option directly
try {
System.setProperty("ASPECTJ_OPTS", "-Xajruntimetarget:1.9");
runTest("tjp 1");
checkPreClinitContains("One","Factory.makeMethodSJP");
} finally {
System.setProperty("ASPECTJ_OPTS", "");
}
}

public void testThisEnclosingJoinPointMethodExecution() {
runTest("tjp 2");
checkPreClinitContains("Two","Factory.makeMethodESJP");
}

public void testThisJoinPointConstructorExecution() {
runTest("tjp 3");
checkPreClinitContains("Three","Factory.makeConstructorSJP");
}

public void testThisEnclosingJoinPointConstructorExecution() {
runTest("tjp 3a");
checkPreClinitContains("ThreeA","Factory.makeConstructorESJP");
}

public void testThisJoinPointHandler() {
runTest("tjp 4");
checkPreClinitContains("Four","Factory.makeCatchClauseSJP");
}

public void testThisEnclosingJoinPointHandler() {
runTest("tjp 4a");
checkPreClinitContains("FourA","Factory.makeMethodESJP");
}
public void testThisJoinPointFieldGet() {
runTest("tjp get fields");
checkPreClinitContains("Fields","Factory.makeFieldSJP");
}
public void testThisEnclosingJoinPointFieldGet() {
runTest("tjp get fieldsE");
checkPreClinitContains("FieldsE","Factory.makeMethodESJP");
}
public void testThisJoinPointFieldSet() {
runTest("tjp set fields");
checkPreClinitContains("Fields2","Factory.makeFieldSJP");
}

public void testThisJoinPointClinit() {
runTest("tjp clinit");
checkPreClinitContains("Clinit","Factory.makeInitializerSJP");
}

public void testThisEnclosingJoinPointClinit() {
runTest("tejp clinit");
checkPreClinitContains("ClinitE","Factory.makeInitializerESJP");
}
public void testThisJoinPointAdvice() {
// covers enclosing joinpoint too
runTest("tjp advice");
checkPreClinitContains("X","Factory.makeAdviceESJP");
}
public void testThisJoinPointInitialization() {
runTest("tjp init");
checkPreClinitContains("A","Factory.makeConstructorESJP");
checkPreClinitContains("B","Factory.makeConstructorESJP");
}

// ///////////////////////////////////////
public static Test suite() {
return XMLBasedAjcTestCase.loadSuite(EfficientTJPTests.class);
}

@Override
protected File getSpecFile() {
return getClassResource("features190.xml");
}
public void checkPreClinitContains(String classname, String text) {
try {
JavaClass jc = getClassFrom(ajc.getSandboxDirectory(), classname);
Method[] meths = jc.getMethods();
for (int i = 0; i < meths.length; i++) {
Method method = meths[i];
if (method.getName().equals("ajc$preClinit")) {
String code = method.getCode().getCodeString();
assertTrue("Expected to contain '"+text+"':\n"+code,code.contains(text));
return;
}
}
Assert.fail("Unable to find ajc$preClinit in class "+classname);
} catch (Exception e) {
Assert.fail(e.toString());
}
}

}

+ 172
- 0
tests/src/org/aspectj/systemtest/ajc190/features190.xml View File

@@ -0,0 +1,172 @@
<!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd"[]>

<suite>

<ajc-test dir="features190/efficientTJP" title="tjp 1">
<compile files="One.java" options="-1.8"/>
<run class="One">
<stdout>
<line text="void One.main(String[])"/>
<line text="One running"/>
</stdout>
</run>
</ajc-test>

<ajc-test dir="features190/efficientTJP" title="tjp 2">
<compile files="Two.java" options="-Xajruntimetarget:1.9 -1.8"/>
<run class="Two">
<stdout>
<line text="void Two.main(String[])"/>
<line text="Two running"/>
</stdout>
</run>
</ajc-test>
<ajc-test dir="features190/efficientTJP" title="tjp 3">
<compile files="Three.java" options="-Xajruntimetarget:1.9 -1.8"/>
<run class="Three">
<stdout>
<line text="Three running"/>
<line text="Three()"/>
<line text="Three(String)"/>
<line text="Three(int, String)"/>
</stdout>
</run>
</ajc-test>
<ajc-test dir="features190/efficientTJP" title="tjp 3a">
<compile files="ThreeA.java" options="-Xajruntimetarget:1.9 -1.8"/>
<run class="ThreeA">
<stdout>
<line text="ThreeA running"/>
<line text="ThreeA()"/>
<line text="ThreeA(String)"/>
<line text="ThreeA(int, String)"/>
</stdout>
</run>
</ajc-test>
<ajc-test dir="features190/efficientTJP" title="tjp 4">
<compile files="Four.java" options="-Xajruntimetarget:1.9 -1.8"/>
<run class="Four">
<stdout>
<line text="run() running"/>
<line text="catch(Throwable)"/>
<line text="caught something"/>
</stdout>
</run>
</ajc-test>
<ajc-test dir="features190/efficientTJP" title="tjp 4a">
<compile files="FourA.java" options="-Xajruntimetarget:1.9 -1.8"/>
<run class="FourA">
<stdout>
<line text="run() running"/>
<line text="void FourA.run()"/>
<line text="caught something"/>
</stdout>
</run>
</ajc-test>
<ajc-test dir="features190/efficientTJP" title="tjp get fields">
<compile files="Fields.java" options="-Xajruntimetarget:1.9 -1.8"/>
<run class="Fields">
<stdout>
<line text="int Fields.a"/>
<line text="String Fields.s"/>
<line text="double Fields.d"/>
<line text="Fields.Inner Fields.obj"/>
<line text="short Fields.ps"/>
<line text="float Fields.fs"/>
<line text="long Fields.ls"/>
<line text="byte Fields.bs"/>
<line text="char Fields.cs"/>
<line text="int Fields.as"/>
<line text="String Fields.ss"/>
<line text="double Fields.ds"/>
<line text="Fields.Inner Fields.objs"/>
</stdout>
</run>
</ajc-test>
<ajc-test dir="features190/efficientTJP" title="tjp get fieldsE">
<compile files="FieldsE.java" options="-Xajruntimetarget:1.9 -1.8"/>
<run class="FieldsE">
<stdout>
<line text="void FieldsE.main(String[])"/>
<line text="void FieldsE.main(String[])"/>
<line text="void FieldsE.main(String[])"/>
<line text="void FieldsE.main(String[])"/>
<line text="void FieldsE.main(String[])"/>
<line text="void FieldsE.main(String[])"/>
<line text="void FieldsE.main(String[])"/>
<line text="void FieldsE.main(String[])"/>
<line text="void FieldsE.main(String[])"/>
<line text="void FieldsE.main(String[])"/>
<line text="void FieldsE.main(String[])"/>
<line text="void FieldsE.main(String[])"/>
<line text="void FieldsE.main(String[])"/>
</stdout>
</run>
</ajc-test>
<ajc-test dir="features190/efficientTJP" title="tjp set fields">
<compile files="Fields2.java" options="-Xajruntimetarget:1.9 -1.8"/>
<run class="Fields2">
<stdout>
<line text="int Fields2.a"/>
<line text="short Fields2.ps"/>
<line text="double Fields2.d"/>
<line text="Fields2.Inner Fields2.obj"/>
<line text="String Fields2.s"/>
<line text="float Fields2.fs"/>
<line text="long Fields2.ls"/>
<line text="byte Fields2.bs"/>
<line text="char Fields2.cs"/>
</stdout>
</run>
</ajc-test>
<ajc-test dir="features190/efficientTJP" title="tjp clinit">
<compile files="Clinit.java" options="-Xajruntimetarget:1.9 -1.8"/>
<run class="Clinit">
<stdout>
<line text="Clinit.&lt;clinit&gt;"/>
<line text="Clinit.Inner.&lt;clinit&gt;"/>
</stdout>
</run>
</ajc-test>
<ajc-test dir="features190/efficientTJP" title="tejp clinit">
<compile files="ClinitE.java" options="-Xajruntimetarget:1.9 -1.8"/>
<run class="ClinitE">
<stdout>
<line text="ClinitE.&lt;clinit&gt;"/>
<line text="ClinitE.Inner.&lt;clinit&gt;"/>
</stdout>
</run>
</ajc-test>
<ajc-test dir="features190/efficientTJP" title="tjp advice">
<compile files="Advice.java" options="-Xajruntimetarget:1.9 -1.8"/>
<run class="Advice">
<stdout>
<line text="tjp:void X.before()"/>
<line text="tejp:void X.before()"/>
</stdout>
</run>
</ajc-test>
<ajc-test dir="features190/efficientTJP" title="tjp init">
<compile files="Init.java" options="-Xajruntimetarget:1.9 -1.8"/>
<run class="Init">
<stdout>
<line text="A()"/>
<line text="A()"/>
<line text="B()"/>
<line text="B()"/>
</stdout>
</run>
</ajc-test>
</suite>

+ 9
- 0
weaver/src/org/aspectj/weaver/bcel/BcelWorld.java View File

@@ -723,26 +723,32 @@ public class BcelWorld extends World implements Repository {

// / The repository interface methods

@Override
public JavaClass findClass(String className) {
return lookupJavaClass(classPath, className);
}

@Override
public JavaClass loadClass(String className) throws ClassNotFoundException {
return lookupJavaClass(classPath, className);
}

@Override
public void storeClass(JavaClass clazz) {
// doesn't need to do anything
}

@Override
public void removeClass(JavaClass clazz) {
throw new RuntimeException("Not implemented");
}

@Override
public JavaClass loadClass(Class clazz) throws ClassNotFoundException {
throw new RuntimeException("Not implemented");
}

@Override
public void clear() {
delegate.clear();
// throw new RuntimeException("Not implemented");
@@ -1291,10 +1297,12 @@ public class BcelWorld extends World implements Repository {

}

@Override
public TypeMap getTypeMap() {
return typeMap;
}

@Override
public boolean isLoadtimeWeaving() {
return false;
}
@@ -1306,6 +1314,7 @@ public class BcelWorld extends World implements Repository {
typeDelegateResolvers.add(typeDelegateResolver);
}

@Override
public void classWriteEvent(char[][] compoundName) {
typeMap.classWriteEvent(new String(CharOperation.concatWith(compoundName, '.')));
}

+ 268
- 8
weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java View File

@@ -53,15 +53,16 @@ import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.SourceLocation;
import org.aspectj.util.LangUtil;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.AjAttribute.WeaverState;
import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.Member;
import org.aspectj.weaver.MemberKind;
import org.aspectj.weaver.NameMangler;
import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.RuntimeVersion;
import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.SignatureUtils;
import org.aspectj.weaver.TypeVariable;
@@ -80,6 +81,45 @@ import org.aspectj.weaver.bcel.asm.StackMapAdder;
*/
public final class LazyClassGen {

private static final Type[] ARRAY_7STRING_INT = new Type[] { Type.STRING, Type.STRING, Type.STRING, Type.STRING, Type.STRING,
Type.STRING, Type.STRING, Type.INT };
private static final Type[] ARRAY_8STRING_INT = new Type[] { Type.STRING, Type.STRING, Type.STRING, Type.STRING, Type.STRING,
Type.STRING, Type.STRING, Type.STRING, Type.INT };

private static final Type[] PARAMSIGNATURE_MAKESJP_METHOD = new Type[] {
Type.STRING, Type.INT, Type.STRING, Type.CLASS, Type.CLASS_ARRAY, Type.STRING_ARRAY, Type.CLASS_ARRAY, Type.CLASS, Type.INT
};

private static final Type[] PARAMSIGNATURE_MAKESJP_CONSTRUCTOR = new Type[] {
Type.STRING, Type.INT, Type.CLASS, Type.CLASS_ARRAY, Type.STRING_ARRAY, Type.CLASS_ARRAY, Type.INT
};
private static final Type[] PARAMSIGNATURE_MAKESJP_CATCHCLAUSE = new Type[] {
Type.STRING, Type.CLASS, Type.CLASS, Type.STRING, Type.INT
};
private static final Type[] PARAMSIGNATURE_MAKESJP_FIELD = new Type[] {
Type.STRING, Type.INT, Type.STRING, Type.CLASS, Type.CLASS, Type.INT
};
private static final Type[] PARAMSIGNATURE_MAKESJP_INITIALIZER = new Type[] {
Type.STRING, Type.INT, Type.CLASS, Type.INT
};
private static final Type[] PARAMSIGNATURE_MAKESJP_MONITOR = new Type[] {
Type.STRING, Type.CLASS, Type.INT
};

private static final Type[] PARAMSIGNATURE_MAKESJP_ADVICE = new Type[] {
Type.STRING, Type.INT, Type.STRING, Type.CLASS, Type.CLASS_ARRAY, Type.STRING_ARRAY,
Type.CLASS_ARRAY, Type.CLASS, Type.INT
};

private static final int ACC_SYNTHETIC = 0x1000;

private static final String[] NO_STRINGS = new String[0];
@@ -1232,6 +1272,7 @@ public final class LazyClassGen {

List<Map.Entry<BcelShadow, Field>> entries = new ArrayList<Map.Entry<BcelShadow, Field>>(tjpFields.entrySet());
Collections.sort(entries, new Comparator<Map.Entry<BcelShadow, Field>>() {
@Override
public int compare(Map.Entry<BcelShadow, Field> a, Map.Entry<BcelShadow, Field> b) {
return (a.getValue()).getName().compareTo((b.getValue()).getName());
}
@@ -1253,6 +1294,10 @@ public final class LazyClassGen {
}

private void initializeTjp(InstructionFactory fact, InstructionList list, Field field, BcelShadow shadow) {
if (world.getTargetAspectjRuntimeLevel() == RuntimeVersion.V1_9) {
initializeTjpOptimal(fact, list, field, shadow);
return;
}
boolean fastSJP = false;
// avoid fast SJP if it is for an enclosing joinpoint
boolean isFastSJPAvailable = shadow.getWorld().isTargettingRuntime1_6_10()
@@ -1274,9 +1319,7 @@ public final class LazyClassGen {
String signatureMakerName = SignatureUtils.getSignatureMakerName(sig);
ObjectType signatureType = new ObjectType(SignatureUtils.getSignatureType(sig));
UnresolvedType[] exceptionTypes = null;
if (world.isTargettingAspectJRuntime12()) { // TAG:SUPPORTING12: We
// didn't have optimized
// factory methods in 1.2
if (world.isTargettingAspectJRuntime12()) { // TAG:SUPPORTING12: We didn't have optimized factory methods in 1.2
list.append(InstructionFactory.PUSH(cp, SignatureUtils.getSignatureString(sig, shadow.getWorld())));
list.append(fact.createInvoke(factoryType.getClassName(), signatureMakerName, signatureType, Type.STRINGARRAY1,
Constants.INVOKEVIRTUAL));
@@ -1370,6 +1413,7 @@ public final class LazyClassGen {
list.append(fact.createInvoke(factoryType.getClassName(), signatureMakerName, signatureType, Type.STRINGARRAY2,
Constants.INVOKEVIRTUAL));
} else {
// TODO looks like this block is unused code
list.append(InstructionFactory.PUSH(cp, SignatureUtils.getSignatureString(sig, shadow.getWorld())));
list.append(fact.createInvoke(factoryType.getClassName(), signatureMakerName, signatureType, Type.STRINGARRAY1,
Constants.INVOKEVIRTUAL));
@@ -1415,10 +1459,208 @@ public final class LazyClassGen {
}
}

private static final Type[] ARRAY_7STRING_INT = new Type[] { Type.STRING, Type.STRING, Type.STRING, Type.STRING, Type.STRING,
Type.STRING, Type.STRING, Type.INT };
private static final Type[] ARRAY_8STRING_INT = new Type[] { Type.STRING, Type.STRING, Type.STRING, Type.STRING, Type.STRING,
Type.STRING, Type.STRING, Type.STRING, Type.INT };
public String getFactoryMethod(Field field, BcelShadow shadow) {
StringBuilder b = new StringBuilder();
b.append("make");
MemberKind kind = shadow.getSignature().getKind();
if (kind.equals(Member.METHOD)) {
b.append("Method");
} else if (kind.equals(Member.CONSTRUCTOR)) {
b.append("Constructor");
} else if (kind.equals(Member.HANDLER)) {
b.append("CatchClause");
} else if (kind.equals(Member.FIELD)) {
b.append("Field");
} else if (kind.equals(Member.STATIC_INITIALIZATION)) {
b.append("Initializer");
} else if (kind.equals(Member.MONITORENTER)) {
b.append("Lock");
} else if (kind.equals(Member.MONITOREXIT)) {
b.append("Unlock");
} else if (kind.equals(Member.ADVICE)) {
b.append("Advice");
} else {
throw new IllegalStateException(kind.toString());
}
if (staticTjpType.equals(field.getType())) {
b.append("SJP");
} else if (enclosingStaticTjpType.equals(field.getType())) {
b.append("ESJP");
}
return b.toString();
}
/**
* Generate optimal joinpoint initialization code.
*
* As of version 1.9.1 the runtime includes new factory methods for joinpoints that take classes, not strings
* and using them requires different code generation. Using these instead of the old ones means we can avoid
* deferred classloading for these types. By using the LDC instruction that loads classes, it also means
* anything modifying woven code and changing type names will also pick up on these references.
*/
private void initializeTjpOptimal(InstructionFactory fact, InstructionList list, Field field, BcelShadow shadow) {
list.append(InstructionFactory.createLoad(factoryType, 0));
pushString(list, shadow.getKind().getName());
String factoryMethod = getFactoryMethod(field, shadow);
Member sig = shadow.getSignature();
BcelWorld w = shadow.getWorld();

if (sig.getKind().equals(Member.METHOD)) {
pushInt(list, sig.getModifiers(w));
pushString(list, sig.getName());
pushClass(list, sig.getDeclaringType());
pushClasses(list, sig.getParameterTypes());
pushStrings(list, sig.getParameterNames(w));
pushClasses(list, sig.getExceptions(w));
pushClass(list, sig.getReturnType());
pushInt(list, shadow.getSourceLine());
list.append(fact.createInvoke(factoryType.getClassName(), factoryMethod, field.getType(),
PARAMSIGNATURE_MAKESJP_METHOD, Constants.INVOKEVIRTUAL));
} else if (sig.getKind().equals(Member.CONSTRUCTOR)) {
if (w.isJoinpointArrayConstructionEnabled() && sig.getDeclaringType().isArray()) {
pushInt(list, Modifier.PUBLIC);
pushClass(list, sig.getDeclaringType());
pushClasses(list, sig.getParameterTypes());
pushStrings(list, null);
pushClasses(list, null);
} else {
pushInt(list, sig.getModifiers(w));
pushClass(list, sig.getDeclaringType());
pushClasses(list, sig.getParameterTypes());
pushStrings(list, sig.getParameterNames(w));
pushClasses(list, sig.getExceptions(w));
}
pushInt(list, shadow.getSourceLine());
list.append(fact.createInvoke(factoryType.getClassName(), factoryMethod, field.getType(),
PARAMSIGNATURE_MAKESJP_CONSTRUCTOR, Constants.INVOKEVIRTUAL));
} else if (sig.getKind().equals(Member.HANDLER)) {
pushClass(list, sig.getDeclaringType());
pushClass(list, sig.getParameterTypes()[0]);
String pname = null;
String[] pnames = sig.getParameterNames(w);
if (pnames != null && pnames.length>0) {
pname = pnames[0];
}
pushString(list, pname);
pushInt(list, shadow.getSourceLine());
list.append(fact.createInvoke(factoryType.getClassName(), factoryMethod, field.getType(),
PARAMSIGNATURE_MAKESJP_CATCHCLAUSE, Constants.INVOKEVIRTUAL));
} else if (sig.getKind().equals(Member.FIELD)) {
pushInt(list, sig.getModifiers(w));
pushString(list, sig.getName());
// see pr227401
UnresolvedType dType = sig.getDeclaringType();
if (dType.getTypekind() == TypeKind.PARAMETERIZED || dType.getTypekind() == TypeKind.GENERIC) {
dType = sig.getDeclaringType().resolve(world).getGenericType();
}
pushClass(list, dType);
pushClass(list, sig.getReturnType());
pushInt(list,shadow.getSourceLine());
list.append(fact.createInvoke(factoryType.getClassName(), factoryMethod, field.getType(),
PARAMSIGNATURE_MAKESJP_FIELD, Constants.INVOKEVIRTUAL));
} else if (sig.getKind().equals(Member.STATIC_INITIALIZATION)) {
pushInt(list, sig.getModifiers(w));
pushClass(list, sig.getDeclaringType());
pushInt(list, shadow.getSourceLine());
list.append(fact.createInvoke(factoryType.getClassName(), factoryMethod, field.getType(),
PARAMSIGNATURE_MAKESJP_INITIALIZER, Constants.INVOKEVIRTUAL));
} else if (sig.getKind().equals(Member.MONITORENTER)) {
pushClass(list, sig.getDeclaringType());
pushInt(list, shadow.getSourceLine());
list.append(fact.createInvoke(factoryType.getClassName(), factoryMethod, field.getType(),
PARAMSIGNATURE_MAKESJP_MONITOR, Constants.INVOKEVIRTUAL));
} else if (sig.getKind().equals(Member.MONITOREXIT)) {
pushClass(list, sig.getDeclaringType());
pushInt(list, shadow.getSourceLine());
list.append(fact.createInvoke(factoryType.getClassName(), factoryMethod, field.getType(),
PARAMSIGNATURE_MAKESJP_MONITOR, Constants.INVOKEVIRTUAL));
} else if (sig.getKind().equals(Member.ADVICE)) {
pushInt(list, sig.getModifiers(w));
pushString(list, sig.getName());
pushClass(list, sig.getDeclaringType());
pushClasses(list, sig.getParameterTypes());
pushStrings(list, sig.getParameterNames(w));
pushClasses(list, sig.getExceptions(w));
pushClass(list, sig.getReturnType());
pushInt(list, shadow.getSourceLine());
list.append(fact.createInvoke(factoryType.getClassName(), factoryMethod, field.getType(),
PARAMSIGNATURE_MAKESJP_ADVICE, Constants.INVOKEVIRTUAL));
} else {
throw new IllegalStateException("not sure what to do: "+shadow);
}
list.append(fact.createFieldAccess(getClassName(), field.getName(), field.getType(), Constants.PUTSTATIC));
}

private void pushStrings(InstructionList list, String[] strings) {
// Build an array loaded with the strings
if (strings == null || strings.length == 0) {
list.append(InstructionFactory.ACONST_NULL);
} else {
list.append(InstructionFactory.PUSH(cp, strings.length));
list.append(fact.createNewArray(Type.STRING, (short)1));
for (int s=0;s<strings.length;s++) {
list.append(InstructionFactory.DUP);
list.append(InstructionFactory.PUSH(cp, s));
list.append(InstructionFactory.PUSH(cp, strings[s]));
list.append(InstructionFactory.AASTORE);
}
}
}

private void pushClass(InstructionList list, UnresolvedType type) {
if (type.isPrimitiveType()) {
if (type.getSignature().equals("I")) {
list.append(fact.createGetStatic("java/lang/Integer","TYPE", Type.CLASS));
} else if (type.getSignature().equals("D")) {
list.append(fact.createGetStatic("java/lang/Double","TYPE", Type.CLASS));
} else if (type.getSignature().equals("S")) {
list.append(fact.createGetStatic("java/lang/Short","TYPE", Type.CLASS));
} else if (type.getSignature().equals("J")) {
list.append(fact.createGetStatic("java/lang/Long","TYPE", Type.CLASS));
} else if (type.getSignature().equals("F")) {
list.append(fact.createGetStatic("java/lang/Float","TYPE", Type.CLASS));
} else if (type.getSignature().equals("C")) {
list.append(fact.createGetStatic("java/lang/Character","TYPE", Type.CLASS));
} else if (type.getSignature().equals("B")) {
list.append(fact.createGetStatic("java/lang/Byte","TYPE", Type.CLASS));
} else if (type.getSignature().equals("Z")) {
list.append(fact.createGetStatic("java/lang/Boolean","TYPE", Type.CLASS));
} else if (type.getSignature().equals("V")) {
list.append(InstructionFactory.ACONST_NULL);
}
return;
}
String classString = makeLdcClassString(type);
if (classString == null) {
list.append(InstructionFactory.ACONST_NULL);
} else {
list.append(fact.PUSHCLASS(cp, classString));
}
}

private void pushClasses(InstructionList list, UnresolvedType[] types) {
// Build an array loaded with the class objects
if (types == null || types.length == 0) {
list.append(InstructionFactory.ACONST_NULL);
} else {
list.append(InstructionFactory.PUSH(cp, types.length));
list.append(fact.createNewArray(Type.CLASS, (short)1));
for (int t=0;t<types.length;t++) {
list.append(InstructionFactory.DUP);
list.append(InstructionFactory.PUSH(cp, t));
pushClass(list, types[t]);
list.append(InstructionFactory.AASTORE);
}
}
}

private final void pushString(InstructionList list, String string) {
list.append(InstructionFactory.PUSH(cp, string));
}
private final void pushInt(InstructionList list, int value) {
list.append(InstructionFactory.PUSH(cp, value));
}

protected String makeString(int i) {
return Integer.toString(i, 16); // ??? expensive
@@ -1438,6 +1680,24 @@ public final class LazyClassGen {
}
}
}
protected String makeLdcClassString(UnresolvedType type) {
if (type.isVoid() || type.isPrimitiveType()) {
return null;
}
if (type.isArray()) {
return type.getSignature();
} else {
if (type.isParameterizedType()) {
type = type.getRawType();
}
String signature = type.getSignature();
if (signature.length() ==1 ) {
return signature;
}
return signature.substring(1,signature.length()-1);
}
}

protected String makeString(UnresolvedType[] types) {
if (types == null) {

Loading…
Cancel
Save