From 593dafdd739613586a604a1e05c36c09d021489e Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Thu, 8 Sep 2016 23:20:07 +0300 Subject: [PATCH] Fixing bugs in GC --- .../java/org/teavm/backend/wasm/WasmRuntime.java | 13 +++++++++---- .../wasm/generate/WasmGenerationVisitor.java | 6 ++++-- .../model/lowlevel/ClassInitializerTransformer.java | 3 +-- core/src/main/java/org/teavm/runtime/Allocator.java | 4 +++- 4 files changed, 17 insertions(+), 9 deletions(-) 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 2e38dfb56..93bfe1ba1 100644 --- a/core/src/main/java/org/teavm/backend/wasm/WasmRuntime.java +++ b/core/src/main/java/org/teavm/backend/wasm/WasmRuntime.java @@ -244,9 +244,10 @@ public final class WasmRuntime { } public static Address allocStack(int size) { - Address result = stack; - stack = stack.add((size + 1) << 2); - stack.add(-4).putInt(size); + Address result = stack.add(4); + stack = result.add(size << 2); + fillZero(result, size << 2); + stack.putInt(size); return result; } @@ -256,7 +257,11 @@ public final class WasmRuntime { public static Address getNextStackRoots(Address address) { int size = address.getInt() + 1; - return address.add(-size * 4); + Address result = address.add(-size * 4); + if (result == initStack()) { + result = null; + } + return result; } public static int getStackRootCount(Address address) { 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 a4894073b..4de48bf91 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 @@ -906,8 +906,10 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor { } int offset = classGenerator.getFieldOffset(new FieldReference(WasmRuntime.class.getName(), "stack")); - result = new WasmStoreInt32(4, new WasmInt32Constant(offset), new WasmGetLocal(stackVariable), - WasmInt32Subtype.INT32); + WasmExpression oldValue = new WasmGetLocal(stackVariable); + oldValue = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.SUB, oldValue, + new WasmInt32Constant(4)); + result = new WasmStoreInt32(4, new WasmInt32Constant(offset), oldValue, WasmInt32Subtype.INT32); } private void generateRegisterGcRoot(Expr slotExpr, Expr gcRootExpr) { diff --git a/core/src/main/java/org/teavm/model/lowlevel/ClassInitializerTransformer.java b/core/src/main/java/org/teavm/model/lowlevel/ClassInitializerTransformer.java index 18199001d..61264c00c 100644 --- a/core/src/main/java/org/teavm/model/lowlevel/ClassInitializerTransformer.java +++ b/core/src/main/java/org/teavm/model/lowlevel/ClassInitializerTransformer.java @@ -98,8 +98,7 @@ public class ClassInitializerTransformer { InvokeInstruction checkInitialized = new InvokeInstruction(); checkInitialized.setType(InvocationType.SPECIAL); - checkInitialized.setMethod(new MethodReference(Allocator.class, "isInitialized", - Class.class, boolean.class)); + checkInitialized.setMethod(new MethodReference(Allocator.class, "isInitialized", Class.class, boolean.class)); checkInitialized.getArguments().add(clsVariable); checkInitialized.setReceiver(initializedVariable); block.getInstructions().add(checkInitialized); diff --git a/core/src/main/java/org/teavm/runtime/Allocator.java b/core/src/main/java/org/teavm/runtime/Allocator.java index f528be033..b1ad8862c 100644 --- a/core/src/main/java/org/teavm/runtime/Allocator.java +++ b/core/src/main/java/org/teavm/runtime/Allocator.java @@ -33,7 +33,9 @@ public final class Allocator { } public static Address allocateArray(RuntimeClass tag, int size) { - int sizeInBytes = tag.itemType.size * size + Structure.sizeOf(RuntimeArray.class); + int itemSize = (tag.itemType.flags & RuntimeClass.PRIMITIVE) != 0 ? tag.itemType.size : 4; + int sizeInBytes = Address.align(Address.fromInt(Structure.sizeOf(RuntimeArray.class)), itemSize).toInt(); + sizeInBytes += itemSize * size; sizeInBytes = Address.align(Address.fromInt(sizeInBytes), 4).toInt(); Address result = GC.alloc(sizeInBytes).toAddress(); fillZero(result, sizeInBytes);