WASM: add some GC interop methods

This commit is contained in:
Alexey Andreev 2016-10-06 16:21:09 +03:00
parent 0041130d00
commit 499ce8c029
3 changed files with 39 additions and 2 deletions

View File

@ -15,6 +15,9 @@
*/
package org.teavm.classlib.java.lang;
import org.teavm.interop.DelegateTo;
import org.teavm.runtime.GC;
/**
* A dummy class for compatibility. Currently these methods don't actually
* do anything.
@ -35,10 +38,15 @@ public class TRuntime {
* Returns the amount of free memory in the system. Calling the gc method
* may result in increasing the value returned by freeMemory.
*/
@DelegateTo("freeMemoryLowLevel")
public long freeMemory() {
return Integer.MAX_VALUE;
}
private long freeMemoryLowLevel() {
return GC.getFreeMemory();
}
/**
* Runs the garbage collector. Calling this method suggests that the Java
* Virtual Machine expend effort toward recycling unused objects in order to
@ -51,6 +59,7 @@ public class TRuntime {
* means of invoking this method.
*/
public void gc() {
System.gc();
}
/**
@ -68,7 +77,12 @@ public class TRuntime {
* environment. Note that the amount of memory required to hold an object of
* any given type may be implementation-dependent.
*/
@DelegateTo("totalMemoryLowLevel")
public long totalMemory() {
return Integer.MAX_VALUE;
}
private long totalMemoryLowLevel() {
return GC.availableBytes();
}
}

View File

@ -26,6 +26,7 @@ import org.teavm.interop.DelegateTo;
import org.teavm.interop.Import;
import org.teavm.interop.Unmanaged;
import org.teavm.runtime.Allocator;
import org.teavm.runtime.GC;
import org.teavm.runtime.RuntimeArray;
import org.teavm.runtime.RuntimeClass;
@ -126,10 +127,15 @@ public final class TSystem extends TObject {
@PluggableDependency(SystemNativeGenerator.class)
public static native void setOut(TPrintStream err);
@DelegateTo("gcLowLevel")
public static void gc() {
// Do nothing
}
private static void gcLowLevel() {
GC.collectGarbage(0);
}
public static void runFinalization() {
// Do nothing
}

View File

@ -30,6 +30,7 @@ public final class GC {
static FreeChunk currentChunk;
static FreeChunkHolder currentChunkPointer;
static int freeChunks;
static int freeMemory = (int) availableBytes();
static native Address gcStorageAddress();
@ -41,10 +42,14 @@ public final class GC {
private static native int regionMaxCount();
private static native long availableBytes();
public static native long availableBytes();
private static native int regionSize();
public static int getFreeMemory() {
return freeMemory;
}
static {
currentChunk = heapAddress().toStructure();
currentChunk.classReference = 0;
@ -71,6 +76,7 @@ public final class GC {
currentChunk.classReference = 0;
currentChunk.size = freeSize;
}
freeMemory -= size;
return current;
}
@ -93,6 +99,7 @@ public final class GC {
if (--freeChunks == 0) {
return false;
}
freeMemory -= currentChunk.size;
currentChunkPointer = Structure.add(FreeChunkHolder.class, currentChunkPointer, 1);
currentChunk = currentChunkPointer.value;
currentChunkLimit = currentChunk.toAddress().add(currentChunk.size);
@ -100,9 +107,10 @@ public final class GC {
return true;
}
private static boolean collectGarbage(int size) {
public static boolean collectGarbage(int size) {
mark();
sweep();
updateFreeMemory();
return true;
}
@ -268,6 +276,15 @@ public final class GC {
currentChunkLimit = currentChunk.toAddress().add(currentChunk.size);
}
private static void updateFreeMemory() {
freeMemory = 0;
FreeChunkHolder freeChunkPtr = currentChunkPointer;
for (int i = 0; i < freeChunks; ++i) {
freeMemory += freeChunkPtr.value.size;
freeChunkPtr = Structure.add(FreeChunkHolder.class, freeChunkPtr, 1);
}
}
private static void sortFreeChunks(int lower, int upper) {
int start = lower;
int end = upper;