Index: vm/gc_gen/src/jni/java_natives.cpp =================================================================== --- vm/gc_gen/src/jni/java_natives.cpp (revision 574175) +++ vm/gc_gen/src/jni/java_natives.cpp (working copy) @@ -58,6 +58,25 @@ GCHelper_clss = *vm_class_ptr; } +#define OFFSET(structure, member) ((int) &((structure *)0)->member) + +JNIEXPORT jlong JNICALL Java_org_apache_harmony_drlvm_gc_1gen_GCHelper_getVTBase(JNIEnv *e, jclass c) +{ + return (jlong)vtable_base; +} +JNIEXPORT jint JNICALL Java_org_apache_harmony_drlvm_gc_1gen_GCHelper_getArrayElemSizeOffsetInGCVT(JNIEnv *e, jclass c) +{ + return (jint)OFFSET(GC_VTable_Info,array_elem_size); +} +JNIEXPORT jint JNICALL Java_org_apache_harmony_drlvm_gc_1gen_GCHelper_getArrayFirstElemOffsetInGCVT(JNIEnv *e, jclass c) +{ + return (jint)OFFSET(GC_VTable_Info,array_first_elem_offset); +} +JNIEXPORT jint JNICALL Java_org_apache_harmony_drlvm_gc_1gen_GCHelper_getGCAllocatedSizeOffsetInGCVT(JNIEnv *e, jclass c) +{ + return (jint)OFFSET(GC_VTable_Info,gc_allocated_size); +} + #ifdef __cplusplus } #endif 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 574175) +++ vm/gc_gen/javasrc/org/apache/harmony/drlvm/gc_gen/GCHelper.java (working copy) @@ -91,9 +91,98 @@ VMHelper.writeBarrier(p_objBase, p_objSlot, p_target); } + private static final long VT_BASE = getVTBase(); + private static final int OBJ_INFO_OFFSET = 4; + private static final int HASHCODE_UNSET = 0x0; + private static final int HASHCODE_SET_ATTACHED = 0x0c; + private static final int HASHCODE_SET_UNALLOCATED = 0x04; + private static final int HASHCODE_MASK = 0x1c; + private static final int GC_CLASS_FLAG_ARRAY = 0x02; + private static final long GC_CLASS_FLAGS_MASK = ~((long)0x07); + private static final int GC_OBJ_ALIGN_MASK = GC_OBJECT_ALIGNMENT - 1; + private static final int ARRAY_ELEM_SIZE_OFFSET_IN_GCVT = getArrayElemSizeOffsetInGCVT(); + private static final int ARRAY_FIRST_ELEM_OFFSET_IN_GCVT = getArrayFirstElemOffsetInGCVT(); + private static final int GC_ALLOCATED_SIZE_OFFSET_IN_GCVT= getGCAllocatedSizeOffsetInGCVT(); + + @Inline + public static int nonArrayObjectSize(Address p_obj){ + Address vt_address = Address.fromLong((p_obj.loadLong()>>32) + VT_BASE); //TODO: support uncompressed 64-bit + Address gcvt_raw_address = vt_address.loadAddress(); + Address gcvt_address = Address.fromLong(gcvt_raw_address.toLong() & GC_CLASS_FLAGS_MASK); + + int obj_size + = gcvt_address.loadInt(Offset.fromIntZeroExtend(GC_ALLOCATED_SIZE_OFFSET_IN_GCVT)); + return obj_size; + } + + @Inline + public static int arrayObjectSize(Address p_obj){ + Address vt_address = Address.fromLong((p_obj.loadLong()>>32) + VT_BASE); //TODO: support uncompressed 64-bit + Address gcvt_raw_address = vt_address.loadAddress(); + Address gcvt_address = Address.fromLong(gcvt_raw_address.toLong() & GC_CLASS_FLAGS_MASK); + + int array_first_elem_offset + = gcvt_address.loadInt(Offset.fromIntZeroExtend(ARRAY_FIRST_ELEM_OFFSET_IN_GCVT)); + int array_elem_size + = gcvt_address.loadInt(Offset.fromIntZeroExtend(ARRAY_ELEM_SIZE_OFFSET_IN_GCVT)); + int array_len + = p_obj.loadInt(Offset.fromIntZeroExtend(ARRAY_LEN_OFFSET)); + int obj_size + = (array_first_elem_offset + array_elem_size * array_len + GC_OBJ_ALIGN_MASK)& (~GC_OBJ_ALIGN_MASK); + return obj_size; + } + + @Inline + public static int objectSize(Address p_obj){ + int obj_size; + Address vt_address = Address.fromLong((p_obj.loadLong()>>32) + VT_BASE); //TODO: support uncompressed 64-bit + Address gcvt_raw_address = vt_address.loadAddress(); + long gcvt = gcvt_raw_address.toLong(); + if((gcvt & GC_CLASS_FLAG_ARRAY) != 0){ + obj_size = arrayObjectSize(p_obj); + }else{ + obj_size = nonArrayObjectSize(p_obj); + } + return obj_size; + } + + @Inline + public static int get_hashcode(Address p_obj){ + int hashcode; + int obj_info = p_obj.loadInt(Offset.fromIntZeroExtend(OBJ_INFO_OFFSET)); + switch(obj_info & HASHCODE_MASK){ + case HASHCODE_SET_ATTACHED: + int obj_size = objectSize(p_obj); + hashcode = p_obj.loadInt(Offset.fromIntZeroExtend(obj_size)); + break; + case HASHCODE_SET_UNALLOCATED: + hashcode = (p_obj.toInt())>>2; + break; + case HASHCODE_UNSET: + obj_info = p_obj.prepareInt(Offset.fromIntZeroExtend(OBJ_INFO_OFFSET)); + int new_obj_info = obj_info | HASHCODE_SET_UNALLOCATED; + while(! p_obj.attempt(obj_info, new_obj_info, Offset.fromIntZeroExtend(OBJ_INFO_OFFSET))){ + obj_info = p_obj.prepareInt(Offset.fromIntZeroExtend(OBJ_INFO_OFFSET)); + if((obj_info & HASHCODE_SET_UNALLOCATED) != 0 ) break; + new_obj_info = obj_info | HASHCODE_SET_UNALLOCATED; + } + hashcode = (p_obj.toInt())>>2; + break; + default: + return VMHelper.getHashcode(p_obj); + } + return hashcode; + } + + private static native int helperCallback(); private static native boolean getGenMode(); private static native long getNosBoundary(); private static native int TLSGCOffset(); + + private static native long getVTBase(); + private static native int getArrayElemSizeOffsetInGCVT(); + private static native int getArrayFirstElemOffsetInGCVT(); + private static native int getGCAllocatedSizeOffsetInGCVT(); } 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 574175) +++ vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/VMHelper.java (working copy) @@ -42,6 +42,8 @@ public static void writeBarrier(Address objBase, Address objSlot, Address source) {fail();} + public static int getHashcode(Address p_obj){fail(); return 0;} + public static Address getInterfaceVTable(Object obj, Address intfTypePtr) {fail(); return null;} public static Object checkCast(Object obj, Address castTypePtr) {fail(); return null;}