From 4e431e2f77446db760cf338f5edc48d2f413f2c8 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Thu, 22 Sep 2016 19:02:53 +0300 Subject: [PATCH] WASM: refactoring shadow stack --- .../org/teavm/backend/wasm/WasmRuntime.java | 4 +- .../org/teavm/backend/wasm/WasmTarget.java | 10 ++-- .../wasm/generate/WasmGenerationVisitor.java | 26 ++++------ .../wasm/intrinsics}/MutatorIntrinsic.java | 50 +++++++----------- ...trinsic.java => ShadowStackIntrinsic.java} | 32 +++++++----- ...ceptionHandlingShadowStackContributor.java | 6 +-- .../lowlevel/GCShadowStackContributor.java | 14 ++--- .../lowlevel/ShadowStackTransformer.java | 6 +-- .../org/teavm/runtime/ExceptionHandling.java | 24 ++------- core/src/main/java/org/teavm/runtime/GC.java | 10 ++-- .../main/java/org/teavm/runtime/Mutator.java | 18 +------ .../java/org/teavm/runtime/ShadowStack.java | 51 +++++++++++++++++++ 12 files changed, 128 insertions(+), 123 deletions(-) rename core/src/main/java/org/teavm/{model/instructions => backend/wasm/intrinsics}/MutatorIntrinsic.java (66%) rename core/src/main/java/org/teavm/backend/wasm/intrinsics/{ExceptionHandlingIntrinsic.java => ShadowStackIntrinsic.java} (57%) create mode 100644 core/src/main/java/org/teavm/runtime/ShadowStack.java diff --git a/core/src/main/java/org/teavm/backend/wasm/WasmRuntime.java b/core/src/main/java/org/teavm/backend/wasm/WasmRuntime.java index 19619c587..256387ae3 100644 --- a/core/src/main/java/org/teavm/backend/wasm/WasmRuntime.java +++ b/core/src/main/java/org/teavm/backend/wasm/WasmRuntime.java @@ -250,11 +250,11 @@ public final class WasmRuntime { return result; } - public static Address getStackGcRoots() { + public static Address getStackTop() { return stack != initStack() ? stack : null; } - public static Address getNextStackRoots(Address address) { + public static Address getNextStackFrame(Address address) { int size = address.getInt() + 2; Address result = address.add(-size * 4); if (result == initStack()) { diff --git a/core/src/main/java/org/teavm/backend/wasm/WasmTarget.java b/core/src/main/java/org/teavm/backend/wasm/WasmTarget.java index e99689785..449b18702 100644 --- a/core/src/main/java/org/teavm/backend/wasm/WasmTarget.java +++ b/core/src/main/java/org/teavm/backend/wasm/WasmTarget.java @@ -38,12 +38,13 @@ import org.teavm.backend.wasm.generate.WasmStringPool; import org.teavm.backend.wasm.intrinsics.AddressIntrinsic; import org.teavm.backend.wasm.intrinsics.AllocatorIntrinsic; import org.teavm.backend.wasm.intrinsics.ClassIntrinsic; -import org.teavm.backend.wasm.intrinsics.ExceptionHandlingIntrinsic; import org.teavm.backend.wasm.intrinsics.FunctionIntrinsic; import org.teavm.backend.wasm.intrinsics.GCIntrinsic; +import org.teavm.backend.wasm.intrinsics.MutatorIntrinsic; import org.teavm.backend.wasm.intrinsics.PlatformClassIntrinsic; import org.teavm.backend.wasm.intrinsics.PlatformIntrinsic; import org.teavm.backend.wasm.intrinsics.PlatformObjectIntrinsic; +import org.teavm.backend.wasm.intrinsics.ShadowStackIntrinsic; import org.teavm.backend.wasm.intrinsics.StructureIntrinsic; import org.teavm.backend.wasm.intrinsics.WasmRuntimeIntrinsic; import org.teavm.backend.wasm.model.WasmFunction; @@ -105,7 +106,6 @@ import org.teavm.model.instructions.CloneArrayInstruction; import org.teavm.model.instructions.InitClassInstruction; import org.teavm.model.instructions.InvocationType; import org.teavm.model.instructions.InvokeInstruction; -import org.teavm.model.instructions.MutatorIntrinsic; import org.teavm.model.lowlevel.ClassInitializerEliminator; import org.teavm.model.lowlevel.ClassInitializerTransformer; import org.teavm.model.lowlevel.ShadowStackTransformer; @@ -206,9 +206,9 @@ public class WasmTarget implements TeaVMTarget { Address.class, int.class, void.class), null).use(); dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "allocStack", int.class, Address.class), null).use(); - dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "getStackGcRoots", Address.class), + dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "getStackTop", Address.class), null) .use(); - dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "getNextStackRoots", Address.class, + dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "getNextStackFrame", Address.class, Address.class), null).use(); dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "getStackRootCount", Address.class, int.class), null).use(); @@ -294,7 +294,7 @@ public class WasmTarget implements TeaVMTarget { context.addIntrinsic(gcIntrinsic); MutatorIntrinsic mutatorIntrinsic = new MutatorIntrinsic(); context.addIntrinsic(mutatorIntrinsic); - context.addIntrinsic(new ExceptionHandlingIntrinsic()); + context.addIntrinsic(new ShadowStackIntrinsic()); WasmGenerator generator = new WasmGenerator(decompiler, classes, context, classGenerator); diff --git a/core/src/main/java/org/teavm/backend/wasm/generate/WasmGenerationVisitor.java b/core/src/main/java/org/teavm/backend/wasm/generate/WasmGenerationVisitor.java index b121f060a..15f871862 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generate/WasmGenerationVisitor.java +++ b/core/src/main/java/org/teavm/backend/wasm/generate/WasmGenerationVisitor.java @@ -113,10 +113,9 @@ import org.teavm.model.ValueType; import org.teavm.model.classes.TagRegistry; import org.teavm.model.classes.VirtualTableEntry; import org.teavm.runtime.Allocator; -import org.teavm.runtime.ExceptionHandling; -import org.teavm.runtime.Mutator; import org.teavm.runtime.RuntimeArray; import org.teavm.runtime.RuntimeClass; +import org.teavm.runtime.ShadowStack; class WasmGenerationVisitor implements StatementVisitor, ExprVisitor { private static FieldReference tagField = new FieldReference(RuntimeClass.class.getName(), "tag"); @@ -783,7 +782,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor { @Override public void visit(InvocationExpr expr) { - if (expr.getMethod().getClassName().equals(Mutator.class.getName())) { + if (expr.getMethod().getClassName().equals(ShadowStack.class.getName())) { switch (expr.getMethod().getName()) { case "allocStack": generateAllocStack(expr.getArguments().get(0)); @@ -791,19 +790,16 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor { case "releaseStack": generateReleaseStack(); return; - case "registerGcRoot": + case "registerGCRoot": generateRegisterGcRoot(expr.getArguments().get(0), expr.getArguments().get(1)); return; - case "removeGcRoot": + case "removeGCRoot": generateRemoveGcRoot(expr.getArguments().get(0)); return; - } - } else if (expr.getMethod().getClassName().equals(ExceptionHandling.class.getName())) { - switch (expr.getMethod().getName()) { case "registerCallSite": generateRegisterCallSite(expr.getArguments().get(0)); return; - case "getHandlerId": + case "getExceptionHandlerId": generateGetHandlerId(); return; } @@ -896,7 +892,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor { private void generateAllocStack(Expr sizeExpr) { if (stackVariable != null) { - throw new IllegalStateException("Call to Mutator.allocStack must be done only once"); + throw new IllegalStateException("Call to ShadowStack.allocStack must be done only once"); } stackVariable = getTemporary(WasmType.INT32); stackVariable.setName("__stack__"); @@ -911,7 +907,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor { private void generateReleaseStack() { if (stackVariable == null) { - throw new IllegalStateException("Call to Mutator.releaseStack must be dominated by " + throw new IllegalStateException("Call to ShadowStack.releaseStack must be dominated by " + "Mutator.allocStack"); } @@ -924,7 +920,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor { private void generateRegisterCallSite(Expr callSiteExpr) { if (stackVariable == null) { - throw new IllegalStateException("Call to ExceptionHandling.registerCallSite must be dominated by " + throw new IllegalStateException("Call to ShadowStack.registerCallSite must be dominated by " + "Mutator.allocStack"); } @@ -936,7 +932,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor { private void generateGetHandlerId() { if (stackVariable == null) { - throw new IllegalStateException("Call to ExceptionHandling.getHandlerId must be dominated by " + throw new IllegalStateException("Call to ShadowStack.getHandlerId must be dominated by " + "Mutator.allocStack"); } @@ -945,7 +941,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor { private void generateRegisterGcRoot(Expr slotExpr, Expr gcRootExpr) { if (stackVariable == null) { - throw new IllegalStateException("Call to Mutator.registerGcRoot must be dominated by " + throw new IllegalStateException("Call to ShadowStack.registerGCRoot must be dominated by " + "Mutator.allocStack"); } @@ -962,7 +958,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor { private void generateRemoveGcRoot(Expr slotExpr) { if (stackVariable == null) { - throw new IllegalStateException("Call to Mutator.removeGcRoot must be dominated by " + throw new IllegalStateException("Call to ShadowStack.removeGCRoot must be dominated by " + "Mutator.allocStack"); } diff --git a/core/src/main/java/org/teavm/model/instructions/MutatorIntrinsic.java b/core/src/main/java/org/teavm/backend/wasm/intrinsics/MutatorIntrinsic.java similarity index 66% rename from core/src/main/java/org/teavm/model/instructions/MutatorIntrinsic.java rename to core/src/main/java/org/teavm/backend/wasm/intrinsics/MutatorIntrinsic.java index 68b8e47d5..67cec60e9 100644 --- a/core/src/main/java/org/teavm/model/instructions/MutatorIntrinsic.java +++ b/core/src/main/java/org/teavm/backend/wasm/intrinsics/MutatorIntrinsic.java @@ -13,15 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.model.instructions; +package org.teavm.backend.wasm.intrinsics; import java.util.ArrayList; import java.util.List; -import org.teavm.ast.*; -import org.teavm.ast.InvocationType; -import org.teavm.backend.wasm.WasmRuntime; -import org.teavm.backend.wasm.intrinsics.WasmIntrinsic; -import org.teavm.backend.wasm.intrinsics.WasmIntrinsicManager; +import org.teavm.ast.InvocationExpr; import org.teavm.backend.wasm.model.expression.WasmExpression; import org.teavm.backend.wasm.model.expression.WasmInt32Constant; import org.teavm.model.MethodReference; @@ -30,46 +26,34 @@ import org.teavm.runtime.Mutator; public class MutatorIntrinsic implements WasmIntrinsic { private List staticGcRootsExpressions = new ArrayList<>(); - @Override - public boolean isApplicable(MethodReference methodReference) { - if (!methodReference.getClassName().equals(Mutator.class.getName())) { - return false; - } - switch (methodReference.getName()) { - case "getStaticGcRoots": - case "getStackGcRoots": - case "getNextStackRoots": - case "getStackRootCount": - case "getStackRootPointer": - return true; - default: - return false; - } - } - public void setStaticGcRootsAddress(int address) { for (WasmInt32Constant constant : staticGcRootsExpressions) { constant.setValue(address); } } + @Override + public boolean isApplicable(MethodReference methodReference) { + if (!methodReference.getClassName().equals(Mutator.class.getName())) { + return false; + } + switch (methodReference.getName()) { + case "getStaticGCRoots": + return true; + default: + return false; + } + } + @Override public WasmExpression apply(InvocationExpr invocation, WasmIntrinsicManager manager) { switch (invocation.getMethod().getName()) { - case "getStaticGcRoots": { + case "getStaticGCRoots": { WasmInt32Constant constant = new WasmInt32Constant(0); staticGcRootsExpressions.add(constant); return constant; } - default: { - InvocationExpr expr = new InvocationExpr(); - MethodReference method = new MethodReference(WasmRuntime.class.getName(), - invocation.getMethod().getDescriptor()); - expr.setMethod(method); - expr.setType(InvocationType.SPECIAL); - expr.getArguments().addAll(invocation.getArguments()); - return manager.generate(expr); - } } + throw new IllegalArgumentException(invocation.getMethod().toString()); } } diff --git a/core/src/main/java/org/teavm/backend/wasm/intrinsics/ExceptionHandlingIntrinsic.java b/core/src/main/java/org/teavm/backend/wasm/intrinsics/ShadowStackIntrinsic.java similarity index 57% rename from core/src/main/java/org/teavm/backend/wasm/intrinsics/ExceptionHandlingIntrinsic.java rename to core/src/main/java/org/teavm/backend/wasm/intrinsics/ShadowStackIntrinsic.java index d4cec9ec8..fb9f4d493 100644 --- a/core/src/main/java/org/teavm/backend/wasm/intrinsics/ExceptionHandlingIntrinsic.java +++ b/core/src/main/java/org/teavm/backend/wasm/intrinsics/ShadowStackIntrinsic.java @@ -16,33 +16,37 @@ package org.teavm.backend.wasm.intrinsics; import org.teavm.ast.InvocationExpr; +import org.teavm.ast.InvocationType; +import org.teavm.backend.wasm.WasmRuntime; import org.teavm.backend.wasm.model.expression.WasmExpression; import org.teavm.model.MethodReference; -import org.teavm.runtime.ExceptionHandling; +import org.teavm.runtime.ShadowStack; -public class ExceptionHandlingIntrinsic implements WasmIntrinsic { +public class ShadowStackIntrinsic implements WasmIntrinsic { @Override public boolean isApplicable(MethodReference methodReference) { - if (!methodReference.getClassName().equals(ExceptionHandling.class.getName())) { + if (!methodReference.getClassName().equals(ShadowStack.class.getName())) { return false; } - switch (methodReference.getName()) { - case "registerCallSite": - case "getHandlerId": + case "getStackTop": + case "getNextStackFrame": + case "getStackRootCount": + case "getStackRootPointer": return true; + default: + return false; } - - return false; } @Override public WasmExpression apply(InvocationExpr invocation, WasmIntrinsicManager manager) { - switch (invocation.getMethod().getName()) { - case "registerCallSite": - break; - } - - throw new IllegalArgumentException(invocation.getMethod().toString()); + InvocationExpr expr = new InvocationExpr(); + MethodReference method = new MethodReference(WasmRuntime.class.getName(), + invocation.getMethod().getDescriptor()); + expr.setMethod(method); + expr.setType(InvocationType.SPECIAL); + expr.getArguments().addAll(invocation.getArguments()); + return manager.generate(expr); } } diff --git a/core/src/main/java/org/teavm/model/lowlevel/ExceptionHandlingShadowStackContributor.java b/core/src/main/java/org/teavm/model/lowlevel/ExceptionHandlingShadowStackContributor.java index b2cc35d03..3434b3c33 100644 --- a/core/src/main/java/org/teavm/model/lowlevel/ExceptionHandlingShadowStackContributor.java +++ b/core/src/main/java/org/teavm/model/lowlevel/ExceptionHandlingShadowStackContributor.java @@ -50,6 +50,7 @@ import org.teavm.model.instructions.SwitchTableEntry; import org.teavm.model.util.DefinitionExtractor; import org.teavm.model.util.ProgramUtils; import org.teavm.runtime.ExceptionHandling; +import org.teavm.runtime.ShadowStack; public class ExceptionHandlingShadowStackContributor { private ManagedMethodRepository managedMethodRepository; @@ -194,8 +195,7 @@ public class ExceptionHandlingShadowStackContributor { instructions.add(idInsn); InvokeInstruction registerInsn = new InvokeInstruction(); - registerInsn.setMethod(new MethodReference(ExceptionHandling.class, "registerCallSite", - int.class, void.class)); + registerInsn.setMethod(new MethodReference(ShadowStack.class, "registerCallSite", int.class, void.class)); registerInsn.setType(InvocationType.SPECIAL); registerInsn.getArguments().add(idVariable); instructions.add(registerInsn); @@ -219,7 +219,7 @@ public class ExceptionHandlingShadowStackContributor { Variable handlerIdVariable = program.createVariable(); InvokeInstruction getHandlerIdInsn = new InvokeInstruction(); - getHandlerIdInsn.setMethod(new MethodReference(ExceptionHandling.class, "getHandlerId", int.class)); + getHandlerIdInsn.setMethod(new MethodReference(ShadowStack.class, "getExceptionHandlerId", int.class)); getHandlerIdInsn.setType(InvocationType.SPECIAL); getHandlerIdInsn.setReceiver(handlerIdVariable); instructions.add(getHandlerIdInsn); diff --git a/core/src/main/java/org/teavm/model/lowlevel/GCShadowStackContributor.java b/core/src/main/java/org/teavm/model/lowlevel/GCShadowStackContributor.java index 74468e8ac..e3bb4c3a0 100644 --- a/core/src/main/java/org/teavm/model/lowlevel/GCShadowStackContributor.java +++ b/core/src/main/java/org/teavm/model/lowlevel/GCShadowStackContributor.java @@ -53,7 +53,7 @@ import org.teavm.model.util.ProgramUtils; import org.teavm.model.util.TypeInferer; import org.teavm.model.util.UsageExtractor; import org.teavm.model.util.VariableType; -import org.teavm.runtime.Mutator; +import org.teavm.runtime.ShadowStack; public class GCShadowStackContributor { private ManagedMethodRepository managedMethodRepository; @@ -92,9 +92,9 @@ public class GCShadowStackContributor { findAutoSpilledPhis(spilled, destinationPhis, inputCount, autoSpilled, i); } - List> liveInStores = reduceGcRootStores(program, usedColors, liveInInformation, + List> liveInStores = reduceGCRootStores(program, usedColors, liveInInformation, colors, autoSpilled); - putLiveInGcRoots(program, liveInStores); + putLiveInGCRoots(program, liveInStores); return usedColors; } @@ -241,7 +241,7 @@ public class GCShadowStackContributor { return inputCount; } - private List> reduceGcRootStores(Program program, int usedColors, + private List> reduceGCRootStores(Program program, int usedColors, List> liveInInformation, int[] colors, boolean[] autoSpilled) { class Step { private final int node; @@ -322,7 +322,7 @@ public class GCShadowStackContributor { return comparison; } - private void putLiveInGcRoots(Program program, List> updateInformation) { + private void putLiveInGCRoots(Program program, List> updateInformation) { for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); IntObjectMap updatesByIndex = updateInformation.get(i); @@ -359,11 +359,11 @@ public class GCShadowStackContributor { registerInvocation.setType(InvocationType.SPECIAL); registerInvocation.getArguments().add(slotVar); if (var >= 0) { - registerInvocation.setMethod(new MethodReference(Mutator.class, "registerGcRoot", int.class, + registerInvocation.setMethod(new MethodReference(ShadowStack.class, "registerGCRoot", int.class, Object.class, void.class)); registerInvocation.getArguments().add(program.variableAt(var)); } else { - registerInvocation.setMethod(new MethodReference(Mutator.class, "removeGcRoot", int.class, + registerInvocation.setMethod(new MethodReference(ShadowStack.class, "removeGCRoot", int.class, void.class)); } instructionsToAdd.add(registerInvocation); diff --git a/core/src/main/java/org/teavm/model/lowlevel/ShadowStackTransformer.java b/core/src/main/java/org/teavm/model/lowlevel/ShadowStackTransformer.java index e607f3808..d161af379 100644 --- a/core/src/main/java/org/teavm/model/lowlevel/ShadowStackTransformer.java +++ b/core/src/main/java/org/teavm/model/lowlevel/ShadowStackTransformer.java @@ -31,7 +31,7 @@ import org.teavm.model.instructions.IntegerConstantInstruction; import org.teavm.model.instructions.InvocationType; import org.teavm.model.instructions.InvokeInstruction; import org.teavm.model.instructions.JumpInstruction; -import org.teavm.runtime.Mutator; +import org.teavm.runtime.ShadowStack; public class ShadowStackTransformer { private ManagedMethodRepository managedMethodRepository; @@ -70,7 +70,7 @@ public class ShadowStackTransformer { InvokeInstruction invocation = new InvokeInstruction(); invocation.setType(InvocationType.SPECIAL); - invocation.setMethod(new MethodReference(Mutator.class, "allocStack", int.class, void.class)); + invocation.setMethod(new MethodReference(ShadowStack.class, "allocStack", int.class, void.class)); invocation.getArguments().add(sizeVariable); instructionsToAdd.add(invocation); @@ -135,7 +135,7 @@ public class ShadowStackTransformer { InvokeInstruction invocation = new InvokeInstruction(); invocation.setType(InvocationType.SPECIAL); - invocation.setMethod(new MethodReference(Mutator.class, "releaseStack", int.class, void.class)); + invocation.setMethod(new MethodReference(ShadowStack.class, "releaseStack", int.class, void.class)); invocation.getArguments().add(sizeVariable); instructionsToAdd.add(invocation); diff --git a/core/src/main/java/org/teavm/runtime/ExceptionHandling.java b/core/src/main/java/org/teavm/runtime/ExceptionHandling.java index c3e0ae3d3..42b72de14 100644 --- a/core/src/main/java/org/teavm/runtime/ExceptionHandling.java +++ b/core/src/main/java/org/teavm/runtime/ExceptionHandling.java @@ -26,20 +26,6 @@ public final class ExceptionHandling { private ExceptionHandling() { } - public static native void registerCallSite(int id); - - public static native int callSiteResult(); - - public static native Address getStackTop(); - - public static native Address getNextStackFrame(Address stackFrame); - - public static native int getCallSiteId(Address stackFrame); - - public static native void setHandlerId(Address stackFrame, int id); - - public static native int getHandlerId(); - public static native CallSite findCallSiteById(int id); public static void throwException(Throwable exception) { @@ -47,23 +33,23 @@ public final class ExceptionHandling { RuntimeClass exceptionClass = RuntimeClass.getClass(exceptionPtr); IsSupertypeFunction isExceptionSupertype = exceptionClass.isSupertypeOf; - Address stackFrame = getStackTop(); + Address stackFrame = ShadowStack.getStackTop(); stackLoop: while (stackFrame != null) { - int callSiteId = getCallSiteId(stackFrame); + int callSiteId = ShadowStack.getCallSiteId(stackFrame); CallSite callSite = findCallSiteById(callSiteId); ExceptionHandler handler = callSite.firstHandler; for (int i = 0; i < callSite.handlerCount; ++i) { if (isExceptionSupertype.apply(handler.exceptionClass)) { - setHandlerId(stackFrame, handler.id); + ShadowStack.setExceptionHandlerId(stackFrame, handler.id); break stackLoop; } handler = Structure.add(ExceptionHandler.class, handler, 1); } - setHandlerId(stackFrame, callSiteId - 1); - stackFrame = getNextStackFrame(stackFrame); + ShadowStack.setExceptionHandlerId(stackFrame, callSiteId - 1); + stackFrame = ShadowStack.getNextStackFrame(stackFrame); } } } diff --git a/core/src/main/java/org/teavm/runtime/GC.java b/core/src/main/java/org/teavm/runtime/GC.java index 2a3737f9c..c9b67ccac 100644 --- a/core/src/main/java/org/teavm/runtime/GC.java +++ b/core/src/main/java/org/teavm/runtime/GC.java @@ -109,7 +109,7 @@ public final class GC { private static void mark() { Allocator.fillZero(regionsAddress().toAddress(), regionMaxCount() * Structure.sizeOf(Region.class)); - Address staticRoots = Mutator.getStaticGcRoots(); + Address staticRoots = Mutator.getStaticGCRoots(); int staticCount = staticRoots.getInt(); staticRoots.add(8); while (staticCount-- > 0) { @@ -120,10 +120,10 @@ public final class GC { staticRoots = staticRoots.add(Address.sizeOf()); } - for (Address stackRoots = Mutator.getStackGcRoots(); stackRoots != null; - stackRoots = Mutator.getNextStackRoots(stackRoots)) { - int count = Mutator.getStackRootCount(stackRoots); - Address stackRootsPtr = Mutator.getStackRootPointer(stackRoots); + for (Address stackRoots = ShadowStack.getStackTop(); stackRoots != null; + stackRoots = ShadowStack.getNextStackFrame(stackRoots)) { + int count = ShadowStack.getStackRootCount(stackRoots); + Address stackRootsPtr = ShadowStack.getStackRootPointer(stackRoots); while (count-- > 0) { RuntimeObject obj = stackRootsPtr.getAddress().toStructure(); mark(obj); diff --git a/core/src/main/java/org/teavm/runtime/Mutator.java b/core/src/main/java/org/teavm/runtime/Mutator.java index 79cd560f9..cc512a00e 100644 --- a/core/src/main/java/org/teavm/runtime/Mutator.java +++ b/core/src/main/java/org/teavm/runtime/Mutator.java @@ -25,21 +25,5 @@ public final class Mutator { private Mutator() { } - public static native void allocStack(int size); - - public static native void registerGcRoot(int index, Object object); - - public static native void removeGcRoot(int index); - - public static native void releaseStack(int size); - - public static native Address getStaticGcRoots(); - - public static native Address getStackGcRoots(); - - public static native Address getNextStackRoots(Address address); - - public static native int getStackRootCount(Address address); - - public static native Address getStackRootPointer(Address address); + public static native Address getStaticGCRoots(); } diff --git a/core/src/main/java/org/teavm/runtime/ShadowStack.java b/core/src/main/java/org/teavm/runtime/ShadowStack.java new file mode 100644 index 000000000..e7f4913b2 --- /dev/null +++ b/core/src/main/java/org/teavm/runtime/ShadowStack.java @@ -0,0 +1,51 @@ +/* + * Copyright 2016 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.runtime; + +import org.teavm.interop.Address; +import org.teavm.interop.StaticInit; +import org.teavm.interop.Unmanaged; + +@Unmanaged +@StaticInit +public final class ShadowStack { + private ShadowStack() { + } + + public static native void allocStack(int size); + + public static native void registerGCRoot(int index, Object object); + + public static native void removeGCRoot(int index); + + public static native void releaseStack(int size); + + public static native Address getStackTop(); + + public static native Address getNextStackFrame(Address stackFrame); + + public static native int getStackRootCount(Address stackFrame); + + public static native Address getStackRootPointer(Address stackFrame); + + public static native int getCallSiteId(Address stackFrame); + + public static native void registerCallSite(int id); + + public static native int getExceptionHandlerId(); + + public static native void setExceptionHandlerId(Address stackFrame, int id); +}