mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-18 04:14:50 -08:00
Zero memory after allocation
This commit is contained in:
parent
ca874d178d
commit
d2cdd5e1e9
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -16,5 +16,6 @@
|
|||
package org.teavm.runtime;
|
||||
|
||||
public class RuntimeArray extends RuntimeObject {
|
||||
RuntimeObject monitor;
|
||||
int size;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user