]> source.dussan.org Git - aspectj.git/commitdiff
Bug#531694: generate more optional thisJoinPoint construction code
authorAndy Clement <aclement@pivotal.io>
Wed, 28 Feb 2018 19:53:14 +0000 (11:53 -0800)
committerAndy Clement <aclement@pivotal.io>
Sat, 10 Mar 2018 01:18:45 +0000 (17:18 -0800)
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).

34 files changed:
bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionFactory.java
bcel-builder/src/org/aspectj/apache/bcel/generic/Type.java
build/products/tools/dist/lib/aspectjrt.jar
build/updateAspectjrt.sh [new file with mode: 0755]
lib/aspectj/lib/aspectjrt.jar
lib/bcel/bcel-src.zip
lib/bcel/bcel-verifier.jar
lib/bcel/bcel.jar
lib/test/aspectjrt.jar
org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/ConfigParser.java
org.aspectj.matcher/src/org/aspectj/weaver/Constants.java
org.aspectj.matcher/src/org/aspectj/weaver/RuntimeVersion.java [new file with mode: 0644]
org.aspectj.matcher/src/org/aspectj/weaver/World.java
runtime/src/org/aspectj/runtime/reflect/Factory.java
tests/features190/efficientTJP/Advice.java [new file with mode: 0644]
tests/features190/efficientTJP/Clinit.java [new file with mode: 0644]
tests/features190/efficientTJP/ClinitE.java [new file with mode: 0644]
tests/features190/efficientTJP/Fields.java [new file with mode: 0644]
tests/features190/efficientTJP/Fields2.java [new file with mode: 0644]
tests/features190/efficientTJP/FieldsE.java [new file with mode: 0644]
tests/features190/efficientTJP/Four.java [new file with mode: 0644]
tests/features190/efficientTJP/FourA.java [new file with mode: 0644]
tests/features190/efficientTJP/Init.java [new file with mode: 0644]
tests/features190/efficientTJP/One.java [new file with mode: 0644]
tests/features190/efficientTJP/Three.java [new file with mode: 0644]
tests/features190/efficientTJP/ThreeA.java [new file with mode: 0644]
tests/features190/efficientTJP/Two.java [new file with mode: 0644]
tests/src/org/aspectj/systemtest/ajc151/NewarrayJoinpointTests.java
tests/src/org/aspectj/systemtest/ajc190/AllTestsAspectJ190.java
tests/src/org/aspectj/systemtest/ajc190/EfficientTJPTests.java [new file with mode: 0644]
tests/src/org/aspectj/systemtest/ajc190/features190.xml [new file with mode: 0644]
weaver/src/org/aspectj/weaver/bcel/BcelWorld.java
weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java

index c5db1904ab5ab55269d888c0d76091301e02f9f9..4e1e6c8a8eaa04791586be137bc1f2cc1c0cbdfa 100644 (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));
index e1dc47348ed033301b776a7a521e050535a4ef20..9ce007b4f35a96aeee3d12bb6abd34cddf99d4d9 100644 (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);
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..935830ebc176feaae89350e38014fe36b0f380dc 100644 (file)
Binary files a/build/products/tools/dist/lib/aspectjrt.jar and b/build/products/tools/dist/lib/aspectjrt.jar differ
diff --git a/build/updateAspectjrt.sh b/build/updateAspectjrt.sh
new file mode 100755 (executable)
index 0000000..03fcd7f
--- /dev/null
@@ -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
index ef06aa7fde25abce3204973886a00967b36c86f9..935830ebc176feaae89350e38014fe36b0f380dc 100644 (file)
Binary files a/lib/aspectj/lib/aspectjrt.jar and b/lib/aspectj/lib/aspectjrt.jar differ
index 1cbe73979fb21d8f855bdc0ce4e77776879f0d64..b98e0889ea88f13d2d13087c7a5e8ef3a97a6c3f 100644 (file)
Binary files a/lib/bcel/bcel-src.zip and b/lib/bcel/bcel-src.zip differ
index b55ed6429665e6bfc63d4ad70e07e8914386e199..cee235ad9d0022efc94b3768069128512a43f161 100644 (file)
Binary files a/lib/bcel/bcel-verifier.jar and b/lib/bcel/bcel-verifier.jar differ
index 2306787c522b960da9977a3d817ff7ab44968aef..793bf0d0d7cafcdf513480db20c64f2e366e9c4f 100644 (file)
Binary files a/lib/bcel/bcel.jar and b/lib/bcel/bcel.jar differ
index f0c7d5f7cb4ba08673c11920c483873d1d2d0277..935830ebc176feaae89350e38014fe36b0f380dc 100644 (file)
Binary files a/lib/test/aspectjrt.jar and b/lib/test/aspectjrt.jar differ
index ada5639efdd00d6d6686796fbbada36b180106b4..0327191652a33ace627c323e2cebce04058c759a 100644 (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);
index b92a4b43990161c346dc170c01690b08e45bbeba..4c7873df02b8e323d251c7668a7e38c40da5a9b3 100644 (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";
                }
