Index: build/make/components/vm.xml =================================================================== --- build/make/components/vm.xml (revision 596828) +++ build/make/components/vm.xml (working copy) @@ -32,6 +32,7 @@ - + + + + + + + + @@ -65,6 +72,7 @@ + Index: build/make/components/vm/gc_gen_uncomp.xml =================================================================== --- build/make/components/vm/gc_gen_uncomp.xml (revision 0) +++ build/make/components/vm/gc_gen_uncomp.xml (revision 0) @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: build/make/selector.xsl =================================================================== --- build/make/selector.xsl (revision 596828) +++ build/make/selector.xsl (working copy) @@ -33,6 +33,7 @@ + @@ -41,7 +42,7 @@ - + Index: build/make/deploy.xml =================================================================== --- build/make/deploy.xml (revision 596828) +++ build/make/deploy.xml (working copy) @@ -51,11 +51,20 @@ + + + bin/default:gc_cc bin/default:gc_cc Index: build/make/harmonyvm.properties =================================================================== --- build/make/harmonyvm.properties (revision 596828) +++ build/make/harmonyvm.properties (working copy) @@ -17,5 +17,9 @@ bootclasspath.kernel.source.4=%LAUNCHER_HOME%/%VM_DIR%/gc_gen-src.jar bootclasspath.kernel.source.packageroot.4=/ +bootclasspath.kernel.5=%LAUNCHER_HOME%/%VM_DIR%/gc_gen_uncomp.jar +bootclasspath.kernel.source.5=%LAUNCHER_HOME%/%VM_DIR%/gc_gen_uncomp-src.jar +bootclasspath.kernel.source.packageroot.5=/ + # end of file Index: build/make/build.xml =================================================================== --- build/make/build.xml (revision 596828) +++ build/make/build.xml (working copy) @@ -349,6 +349,10 @@ + + + + @@ -392,6 +396,7 @@ + Index: vm/gc_gen/src/mark_compact/mspace_slide_compact.cpp =================================================================== --- vm/gc_gen/src/mark_compact/mspace_slide_compact.cpp (revision 596828) +++ vm/gc_gen/src/mark_compact/mspace_slide_compact.cpp (working copy) @@ -116,7 +116,7 @@ if( obj_info != 0 ) { collector_remset_add_entry(collector, (Partial_Reveal_Object **)dest_addr); - collector_remset_add_entry(collector, (Partial_Reveal_Object **)(POINTER_SIZE_INT)obj_info); + collector_remset_add_entry(collector, (Partial_Reveal_Object **)obj_info); } obj_set_fw_in_oi(p_obj, dest_addr); Index: vm/gc_gen/src/thread/collector_alloc.h =================================================================== --- vm/gc_gen/src/thread/collector_alloc.h (revision 596828) +++ vm/gc_gen/src/thread/collector_alloc.h (working copy) @@ -60,8 +60,8 @@ /* else, take the obj by setting the forwarding flag atomically we don't put a simple bit in vt because we need compute obj size later. */ - REF target = obj_ptr_to_ref(p_targ_obj); - if (oi != (Obj_Info_Type)atomic_cas32((volatile unsigned int*)get_obj_info_addr(p_obj), ( ( (unsigned int)target |FORWARD_BIT)), oi)) { + Obj_Info_Type target_oi = (Obj_Info_Type)obj_ptr_to_ref(p_targ_obj); + if (oi != atomic_casptrsz((volatile POINTER_SIZE_INT*)get_obj_info_addr(p_obj), (target_oi |FORWARD_BIT), oi)) { /* forwarded by other, we need unalloc the allocated obj. We may waste some space if the allocation switched block. The remaining part of the switched block cannot be revivied for next allocation of object that has smaller size than this one. */ Index: vm/gc_gen/src/common/gc_for_vm.cpp =================================================================== --- vm/gc_gen/src/common/gc_for_vm.cpp (revision 596828) +++ vm/gc_gen/src/common/gc_for_vm.cpp (working copy) @@ -56,7 +56,11 @@ static void init_gc_helpers() { +#ifdef COMPRESS_REFERENCE set_property("vm.component.classpath.gc_gen", "gc_gen.jar", VM_PROPERTIES); +#else + set_property("vm.component.classpath.gc_gen_uncomp", "gc_gen_uncomp.jar", VM_PROPERTIES); +#endif vm_helper_register_magic_helper(VM_RT_NEW_RESOLVED_USING_VTABLE_AND_SIZE, "org/apache/harmony/drlvm/gc_gen/GCHelper", "alloc"); vm_helper_register_magic_helper(VM_RT_NEW_VECTOR_USING_VTABLE, "org/apache/harmony/drlvm/gc_gen/GCHelper", "allocArray"); } @@ -80,10 +84,12 @@ gc_parse_options(gc); - if(vm_vtable_pointers_are_compressed()) { +// iberezhniuk: compile-time switching is now used in both VM and GC +#ifdef COMPRESS_VTABLE + assert(vm_vtable_pointers_are_compressed()); // ppervov: reference compression and vtable compression are orthogonal - vtable_base = vm_get_vtable_base(); - } + vtable_base = vm_get_vtable_base(); +#endif gc_tls_init(); @@ -149,12 +155,14 @@ INFO2("gc.process", "GC: end of GC wrapup\n"); } -#ifdef COMPRESS_REFERENCE Boolean gc_supports_compressed_references() { +#ifdef COMPRESS_REFERENCE return TRUE; +#else + return FALSE; +#endif } -#endif /* this interface need reconsidering. is_pinned is unused. */ void gc_add_root_set_entry(Managed_Object_Handle *ref, Boolean is_pinned) @@ -316,16 +324,17 @@ if(!obj) return 0; assert(address_belongs_to_gc_heap(obj, p_global_gc)); Obj_Info_Type info = get_obj_info_raw(obj); - int hash = info & GCGEN_HASH_MASK; + int hash = (int)(info & GCGEN_HASH_MASK); if (!hash) { hash = (int)((((POINTER_SIZE_INT)obj) >> 3) & GCGEN_HASH_MASK); if(!hash) hash = (0x173 & GCGEN_HASH_MASK); - unsigned int new_info = (unsigned int)(info | hash); + POINTER_SIZE_INT new_info = info | hash; while (true) { - unsigned int temp = atomic_cas32((volatile unsigned int*)(&obj->obj_info), new_info, info); + Obj_Info_Type temp = + atomic_casptrsz((volatile POINTER_SIZE_INT*)(&obj->obj_info), new_info, info); if (temp == info) break; info = get_obj_info_raw(obj); - new_info = (unsigned int)(info | hash); + new_info = info | hash; } } return hash; @@ -341,7 +350,7 @@ if(!p_obj) return 0; assert(address_belongs_to_gc_heap(p_obj, p_global_gc)); Obj_Info_Type info = get_obj_info_raw(p_obj); - unsigned int new_info = 0; + Obj_Info_Type new_info = 0; int hash; switch(info & HASHCODE_MASK){ @@ -355,12 +364,13 @@ hash = hashcode_lookup(p_obj,info); break; case HASHCODE_UNSET: - new_info = (unsigned int)(info | HASHCODE_SET_BIT); + new_info = info | HASHCODE_SET_BIT; while (true) { - unsigned int temp = atomic_cas32((volatile unsigned int*)(&p_obj->obj_info), new_info, info); + Obj_Info_Type temp = + atomic_casptrsz((volatile POINTER_SIZE_INT*)(&p_obj->obj_info), new_info, info); if (temp == info) break; info = get_obj_info_raw(p_obj); - new_info = (unsigned int)(info | HASHCODE_SET_BIT); + new_info = info | HASHCODE_SET_BIT; } hash = hashcode_gen((void*)p_obj); break; Index: vm/gc_gen/src/common/gc_platform.h =================================================================== --- vm/gc_gen/src/common/gc_platform.h (revision 596828) +++ vm/gc_gen/src/common/gc_platform.h (working copy) @@ -118,14 +118,10 @@ { return apr_atomic_casptr(mem, with, cmp); } inline POINTER_SIZE_INT atomic_casptrsz(volatile POINTER_SIZE_INT* mem, - POINTER_SIZE_INT swap, - POINTER_SIZE_INT cmp) + POINTER_SIZE_INT swap, + POINTER_SIZE_INT cmp) { -#ifdef POINTER64 - return port_atomic_cas64(mem, swap, cmp); -#else - return apr_atomic_cas32(mem, swap, cmp); -#endif + return (POINTER_SIZE_INT)apr_atomic_casptr((volatile void **)mem, (void*)swap, (void*)cmp); } inline uint32 atomic_cas32(volatile apr_uint32_t *mem, Index: vm/gc_gen/src/common/gc_common.h =================================================================== --- vm/gc_gen/src/common/gc_common.h (revision 596828) +++ vm/gc_gen/src/common/gc_common.h (working copy) @@ -137,21 +137,19 @@ GC_CAUSE_RUNTIME_FORCE_GC }; -/*Fixme: There is only compressed mode under em64t currently.*/ -#ifdef POINTER64 - #define COMPRESS_REFERENCE -#endif extern POINTER_SIZE_INT HEAP_NULL; -#ifdef POINTER64 - #ifdef COMPRESS_REFERENCE +//#define COMPRESS_REFERENCE // Now passed from outside + +#if !defined(POINTER64) && defined(COMPRESS_REFERENCE) +#error "32-bit architecture does not support references compression" +#endif + +#ifdef COMPRESS_REFERENCE #define REF uint32 - #else +#else #define REF Partial_Reveal_Object* - #endif -#else/*ifdef POINTER64*/ - #define REF Partial_Reveal_Object* #endif ///////////////////////////////////////////// @@ -161,17 +159,17 @@ { #ifdef COMPRESS_REFERENCE if(!p_obj){ - /*Fixme: em64t: vm performs a simple compress/uncompress machenism - i.e. just add or minus HEAP_NULL to p_obj - But in gc we distinguish zero from other p_obj - Now only in prefetch next live object we can hit this point. */ + /*Fixme: em64t: vm performs a simple compress/uncompress machenism + i.e. just add or minus HEAP_NULL to p_obj + But in gc we distinguish zero from other p_obj + Now only in prefetch next live object we can hit this point. */ return (REF)0; } else return (REF) ((POINTER_SIZE_INT) p_obj - HEAP_NULL); #else - return (REF)p_obj; + return (REF)p_obj; #endif @@ -187,7 +185,7 @@ #else - return (Partial_Reveal_Object *)ref; + return (Partial_Reveal_Object *)ref; #endif @@ -240,35 +238,35 @@ /****************************************/ inline Boolean obj_is_marked_in_vt(Partial_Reveal_Object *obj) -{ return (Boolean)((POINTER_SIZE_INT)obj_get_vt_raw(obj) & CONST_MARK_BIT); } +{ return (((VT_SIZE_INT)obj_get_vt_raw(obj) & CONST_MARK_BIT) != 0); } inline Boolean obj_mark_in_vt(Partial_Reveal_Object *obj) { VT vt = obj_get_vt_raw(obj); - if((POINTER_SIZE_INT)vt & CONST_MARK_BIT) return FALSE; - obj_set_vt(obj, (VT)( (POINTER_SIZE_INT)vt | CONST_MARK_BIT ) ); + if((VT_SIZE_INT)vt & CONST_MARK_BIT) return FALSE; + obj_set_vt(obj, (VT)( (VT_SIZE_INT)vt | CONST_MARK_BIT ) ); return TRUE; } inline void obj_unmark_in_vt(Partial_Reveal_Object *obj) { VT vt = obj_get_vt_raw(obj); - obj_set_vt(obj, (VT)((POINTER_SIZE_INT)vt & ~CONST_MARK_BIT)); + obj_set_vt(obj, (VT)((VT_SIZE_INT)vt & ~CONST_MARK_BIT)); } inline void obj_clear_dual_bits_in_vt(Partial_Reveal_Object* p_obj){ VT vt = obj_get_vt_raw(p_obj); - obj_set_vt(p_obj,(VT)((POINTER_SIZE_INT)vt & DUAL_MARKBITS_MASK)); + obj_set_vt(p_obj,(VT)((VT_SIZE_INT)vt & DUAL_MARKBITS_MASK)); } inline Boolean obj_is_marked_or_fw_in_oi(Partial_Reveal_Object *obj) -{ return get_obj_info_raw(obj) & DUAL_MARKBITS; } +{ return ((get_obj_info_raw(obj) & DUAL_MARKBITS) != 0); } inline void obj_clear_dual_bits_in_oi(Partial_Reveal_Object *obj) { Obj_Info_Type info = get_obj_info_raw(obj); - set_obj_info(obj, (unsigned int)info & DUAL_MARKBITS_MASK); + set_obj_info(obj, info & DUAL_MARKBITS_MASK); } /****************************************/ @@ -292,7 +290,7 @@ inline Boolean obj_is_marked_in_oi(Partial_Reveal_Object *obj) -{ return ( get_obj_info_raw(obj) & CONST_MARK_BIT ); } +{ return ((get_obj_info_raw(obj) & CONST_MARK_BIT) != 0); } FORCE_INLINE Boolean obj_mark_in_oi(Partial_Reveal_Object *obj) { @@ -308,7 +306,6 @@ Obj_Info_Type info = get_obj_info_raw(obj); info = info & ~CONST_MARK_BIT; set_obj_info(obj, info); - return; } /* ********************************** */ @@ -327,7 +324,7 @@ } inline Boolean obj_is_fw_in_oi(Partial_Reveal_Object *obj) -{ return (get_obj_info_raw(obj) & FLIP_FORWARD_BIT); } +{ return ((get_obj_info_raw(obj) & FLIP_FORWARD_BIT) != 0); } inline void obj_set_fw_in_oi(Partial_Reveal_Object *obj, void *dest) { @@ -366,7 +363,7 @@ inline Boolean obj_is_marked_in_oi(Partial_Reveal_Object* p_obj) { Obj_Info_Type info = get_obj_info_raw(p_obj); - return (info & FLIP_MARK_BIT); + return ((info & FLIP_MARK_BIT) != 0); } #endif /* MARK_BIT_FLIPPING */ @@ -374,7 +371,7 @@ inline Boolean obj_is_dirty_in_oi(Partial_Reveal_Object* p_obj) { Obj_Info_Type info = get_obj_info_raw(p_obj); - return (Boolean)(info & OBJ_DIRTY_BIT); + return ((info & OBJ_DIRTY_BIT) != 0); } inline Boolean obj_dirty_in_oi(Partial_Reveal_Object* p_obj) @@ -383,7 +380,7 @@ if( info & OBJ_DIRTY_BIT ) return FALSE; Obj_Info_Type new_info = info | OBJ_DIRTY_BIT; - while(info != atomic_cas32((volatile unsigned int *)get_obj_info_addr(p_obj),new_info, info)){ + while(info != atomic_casptrsz((volatile POINTER_SIZE_INT*)get_obj_info_addr(p_obj), new_info, info)){ info = get_obj_info_raw(p_obj); if( info & OBJ_DIRTY_BIT ) return FALSE; new_info = info |OBJ_DIRTY_BIT; @@ -506,11 +503,11 @@ //#define NOS_BOUNDARY ((void*)0x2ea20000) //this is for 512M #define NOS_BOUNDARY ((void*)0x40000000) //this is for 256M - #define nos_boundary NOS_BOUNDARY + #define nos_boundary NOS_BOUNDARY #else /* STATIC_NOS_MAPPING */ - extern void* nos_boundary; + extern void* nos_boundary; #endif /* STATIC_NOS_MAPPING */ Index: vm/gc_gen/src/common/gc_block.h =================================================================== --- vm/gc_gen/src/common/gc_block.h (revision 596828) +++ vm/gc_gen/src/common/gc_block.h (working copy) @@ -142,17 +142,17 @@ inline void obj_set_prefetched_next_pointer(Partial_Reveal_Object* obj, Partial_Reveal_Object* raw_prefetched_next){ /*Fixme: em64t: This may be not necessary!*/ if(raw_prefetched_next == 0){ - *((REF*)obj + 1) = 0; + *((POINTER_SIZE_INT*)obj + 1) = 0; return; } REF ref = obj_ptr_to_ref(raw_prefetched_next); - *((REF*)obj + 1) = ref; + *( (REF*)((POINTER_SIZE_INT*)obj + 1) ) = ref; } inline Partial_Reveal_Object* obj_get_prefetched_next_pointer(Partial_Reveal_Object* obj){ /*Fixme: em64t: This may be not necessary!*/ assert(obj); - return read_slot( (REF*)obj + 1); + return read_slot( (REF*)((POINTER_SIZE_INT*)obj + 1) ); } inline Partial_Reveal_Object *next_marked_obj_in_block(Partial_Reveal_Object *cur_obj, Partial_Reveal_Object *block_end) Index: vm/gc_gen/src/common/hashcode.h =================================================================== --- vm/gc_gen/src/common/hashcode.h (revision 596828) +++ vm/gc_gen/src/common/hashcode.h (working copy) @@ -38,30 +38,30 @@ }; inline Boolean obj_is_sethash_in_vt(Partial_Reveal_Object* p_obj){ - return (Boolean)((POINTER_SIZE_INT)obj_get_vt_raw(p_obj) & HASHCODE_EXTENDED_VT_BIT); + return (((VT_SIZE_INT)obj_get_vt_raw(p_obj) & HASHCODE_EXTENDED_VT_BIT) != 0); } inline void obj_sethash_in_vt(Partial_Reveal_Object* p_obj){ VT vt = obj_get_vt_raw(p_obj); - obj_set_vt(p_obj,(VT)((POINTER_SIZE_INT)vt | HASHCODE_EXTENDED_VT_BIT)); + obj_set_vt(p_obj,(VT)((VT_SIZE_INT)vt | HASHCODE_EXTENDED_VT_BIT)); } inline Boolean hashcode_is_set(Partial_Reveal_Object* p_obj) { Obj_Info_Type obj_info = get_obj_info_raw(p_obj); - return obj_info & HASHCODE_SET_BIT; + return ((obj_info & HASHCODE_SET_BIT) != 0); } inline Boolean hashcode_is_attached(Partial_Reveal_Object* p_obj) { Obj_Info_Type obj_info = get_obj_info_raw(p_obj); - return obj_info & HASHCODE_ATTACHED_BIT; + return ((obj_info & HASHCODE_ATTACHED_BIT) != 0); } inline Boolean hashcode_is_buffered(Partial_Reveal_Object* p_obj) { Obj_Info_Type obj_info = get_obj_info_raw(p_obj); - return obj_info & HASHCODE_BUFFERED_BIT; + return ((obj_info & HASHCODE_BUFFERED_BIT) != 0); } inline int hashcode_gen(void* addr) @@ -294,7 +294,7 @@ Hashcode_Buf* old_buf, Hashcode_Buf* new_buf) { Obj_Info_Type obj_info = get_obj_info(p_obj); - POINTER_SIZE_INT hashcode; + POINTER_SIZE_INT hashcode = 0; switch(obj_info & HASHCODE_MASK){ case HASHCODE_SET_UNALLOCATED: Index: vm/gc_gen/src/common/gc_for_class.h =================================================================== --- vm/gc_gen/src/common/gc_for_class.h (revision 596828) +++ vm/gc_gen/src/common/gc_for_class.h (working copy) @@ -71,19 +71,19 @@ #define OBJ_DIRTY_BIT 0x20 -/*emt64 related!*/ -#define COMPRESS_VTABLE +#ifdef POINTER64 // Like in VM + #define COMPRESS_VTABLE +#endif -#ifdef POINTER64 - #ifdef COMPRESS_VTABLE +#ifdef COMPRESS_VTABLE #define VT uint32 - #else + #define VT_SIZE_INT uint32 +#else #define VT Partial_Reveal_VTable* - #endif -#else/*ifdef POINTER64*/ - #define VT Partial_Reveal_VTable* + #define VT_SIZE_INT POINTER_SIZE_INT #endif + typedef void *Thread_Handle; #define GC_CLASS_FLAG_FINALIZER 1 @@ -96,7 +96,7 @@ #define GCVT_ALIGNMENT 8 #define GCVT_ALIGN_MASK (GCVT_ALIGNMENT-1) -typedef uint32 Obj_Info_Type; +typedef POINTER_SIZE_INT Obj_Info_Type; typedef struct GC_VTable_Info { @@ -131,19 +131,24 @@ struct Partial_Reveal_Object; typedef struct Partial_Reveal_VTable { - //--Fixme: emt64 GC_VTable_Info *gcvt; Partial_Reveal_Object* jlC; unsigned int vtmark; } Partial_Reveal_VTable; typedef struct Partial_Reveal_Object { + union { VT vt_raw; + POINTER_SIZE_INT padding; + }; Obj_Info_Type obj_info; } Partial_Reveal_Object; typedef struct Partial_Reveal_Array { + union { VT vt_raw; + POINTER_SIZE_INT padding; + }; Obj_Info_Type obj_info; unsigned int array_len; } Partial_Reveal_Array; @@ -202,14 +207,12 @@ FORCE_INLINE VT *obj_get_vt_addr(Partial_Reveal_Object *obj) { assert(obj && obj->vt_raw); return &obj->vt_raw; } -/*Fixme: emt64*/ FORCE_INLINE VT obj_get_vt(Partial_Reveal_Object *obj) -{ assert(obj && obj->vt_raw); return (VT)((POINTER_SIZE_INT)obj->vt_raw & ~CLEAR_VT_MARK); } +{ assert(obj && obj->vt_raw); return (VT)((VT_SIZE_INT)obj->vt_raw & ~CLEAR_VT_MARK); } FORCE_INLINE void obj_set_vt(Partial_Reveal_Object *obj, VT ah) { assert(obj && ah); obj->vt_raw = ah; } -/*Fixme: emt64, we should check whether gcvt is compressed first!*/ FORCE_INLINE GC_VTable_Info *vtable_get_gcvt_raw(Partial_Reveal_VTable* vt) { assert(vt && vt->gcvt); return vt->gcvt; } @@ -220,7 +223,6 @@ } FORCE_INLINE void vtable_set_gcvt(Partial_Reveal_VTable *vt, GC_VTable_Info *new_gcvt) -/*Fixme: emt64*/ { assert(vt && new_gcvt); vt->gcvt = new_gcvt; } FORCE_INLINE GC_VTable_Info *obj_get_gcvt_raw(Partial_Reveal_Object *obj) Index: vm/gc_gen/src/los/lspace_alloc_collect.cpp =================================================================== --- vm/gc_gen/src/los/lspace_alloc_collect.cpp (revision 596828) +++ vm/gc_gen/src/los/lspace_alloc_collect.cpp (working copy) @@ -273,7 +273,7 @@ if( obj_info != 0 ) { collector_remset_add_entry(collector, (Partial_Reveal_Object **)dest_addr); - collector_remset_add_entry(collector, (Partial_Reveal_Object **)(POINTER_SIZE_INT)obj_info); + collector_remset_add_entry(collector, (Partial_Reveal_Object **)obj_info); } obj_set_fw_in_oi(p_obj, dest_addr); 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 0) +++ vm/gc_gen/javasrc_uncomp/org/apache/harmony/drlvm/gc_gen/GCHelper.java (revision 0) @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +/** + * @author Xiao-Feng Li + */ + +package org.apache.harmony.drlvm.gc_gen; + +import org.apache.harmony.drlvm.VMHelper; +import org.vmmagic.unboxed.*; +import org.vmmagic.pragma.*; + +public class GCHelper { + + static { + System.loadLibrary("gc_gen_uncomp"); + helperCallback(); + } + + public static final int TLS_GC_OFFSET = TLSGCOffset(); + + @Inline + public static Address alloc(int objSize, int 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 = free_addr.loadAddress(); + Address ceiling = allocator.plus(4).loadAddress(); + + Address new_free = free.plus(objSize); + + if (new_free.LE(ceiling)) { + free_addr.store(new_free); + free.store(allocationHandle); + return free; + } + + return VMHelper.newResolvedUsingAllocHandleAndSize(objSize, allocationHandle); + } + + private static final int ARRAY_LEN_OFFSET = 8; + private static final int GC_OBJECT_ALIGNMENT = 4; //TODO: EM64 or IPF could have 8! + + @Inline + public static Address allocArray(int arrayLen, int elemSize, int allocationHandle) { + if (arrayLen >= 0) { + int firstElementOffset = ARRAY_LEN_OFFSET + (elemSize==8?8:4); + int size = firstElementOffset + elemSize*arrayLen; + size = (((size + (GC_OBJECT_ALIGNMENT - 1)) & (~(GC_OBJECT_ALIGNMENT - 1)))); + + Address arrayAddress = alloc(size, allocationHandle); //never null! + arrayAddress.store(arrayLen, Offset.fromIntZeroExtend(ARRAY_LEN_OFFSET)); + return arrayAddress; + } + return VMHelper.newVectorUsingAllocHandle(arrayLen, allocationHandle); + } + + /** NOS (nursery object space) is higher in address than other spaces. + The boundary currently is produced in GC initialization. It can + be a constant in future. + */ + + public static Address NOS_BOUNDARY = Address.fromLong(getNosBoundary()); + public static boolean GEN_MODE = getGenMode(); + + @Inline + public static void write_barrier_slot_rem(Address p_objBase, Address p_objSlot, Address p_target) { + + /* If the slot is in NOS or the target is not in NOS, we simply return*/ + if(p_objSlot.GE(NOS_BOUNDARY) || p_target.LT(NOS_BOUNDARY) || !GEN_MODE) { + p_objSlot.store(p_target); + return; + } + + VMHelper.writeBarrier(p_objBase, p_objSlot, p_target); + } + + private static native int helperCallback(); + private static native boolean getGenMode(); + private static native long getNosBoundary(); + private static native int TLSGCOffset(); +} + Index: vm/vmcore/include/object_layout.h =================================================================== --- vm/vmcore/include/object_layout.h (revision 596828) +++ vm/vmcore/include/object_layout.h (working copy) @@ -220,14 +220,17 @@ typedef struct ManagedObject { #if defined USE_COMPRESSED_VTABLE_POINTERS + union { uint32 vt_offset; - uint32 obj_info; + POINTER_SIZE_INT padding; + }; + POINTER_SIZE_INT obj_info; VTable *vt_unsafe() { return (VTable*)(vt_offset + vm_get_vtable_base()); } VTable *vt() { assert(vt_offset); return vt_unsafe(); } static VTable *allocation_handle_to_vtable(Allocation_Handle ah) { return (VTable *) ((POINTER_SIZE_INT)ah + vm_get_vtable_base()); } - static unsigned header_offset() { return sizeof(uint32); } + static unsigned header_offset() { return sizeof(POINTER_SIZE_INT); } static bool are_vtable_pointers_compressed() { return true; } #else // USE_COMPRESSED_VTABLE_POINTERS VTable *vt_raw; @@ -247,9 +250,11 @@ return get_constant_header_size() + (_tag_pointer ? sizeof(void*) : 0); } - uint32 get_obj_info() { return (uint32)obj_info; } - void set_obj_info(uint32 value) { obj_info = value; } - uint32 *get_obj_info_addr() { return (uint32 *)((char *)this + header_offset()); } + POINTER_SIZE_INT get_obj_info() { return obj_info; } + void set_obj_info(POINTER_SIZE_INT value) { obj_info = value; } + POINTER_SIZE_INT* get_obj_info_addr() { + return (POINTER_SIZE_INT*)((char*)this + header_offset()); + } /** * returns address of a tag pointer field in a _non-array_ object. Index: vm/vmcore/src/init/vm_properties.cpp =================================================================== --- vm/vmcore/src/init/vm_properties.cpp (revision 596828) +++ vm/vmcore/src/init/vm_properties.cpp (working copy) @@ -65,8 +65,6 @@ "hyarchive" }; -#define GC_DLL "gc_gen" - /** * Compose a string of file names each of them beginning with path, * names separated by PORT_PATH_SEPARATOR. If patch is NULL, no path @@ -302,7 +300,6 @@ properties.set_new("vm.jvmti.enabled", "false"); properties.set_new("vm.jvmti.compiled_method_load.inlined", "false"); properties.set_new("vm.bootclasspath.appendclasspath", "false"); - properties.set_new("gc.dll", PORT_DSO_NAME(GC_DLL)); properties.set_new("thread.soft_unreservation", "false"); #ifdef REFS_USE_RUNTIME_SWITCH Index: vm/vmcore/src/init/vm_init.cpp =================================================================== --- vm/vmcore/src/init/vm_init.cpp (revision 596828) +++ vm/vmcore/src/init/vm_init.cpp (working copy) @@ -120,6 +120,19 @@ } } //create_instance_for_class + +#define GC_DLL_COMP PORT_DSO_NAME("gc_gen") +#define GC_DLL_UNCOMP PORT_DSO_NAME("gc_gen_uncomp") + +#if defined(REFS_USE_COMPRESSED) +#define GC_DLL GC_DLL_COMP +#elif defined(REFS_USE_UNCOMPRESSED) +#define GC_DLL GC_DLL_UNCOMP +#else // for REFS_USE_RUNTIME_SWITCH +#define GC_DLL (vm_env->compress_references ? GC_DLL_COMP : GC_DLL_UNCOMP) +#endif + + /** * Loads DLLs. */ @@ -154,12 +167,14 @@ /* * Preload .dll which is specified by 'gc.dll' property. - * - * According to current design (r552465) 'gc.dll' property - * is always set: in configuration file (by default), or it can - * be reset from command line... + * 'gc.dll' property is set when specified in command line. + * When undefined, set default gc */ #ifndef USE_GC_STATIC + if (!vm_env->VmProperties()->is_set("gc.dll")) { + vm_env->VmProperties()->set_new("gc.dll", GC_DLL); + } + char* gc_dll = vm_env->VmProperties()->get("gc.dll"); if (!gc_dll) { Index: vm/vmcore/src/thread/mon_enter_exit.cpp =================================================================== --- vm/vmcore/src/thread/mon_enter_exit.cpp (revision 596828) +++ vm/vmcore/src/thread/mon_enter_exit.cpp (working copy) @@ -144,11 +144,11 @@ } static uint32 vm_monitor_try_enter_default(ManagedObject *p_obj) { - return (uint32)hythread_thin_monitor_try_enter((hythread_thin_monitor_t *)((char *)p_obj+4)); + return (uint32)hythread_thin_monitor_try_enter((hythread_thin_monitor_t *)p_obj->get_obj_info_addr()); } static uint32 vm_monitor_try_exit_default(ManagedObject *p_obj) { - return (uint32)hythread_thin_monitor_exit((hythread_thin_monitor_t *)((char *)p_obj+4)); + return (uint32)hythread_thin_monitor_exit((hythread_thin_monitor_t *)p_obj->get_obj_info_addr()); }