mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
WASM: refactoring shadow stack
This commit is contained in:
parent
b67d243ad4
commit
4e431e2f77
|
@ -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()) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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<WasmInt32Constant> 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());
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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<IntObjectMap<int[]>> liveInStores = reduceGcRootStores(program, usedColors, liveInInformation,
|
||||
List<IntObjectMap<int[]>> 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<IntObjectMap<int[]>> reduceGcRootStores(Program program, int usedColors,
|
||||
private List<IntObjectMap<int[]>> reduceGCRootStores(Program program, int usedColors,
|
||||
List<IntObjectMap<BitSet>> 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<IntObjectMap<int[]>> updateInformation) {
|
||||
private void putLiveInGCRoots(Program program, List<IntObjectMap<int[]>> updateInformation) {
|
||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||
BasicBlock block = program.basicBlockAt(i);
|
||||
IntObjectMap<int[]> 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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
51
core/src/main/java/org/teavm/runtime/ShadowStack.java
Normal file
51
core/src/main/java/org/teavm/runtime/ShadowStack.java
Normal file
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user