summaryrefslogtreecommitdiffstats
path: root/weaver
diff options
context:
space:
mode:
authoraclement <aclement>2008-09-17 19:49:01 +0000
committeraclement <aclement>2008-09-17 19:49:01 +0000
commit3a9d4a2bc3092d0e8bd92eec472ddd8203f8ece8 (patch)
tree4393287e055bae38f65c19d19f1d9b0776e27440 /weaver
parent98d29e0a89334d51682e6e36467f01808dfabc16 (diff)
downloadaspectj-3a9d4a2bc3092d0e8bd92eec472ddd8203f8ece8.tar.gz
aspectj-3a9d4a2bc3092d0e8bd92eec472ddd8203f8ece8.zip
can add stackmap attributes with: -1.6 -Xset:generateStackMaps=true
Diffstat (limited to 'weaver')
-rw-r--r--weaver/.classpath1
-rw-r--r--weaver/src/org/aspectj/weaver/World.java12
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java30
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/asm/AsmDetector.java26
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/asm/StackMapAdder.java63
5 files changed, 117 insertions, 15 deletions
diff --git a/weaver/.classpath b/weaver/.classpath
index 0ac3d80ff..adee2df97 100644
--- a/weaver/.classpath
+++ b/weaver/.classpath
@@ -12,5 +12,6 @@
<classpathentry kind="lib" path="/lib/commons/commons.jar" sourcepath="/lib/commons/commons-src.zip"/>
<classpathentry kind="lib" path="/lib/bcel/bcel.jar" sourcepath="/lib/bcel/bcel-src.zip"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="lib" path="/lib/asm/asm-3.1.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/weaver/src/org/aspectj/weaver/World.java b/weaver/src/org/aspectj/weaver/World.java
index 265ccbc08..ea1253a0a 100644
--- a/weaver/src/org/aspectj/weaver/World.java
+++ b/weaver/src/org/aspectj/weaver/World.java
@@ -111,6 +111,7 @@ public abstract class World implements Dump.INode {
// Xset'table options
private boolean runMinimalMemory = false;
private boolean shouldPipelineCompilation = true;
+ private boolean shouldGenerateStackMaps = false;
protected boolean bcelRepositoryCaching = xsetBCEL_REPOSITORY_CACHING_DEFAULT.equalsIgnoreCase("true");
private boolean fastMethodPacking = false;
private boolean completeBinaryTypes = false;
@@ -758,6 +759,7 @@ public abstract class World implements Dump.INode {
public final static String xsetDEBUG_BRIDGING = "debugBridging"; // default false
public final static String xsetBCEL_REPOSITORY_CACHING = "bcelRepositoryCaching";
public final static String xsetPIPELINE_COMPILATION = "pipelineCompilation";
+ public final static String xsetGENERATE_STACKMAPS = "generateStackMaps";
public final static String xsetPIPELINE_COMPILATION_DEFAULT = "true";
public final static String xsetCOMPLETE_BINARY_TYPES = "completeBinaryTypes";
public final static String xsetCOMPLETE_BINARY_TYPES_DEFAULT = "false";
@@ -1144,6 +1146,9 @@ public abstract class World implements Dump.INode {
s = p.getProperty(xsetPIPELINE_COMPILATION, xsetPIPELINE_COMPILATION_DEFAULT);
shouldPipelineCompilation = s.equalsIgnoreCase("true");
+
+ s = p.getProperty(xsetGENERATE_STACKMAPS, "false");
+ shouldGenerateStackMaps = s.equalsIgnoreCase("true");
s = p.getProperty(xsetCOMPLETE_BINARY_TYPES, xsetCOMPLETE_BINARY_TYPES_DEFAULT);
completeBinaryTypes = s.equalsIgnoreCase("true");
@@ -1183,7 +1188,12 @@ public abstract class World implements Dump.INode {
ensureAdvancedConfigurationProcessed();
return shouldPipelineCompilation;
}
-
+
+ public boolean shouldGenerateStackMaps() {
+ ensureAdvancedConfigurationProcessed();
+ return shouldGenerateStackMaps;
+ }
+
public void setIncrementalCompileCouldFollow(boolean b) {
incrementalCompileCouldFollow = b;
}
diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java
index 253e50e15..b70f7db94 100644
--- a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java
+++ b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java
@@ -65,6 +65,8 @@ import org.aspectj.weaver.WeaverStateInfo;
import org.aspectj.weaver.World;
import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.UnresolvedType.TypeKind;
+import org.aspectj.weaver.bcel.asm.AsmDetector;
+import org.aspectj.weaver.bcel.asm.StackMapAdder;
/**
* Lazy lazy lazy. We don't unpack the underlying class unless necessary. Things like new methods and annotations accumulate in here
@@ -79,23 +81,23 @@ public final class LazyClassGen {
int highestLineNumber = 0; // ---- JSR 45 info
- private final SortedMap /* <String, InlinedSourceFileInfo> */inlinedFiles = new TreeMap();
+ private SortedMap /* <String, InlinedSourceFileInfo> */inlinedFiles = new TreeMap();
private boolean regenerateGenericSignatureAttribute = false;
private BcelObjectType myType; // XXX is not set for types we create
private ClassGen myGen;
- private final ConstantPool cp;
- private final World world;
- private final String packageName = null;
-
- private final List /* BcelField */fields = new ArrayList();
- private final List /* LazyMethodGen */methodGens = new ArrayList();
- private final List /* LazyClassGen */classGens = new ArrayList();
- private final List /* AnnotationGen */annotations = new ArrayList();
+ private ConstantPool cp;
+ private World world;
+ private String packageName = null;
+
+ private List /* BcelField */fields = new ArrayList();
+ private List /* LazyMethodGen */methodGens = new ArrayList();
+ private List /* LazyClassGen */classGens = new ArrayList();
+ private List /* AnnotationGen */annotations = new ArrayList();
private int childCounter = 0;
- private final InstructionFactory fact;
+ private InstructionFactory fact;
private boolean isSerializable = false;
private boolean hasSerialVersionUIDField = false;
@@ -613,10 +615,10 @@ public final class LazyClassGen {
writeBack(world);
byte[] wovenClassFileData = myGen.getJavaClass().getBytes();
// if is java 6 class file
- // if (myGen.getMajor()>=Constants.MAJOR_1_6 && AsmDetector.isAsmAround) {
- // wovenClassFileData = StackMapAdder.addStackMaps(wovenClassFileData);
- // }
-
+ if (myGen.getMajor()>=Constants.MAJOR_1_6 && world.shouldGenerateStackMaps() && AsmDetector.isAsmAround) {
+ wovenClassFileData = StackMapAdder.addStackMaps(world,wovenClassFileData);
+ }
+
WeaverStateInfo wsi = myType.getWeaverState();// getOrCreateWeaverStateInfo();
if (wsi != null && wsi.isReweavable()) { // && !reweavableDataInserted
// reweavableDataInserted = true;
diff --git a/weaver/src/org/aspectj/weaver/bcel/asm/AsmDetector.java b/weaver/src/org/aspectj/weaver/bcel/asm/AsmDetector.java
new file mode 100644
index 000000000..415e38efc
--- /dev/null
+++ b/weaver/src/org/aspectj/weaver/bcel/asm/AsmDetector.java
@@ -0,0 +1,26 @@
+package org.aspectj.weaver.bcel.asm;
+
+import java.lang.reflect.Method;
+
+/**
+ * Determines if a version of asm is around that will enable us to add
+ * stack map attributes to classes that we produce.
+ *
+ * @author Andy Clement
+ */
+public class AsmDetector {
+
+ public static boolean isAsmAround;
+
+ static {
+ try {
+ Class reader = Class.forName("org.objectweb.asm.ClassReader");
+ Class visitor = Class.forName("org.objectweb.asm.ClassVisitor");
+ Method m = reader.getMethod("accept",new Class[]{visitor,Integer.TYPE});
+ isAsmAround = m!=null;
+ } catch (Exception e ) {
+ isAsmAround = false;
+ }
+ // System.out.println(isAsmAround?"ASM detected":"No ASM found");
+ }
+}
diff --git a/weaver/src/org/aspectj/weaver/bcel/asm/StackMapAdder.java b/weaver/src/org/aspectj/weaver/bcel/asm/StackMapAdder.java
new file mode 100644
index 000000000..96d6a8822
--- /dev/null
+++ b/weaver/src/org/aspectj/weaver/bcel/asm/StackMapAdder.java
@@ -0,0 +1,63 @@
+package org.aspectj.weaver.bcel.asm;
+
+import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.UnresolvedType;
+import org.aspectj.weaver.World;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+
+/**
+ * Uses asm to add the stack map attribute to methods in a class. The class is passed in as pure byte data
+ * and then a reader/writer process it. The writer is wired into the world so that types can be resolved
+ * and getCommonSuperClass() can be implemented without class loading using the context class loader.
+ *
+ * @author Andy Clement
+ */
+public class StackMapAdder {
+
+ public static byte[] addStackMaps(World world, byte[] data) {
+ try {
+ ClassReader cr = new ClassReader(data);
+ ClassWriter cw = new AspectJConnectClassWriter(world);
+ cr.accept(cw,0);
+ return cw.toByteArray();
+ } catch (Throwable t) {
+ System.err.println("AspectJ Internal Error: unable to add stackmap attributes. "+t.getMessage());
+ AsmDetector.isAsmAround=false;
+ return data;
+ }
+ }
+
+ private static class AspectJConnectClassWriter extends ClassWriter {
+ private World world;
+
+ public AspectJConnectClassWriter(World w) {
+ super(ClassWriter.COMPUTE_FRAMES);
+ this.world = w;
+ }
+
+ // Implementation of getCommonSuperClass() that avoids Class.forName()
+ protected String getCommonSuperClass(final String type1, final String type2) {
+
+ ResolvedType resolvedType1 = world.resolve(UnresolvedType.forName(type1.replace('/','.')));
+ ResolvedType resolvedType2 = world.resolve(UnresolvedType.forName(type2.replace('/','.')));
+
+ if (resolvedType1.isAssignableFrom(resolvedType2)) {
+ return type1;
+ }
+
+ if (resolvedType2.isAssignableFrom(resolvedType1)) {
+ return type2;
+ }
+
+ if (resolvedType1.isInterface() || resolvedType2.isInterface()) {
+ return "java/lang/Object";
+ } else {
+ do {
+ resolvedType1 = resolvedType1.getSuperclass();
+ } while (!resolvedType1.isAssignableFrom(resolvedType2));
+ return resolvedType1.getName().replace('.','/');
+ }
+ }
+ }
+}