Author: tcurdt
Date: Mon Dec 21 19:56:09 2009
New Revision: 892948
URL: http://svn.apache.org/viewvc?rev=892948&view=rev
Log:
applied fix for ASM rewriting contributed by Valery Silaev ([email protected])
Modified:
commons/sandbox/javaflow/trunk/src/main/java/org/apache/commons/javaflow/bytecode/transformation/asm/ContinuationMethodAdapter.java
commons/sandbox/javaflow/trunk/src/main/java/org/apache/commons/javaflow/bytecode/transformation/asm/ContinuationMethodAnalyzer.java
Modified:
commons/sandbox/javaflow/trunk/src/main/java/org/apache/commons/javaflow/bytecode/transformation/asm/ContinuationMethodAdapter.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/javaflow/trunk/src/main/java/org/apache/commons/javaflow/bytecode/transformation/asm/ContinuationMethodAdapter.java?rev=892948&r1=892947&r2=892948&view=diff
==============================================================================
---
commons/sandbox/javaflow/trunk/src/main/java/org/apache/commons/javaflow/bytecode/transformation/asm/ContinuationMethodAdapter.java
(original)
+++
commons/sandbox/javaflow/trunk/src/main/java/org/apache/commons/javaflow/bytecode/transformation/asm/ContinuationMethodAdapter.java
Mon Dec 21 19:56:09 2009
@@ -214,7 +214,7 @@
int argSize = params.length;
int ownerSize = opcode == INVOKESTATIC ? 0 : 1; // TODO
int ssize = currentFrame.getStackSize() - argSize - ownerSize;
- for (int i = 0; i < ssize; i++) {
+ for (int i = ssize - 1; i >= 0; i--) {
BasicValue value = (BasicValue) currentFrame.getStack(i);
if (value == null) {
mv.visitInsn(POP);
@@ -226,14 +226,15 @@
mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER,
PUSH_METHOD + "Object", "(Ljava/lang/Object;)V");
} else {
Type type = value.getType();
- mv.visitVarInsn(ALOAD, stackRecorderVar);
if (type.getSize() > 1) {
- mv.visitInsn(DUP); // dummy stack entry
+ mv.visitInsn(ACONST_NULL); // dummy stack entry
+ mv.visitVarInsn(ALOAD, stackRecorderVar);
mv.visitInsn(DUP2_X2); // swap2 for long/double
mv.visitInsn(POP2);
mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER,
getPushMethod(type), "(" + type.getDescriptor() + ")V");
mv.visitInsn(POP); // remove dummy stack entry
} else {
+ mv.visitVarInsn(ALOAD, stackRecorderVar);
mv.visitInsn(SWAP);
mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER,
getPushMethod(type), "(" + type.getDescriptor() + ")V");
}
Modified:
commons/sandbox/javaflow/trunk/src/main/java/org/apache/commons/javaflow/bytecode/transformation/asm/ContinuationMethodAnalyzer.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/javaflow/trunk/src/main/java/org/apache/commons/javaflow/bytecode/transformation/asm/ContinuationMethodAnalyzer.java?rev=892948&r1=892947&r2=892948&view=diff
==============================================================================
---
commons/sandbox/javaflow/trunk/src/main/java/org/apache/commons/javaflow/bytecode/transformation/asm/ContinuationMethodAnalyzer.java
(original)
+++
commons/sandbox/javaflow/trunk/src/main/java/org/apache/commons/javaflow/bytecode/transformation/asm/ContinuationMethodAnalyzer.java
Mon Dec 21 19:56:09 2009
@@ -30,6 +30,7 @@
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.InsnNode;
+import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.VarInsnNode;
@@ -40,6 +41,8 @@
import org.objectweb.asm.tree.analysis.SourceInterpreter;
import org.objectweb.asm.tree.analysis.SourceValue;
+import org.objectweb.asm.util.TraceMethodVisitor;
+
public class ContinuationMethodAnalyzer extends MethodNode implements Opcodes {
protected final String className;
protected final ClassVisitor cv;
@@ -84,18 +87,20 @@
return;
}
+{
+ TraceMethodVisitor mv = new TraceMethodVisitor();
+ System.err.println(name + desc);
+ for (int j = 0; j < instructions.size(); ++j) {
+ ((AbstractInsnNode) instructions.get(j)).accept(mv);
+ System.err.print(" " + mv.text.get(j)); // mv.text.get(j));
+ }
+ System.err.println();
+}
+
this.stackRecorderVar = maxLocals;
try {
moveNew();
-// TraceMethodVisitor mv = new TraceMethodVisitor();
-// System.err.println(name + desc);
-// for (int j = 0; j < instructions.size(); ++j) {
-// ((AbstractInsnNode) instructions.get(j)).accept(mv);
-// System.err.print(" " + mv.text.get(j)); // mv.text.get(j));
-// }
-// System.err.println();
-
// analyzer = new Analyzer(new BasicVerifier());
analyzer = new Analyzer(new SimpleVerifier() {
protected Class getClass(Type t) {
@@ -132,9 +137,23 @@
return framesa;
}
};
+
analyzer.analyze(className, this);
accept(new ContinuationMethodAdapter(this));
+{
+ TraceMethodVisitor mv = new TraceMethodVisitor();
+ System.err.println("=================");
+
+ System.err.println(name + desc);
+ for (int j = 0; j < instructions.size(); ++j) {
+ ((AbstractInsnNode) instructions.get(j)).accept(mv);
+ System.err.print(" " + mv.text.get(j)); // mv.text.get(j));
+ }
+ System.err.println();
+}
+
+
} catch (AnalyzerException ex) {
// TODO log the error or fail?
ex.printStackTrace();
@@ -210,126 +229,90 @@
int varOffset = stackRecorderVar + 1;
Type[] args = Type.getArgumentTypes(mnode.desc);
+
// optimizations for some common cases
if (args.length == 0) {
- next = node1;
- instructions.insert(nm, next); // NEW
- nm = next;
- if (requireDup) {
- next = new InsnNode(DUP);
- instructions.insert(nm, next);
- nm = next;
- }
+ final InsnList doNew = new InsnList();
+ doNew.add(node1); // NEW
+ if (requireDup)
+ doNew.add(new InsnNode(DUP));
+ instructions.insertBefore(nm, doNew);
+ nm = doNew.getLast();
continue;
}
if (args.length == 1 && args[0].getSize() == 1) {
- next = node1;
- instructions.insert(nm, next); // NEW
- nm = next;
+ final InsnList doNew = new InsnList();
+ doNew.add(node1); // NEW
if (requireDup) {
- next = new InsnNode(DUP);
- instructions.insert(nm, next);
- nm = next;
-
- next = new InsnNode(DUP2_X1);
- instructions.insert(nm, next);
- nm = next;
-
- next = new InsnNode(POP2);
- instructions.insert(nm, next);
- nm = next;
-
+ doNew.add(new InsnNode(DUP));
+ doNew.add(new InsnNode(DUP2_X1));
+ doNew.add(new InsnNode(POP2));
updateMaxStack = updateMaxStack < 2 ? 2 : updateMaxStack;
// a two extra slots for temp values
- } else {
- next = new InsnNode(SWAP);
- instructions.insert(nm, next);
- nm = next;
- }
+ } else
+ doNew.add(new InsnNode(SWAP));
+ instructions.insertBefore(nm, doNew);
+ nm = doNew.getLast();
continue;
}
+
// TODO this one untested!
if ((args.length == 1 && args[0].getSize() == 2) ||
(args.length == 2 && args[0].getSize() == 1 &&
args[1].getSize() == 1)) {
- next = node1;
- instructions.insert(nm, next); // NEW
- nm = next;
+ final InsnList doNew = new InsnList();
+ doNew.add(node1); // NEW
if (requireDup) {
- next = new InsnNode(DUP);
- instructions.insert(nm, next);
- nm = next;
-
- next = new InsnNode(DUP2_X2);
- instructions.insert(nm, next);
- nm = next;
-
- next = new InsnNode(POP2);
- instructions.insert(nm, next);
- nm = next;
-
+ doNew.add(new InsnNode(DUP));
+ doNew.add(new InsnNode(DUP2_X2));
+ doNew.add(new InsnNode(POP2));
updateMaxStack = updateMaxStack < 2 ? 2 : updateMaxStack;
// a two extra slots for temp values
} else {
- next = new InsnNode(DUP_X2);
- instructions.insert(nm, next);
- nm = next;
-
- next = new InsnNode(POP);
- instructions.insert(nm, next);
- nm = next;
-
+ doNew.add(new InsnNode(DUP_X2));
+ doNew.add(new InsnNode(POP));
updateMaxStack = updateMaxStack < 1 ? 1 : updateMaxStack;
// an extra slot for temp value
}
+ instructions.insertBefore(nm, doNew);
+ nm = doNew.getLast();
continue;
}
-
+
+ final InsnList doNew = new InsnList();
// generic code using temporary locals
// save stack
for (int j = args.length - 1; j >= 0; j--) {
Type type = args[j];
- next = new VarInsnNode(type.getOpcode(ISTORE), varOffset);
- instructions.insert(nm, next);
- nm = next;
-
+ doNew.add(new VarInsnNode(type.getOpcode(ISTORE), varOffset));
varOffset += type.getSize();
}
if (varOffset > maxLocals) {
maxLocals = varOffset;
}
- next = node1;
- instructions.insert(nm, next); // NEW
- nm = next;
-
- if (requireDup) {
- next = new InsnNode(DUP);
- instructions.insert(nm, next);
- nm = next;
- }
+ doNew.add(node1); // NEW
+
+ if (requireDup)
+ doNew.add(new InsnNode(DUP));
// restore stack
for (int j = 0; j < args.length; j++) {
Type type = args[j];
varOffset -= type.getSize();
- next = new VarInsnNode(type.getOpcode(ILOAD), varOffset);
- instructions.insert(nm, next);
- nm = next;
+ doNew.add(new VarInsnNode(type.getOpcode(ILOAD), varOffset));
// clean up store to avoid memory leak?
if (type.getSort() == Type.OBJECT || type.getSort() ==
Type.ARRAY) {
updateMaxStack = updateMaxStack < 1 ? 1 : updateMaxStack;
// an extra slot for ACONST_NULL
- next = new InsnNode(ACONST_NULL);
- instructions.insert(nm, next);
- nm = next;
-
- next = new VarInsnNode(type.getOpcode(ISTORE), varOffset);
- instructions.insert(nm, next);
- nm = next;
+ doNew.add(new InsnNode(ACONST_NULL));
+
+ doNew.add(new VarInsnNode(type.getOpcode(ISTORE),
varOffset));
}
}
+ instructions.insertBefore(nm, doNew);
+ nm = doNew.getLast();
}
maxStack += updateMaxStack;