Zero memory after allocation

This commit is contained in:
Alexey Andreev 2016-08-18 23:47:43 +03:00
parent ca874d178d
commit d2cdd5e1e9
6 changed files with 107 additions and 2 deletions

View File

@ -28,6 +28,7 @@ public final class Allocator {
public static Address allocate(RuntimeClass tag) {
Address result = address;
address = result.add(tag.size);
fillZero(result, tag.size);
RuntimeObject object = result.toStructure();
object.classReference = tag.toAddress().toInt() >> 3;
return result;
@ -37,6 +38,7 @@ public final class Allocator {
Address result = address;
int sizeInBytes = tag.size * 4 + Structure.sizeOf(RuntimeArray.class);
address = result.add(sizeInBytes);
fillZero(result, sizeInBytes);
RuntimeArray array = result.toStructure();
array.classReference = tag.toAddress().toInt() >> 3;
@ -44,4 +46,6 @@ public final class Allocator {
return result;
}
public static native void fillZero(Address address, int count);
}

View File

@ -16,5 +16,6 @@
package org.teavm.runtime;
public class RuntimeArray extends RuntimeObject {
RuntimeObject monitor;
int size;
}

View File

@ -191,4 +191,48 @@ public final class WasmRuntime {
@Import(name = "print", module = "spectest")
public static native void print(int a);
public static void fillZero(Address address, int count) {
int start = address.toInt();
int alignedStart = start >>> 2 << 2;
address = Address.fromInt(alignedStart);
switch (start - alignedStart) {
case 0:
address.putInt(0);
break;
case 1:
address.add(1).putByte((byte) 0);
address.add(2).putShort((short) 0);
break;
case 2:
address.add(2).putShort((short) 0);
break;
case 3:
address.add(3).putByte((byte) 0);
break;
}
int end = start + count;
int alignedEnd = end >>> 2 << 2;
address = Address.fromInt(alignedEnd);
switch (end - alignedEnd) {
case 0:
break;
case 1:
address.putByte((byte) 0);
break;
case 2:
address.putShort((short) 0);
break;
case 3:
address.putShort((short) 0);
address.add(2).putByte((byte) 0);
break;
}
for (address = Address.fromInt(alignedStart); address.toInt() < alignedEnd; address = address.add(4)) {
address.putInt(0);
}
}
}

View File

@ -64,6 +64,7 @@ import org.teavm.wasm.generate.WasmGenerationContext;
import org.teavm.wasm.generate.WasmGenerator;
import org.teavm.wasm.generate.WasmMangling;
import org.teavm.wasm.generate.WasmStringPool;
import org.teavm.wasm.intrinsics.AllocatorIntrinsic;
import org.teavm.wasm.intrinsics.WasmAddressIntrinsic;
import org.teavm.wasm.intrinsics.WasmRuntimeIntrinsic;
import org.teavm.wasm.intrinsics.WasmStructureIntrinsic;
@ -116,6 +117,8 @@ public class WasmTarget implements TeaVMTarget {
dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "decodeData", Address.class,
Address.class, void.class), null).use();
dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "fillZero", Address.class, int.class,
void.class), null).use();
dependencyChecker.linkMethod(new MethodReference(Allocator.class, "allocate",
RuntimeClass.class, Address.class), null).use();
@ -146,6 +149,7 @@ public class WasmTarget implements TeaVMTarget {
context.addIntrinsic(new WasmAddressIntrinsic());
context.addIntrinsic(new WasmStructureIntrinsic(classGenerator));
context.addIntrinsic(new WasmRuntimeIntrinsic());
context.addIntrinsic(new AllocatorIntrinsic());
WasmGenerator generator = new WasmGenerator(decompiler, classes, context, classGenerator);

View File

@ -28,7 +28,10 @@ public class WasmStringPool {
private WasmClassGenerator classGenerator;
private BinaryWriter binaryWriter;
private Map<String, Integer> stringMap = new HashMap<>();
private DataStructure arrayHeaderType = new DataStructure((byte) 0, DataPrimitives.INT, DataPrimitives.INT);
private DataStructure arrayHeaderType = new DataStructure((byte) 0,
DataPrimitives.INT, /* class pointer */
DataPrimitives.ADDRESS, /* monitor */
DataPrimitives.INT /* size */);
private DataStructure stringType = new DataStructure((byte) 0,
DataPrimitives.INT, /* class pointer */
DataPrimitives.ADDRESS, /* monitor */
@ -49,7 +52,7 @@ public class WasmStringPool {
DataValue characters = wrapper.getValue(1);
header.setInt(0, classGenerator.getClassPointer(ValueType.arrayOf(ValueType.CHARACTER)));
header.setInt(1, str.length());
header.setInt(2, str.length());
for (int i = 0; i < str.length(); ++i) {
characters.setShort(i, (short) str.charAt(i));
}

View File

@ -0,0 +1,49 @@
/*
* 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.wasm.intrinsics;
import java.util.stream.Collectors;
import org.teavm.ast.InvocationExpr;
import org.teavm.interop.Address;
import org.teavm.model.MethodReference;
import org.teavm.runtime.Allocator;
import org.teavm.wasm.WasmRuntime;
import org.teavm.wasm.generate.WasmMangling;
import org.teavm.wasm.model.expression.WasmCall;
import org.teavm.wasm.model.expression.WasmExpression;
public class AllocatorIntrinsic implements WasmIntrinsic {
@Override
public boolean isApplicable(MethodReference methodReference) {
return methodReference.getClassName().equals(Allocator.class.getName()) &&
methodReference.getName().equals("fillZero");
}
@Override
public WasmExpression apply(InvocationExpr invocation, WasmIntrinsicManager manager) {
switch (invocation.getMethod().getName()) {
case "fillZero": {
WasmCall call = new WasmCall(WasmMangling.mangleMethod(new MethodReference(WasmRuntime.class,
"fillZero", Address.class, int.class, void.class)));
call.getArguments().addAll(invocation.getArguments().stream().map(manager::generate)
.collect(Collectors.toList()));
return call;
}
default:
throw new IllegalArgumentException(invocation.getMethod().toString());
}
}
}