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; 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 * A dummy class for compatibility. Currently these methods don't actually
* do anything. * do anything.
@ -35,10 +38,15 @@ public class TRuntime {
* Returns the amount of free memory in the system. Calling the gc method * Returns the amount of free memory in the system. Calling the gc method
* may result in increasing the value returned by freeMemory. * may result in increasing the value returned by freeMemory.
*/ */
@DelegateTo("freeMemoryLowLevel")
public long freeMemory() { public long freeMemory() {
return Integer.MAX_VALUE; return Integer.MAX_VALUE;
} }
private long freeMemoryLowLevel() {
return GC.getFreeMemory();
}
/** /**
* Runs the garbage collector. Calling this method suggests that the Java * Runs the garbage collector. Calling this method suggests that the Java
* Virtual Machine expend effort toward recycling unused objects in order to * Virtual Machine expend effort toward recycling unused objects in order to
@ -51,6 +59,7 @@ public class TRuntime {
* means of invoking this method. * means of invoking this method.
*/ */
public void gc() { 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 * environment. Note that the amount of memory required to hold an object of
* any given type may be implementation-dependent. * any given type may be implementation-dependent.
*/ */
@DelegateTo("totalMemoryLowLevel")
public long totalMemory() { public long totalMemory() {
return Integer.MAX_VALUE; 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.Import;
import org.teavm.interop.Unmanaged; import org.teavm.interop.Unmanaged;
import org.teavm.runtime.Allocator; import org.teavm.runtime.Allocator;
import org.teavm.runtime.GC;
import org.teavm.runtime.RuntimeArray; import org.teavm.runtime.RuntimeArray;
import org.teavm.runtime.RuntimeClass; import org.teavm.runtime.RuntimeClass;
@ -126,10 +127,15 @@ public final class TSystem extends TObject {
@PluggableDependency(SystemNativeGenerator.class) @PluggableDependency(SystemNativeGenerator.class)
public static native void setOut(TPrintStream err); public static native void setOut(TPrintStream err);
@DelegateTo("gcLowLevel")
public static void gc() { public static void gc() {
// Do nothing // Do nothing
} }
private static void gcLowLevel() {
GC.collectGarbage(0);
}
public static void runFinalization() { public static void runFinalization() {
// Do nothing // Do nothing
} }

View File

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