index 4b99a32abdc7e5e9f09eea2be42c50a7e2fa1d97..bdbde3853e45331cf65fbb6e91707fdd76880bb1 100644 (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;
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/RuntimeVersion.java b/org.aspectj.matcher/src/org/aspectj/weaver/RuntimeVersion.java
new file mode 100644 (file)
index 0000000..0cf90a9
--- /dev/null
@@ -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;
+       }
+}
index 19d61f5be9580d02123478cfd176617abce1f107..644f232acf969ed88653b231c5112e971f107ca1 100644 (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;
        }
 
index 06e07387332827d6e934666b7f06aa40d296e748..759a1367b71fac0b0899ec38138256d3c2ffc01a 100644 (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;
        }
diff --git a/tests/features190/efficientTJP/Advice.java b/tests/features190/efficientTJP/Advice.java
new file mode 100644 (file)
index 0000000..a85a445
--- /dev/null
@@ -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());
+       }
+
+}
diff --git a/tests/features190/efficientTJP/Clinit.java b/tests/features190/efficientTJP/Clinit.java
new file mode 100644 (file)
index 0000000..e8acea8
--- /dev/null
@@ -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());
+       }
+}
diff --git a/tests/features190/efficientTJP/ClinitE.java b/tests/features190/efficientTJP/ClinitE.java
new file mode 100644 (file)
index 0000000..a007a20
--- /dev/null
@@ -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());
+       }
+}
diff --git a/tests/features190/efficientTJP/Fields.java b/tests/features190/efficientTJP/Fields.java
new file mode 100644 (file)
index 0000000..ad12465
--- /dev/null
@@ -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());
+       }
+}
diff --git a/tests/features190/efficientTJP/Fields2.java b/tests/features190/efficientTJP/Fields2.java
new file mode 100644 (file)
index 0000000..0a8aed7
--- /dev/null
@@ -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());
+       }
+}
diff --git a/tests/features190/efficientTJP/FieldsE.java b/tests/features190/efficientTJP/FieldsE.java
new file mode 100644 (file)
index 0000000..51bc923
--- /dev/null
@@ -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());
+       }
+}
diff --git a/tests/features190/efficientTJP/Four.java b/tests/features190/efficientTJP/Four.java
new file mode 100644 (file)
index 0000000..9857c8c
--- /dev/null
@@ -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());
+       }
+}
diff --git a/tests/features190/efficientTJP/FourA.java b/tests/features190/efficientTJP/FourA.java
new file mode 100644 (file)
index 0000000..47694dc
--- /dev/null
@@ -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());
+       }
+}
diff --git a/tests/features190/efficientTJP/Init.java b/tests/features190/efficientTJP/Init.java
new file mode 100644 (file)
index 0000000..200ce18
--- /dev/null
@@ -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());
+       }
+}
diff --git a/tests/features190/efficientTJP/One.java b/tests/features190/efficientTJP/One.java
new file mode 100644 (file)
index 0000000..4fafcda
--- /dev/null
@@ -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();
+       }
+}
diff --git a/tests/features190/efficientTJP/Three.java b/tests/features190/efficientTJP/Three.java
new file mode 100644 (file)
index 0000000..479c7f7
--- /dev/null
@@ -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();
+       }
+}
diff --git a/tests/features190/efficientTJP/ThreeA.java b/tests/features190/efficientTJP/ThreeA.java
new file mode 100644 (file)
index 0000000..e3ffac9
--- /dev/null
@@ -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();
+       }
+}
diff --git a/tests/features190/efficientTJP/Two.java b/tests/features190/efficientTJP/Two.java
new file mode 100644 (file)
index 0000000..2d5d1da
--- /dev/null
@@ -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();
+       }
+}
index 9c92f848858e24f659cc15b5cde8568dc65edfe5..9654c04ddc52f0a5c08148688716a89f04b378eb 100644 (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");
        }
index 2ebc12e7c6c8e916a8994a7f0f1c3f938e5d510c..d0f7734f3ed6f7ac4cef0147525970d37b00c9ed 100644 (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$
diff --git a/tests/src/org/aspectj/systemtest/ajc190/EfficientTJPTests.java b/tests/src/org/aspectj/systemtest/ajc190/EfficientTJPTests.java
new file mode 100644 (file)
index 0000000..3564f94
--- /dev/null
@@ -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());
+               }
+       }
+
+}
diff --git a/tests/src/org/aspectj/systemtest/ajc190/features190.xml b/tests/src/org/aspectj/systemtest/ajc190/features190.xml
new file mode 100644 (file)
index 0000000..1fb931e
--- /dev/null
@@ -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>
index 395e07e1095e625d652b4a6c86071f45ae482635..4ade1e1256dc74cf1496362594416c47ad119e2d 100644 (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, '.')));
        }
index 24240d7caa7529da9517f77da33163cdb448bd0e..95ef524b5fd3f14fb79dbf9c4fa5f93345d9df58 100644 (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) {