diff --git a/src/compile.cpp b/src/compile.cpp index 9ec2c66ae3..e96e308629 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -1480,7 +1480,7 @@ class Frame { } void endSubroutine(unsigned nextIndexIndex) { - c->cleanLocals(); + c->linkSubroutine(subroutine->handle); poppedInt(); diff --git a/src/compiler.cpp b/src/compiler.cpp index bae1f1128b..85fbc379d6 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -4952,9 +4952,14 @@ class MyCompiler: public Compiler { } virtual void endSubroutine(Subroutine* subroutine) { + appendCleanLocals(&c); static_cast(subroutine)->forkState = ::saveState(&c); } + virtual void linkSubroutine(Subroutine* subroutine) { + restoreState(static_cast(subroutine)->forkState); + } + virtual void init(unsigned logicalCodeLength, unsigned parameterFootprint, unsigned localFootprint, unsigned alignedFrameSize) { @@ -5372,10 +5377,6 @@ class MyCompiler: public Compiler { appendSaveLocals(&c); } - virtual void cleanLocals() { - appendCleanLocals(&c); - } - virtual void checkBounds(Operand* object, unsigned lengthOffset, Operand* index, intptr_t handler) { diff --git a/src/compiler.h b/src/compiler.h index 1a42888e8d..8c40def7cc 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -43,6 +43,7 @@ class Compiler { virtual Subroutine* startSubroutine() = 0; virtual void endSubroutine(Subroutine* subroutine) = 0; + virtual void linkSubroutine(Subroutine* subroutine) = 0; virtual void init(unsigned logicalCodeSize, unsigned parameterFootprint, unsigned localFootprint, unsigned alignedFrameSize) = 0; @@ -95,7 +96,6 @@ class Compiler { unsigned index) = 0; virtual Operand* loadLocal(unsigned footprint, unsigned index) = 0; virtual void saveLocals() = 0; - virtual void cleanLocals() = 0; virtual void checkBounds(Operand* object, unsigned lengthOffset, Operand* index, intptr_t handler) = 0; diff --git a/test/Subroutine.java b/test/Subroutine.java index cf3917450f..1a631e25d5 100644 --- a/test/Subroutine.java +++ b/test/Subroutine.java @@ -113,6 +113,31 @@ public class Subroutine { } } + private static long test4(int path) { + try { + try { + switch (path) { + case 1: + return 42L; + + case 2: { + int a = 42; + return 52L; + } + + case 3: + throw new DummyException(); + } + } finally { + System.gc(); + } + return 0L; + } catch (DummyException e) { + e.printStackTrace(); + return 0L; + } + } + public static void main(String[] args) { test(false, false); test(false, true); @@ -157,6 +182,10 @@ public class Subroutine { String.valueOf(test3(1, 3, 3)); String.valueOf(test3(2, 3, 3)); String.valueOf(test3(3, 3, 3)); + + String.valueOf(test4(1)); + String.valueOf(test4(2)); + String.valueOf(test4(3)); } private static class DummyException extends RuntimeException { }