Permalink
Browse files

Fix for Issue #16. If a method is marked pausable, but doesn't make a…

…ny pausable calls, then the prelude was being generated incorrectly: the fiber argument was loaed onto the stack, but not popped on return.

	modified:   src/kilim/analysis/MethodWeaver.java
	modified:   test/kilim/test/ex/ExBasicBlock.java
  • Loading branch information...
1 parent d29e9f9 commit 706cbb510585092d5eb2fbfd8a5ab2eedee11599 @sriram-srinivasan sriram-srinivasan committed Nov 29, 2012
Showing with 18 additions and 5 deletions.
  1. +17 −4 src/kilim/analysis/MethodWeaver.java
  2. +1 −1 test/kilim/test/ex/ExBasicBlock.java
@@ -75,6 +75,7 @@
}
}
+
public void accept(ClassVisitor cv) {
MethodFlow mf = methodFlow;
String[] exceptions = ClassWeaver.toStringArray(mf.exceptions);
@@ -94,7 +95,7 @@ public void accept(ClassVisitor cv) {
}
}
}
-
+
void accept(MethodVisitor mv) {
visitAttrs(mv);
visitCode(mv);
@@ -280,6 +281,14 @@ void genGetCurrentTask(MethodVisitor mv, BasicBlock bb) {
mv.visitFieldInsn(GETFIELD, FIBER_CLASS, "task", Constants.D_TASK);
}
+ private boolean hasGetCurrentTask() {
+ MethodFlow mf = methodFlow;
+ for (BasicBlock bb : mf.getBasicBlocks()) {
+ if (!bb.isPausable() || bb.startFrame==null) continue;
+ if (bb.isGetCurrentTask()) return true;
+ }
+ return false;
+ }
private void createCallWeavers() {
MethodFlow mf = methodFlow;
for (BasicBlock bb : mf.getBasicBlocks()) {
@@ -311,10 +320,14 @@ private void createCallWeavers() {
*/
private void genPrelude(MethodVisitor mv) {
assert isPausable : "MethodWeaver.genPrelude called for nonPausable method";
+ if (callWeavers.size() == 0 && (!hasGetCurrentTask())) {
+ return; // No pausable methods, no getCurrentTask. Prelude is not needed at all.
+ }
+
MethodFlow mf = methodFlow;
// load fiber from last var
int lastVar = getFiberArgVar();
-
+
mv.visitVarInsn(ALOAD, lastVar);
if (lastVar < fiberVar) {
if (callWeavers.size() > 0) {
@@ -324,8 +337,8 @@ private void genPrelude(MethodVisitor mv) {
}
if (callWeavers.size() == 0) {
- // Can happen if Task.getCurrentTask() is the only pausable method
- // call. We don't need the rest of the prelude.
+ // No pausable method calls, but Task.getCurrentTask() is present.
+ // We don't need the rest of the prelude.
return;
}
@@ -8,7 +8,7 @@ void noop() throws ArrayIndexOutOfBoundsException {
}
static void pausable() throws Pausable {
-
+ "afakflkaflakd".getBytes();
}
static int testFiber(Object testArgs1, Object[] testArgs) throws Pausable {

0 comments on commit 706cbb5

Please sign in to comment.