Index: vm/gc_gen/javasrc/org/apache/harmony/drlvm/gc_gen/GCHelper.java =================================================================== --- vm/gc_gen/javasrc/org/apache/harmony/drlvm/gc_gen/GCHelper.java (revision 600908) +++ vm/gc_gen/javasrc/org/apache/harmony/drlvm/gc_gen/GCHelper.java (working copy) @@ -32,25 +32,63 @@ } public static final int TLS_GC_OFFSET = TLSGCOffset(); + public static final int PREFETCH_DISTANCE = getPrefetchDist(); + public static final int ZEROING_SIZE = getZeroingSize(); + public static final int PREFETCH_STRIDE = getPrefetchStride(); + public static final int TLA_FREE_OFFSET = getTlaFreeOffset(); + public static final int TLA_CEILING_OFFSET = getTlaCeilingOffset(); + public static final int TLA_END_OFFSET = getTlaEndOffset(); + + public static final int LARGE_OBJECT_SIZE = getLargeObjectSize(); + public static final boolean PREFETCH_ENABLED = isPrefetchEnabled(); + + @Inline private static Address alloc(int objSize, int allocationHandle ) { + if (objSize > LARGE_OBJECT_SIZE) { + return VMHelper.newResolvedUsingAllocHandleAndSize(objSize, allocationHandle); + } + Address TLS_BASE = VMHelper.getTlsBaseAddress(); Address allocator_addr = TLS_BASE.plus(TLS_GC_OFFSET); Address allocator = allocator_addr.loadAddress(); - Address free_addr = allocator.plus(0); + Address free_addr = allocator.plus(TLA_FREE_OFFSET); Address free = free_addr.loadAddress(); - Address ceiling = allocator.plus(4).loadAddress(); - + Address ceiling_addr = allocator.plus(TLA_CEILING_OFFSET); + Address ceiling = ceiling_addr.loadAddress(); + Address new_free = free.plus(objSize); if (new_free.LE(ceiling)) { free_addr.store(new_free); free.store(allocationHandle); return free; - } + } else if (PREFETCH_ENABLED) { + Address end = allocator.plus(TLA_END_OFFSET).loadAddress(); + if(new_free.LE(end)) { + // do prefetch from new_free to new_free + PREFETCH_DISTANCE + ZEROING_SIZE + VMHelper.prefetch(new_free, PREFETCH_DISTANCE + ZEROING_SIZE, PREFETCH_STRIDE); + + Address new_ceiling = new_free.plus(ZEROING_SIZE); + // align ceiling to 64 bytes + int remainder = new_ceiling.toInt() & 63; + new_ceiling = new_ceiling.minus(remainder); + + if( !new_ceiling.LE(end) ){ + new_ceiling = end; + } + + VMHelper.memset0(ceiling , new_ceiling.diff(ceiling).toInt()); + + ceiling_addr.store(new_ceiling); + free_addr.store(new_free); + free.store(allocationHandle); + return free; + } + } return VMHelper.newResolvedUsingAllocHandleAndSize(objSize, allocationHandle); } @@ -64,7 +102,7 @@ private static final int ARRAY_LEN_OFFSET = 8; - private static final int GC_OBJECT_ALIGNMENT = 4; + private static final int GC_OBJECT_ALIGNMENT = getGCObjectAlignment(); @Inline public static Address allocArray(Address elemClassHandle, int arrayLen) { @@ -103,9 +141,21 @@ VMHelper.writeBarrier(p_objBase, p_objSlot, p_target); } + private static native boolean isPrefetchEnabled(); + private static native int getLargeObjectSize(); + private static native int getTlaFreeOffset(); + private static native int getTlaCeilingOffset(); + private static native int getTlaEndOffset(); + private static native int getGCObjectAlignment(); + private static native int getPrefetchDist(); + private static native int getZeroingSize(); + private static native int getPrefetchStride(); private static native int helperCallback(); private static native boolean getGenMode(); private static native long getNosBoundary(); private static native int TLSGCOffset(); } + + + Index: vm/gc_gen/javasrc_uncomp/org/apache/harmony/drlvm/gc_gen/GCHelper.java =================================================================== --- vm/gc_gen/javasrc_uncomp/org/apache/harmony/drlvm/gc_gen/GCHelper.java (revision 600908) +++ vm/gc_gen/javasrc_uncomp/org/apache/harmony/drlvm/gc_gen/GCHelper.java (working copy) @@ -32,25 +32,62 @@ } public static final int TLS_GC_OFFSET = TLSGCOffset(); + public static final int PREFETCH_DISTANCE = getPrefetchDist(); + public static final int ZEROING_SIZE = getZeroingSize(); + public static final int PREFETCH_STRIDE = getPrefetchStride(); + public static final int TLA_FREE_OFFSET = getTlaFreeOffset(); + public static final int TLA_CEILING_OFFSET = getTlaCeilingOffset(); + public static final int TLA_END_OFFSET = getTlaEndOffset(); + + public static final int LARGE_OBJECT_SIZE = getLargeObjectSize(); + public static final boolean PREFETCH_ENABLED = isPrefetchEnabled(); + + @Inline private static Address alloc(int objSize, int allocationHandle ) { + if (objSize > LARGE_OBJECT_SIZE) { + return VMHelper.newResolvedUsingAllocHandleAndSize(objSize, allocationHandle); + } + Address TLS_BASE = VMHelper.getTlsBaseAddress(); Address allocator_addr = TLS_BASE.plus(TLS_GC_OFFSET); Address allocator = allocator_addr.loadAddress(); - Address free_addr = allocator.plus(0); + Address free_addr = allocator.plus(TLA_FREE_OFFSET); Address free = free_addr.loadAddress(); - Address ceiling = allocator.plus(4).loadAddress(); - + Address ceiling_addr = allocator.plus(TLA_CEILING_OFFSET); + Address ceiling = ceiling_addr.loadAddress(); + Address new_free = free.plus(objSize); if (new_free.LE(ceiling)) { free_addr.store(new_free); free.store(allocationHandle); return free; - } + } else if (PREFETCH_ENABLED) { + Address end = allocator.plus(TLA_END_OFFSET).loadAddress(); + if(new_free.LE(end)) { + // do prefetch from new_free to new_free + PREFETCH_DISTANCE + ZEROING_SIZE + VMHelper.prefetch(new_free, PREFETCH_DISTANCE + ZEROING_SIZE, PREFETCH_STRIDE); + + Address new_ceiling = new_free.plus(ZEROING_SIZE); + // align ceiling to 64 bytes + int remainder = new_ceiling.toInt() & 63; + new_ceiling = new_ceiling.minus(remainder); + if( !new_ceiling.LE(end) ){ + new_ceiling = end; + } + + VMHelper.memset0(ceiling , new_ceiling.diff(ceiling).toInt()); + + ceiling_addr.store(new_ceiling); + free_addr.store(new_free); + free.store(allocationHandle); + return free; + } + } return VMHelper.newResolvedUsingAllocHandleAndSize(objSize, allocationHandle); } @@ -64,7 +101,7 @@ private static final int ARRAY_LEN_OFFSET = 8; - private static final int GC_OBJECT_ALIGNMENT = 4; + private static final int GC_OBJECT_ALIGNMENT = getGCObjectAlignment(); @Inline public static Address allocArray(Address elemClassHandle, int arrayLen) { @@ -103,9 +140,21 @@ VMHelper.writeBarrier(p_objBase, p_objSlot, p_target); } + private static native boolean isPrefetchEnabled(); + private static native int getLargeObjectSize(); + private static native int getTlaFreeOffset(); + private static native int getTlaCeilingOffset(); + private static native int getTlaEndOffset(); + private static native int getGCObjectAlignment(); + private static native int getPrefetchDist(); + private static native int getZeroingSize(); + private static native int getPrefetchStride(); private static native int helperCallback(); private static native boolean getGenMode(); private static native long getNosBoundary(); private static native int TLSGCOffset(); } + + + Index: vm/gc_gen/src/jni/java_natives.cpp =================================================================== --- vm/gc_gen/src/jni/java_natives.cpp (revision 600908) +++ vm/gc_gen/src/jni/java_natives.cpp (working copy) @@ -58,6 +58,48 @@ GCHelper_clss = *vm_class_ptr; } +JNIEXPORT jint JNICALL Java_org_apache_harmony_drlvm_gc_1gen_GCHelper_getPrefetchDist(JNIEnv *e, jclass c) +{ + return (jint)PREFETCH_DISTANCE; +} + +JNIEXPORT jint JNICALL Java_org_apache_harmony_drlvm_gc_1gen_GCHelper_getZeroingSize(JNIEnv *e, jclass c) +{ + return (jint)ZEROING_SIZE; +} + +JNIEXPORT jint JNICALL Java_org_apache_harmony_drlvm_gc_1gen_GCHelper_getPrefetchStride(JNIEnv *e, jclass c) +{ + return (jint)PREFETCH_STRIDE; +} + +JNIEXPORT jint JNICALL Java_org_apache_harmony_drlvm_gc_1gen_GCHelper_getTlaFreeOffset(JNIEnv *, jclass) { + Allocator allocator; + return (jint) ((POINTER_SIZE_INT)&allocator.free - (POINTER_SIZE_INT)&allocator); +} + +JNIEXPORT jint JNICALL Java_org_apache_harmony_drlvm_gc_1gen_GCHelper_getTlaCeilingOffset(JNIEnv *, jclass) { + Allocator allocator; + return (jint) ((POINTER_SIZE_INT)&allocator.ceiling - (POINTER_SIZE_INT)&allocator); +} + +JNIEXPORT jint JNICALL Java_org_apache_harmony_drlvm_gc_1gen_GCHelper_getTlaEndOffset(JNIEnv *, jclass) { + Allocator allocator; + return (jint) ((POINTER_SIZE_INT)&allocator.end - (POINTER_SIZE_INT)&allocator); +} + +JNIEXPORT jint JNICALL Java_org_apache_harmony_drlvm_gc_1gen_GCHelper_getGCObjectAlignment(JNIEnv *, jclass) { + return (jint) GC_OBJECT_ALIGNMENT; +} + +JNIEXPORT jint JNICALL Java_org_apache_harmony_drlvm_gc_1gen_GCHelper_getLargeObjectSize(JNIEnv *, jclass) { + return (jint) GC_OBJ_SIZE_THRESHOLD; +} + +JNIEXPORT jboolean JNICALL Java_org_apache_harmony_drlvm_gc_1gen_GCHelper_isPrefetchEnabled(JNIEnv *, jclass) { + return (jboolean) PREFETCH_ENABLED; +} + #ifdef __cplusplus } #endif Index: vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/VMHelper.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/VMHelper.java (revision 600908) +++ vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/VMHelper.java (working copy) @@ -75,6 +75,10 @@ public static void monitorExit(Object obj) {fail();} + public static void memset0(Address addr, int size) {fail();} + + public static void prefetch(Address addr, int distance, int stride) {fail();} + public static void writeBarrier(Address objBase, Address objSlot, Address source) {fail();} public static Address getInterfaceVTable(Object obj, Address intfTypePtr) {fail(); return null;} @@ -146,3 +150,5 @@ private static native long getCompressedModeObjectBaseOffset(); } + +