harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From x..@apache.org
Subject svn commit: r519564 [1/2] - in /harmony/enhanced/drlvm/trunk/vm/gc_gen/src: common/ finalizer_weakref/ gen/ mark_compact/ mark_sweep/ thread/ trace_forward/ utils/
Date Sun, 18 Mar 2007 06:02:58 GMT
Author: xli
Date: Sat Mar 17 23:02:56 2007
New Revision: 519564

URL: http://svn.apache.org/viewvc?view=rev&rev=519564
Log:
GCv5 64bit support with compressed pointer

Added:
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/compressed_ref.cpp   (with props)
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/compressed_ref.h   (with props)
Modified:
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/fix_repointed_refs.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_block.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_vm.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/interior_pointer.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/large_pages.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan_pool.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen_adapt.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/fallback_mark_scan.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect_compact.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_extend_compact.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_move_compact.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_slide_compact.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/free_area_pool.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector_alloc.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator_alloc.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_gen_forward_pool.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_nongen_forward_pool.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/bit_ops.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/sync_queue.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/sync_stack.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/vector_block.h

Added: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/compressed_ref.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/compressed_ref.cpp?view=auto&rev=519564
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/compressed_ref.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/compressed_ref.cpp Sat Mar 17 23:02:56 2007
@@ -0,0 +1,72 @@
+/*
+ *  Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed 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, 2007/01/24
+ */
+
+#include "gc_common.h"
+#include "../utils/vector_block.h"
+#include "../utils/sync_pool.h"
+#include "../thread/collector.h"
+#include "../thread/mutator.h"
+#include "compressed_ref.h"
+
+typedef struct Uncompressed_Root{
+  Partial_Reveal_Object **p_ref;   /* pointing to the uncompressed address of the root object */
+  REF ref;  /* temporal compressed pointer pointing to the root object */
+}Compressed_Root;
+
+POINTER_SIZE_INT vtable_base = 0;
+POINTER_SIZE_INT HEAP_NULL = 0;
+
+void gc_set_uncompressed_rootset(GC *gc)
+{
+  Pool *rootset_pool = gc->metadata->gc_uncompressed_rootset_pool;
+  
+  pool_put_entry(rootset_pool, gc->uncompressed_root_set);
+  gc->uncompressed_root_set = NULL;
+  
+  pool_iterator_init(rootset_pool);
+  while(Vector_Block *root_set = pool_iterator_next(rootset_pool)){
+    POINTER_SIZE_INT *iter = vector_block_iterator_init(root_set);
+    for(; !vector_block_iterator_end(root_set, iter); iter = vector_block_iterator_advance(root_set, iter)){
+      iter = vector_block_iterator_advance(root_set, iter);
+      assert(!vector_block_iterator_end(root_set, iter));
+      /* add the pointer to ref of Uncmpressed_Root to rootset */
+      gc_compressed_rootset_add_entry(gc, (REF *)iter);
+    }
+  }
+}
+
+void gc_fix_uncompressed_rootset(GC *gc)
+{
+  Pool *rootset_pool = gc->metadata->gc_uncompressed_rootset_pool;
+  
+  pool_iterator_init(rootset_pool);
+  while(Vector_Block *root_set = pool_iterator_next(rootset_pool)){
+    POINTER_SIZE_INT *iter = vector_block_iterator_init(root_set);
+    for(; !vector_block_iterator_end(root_set, iter); iter = vector_block_iterator_advance(root_set, iter)){
+      Partial_Reveal_Object **p_ref = (Partial_Reveal_Object **)*iter;
+      iter = vector_block_iterator_advance(root_set, iter);
+      assert(!vector_block_iterator_end(root_set, iter));
+      REF ref = (REF)*iter;
+      Partial_Reveal_Object *p_obj = uncompress_ref(ref);
+      *p_ref = p_obj;
+    }
+  }
+}
+

Propchange: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/compressed_ref.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/compressed_ref.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/compressed_ref.h?view=auto&rev=519564
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/compressed_ref.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/compressed_ref.h Sat Mar 17 23:02:56 2007
@@ -0,0 +1,51 @@
+/*
+ *  Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed 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, 2007/01/24
+ */
+#ifndef _COMPRESSED_REF_H_
+#define _COMPRESSED_REF_H_
+
+#include "gc_common.h"
+#include "gc_metadata.h"
+#include "../utils/vector_block.h"
+#include "../utils/sync_pool.h"
+#include "../thread/collector.h"
+#include "../thread/mutator.h"
+
+void gc_set_uncompressed_rootset(GC *gc);
+void gc_fix_uncompressed_rootset(GC *gc);
+
+
+FORCE_INLINE void gc_compressed_rootset_add_entry(GC *gc, REF *p_ref)
+{
+  assert( p_ref < gc_heap_base(gc) || p_ref >= gc_heap_ceiling(gc));
+  
+  GC_Metadata *metadata = gc->metadata;
+  Vector_Block *root_set = gc->root_set;
+  assert(root_set);
+  
+  vector_block_add_entry(root_set, (POINTER_SIZE_INT)p_ref);
+  
+  if(!vector_block_is_full(root_set)) return;
+  
+  pool_put_entry(metadata->gc_rootset_pool, root_set);
+  gc->root_set = free_set_pool_get_entry(metadata);
+  assert(gc->root_set);
+}
+
+#endif /* #ifndef _COMPRESSED_REF_H_ */

Propchange: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/compressed_ref.h
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/fix_repointed_refs.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/fix_repointed_refs.h?view=diff&rev=519564&r1=519563&r2=519564
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/fix_repointed_refs.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/fix_repointed_refs.h Sat Mar 17 23:02:56 2007
@@ -22,11 +22,12 @@
 #define _FIX_REPOINTED_REFS_H_
 
 #include "gc_common.h"
+#include "compressed_ref.h"
 extern Boolean IS_MOVE_COMPACT;
 
-inline void slot_fix(Partial_Reveal_Object** p_ref)
+inline void slot_fix(REF* p_ref)
 {
-  Partial_Reveal_Object* p_obj = *p_ref;
+  Partial_Reveal_Object* p_obj = read_slot(p_ref);
   if(!p_obj) return;
 
   if(IS_MOVE_COMPACT){
@@ -40,7 +41,7 @@
        * since those which can be scanned in MOS & NOS must have been set fw bit in oi.
        */
       assert((POINTER_SIZE_INT)obj_get_fw_in_oi(p_obj) > DUAL_MARKBITS);
-      *p_ref = obj_get_fw_in_oi(p_obj);
+      write_slot(p_ref, obj_get_fw_in_oi(p_obj));
     }
   }
     
@@ -57,7 +58,7 @@
     assert(!obj_is_primitive_array(p_obj));
     
     int32 array_length = array->array_len;
-    Partial_Reveal_Object** p_refs = (Partial_Reveal_Object**)((POINTER_SIZE_INT)array + (int)array_first_element_offset(array));
+    REF* p_refs = (REF *)((POINTER_SIZE_INT)array + (int)array_first_element_offset(array));
     for (int i = 0; i < array_length; i++) {
       slot_fix(p_refs + i);
     }   
@@ -67,7 +68,7 @@
   /* scan non-array object */
   int *offset_scanner = init_object_scanner(p_obj);
   while (true) {
-    Partial_Reveal_Object** p_ref = (Partial_Reveal_Object**)offset_get_ref(offset_scanner, p_obj);
+    REF* p_ref = (REF*)offset_get_ref(offset_scanner, p_obj);
     if (p_ref == NULL) break; /* terminating ref slot */
   
     slot_fix(p_ref);
@@ -77,6 +78,7 @@
   return;
 }
 
+
 inline void block_fix_ref_after_copying(Block_Header* curr_block)
 {
   POINTER_SIZE_INT cur_obj = (POINTER_SIZE_INT)curr_block->base;
@@ -106,7 +108,7 @@
 {
   void* start_pos;
   Partial_Reveal_Object* p_obj = block_get_first_marked_obj_after_prefetch(curr_block, &start_pos);
-  
+
   while( p_obj ){
     assert( obj_is_marked_in_vt(p_obj));
     object_fix_ref_slots(p_obj);   
@@ -114,6 +116,5 @@
   }
   return;
 }
-
 
 #endif /* #ifndef _FIX_REPOINTED_REFS_H_ */

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_block.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_block.h?view=diff&rev=519564&r1=519563&r2=519564
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_block.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_block.h Sat Mar 17 23:02:56 2007
@@ -102,6 +102,24 @@
   return (Partial_Reveal_Object *)((POINTER_SIZE_INT)obj + vm_object_size(obj));
 }
 
+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;
+    return;
+  }
+  REF ref = compress_ref(raw_prefetched_next);
+  *((REF*)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);
+  
+  REF ref = *( (REF*)obj + 1);
+  return uncompress_ref(ref);
+}
+
 inline Partial_Reveal_Object *next_marked_obj_in_block(Partial_Reveal_Object *cur_obj, Partial_Reveal_Object *block_end)
 {
   while(cur_obj < block_end){
@@ -160,11 +178,10 @@
   
   if(next_marked_obj){
     if(next_marked_obj != next_obj)
-      set_obj_info(next_obj, (Obj_Info_Type)next_marked_obj);
+      obj_set_prefetched_next_pointer(next_obj, next_marked_obj);
   } else {
-    set_obj_info(next_obj, 0);
+      obj_set_prefetched_next_pointer(next_obj, 0);
   }
-  
   return first_marked_obj;
 }
 
@@ -186,8 +203,8 @@
   if(obj_is_marked_in_vt(cur_obj))
     cur_marked_obj = cur_obj;
   else
-    cur_marked_obj = (Partial_Reveal_Object *)get_obj_info_raw(cur_obj);
-  
+    cur_marked_obj = (Partial_Reveal_Object *)obj_get_prefetched_next_pointer(cur_obj);
+
   if(!cur_marked_obj)
     return NULL;
   
@@ -201,9 +218,9 @@
   
   if(next_marked_obj){
     if(next_marked_obj != next_obj)
-      set_obj_info(next_obj, (Obj_Info_Type)next_marked_obj);
+      obj_set_prefetched_next_pointer(next_obj, next_marked_obj);
   } else {
-    set_obj_info(next_obj, 0);
+      obj_set_prefetched_next_pointer(next_obj, 0);
   }
   
   return cur_marked_obj;  
@@ -211,7 +228,7 @@
 
 inline Partial_Reveal_Object *block_get_next_marked_obj_after_prefetch(Block_Header *block, void **start_pos)
 {
-  Partial_Reveal_Object *cur_obj = *(Partial_Reveal_Object **)start_pos;
+  Partial_Reveal_Object *cur_obj = (Partial_Reveal_Object *)(*start_pos);
   Partial_Reveal_Object *block_end = (Partial_Reveal_Object *)block->free;
 
   if(cur_obj >= block_end)
@@ -222,7 +239,7 @@
   if(obj_is_marked_in_vt(cur_obj) || obj_is_fw_in_oi(cur_obj))
     cur_marked_obj = cur_obj;
   else
-    cur_marked_obj = (Partial_Reveal_Object *)get_obj_info_raw(cur_obj);
+    cur_marked_obj = obj_get_prefetched_next_pointer(cur_obj);
   
   if(!cur_marked_obj)
     return NULL;
@@ -233,12 +250,14 @@
   return cur_marked_obj;
 }
 
-inline Partial_Reveal_Object * obj_get_fw_in_table(Partial_Reveal_Object *p_obj)
+inline REF obj_get_fw_in_table(Partial_Reveal_Object *p_obj)
 {
   /* only for inter-sector compaction */
   unsigned int index    = OBJECT_INDEX_TO_OFFSET_TABLE(p_obj);
   Block_Header *curr_block = GC_BLOCK_HEADER(p_obj);
-  return (Partial_Reveal_Object *)(((POINTER_SIZE_INT)p_obj) - curr_block->table[index]);
+  Partial_Reveal_Object* new_addr = (Partial_Reveal_Object *)(((POINTER_SIZE_INT)p_obj) - curr_block->table[index]);
+  REF new_ref = compress_ref(new_addr);
+  return new_ref;
 }
 
 inline void block_clear_table(Block_Header* block)
@@ -248,5 +267,5 @@
   return;
 }
 
-
 #endif //#ifndef _BLOCK_H_
+

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp?view=diff&rev=519564&r1=519563&r2=519564
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp Sat Mar 17 23:02:56 2007
@@ -51,6 +51,8 @@
 
 extern Boolean JVMTI_HEAP_ITERATION ;
 
+extern Boolean IS_MOVE_COMPACT;
+
 static int get_int_property(const char *property_name)
 {
     assert(property_name);
@@ -234,7 +236,7 @@
   }
 
   if (is_property_set("gc.use_large_page", VM_PROPERTIES) == 1){
-    char* value = get_property("gc.use_large_page", VM_PROPERTIES);
+    char* value = get_property("gc.large_page", VM_PROPERTIES);
     large_page_hint = strdup(value);
     destroy_property_value(value);
   }
@@ -257,14 +259,14 @@
 
   //For_LOS_extend!
 #ifdef GC_FIXED_SIZE_TUNER
-  gc_space_tune_before_gc_simplified(gc, gc_cause);
+  gc_space_tune_before_gc_fixed_size(gc, gc_cause);
 #else
   gc_space_tune_prepare(gc, gc_cause);
   gc_space_tune_before_gc(gc, gc_cause);
 #endif
 
 #ifdef MARK_BIT_FLIPPING
-  if(gc->collect_kind == MINOR_COLLECTION)
+  if(gc_match_kind(gc, MINOR_COLLECTION))
     mark_bit_flip();
 #endif
   
@@ -314,4 +316,5 @@
   vm_resume_threads_after();
   return;
 }
+
 

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.h?view=diff&rev=519564&r1=519563&r2=519564
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.h Sat Mar 17 23:02:56 2007
@@ -41,17 +41,28 @@
 #define KB  (1<<10)
 #define MB  (1<<20)
 
-#define BYTES_PER_WORD 4
 #define BITS_PER_BYTE 8 
-#define BITS_PER_WORD 32
+#define BYTES_PER_WORD (sizeof(POINTER_SIZE_INT))
+#define BITS_PER_WORD (BITS_PER_BYTE * BYTES_PER_WORD)
+
 
 #define MASK_OF_BYTES_PER_WORD (BYTES_PER_WORD-1) /* 0x11 */
 
-#define BIT_SHIFT_TO_BYTES_PER_WORD 2 /* 2 */
 #define BIT_SHIFT_TO_BITS_PER_BYTE 3
-#define BIT_SHIFT_TO_BITS_PER_WORD 5
-#define BIT_SHIFT_TO_KILO 10 
 
+#ifdef POINTER64
+  #define BIT_SHIFT_TO_BYTES_PER_WORD 3 /* 3 */
+#else
+  #define BIT_SHIFT_TO_BYTES_PER_WORD 2 /* 2 */
+#endif
+
+#ifdef POINTER64
+  #define BIT_SHIFT_TO_BITS_PER_WORD 6
+#else
+  #define BIT_SHIFT_TO_BITS_PER_WORD 5
+#endif
+
+#define BIT_SHIFT_TO_KILO 10 
 #define BIT_MASK_TO_BITS_PER_WORD ((1<<BIT_SHIFT_TO_BITS_PER_WORD)-1)
 #define BITS_OF_POINTER_SIZE_INT (sizeof(POINTER_SIZE_INT) << BIT_SHIFT_TO_BITS_PER_BYTE)
 #define BYTES_OF_POINTER_SIZE_INT (sizeof(POINTER_SIZE_INT))
@@ -76,11 +87,18 @@
   
 };
 
+/* Possible combinations:
+ * MINOR_COLLECTION
+ * MAJOR_COLLECTION
+ * FALLBACK_COLLECTION
+ * MAJOR_COLLECTION | EXTEND_COLLECTION
+ * FALLBACK_COLLECTION | EXTEND_COLLECTION
+ */
 enum Collection_Kind {
-  MINOR_COLLECTION,
-  MAJOR_COLLECTION,
-  FALLBACK_COLLECTION,
-  EXTEND_COLLECTION
+  MINOR_COLLECTION = 0x1,
+  MAJOR_COLLECTION = 0x2,
+  FALLBACK_COLLECTION = 0x4,
+  EXTEND_COLLECTION = 0x8
 };
 
 extern Boolean IS_FALLBACK_COMPACTION;  /* only for mark/fw bits debugging purpose */
@@ -92,6 +110,70 @@
   GC_CAUSE_RUNTIME_FORCE_GC
 };
 
+/*Fixme: There is only compressed mode under em64t currently.*/
+#ifdef POINTER64
+  #define COMPRESS_REFERENCE
+#endif
+
+#define COMPRESSED_NULL ((REF)0)
+extern POINTER_SIZE_INT HEAP_NULL;
+
+#ifdef POINTER64
+  #ifdef COMPRESS_REFERENCE
+    #define REF uint32
+  #else
+    #define REF Partial_Reveal_Object*
+  #endif
+#else/*ifdef POINTER64*/
+  #define REF Partial_Reveal_Object*
+#endif
+
+/////////////////////////////////////////////
+//Compress reference related!///////////////////
+/////////////////////////////////////////////
+#ifdef COMPRESS_REFERENCE
+FORCE_INLINE REF compress_ref(Partial_Reveal_Object *p_obj)
+{
+  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.*/
+    return COMPRESSED_NULL;
+  }
+  else
+    return (REF) ( (POINTER_SIZE_INT) p_obj - HEAP_NULL);
+}
+
+FORCE_INLINE Partial_Reveal_Object *uncompress_ref(REF ref)
+{
+  if(!ref){
+    return NULL; 
+  }
+  return (Partial_Reveal_Object *)(HEAP_NULL + ref);
+}
+
+FORCE_INLINE Partial_Reveal_Object *read_slot(REF *p_slot)
+{  return uncompress_ref(*p_slot); }
+
+FORCE_INLINE void write_slot(REF *p_slot, Partial_Reveal_Object *p_obj)
+{  *p_slot = compress_ref(p_obj); }
+
+#else /* COMPRESS_REFERENCE */
+
+FORCE_INLINE REF compress_ref(Partial_Reveal_Object *p_obj)
+{  return (REF)p_obj; }
+
+FORCE_INLINE Partial_Reveal_Object *uncompress_ref(REF ref)
+{  return (Partial_Reveal_Object *)ref; }
+
+FORCE_INLINE Partial_Reveal_Object *read_slot(REF *p_slot)
+{  return *p_slot; }
+
+FORCE_INLINE void write_slot(REF *p_slot, Partial_Reveal_Object *p_obj)
+{  *p_slot = p_obj; }
+#endif
+
 inline POINTER_SIZE_INT round_up_to_size(POINTER_SIZE_INT size, int block_size) 
 {  return (size + block_size - 1) & ~(block_size - 1); }
 
@@ -106,9 +188,9 @@
   return gcvt->gc_ref_offset_array;    
 }
 
-inline Partial_Reveal_Object** object_ref_iterator_get(int* iterator, Partial_Reveal_Object* obj)
+inline REF* object_ref_iterator_get(int* iterator, Partial_Reveal_Object *obj)
 {
-  return (Partial_Reveal_Object**)((POINTER_SIZE_INT)obj + *iterator);
+  return (REF*)((POINTER_SIZE_INT)obj + *iterator);
 }
 
 inline int* object_ref_iterator_next(int* iterator)
@@ -132,20 +214,20 @@
 /****************************************/
 
 inline Boolean obj_is_marked_in_vt(Partial_Reveal_Object *obj) 
-{  return ((POINTER_SIZE_INT)obj_get_vt_raw(obj) & CONST_MARK_BIT); }
+{  return (Boolean)((POINTER_SIZE_INT)obj_get_vt_raw(obj) & CONST_MARK_BIT); }
 
 inline Boolean obj_mark_in_vt(Partial_Reveal_Object *obj) 
 {  
-  Partial_Reveal_VTable* vt = obj_get_vt_raw(obj);
+  VT vt = obj_get_vt_raw(obj);
   if((POINTER_SIZE_INT)vt & CONST_MARK_BIT) return FALSE;
-  obj_set_vt(obj, (POINTER_SIZE_INT)vt | CONST_MARK_BIT);
+  obj_set_vt(obj,  (VT)( (POINTER_SIZE_INT)vt | CONST_MARK_BIT ) );
   return TRUE;
 }
 
 inline void obj_unmark_in_vt(Partial_Reveal_Object *obj) 
 { 
-  Partial_Reveal_VTable* vt = obj_get_vt_raw(obj);
-  obj_set_vt(obj, (POINTER_SIZE_INT)vt & ~CONST_MARK_BIT);
+  VT vt = obj_get_vt_raw(obj);
+  obj_set_vt(obj, (VT)((POINTER_SIZE_INT)vt & ~CONST_MARK_BIT));
 }
 
 inline Boolean obj_is_marked_or_fw_in_oi(Partial_Reveal_Object *obj)
@@ -164,7 +246,7 @@
 inline Partial_Reveal_Object *obj_get_fw_in_oi(Partial_Reveal_Object *obj) 
 {
   assert(get_obj_info_raw(obj) & CONST_FORWARD_BIT);
-  return (Partial_Reveal_Object*) (get_obj_info_raw(obj) & ~CONST_FORWARD_BIT);
+  return (Partial_Reveal_Object*)(uncompress_ref((REF)(get_obj_info_raw(obj) & ~CONST_FORWARD_BIT)));
 }
 
 inline Boolean obj_is_fw_in_oi(Partial_Reveal_Object *obj) 
@@ -173,6 +255,7 @@
 inline void obj_set_fw_in_oi(Partial_Reveal_Object *obj,void *dest)
 {  
   assert(!(get_obj_info_raw(obj) & CONST_FORWARD_BIT));
+  REF dest = compress_ref((Partial_Reveal_Object *) dest);
   set_obj_info(obj,(Obj_Info_Type)dest | CONST_FORWARD_BIT); 
 }
 
@@ -209,7 +292,7 @@
 inline Partial_Reveal_Object *obj_get_fw_in_oi(Partial_Reveal_Object *obj) 
 {
   assert(get_obj_info_raw(obj) & FLIP_FORWARD_BIT);
-  return (Partial_Reveal_Object*) get_obj_info(obj);
+  return (Partial_Reveal_Object*) ( uncompress_ref( (REF)get_obj_info(obj) ) );
 }
 
 inline Boolean obj_is_fw_in_oi(Partial_Reveal_Object *obj) 
@@ -225,7 +308,8 @@
   /* It's important to clear the FLIP_FORWARD_BIT before collection ends, since it is the same as
      next minor cycle's FLIP_MARK_BIT. And if next cycle is major, it is also confusing
      as FLIP_FORWARD_BIT. (The bits are flipped only in minor collection). */
-  set_obj_info(obj,(Obj_Info_Type)dest | FLIP_FORWARD_BIT); 
+  Obj_Info_Type dst = (Obj_Info_Type)compress_ref((Partial_Reveal_Object *) dest);     
+  set_obj_info(obj, dst | FLIP_FORWARD_BIT); 
 }
 
 inline Boolean obj_mark_in_oi(Partial_Reveal_Object* p_obj)
@@ -296,6 +380,7 @@
   
   /* FIXME:: this is wrong! root_set belongs to mutator */
   Vector_Block* root_set;
+  Vector_Block* uncompressed_root_set;
 
   //For_LOS_extend
   Space_Tuner* tuner;
@@ -316,6 +401,12 @@
   return (addr >= gc_heap_base(gc) && addr < gc_heap_ceiling(gc));
 }
 
+inline Boolean gc_match_kind(GC *gc, unsigned int kind)
+{
+  assert(gc->collect_kind && kind);
+  return gc->collect_kind & kind;
+}
+
 void gc_parse_options(GC* gc);
 void gc_reclaim_heap(GC* gc, unsigned int gc_cause);
 
@@ -330,7 +421,7 @@
   //#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 */
 

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.cpp?view=diff&rev=519564&r1=519563&r2=519564
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.cpp Sat Mar 17 23:02:56 2007
@@ -70,7 +70,7 @@
   unsigned idx;
   for(idx = 0; idx < num_fields; idx++) {
     Field_Handle fh = class_get_instance_field_recursive(ch, idx);
-	if(field_is_enumerable_reference(fh)){
+    if(field_is_reference(fh)) {
       num_ref_fields++;
     }
   }
@@ -102,7 +102,7 @@
   int *result = new_ref_array;
   for(unsigned int idx = 0; idx < num_fields; idx++) {
     Field_Handle fh = class_get_instance_field_recursive(ch, idx);
-	if(field_is_enumerable_reference(fh)) {
+    if(field_is_reference(fh)) {
       int offset = field_get_offset(fh);
 #ifndef BUILD_IN_REFERENT
       if(is_reference && offset == gc_referent_offset) continue;
@@ -195,5 +195,6 @@
 
   return;
 }  /* gc_class_prepared */
+
 
 

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.h?view=diff&rev=519564&r1=519563&r2=519564
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.h Sat Mar 17 23:02:56 2007
@@ -41,6 +41,7 @@
    
 */
 #define CONST_MARK_BIT 0x1
+#define CLEAR_VT_MARK 0x03
 
 #define DUAL_MARKBITS  0x3
 #define DUAL_MARKBITS_MASK  (~DUAL_MARKBITS)
@@ -63,6 +64,19 @@
 
 #endif /* else MARK_BIT_FLIPPING */
 
+/*emt64 related!*/
+#define COMPRESS_VTABLE
+
+#ifdef POINTER64
+  #ifdef COMPRESS_VTABLE
+    #define VT uint32
+  #else
+    #define VT Partial_Reveal_VTable*
+  #endif
+#else/*ifdef POINTER64*/
+  #define VT Partial_Reveal_VTable*
+#endif
+
 typedef void *Thread_Handle; 
 
 #define GC_CLASS_FLAG_FINALIZER 1
@@ -75,7 +89,7 @@
 #define GCVT_ALIGNMENT 8
 #define GCVT_ALIGN_MASK (GCVT_ALIGNMENT-1)
 
-typedef POINTER_SIZE_INT Obj_Info_Type;
+typedef uint32 Obj_Info_Type;
 
 typedef struct GC_VTable_Info {
 
@@ -103,20 +117,48 @@
 } GC_VTable_Info;
 
 typedef struct Partial_Reveal_VTable {
+  //--Fixme: emt64
   GC_VTable_Info *gcvt;
 } Partial_Reveal_VTable;
 
 typedef struct Partial_Reveal_Object {
-  Partial_Reveal_VTable *vt_raw;
+  VT vt_raw;
   Obj_Info_Type obj_info;
 } Partial_Reveal_Object;
 
 typedef struct Partial_Reveal_Array {
-  Partial_Reveal_VTable *vt_raw;
+  VT vt_raw;
   Obj_Info_Type obj_info;
   unsigned int array_len;
 } Partial_Reveal_Array;
 
+//////////////////////////////////////////
+//Compress vtable related!///////////////////
+//////////////////////////////////////////
+extern POINTER_SIZE_INT vtable_base;
+
+#ifdef COMPRESS_VTABLE
+FORCE_INLINE VT compress_vt(Partial_Reveal_VTable* vt)
+{
+  assert(vt);
+  return (VT)((POINTER_SIZE_INT)vt - vtable_base);
+}
+
+FORCE_INLINE Partial_Reveal_VTable* uncompress_vt(VT vt)
+{
+  assert(vt);
+  return (Partial_Reveal_VTable*)((POINTER_SIZE_INT)vt + vtable_base);
+}
+#else/*ifdef COMPRESS_VTABLE*/
+
+FORCE_INLINE VT compress_vt(Partial_Reveal_VTable* vt)
+{  return (VT)vt; }
+
+FORCE_INLINE Partial_Reveal_VTable* uncompress_vt(VT vt)
+{  return (Partial_Reveal_VTable*) vt;  }
+#endif
+
+
 inline Obj_Info_Type get_obj_info_raw(Partial_Reveal_Object *obj) 
 {  assert(obj); return obj->obj_info; }
 
@@ -138,50 +180,56 @@
 inline Obj_Info_Type *get_obj_info_addr(Partial_Reveal_Object *obj) 
 {  assert(obj); return &obj->obj_info; }
 
-inline Partial_Reveal_VTable *obj_get_vt_raw(Partial_Reveal_Object *obj) 
+inline VT obj_get_vt_raw(Partial_Reveal_Object *obj) 
 {  assert(obj && obj->vt_raw); return obj->vt_raw; }
 
-inline Partial_Reveal_VTable **obj_get_vt_addr(Partial_Reveal_Object *obj) 
+inline VT *obj_get_vt_addr(Partial_Reveal_Object *obj) 
 {  assert(obj && obj->vt_raw); return &obj->vt_raw; }
 
-inline Partial_Reveal_VTable *obj_get_vt(Partial_Reveal_Object *obj) 
-{  assert(obj && obj->vt_raw); return (Partial_Reveal_VTable *)((POINTER_SIZE_INT)obj->vt_raw & ~CONST_MARK_BIT); }
+/*Fixme: emt64*/
+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); }
 
-inline void obj_set_vt(Partial_Reveal_Object *obj, Allocation_Handle ah) 
-{  assert(obj && ah); obj->vt_raw = (Partial_Reveal_VTable *)ah; }
+inline void obj_set_vt(Partial_Reveal_Object *obj, VT ah) 
+{  assert(obj && ah); obj->vt_raw = ah; }
 
-inline GC_VTable_Info *vtable_get_gcvt_raw(Partial_Reveal_VTable *vt) 
+/*Fixme: emt64, we should check whether gcvt is compressed first!*/
+inline GC_VTable_Info *vtable_get_gcvt_raw(Partial_Reveal_VTable* vt) 
 {  assert(vt && vt->gcvt); return vt->gcvt; }
 
-inline GC_VTable_Info *vtable_get_gcvt(Partial_Reveal_VTable *vt) 
-{  assert(vt && vt->gcvt); return (GC_VTable_Info*)((POINTER_SIZE_INT)vt->gcvt & GC_CLASS_FLAGS_MASK); }
+inline GC_VTable_Info *vtable_get_gcvt(Partial_Reveal_VTable* vt) 
+{
+  assert(vt && vt->gcvt);
+  return (GC_VTable_Info*)((POINTER_SIZE_INT)vt->gcvt & GC_CLASS_FLAGS_MASK);
+}
 
 inline void vtable_set_gcvt(Partial_Reveal_VTable *vt, GC_VTable_Info *new_gcvt) 
+/*Fixme: emt64*/
 {  assert(vt && new_gcvt); vt->gcvt = new_gcvt; }
 
 inline GC_VTable_Info *obj_get_gcvt_raw(Partial_Reveal_Object *obj) 
 {
-  Partial_Reveal_VTable *vt = obj_get_vt(obj);
-  return vtable_get_gcvt_raw(vt);
+  Partial_Reveal_VTable *vtable = uncompress_vt(obj_get_vt(obj));
+  return vtable_get_gcvt_raw(vtable);
 }
 
 inline GC_VTable_Info *obj_get_gcvt(Partial_Reveal_Object *obj) 
 {
-  Partial_Reveal_VTable *vt = obj_get_vt(obj);
-  return vtable_get_gcvt(vt);
+  Partial_Reveal_VTable* vtable = uncompress_vt(obj_get_vt(obj) );
+  return vtable_get_gcvt(vtable);
 }
 
 inline Boolean object_has_ref_field(Partial_Reveal_Object *obj) 
 {
   GC_VTable_Info *gcvt = obj_get_gcvt_raw(obj);
-  return (POINTER_SIZE_INT)gcvt & GC_CLASS_FLAG_REFS;   
+  return (Boolean)((POINTER_SIZE_INT)gcvt & GC_CLASS_FLAG_REFS);
 }
 
 inline Boolean object_has_ref_field_before_scan(Partial_Reveal_Object *obj) 
 {
-  Partial_Reveal_VTable *vt = obj_get_vt_raw(obj);  
+  Partial_Reveal_VTable *vt = uncompress_vt(obj_get_vt_raw(obj));
   GC_VTable_Info *gcvt = vtable_get_gcvt_raw(vt);
-  return (POINTER_SIZE_INT)gcvt & GC_CLASS_FLAG_REFS;   
+  return (Boolean)((POINTER_SIZE_INT)gcvt & GC_CLASS_FLAG_REFS);
 }
 
 inline unsigned int object_ref_field_num(Partial_Reveal_Object *obj) 
@@ -193,7 +241,7 @@
 inline Boolean object_is_array(Partial_Reveal_Object *obj) 
 {
   GC_VTable_Info *gcvt = obj_get_gcvt_raw(obj);
-  return ((POINTER_SIZE_INT)gcvt & GC_CLASS_FLAG_ARRAY);
+  return (Boolean)((POINTER_SIZE_INT)gcvt & GC_CLASS_FLAG_ARRAY);
 } 
 
 inline Boolean obj_is_primitive_array(Partial_Reveal_Object *obj) 
@@ -244,8 +292,10 @@
 inline Boolean type_has_finalizer(Partial_Reveal_VTable *vt)
 {
   GC_VTable_Info *gcvt = vtable_get_gcvt_raw(vt);
-  return (POINTER_SIZE_INT)gcvt & GC_CLASS_FLAG_FINALIZER;
+  return (Boolean)(POINTER_SIZE_INT)gcvt & GC_CLASS_FLAG_FINALIZER;
 }
 
 #endif //#ifndef _GC_TYPES_H_
+
+
 

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_vm.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_vm.cpp?view=diff&rev=519564&r1=519563&r2=519564
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_vm.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_vm.cpp Sat Mar 17 23:02:56 2007
@@ -20,6 +20,7 @@
 
 #include <cxxlog.h>
 #include "vm_threads.h"
+#include "compressed_ref.h"
 
 #include "../gen/gen.h"
 #include "interior_pointer.h"
@@ -77,15 +78,27 @@
   p_global_gc = NULL;
 }
 
+#ifdef COMPRESS_REFERENCE
+Boolean gc_supports_compressed_references()
+{
+  vtable_base = vm_get_vtable_base();
+  return TRUE;
+}
+#endif
+
 /* this interface need reconsidering. is_pinned is unused. */
 void gc_add_root_set_entry(Managed_Object_Handle *ref, Boolean is_pinned) 
-{   
+{
   Partial_Reveal_Object** p_ref = (Partial_Reveal_Object**)ref;
   Partial_Reveal_Object* p_obj = *p_ref;
   /* we don't enumerate NULL reference and nos_boundary
      FIXME:: nos_boundary is a static field in GCHelper.java for fast write barrier, not a real object reference 
      this should be fixed that magic Address field should not be enumerated. */
+#ifdef COMPRESS_REFERENCE
+  if (p_obj == (Partial_Reveal_Object*)HEAP_NULL || p_obj == NULL || p_obj == nos_boundary ) return;
+#else
   if (p_obj == NULL || p_obj == nos_boundary ) return;
+#endif  
   assert( !obj_is_marked_in_vt(p_obj));
   /* for Minor_collection, it's possible for p_obj be forwarded in non-gen mark-forward GC. 
      The forward bit is actually last cycle's mark bit.
@@ -101,6 +114,16 @@
   add_root_set_entry_interior_pointer(slot, offset, is_pinned); 
 }
 
+void gc_add_compressed_root_set_entry(REF* ref, Boolean is_pinned)
+{
+  REF *p_ref = (REF *)ref;
+  if(*p_ref == COMPRESSED_NULL) return;
+  Partial_Reveal_Object* p_obj = read_slot(p_ref);
+  assert(!obj_is_marked_in_vt(p_obj));
+  assert( address_belongs_to_gc_heap(p_obj, p_global_gc));
+  gc_compressed_rootset_add_entry(p_global_gc, p_ref);
+}
+
 /* VM to force GC */
 void gc_force_gc() 
 {
@@ -179,6 +202,7 @@
 
     gc_gen_iterate_heap((GC_Gen *)p_global_gc);
 }
+
 
 
 

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.cpp?view=diff&rev=519564&r1=519563&r2=519564
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.cpp Sat Mar 17 23:02:56 2007
@@ -22,6 +22,8 @@
 #include "interior_pointer.h"
 #include "../finalizer_weakref/finalizer_weakref.h"
 #include "gc_block.h"
+#include "compressed_ref.h"
+#include "../utils/sync_stack.h"
 
 #define GC_METADATA_SIZE_BYTES (1*MB)
 #define GC_METADATA_EXTEND_SIZE_BYTES (1*MB)
@@ -64,11 +66,12 @@
   gc_metadata.free_set_pool = sync_pool_create();
   /* initialize free rootset pool so that mutators can use them */  
   for(; i<num_blocks; i++){
-    POINTER_SIZE_INT block = (POINTER_SIZE_INT)metadata + i*METADATA_BLOCK_SIZE_BYTES;    
+    POINTER_SIZE_INT block = (POINTER_SIZE_INT)metadata + i*METADATA_BLOCK_SIZE_BYTES;
     pool_put_entry(gc_metadata.free_set_pool, (void*)block); 
   }
 
   gc_metadata.gc_rootset_pool = sync_pool_create();
+  gc_metadata.gc_uncompressed_rootset_pool = sync_pool_create();
   gc_metadata.mutator_remset_pool = sync_pool_create();
   gc_metadata.collector_remset_pool = sync_pool_create();
   gc_metadata.collector_repset_pool = sync_pool_create();
@@ -84,8 +87,9 @@
   sync_pool_destruct(metadata->mark_task_pool);
   
   sync_pool_destruct(metadata->free_set_pool);
-  sync_pool_destruct(metadata->gc_rootset_pool); 
-  sync_pool_destruct(metadata->mutator_remset_pool);  
+  sync_pool_destruct(metadata->gc_rootset_pool);
+  sync_pool_destruct(metadata->gc_uncompressed_rootset_pool);
+  sync_pool_destruct(metadata->mutator_remset_pool);
   sync_pool_destruct(metadata->collector_remset_pool);
   sync_pool_destruct(metadata->collector_repset_pool);
 
@@ -106,12 +110,13 @@
     unlock(metadata->alloc_lock);
     return block;
   }
-  
+ 
   unsigned int num_alloced = metadata->num_alloc_segs;
   if(num_alloced == GC_METADATA_SEGMENT_NUM){
     printf("Run out GC metadata, please give it more segments!\n");
     exit(0);
   }
+
   unsigned int seg_size =  GC_METADATA_EXTEND_SIZE_BYTES + METADATA_BLOCK_SIZE_BYTES;
   void *new_segment = STD_MALLOC(seg_size);
   memset(new_segment, 0, seg_size);
@@ -145,6 +150,7 @@
   
   block = pool_get_entry(pool);
   unlock(metadata->alloc_lock);
+
   return block;
 }
 
@@ -161,10 +167,10 @@
   while(root_set){
     POINTER_SIZE_INT* iter = vector_block_iterator_init(root_set);
     while(!vector_block_iterator_end(root_set,iter)){
-      Partial_Reveal_Object** p_ref = (Partial_Reveal_Object** )*iter;
+      REF* p_ref = (REF* )*iter;
       iter = vector_block_iterator_advance(root_set,iter);
 
-      Partial_Reveal_Object* p_obj = *p_ref;
+      Partial_Reveal_Object* p_obj = read_slot(p_ref);
       if(IS_MOVE_COMPACT){
         if(obj_is_moved(p_obj))
           *p_ref = obj_get_fw_in_table(p_obj);
@@ -177,7 +183,7 @@
            * since those which can be scanned in MOS & NOS must have been set fw bit in oi.
            */
           assert(address_belongs_to_gc_heap(obj_get_fw_in_oi(p_obj), gc));
-          *p_ref = obj_get_fw_in_oi(p_obj);
+          write_slot(p_ref , obj_get_fw_in_oi(p_obj));
         }
       }
     }
@@ -192,20 +198,25 @@
   GC* gc = collector->gc;  
   GC_Metadata* metadata = gc->metadata;
 
-  /* generational MINOR_COLLECTION doesn't need rootset update, but need reset */
-  if( gc->collect_kind != MINOR_COLLECTION ) /* MINOR but not forwarding */
+  /* MINOR_COLLECTION doesn't need rootset update, but need reset */
+  if( !gc_match_kind(gc, MINOR_COLLECTION)){
     gc_update_repointed_sets(gc, metadata->gc_rootset_pool);
-  else
-    gc_set_pool_clear(metadata->gc_rootset_pool);
-  
 #ifndef BUILD_IN_REFERENT
-  gc_update_finref_repointed_refs(gc);
+    gc_update_finref_repointed_refs(gc);
+#endif
+  } else {
+    gc_set_pool_clear(metadata->gc_rootset_pool);
+  }
+
+#ifdef COMPRESS_REFERENCE
+  gc_fix_uncompressed_rootset(gc);
 #endif
 
+
   update_rootset_interior_pointer();
   /* it was pointing to the last root_set entry in gc_rootset_pool (before rem_sets). */
   gc->root_set = NULL;
-      
+  
   return;
 }
 
@@ -218,7 +229,9 @@
   Pool* free_set_pool = metadata->free_set_pool;
 
   Vector_Block* root_set = NULL;
-  
+#ifdef COMPRESS_REFERENCE  
+  gc_set_uncompressed_rootset(gc);
+#endif
   /* put back last rootset block */
   pool_put_entry(gc_rootset_pool, gc->root_set);
   
@@ -250,7 +263,7 @@
     collector->rem_set = NULL;
   }
 
-  if( gc->collect_kind != MINOR_COLLECTION ){
+  if( !gc_match_kind(gc, MINOR_COLLECTION )){
     /* all the remsets are useless now */
     /* clean and put back mutator remsets */  
     root_set = pool_get_entry( mutator_remset_pool );
@@ -293,11 +306,18 @@
 {
   assert(pool_is_empty(gc_metadata.gc_rootset_pool));
   assert(gc->root_set == NULL);
-  gc->root_set = free_set_pool_get_entry(&gc_metadata); 
-  
-  assert(vector_block_is_empty(gc->root_set)); 
+  gc->root_set = free_set_pool_get_entry(&gc_metadata);
+  assert(vector_block_is_empty(gc->root_set));
+
+#ifdef COMPRESS_REFERENCE
+  assert(pool_is_empty(gc_metadata.gc_uncompressed_rootset_pool));
+  assert(gc->uncompressed_root_set == NULL);
+  gc->uncompressed_root_set = free_set_pool_get_entry(&gc_metadata);
+  assert(vector_block_is_empty(gc->uncompressed_root_set));
+#endif
+
   return;
-}  
+}
 
 void gc_clear_remset(GC* gc)
 {
@@ -340,4 +360,5 @@
   
   return;  
 }
+
 

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.h?view=diff&rev=519564&r1=519563&r2=519564
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.h Sat Mar 17 23:02:56 2007
@@ -39,6 +39,7 @@
   /* FIXME:: the mutator remset pool can be merged with the rootset pool*/
   Pool* free_set_pool; /* list of free buffers for rootsets remsets */
   Pool* gc_rootset_pool; /* list of root sets for enumeration */
+  Pool* gc_uncompressed_rootset_pool; /* list of uncompressed root sets for enumeration */
   Pool* mutator_remset_pool; /* list of remsets generated by app during execution */
   Pool* collector_remset_pool; /* list of remsets generated by gc during collection */
   Pool* collector_repset_pool; /* list of repointed ref slot sets */
@@ -71,7 +72,7 @@
 {
   Vector_Block* set = pool_get_entry(set_pool);
   while(set){
-    vector_block_clear(set);  
+    vector_block_clear(set);
     pool_put_entry(gc_metadata.free_set_pool, set);
     set = pool_get_entry(set_pool);
   } 
@@ -158,6 +159,33 @@
   assert(collector->trace_stack);
 }
 
+
+#ifdef COMPRESS_REFERENCE
+
+inline void gc_rootset_add_entry(GC* gc, Partial_Reveal_Object** p_ref)
+{
+  assert( p_ref < gc_heap_base(gc) || p_ref >= gc_heap_ceiling(gc));
+  
+  GC_Metadata *metadata = gc->metadata;
+  Vector_Block *uncompressed_root_set = gc->uncompressed_root_set;
+  assert(uncompressed_root_set);
+  
+  Partial_Reveal_Object *p_obj = *p_ref;
+  REF ref = compress_ref(p_obj);
+  
+  /* construct an Uncompressed_Root */
+  vector_block_add_entry(uncompressed_root_set, (POINTER_SIZE_INT)p_ref);
+  assert(!vector_block_is_full(uncompressed_root_set));
+  vector_block_add_entry(uncompressed_root_set, (POINTER_SIZE_INT)ref);
+  
+  if(!vector_block_is_full(uncompressed_root_set)) return;
+  
+  pool_put_entry(metadata->gc_uncompressed_rootset_pool, uncompressed_root_set);
+  gc->uncompressed_root_set = free_set_pool_get_entry(metadata);
+  assert(gc->uncompressed_root_set);
+}
+
+#else /* COMPRESS_REFERENCE */
 inline void gc_rootset_add_entry(GC* gc, Partial_Reveal_Object** p_ref)
 {
   assert( p_ref < gc_heap_base_address() || p_ref >= gc_heap_ceiling_address()); 
@@ -171,5 +199,6 @@
   gc->root_set = free_set_pool_get_entry(&gc_metadata);  
   assert(gc->root_set);
 }
+#endif
 
 #endif /* #ifndef _GC_METADATA_H_ */

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/interior_pointer.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/interior_pointer.cpp?view=diff&rev=519564&r1=519563&r2=519564
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/interior_pointer.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/interior_pointer.cpp Sat Mar 17 23:02:56 2007
@@ -58,8 +58,8 @@
   unsigned int i;
   for( i = 0; i<interior_pointer_num_count; i++)
   {
-  slot_offset_entry* entry_traverser = (slot_offset_entry*)&interior_pointer_set[i];
-  gc_add_root_set_entry((Managed_Object_Handle*)(&(entry_traverser->base)), FALSE);
+    slot_offset_entry* entry_traverser = (slot_offset_entry*)&interior_pointer_set[i];
+    gc_add_root_set_entry((Managed_Object_Handle*)(&(entry_traverser->base)), FALSE);
   }
 }
 
@@ -68,14 +68,14 @@
   unsigned int i;
   for( i = 0; i<interior_pointer_num_count; i++)
   {
-  slot_offset_entry* entry_traverser = (slot_offset_entry*)&interior_pointer_set[i];
-  void** root_slot = entry_traverser->slot;
-  Partial_Reveal_Object* root_base = (Partial_Reveal_Object*)entry_traverser->base;
-  unsigned int root_offset = entry_traverser->offset;
-  void *new_slot_contents = (void *)((Byte*)root_base + root_offset);
-  *root_slot = new_slot_contents;
+    slot_offset_entry* entry_traverser = (slot_offset_entry*)&interior_pointer_set[i];
+    void** root_slot = entry_traverser->slot;
+    Partial_Reveal_Object* root_base = (Partial_Reveal_Object*)entry_traverser->base;
+    unsigned int root_offset = entry_traverser->offset;
+    void *new_slot_contents = (void *)((Byte*)root_base + root_offset);	
+    *root_slot = new_slot_contents;
   }
-       //can not reset the table here, for the rootset may be updated multi times
+  //can not reset the table here, for the rootset may be updated multi times
 }
 
 void gc_reset_interior_pointer_table()
@@ -83,4 +83,5 @@
   interior_pointer_num_count = 0;
   //this function is for the case of out of memory which need to call update_rootset_interior_pointer multi-times
 }
+
 

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/large_pages.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/large_pages.cpp?view=diff&rev=519564&r1=519563&r2=519564
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/large_pages.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/large_pages.cpp Sat Mar 17 23:02:56 2007
@@ -134,6 +134,7 @@
     } else {
       printf("GC large_page: Not enough reserved large pages.\n");
     }
+    printf("GC large_page: Large pages can be only allocated.\n");
   }
 }
 
@@ -148,9 +149,9 @@
 
   int fd = open(buf, O_CREAT | O_RDWR, 0700);
   if (fd == -1){
-    printf("GC large_page: Can't open Mount hugetlbfs with: mount none /mnt/huge -t hugetlbfs.\n");
+    printf("GC large_page: Can't open Mount hugetlbfs with: mount none /mnt/huge -t hugetlbfsi.\n");
     printf("GC large_page: Check you have appropriate permissions to /mnt/huge.\n");
-    printf("GC large_page: Use command line switch -Dgc.use_large_page=/mnt/huge.\n");
+    printf("GC large_page: Use command line switch -Dgc.lp=/mnt/huge.\n");
     free(buf);
     return NULL;
   }
@@ -171,7 +172,7 @@
 void* alloc_large_pages(size_t size, const char* hint){
   parse_proc_meminfo(size);
   void* alloc_addr = mmap_large_pages(size, hint);
-  if(alloc_addr == NULL || ((POINTER_SIZE_INT)alloc_addr%proc_huge_page_size!=0)){
+  if(alloc_addr == NULL){
     printf("GC large_page: Large pages allocation failed.\n");
     return NULL;
   }

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan_pool.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan_pool.cpp?view=diff&rev=519564&r1=519563&r2=519564
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan_pool.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan_pool.cpp Sat Mar 17 23:02:56 2007
@@ -23,30 +23,30 @@
 #include "../gen/gen.h"
 #include "../finalizer_weakref/finalizer_weakref.h"
 
-static FORCE_INLINE void scan_slot(Collector* collector, Partial_Reveal_Object** p_ref)
+static FORCE_INLINE void scan_slot(Collector* collector, REF *p_ref)
 {
-  Partial_Reveal_Object* p_obj = *p_ref;
-  if(p_obj==NULL) return;
+  REF ref = *p_ref;
+  if(ref == COMPRESSED_NULL) return;
 
+  Partial_Reveal_Object *p_obj = uncompress_ref(ref);
   if(obj_mark_in_vt(p_obj))
     collector_tracestack_push(collector, p_obj);
   
   return;
 }
 
-
 static FORCE_INLINE void scan_object(Collector* collector, Partial_Reveal_Object *p_obj)
 {
   if( !object_has_ref_field(p_obj) ) return;
   
-  Partial_Reveal_Object **p_ref;
+  REF *p_ref;
 
   if (object_is_array(p_obj)) {   /* scan array object */
   
     Partial_Reveal_Array* array = (Partial_Reveal_Array*)p_obj;
     unsigned int array_length = array->array_len;
   
-    p_ref = (Partial_Reveal_Object**)((POINTER_SIZE_INT)array + (int)array_first_element_offset(array));
+    p_ref = (REF *)((POINTER_SIZE_INT)array + (int)array_first_element_offset(array));
 
     for (unsigned int i = 0; i < array_length; i++) {
       scan_slot(collector, p_ref+i);
@@ -122,10 +122,10 @@
   while(root_set){
     POINTER_SIZE_INT* iter = vector_block_iterator_init(root_set);
     while(!vector_block_iterator_end(root_set,iter)){
-      Partial_Reveal_Object** p_ref = (Partial_Reveal_Object** )*iter;
+      REF *p_ref = (REF *)*iter;
       iter = vector_block_iterator_advance(root_set,iter);
 
-      Partial_Reveal_Object* p_obj = *p_ref;
+      Partial_Reveal_Object *p_obj = read_slot(p_ref);
       /* root ref can't be NULL, (remset may have NULL ref entry, but this function is only for MAJOR_COLLECTION */
       assert(p_obj!=NULL);
       /* we have to mark the object before put it into marktask, because

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.cpp?view=diff&rev=519564&r1=519563&r2=519564
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.cpp Sat Mar 17 23:02:56 2007
@@ -34,8 +34,8 @@
 /*Now just prepare the alloc_size field of mspace, used to compute new los size.*/
 void gc_space_tune_prepare(GC* gc, unsigned int cause)
 {
-  if(gc->collect_kind == MINOR_COLLECTION)
-    return;
+  if(gc_match_kind(gc, MINOR_COLLECTION))
+  	return;
   
   Blocked_Space* mspace = (Blocked_Space*)gc_get_mos((GC_Gen*)gc);
   Blocked_Space* fspace = (Blocked_Space*)gc_get_nos((GC_Gen*)gc);  
@@ -76,7 +76,7 @@
 
 void gc_space_tune_before_gc(GC* gc, unsigned int cause)
 {
-  if(gc->collect_kind == MINOR_COLLECTION) return;
+  if(gc_match_kind(gc, MINOR_COLLECTION)) return;
 
   Space_Tuner* tuner = gc->tuner;
 
@@ -123,21 +123,18 @@
         
      tuner->tuning_size = tuner->least_tuning_size;
 
-     if(tuner->tuning_size == 0) tuner->kind = TRANS_NOTHING;
-     
-     if(tuner->tuning_size < none_los_size) return;
-     
-     printf("Out of Memory!\n");
-     assert(0);
-     exit(0);    
+     if((tuner->tuning_size + gc->num_active_collectors * GC_BLOCK_SIZE_BYTES) >= none_los_size){
+       tuner->tuning_size = 0;
+     }
 
+     if(tuner->tuning_size == 0) tuner->kind = TRANS_NOTHING;
   }
 }
 
-void gc_space_tune_before_gc_simplified(GC* gc, unsigned int cause)
+void gc_space_tune_before_gc_fixed_size(GC* gc, unsigned int cause)
 {
-  if((gc->collect_kind == MINOR_COLLECTION) || (cause != GC_CAUSE_LOS_IS_FULL) )
-    return;
+  if(gc_match_kind(gc, MINOR_COLLECTION) || (cause != GC_CAUSE_LOS_IS_FULL) )
+  	 return;
 
   Space_Tuner* tuner = gc->tuner;
   tuner->kind = TRANS_FROM_MOS_TO_LOS;
@@ -190,16 +187,13 @@
     if(tuner->tuning_size > none_los_size){
       tuner->tuning_size = tuner->least_tuning_size;
     }
-    if(tuner->tuning_size > none_los_size){
-      printf("Out of Memory!\n");
-      assert(0);
-      exit(0);    
+    if((tuner->tuning_size + gc->num_active_collectors * GC_BLOCK_SIZE_BYTES) >= none_los_size){
+      tuner->tuning_size = 0;
     }
-
   }
   
   /*Fixme: Should MOS heap_start must be 64k aligned?*/
-  tuner->tuning_size = round_down_to_size(tuner->tuning_size, SPACE_ALLOC_UNIT);
+  tuner->tuning_size = round_up_to_size(tuner->tuning_size, SPACE_ALLOC_UNIT);
   if(tuner->tuning_size == 0) tuner->kind = TRANS_NOTHING;
 
   return;  
@@ -207,7 +201,7 @@
 
 void  gc_space_tuner_reset(GC* gc)
 {
-  if((gc->collect_kind != MINOR_COLLECTION) && (gc->tuner->kind != TRANS_NOTHING)){
+  if( !gc_match_kind(gc, MINOR_COLLECTION) && (gc->tuner->kind != TRANS_NOTHING)){
     Space_Tuner* tuner = gc->tuner;
     memset(tuner, 0, sizeof(Space_Tuner));
   }

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.h?view=diff&rev=519564&r1=519563&r2=519564
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.h Sat Mar 17 23:02:56 2007
@@ -69,7 +69,7 @@
 
 void gc_space_tune_prepare(GC* gc, unsigned int cause);
 void gc_space_tune_before_gc(GC* gc, unsigned int cause);
-void gc_space_tune_before_gc_simplified(GC* gc, unsigned int cause);
+void gc_space_tune_before_gc_fixed_size(GC* gc, unsigned int cause);
 void gc_space_tuner_reset(GC* gc);
 void gc_space_tuner_initialize(GC* gc);
 

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.cpp?view=diff&rev=519564&r1=519563&r2=519564
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.cpp Sat Mar 17 23:02:56 2007
@@ -52,11 +52,9 @@
 // clear the two least significant bits of p_obj first
 static inline Boolean gc_obj_is_dead(GC *gc, Partial_Reveal_Object *p_obj)
 {
-  unsigned int collect_kind = gc->collect_kind;
-  
   assert(p_obj);
-  if(collect_kind == MINOR_COLLECTION){
-    if( gc_is_gen_mode())
+  if(gc_match_kind(gc, MINOR_COLLECTION)){
+    if(gc_is_gen_mode())
       return obj_is_dead_in_gen_minor_gc(p_obj);
     else
       return obj_is_dead_in_nongen_minor_gc(p_obj);
@@ -74,7 +72,7 @@
 {
   assert(!gc_obj_is_dead(gc, p_obj));
   
-  if(gc_is_gen_mode() && gc->collect_kind == MINOR_COLLECTION)
+  if(gc_is_gen_mode() && gc_match_kind(gc, MINOR_COLLECTION))
     return fspace_obj_to_be_forwarded(p_obj);
   
   Space *space = space_of_addr(gc, p_obj);
@@ -88,26 +86,27 @@
   while(Vector_Block *block = pool_iterator_next(pool)){
     POINTER_SIZE_INT *iter = vector_block_iterator_init(block);
     for(; !vector_block_iterator_end(block, iter); iter = vector_block_iterator_advance(block, iter)){
-      Partial_Reveal_Object **p_ref = (Partial_Reveal_Object **)iter;
-      if(*p_ref && obj_need_move(gc, *p_ref))
+      REF* p_ref = (REF*)iter;
+      Partial_Reveal_Object* p_obj = read_slot(p_ref);
+      if(*p_ref && obj_need_move(gc, p_obj))
         finref_repset_add_entry(gc, p_ref);
     }
   }
   finref_put_repset(gc);
 }
 
-static inline void fallback_update_fw_ref(Partial_Reveal_Object **p_ref)
+static inline void fallback_update_fw_ref(REF* p_ref)
 {
   if(!IS_FALLBACK_COMPACTION)
     return;
   
-  Partial_Reveal_Object *p_obj = *p_ref;
+  Partial_Reveal_Object *p_obj = read_slot(p_ref);
   if(obj_belongs_to_nos(p_obj) && obj_is_fw_in_oi(p_obj)){
     assert(!obj_is_marked_in_vt(p_obj));
     assert(obj_get_vt(p_obj) == obj_get_vt(obj_get_fw_in_oi(p_obj)));
     p_obj = obj_get_fw_in_oi(p_obj);
     assert(p_obj);
-    *p_ref = p_obj;
+    write_slot(p_ref, p_obj);
   }
 }
 
@@ -123,15 +122,20 @@
     unsigned int block_has_ref = 0;
     POINTER_SIZE_INT *iter = vector_block_iterator_init(block);
     for(; !vector_block_iterator_end(block, iter); iter = vector_block_iterator_advance(block, iter)){
-      Partial_Reveal_Object **p_ref = (Partial_Reveal_Object **)iter;
-      fallback_update_fw_ref(p_ref);
-      Partial_Reveal_Object *p_obj = *p_ref;
+      REF* p_ref = (REF *)iter;
+      if(IS_FALLBACK_COMPACTION)
+      fallback_update_fw_ref(p_ref);  // in case that this collection is FALLBACK_COLLECTION
+      Partial_Reveal_Object *p_obj = read_slot(p_ref);
       if(!p_obj)
         continue;
       if(gc_obj_is_dead(gc, p_obj)){
         gc_add_finalizable_obj(gc, p_obj);
-        *p_ref = NULL;
+        *p_ref = (REF)NULL;
       } else {
+        if(gc_match_kind(gc, MINOR_COLLECTION) && obj_need_move(gc, p_obj)){
+          assert(obj_is_fw_in_oi(p_obj));
+          write_slot(p_ref, obj_get_fw_in_oi(p_obj));
+        }
         ++block_has_ref;
       }
     }
@@ -139,6 +143,9 @@
       vector_block_clear(block);
   }
   gc_put_finalizable_objects(gc);
+  
+  if(!gc_match_kind(gc, MINOR_COLLECTION))
+    finref_add_repset_from_pool(gc, obj_with_fin_pool);
 }
 
 extern void trace_obj_in_gen_fw(Collector *collector, void *p_ref);
@@ -149,29 +156,28 @@
 typedef void (* Trace_Object_Func)(Collector *collector, void *p_ref_or_obj);
 // clear the two least significant bits of p_obj first
 // add p_ref to repset
-static inline void resurrect_obj_tree(Collector *collector, Partial_Reveal_Object **p_ref)
+static inline void resurrect_obj_tree(Collector *collector, REF* p_ref)
 {
   GC *gc = collector->gc;
   GC_Metadata* metadata = gc->metadata;
-  unsigned int collect_kind = gc->collect_kind;
-  Partial_Reveal_Object *p_obj = *p_ref;
+  Partial_Reveal_Object *p_obj = read_slot(p_ref);
   assert(p_obj && gc_obj_is_dead(gc, p_obj));
   
   void *p_ref_or_obj = p_ref;
   Trace_Object_Func trace_object;
   
   /* set trace_object() function */
-  if(collect_kind == MINOR_COLLECTION){
+  if(gc_match_kind(gc, MINOR_COLLECTION)){
     if(gc_is_gen_mode())
       trace_object = trace_obj_in_gen_fw;
     else
       trace_object = trace_obj_in_nongen_fw;
-  } else if(collect_kind == MAJOR_COLLECTION){
+  } else if(gc_match_kind(gc, MAJOR_COLLECTION)){
     p_ref_or_obj = p_obj;
     trace_object = trace_obj_in_marking;
     obj_mark_in_vt(p_obj);
   } else {
-    assert(collect_kind == FALLBACK_COLLECTION);
+    assert(gc_match_kind(gc, FALLBACK_COLLECTION));
     trace_object = trace_obj_in_fallback_marking;
   }
   
@@ -185,13 +191,21 @@
     POINTER_SIZE_INT *iter = vector_block_iterator_init(task_block);
     while(!vector_block_iterator_end(task_block, iter)){
       void* p_ref_or_obj = (void *)*iter;
-      assert((collect_kind!=MAJOR_COLLECTION && *(Partial_Reveal_Object **)p_ref_or_obj)
-              || (collect_kind==MAJOR_COLLECTION && p_ref_or_obj));
+      assert((gc_match_kind(gc, MINOR_COLLECTION | FALLBACK_COLLECTION) && *(Partial_Reveal_Object **)p_ref_or_obj)
+              || (gc_match_kind(gc, MAJOR_COLLECTION) && p_ref_or_obj));
       trace_object(collector, p_ref_or_obj);
+      if(collector->result == FALSE)  break; /* force return */
+      
       iter = vector_block_iterator_advance(task_block, iter);
     }
     vector_stack_clear(task_block);
     pool_put_entry(metadata->free_task_pool, task_block);
+    
+    if(collector->result == FALSE){
+      gc_task_pool_clear(metadata->mark_task_pool);
+      break; /* force return */
+    }
+    
     task_block = pool_get_entry(metadata->mark_task_pool);      
   }
   
@@ -205,83 +219,94 @@
 {
   GC *gc = collector->gc;
   Finref_Metadata *metadata = gc->finref_metadata;
-  Pool *obj_with_fin_pool = metadata->obj_with_fin_pool;
   Pool *finalizable_obj_pool = metadata->finalizable_obj_pool;
-  unsigned int collect_kind = gc->collect_kind;
   
-  if(!finalizable_obj_pool_is_empty(gc)){
+  if(finalizable_obj_pool_is_empty(gc))
+    return;
+  
+  if(!gc_match_kind(gc, MINOR_COLLECTION))
     finref_reset_repset(gc);
-    pool_iterator_init(finalizable_obj_pool);
-    while(Vector_Block *block = pool_iterator_next(finalizable_obj_pool)){
-      POINTER_SIZE_INT *iter = vector_block_iterator_init(block);
-      for(; !vector_block_iterator_end(block, iter); iter = vector_block_iterator_advance(block, iter)){
-        Partial_Reveal_Object **p_ref = (Partial_Reveal_Object **)iter;
-        Partial_Reveal_Object *p_obj = *p_ref;
-        assert(p_obj);
-        
-        /*
-         * In major & fallback collection we need record p_ref of the root dead obj to update it later.
-         * Because it is outside heap, we can't update in ref fixing.
-         * In minor collection p_ref of the root dead obj is automatically updated while tracing.
-         */
-        if(collect_kind != MINOR_COLLECTION)
-          finref_repset_add_entry(gc, p_ref);
-        
-        /* Perhaps obj has been resurrected by previous resurrections */
-        if(!gc_obj_is_dead(gc, p_obj)){
-          if(gc->collect_kind == MINOR_COLLECTION && obj_need_move(gc, p_obj))
-            *p_ref = obj_get_fw_in_oi(p_obj);
-          continue;
-        }
-        
-        resurrect_obj_tree(collector, p_ref);
+  pool_iterator_init(finalizable_obj_pool);
+  while(Vector_Block *block = pool_iterator_next(finalizable_obj_pool)){
+    POINTER_SIZE_INT *iter = vector_block_iterator_init(block);
+    for(; !vector_block_iterator_end(block, iter); iter = vector_block_iterator_advance(block, iter)){
+      REF* p_ref = (REF *)iter;
+      Partial_Reveal_Object *p_obj = read_slot(p_ref);
+      assert(p_obj);
+      
+      /* In major & fallback collection we need record p_ref of the root dead obj to update it later.
+       * Because it is outside heap, we can't update in ref fixing.
+       * In minor collection p_ref of the root dead obj is automatically updated while tracing.
+       */
+      if(!gc_match_kind(gc, MINOR_COLLECTION))
+        finref_repset_add_entry(gc, p_ref);
+      
+      /* Perhaps obj has been resurrected by previous resurrections */
+      if(!gc_obj_is_dead(gc, p_obj)){
+        if(gc_match_kind(gc, MINOR_COLLECTION) && obj_need_move(gc, p_obj))
+          write_slot(p_ref, obj_get_fw_in_oi(p_obj));
+        continue;
+      }
+      
+      resurrect_obj_tree(collector, p_ref);
+      if(collector->result == FALSE){
+        /* Resurrection fallback happens */
+        assert(gc_match_kind(gc, MINOR_COLLECTION));
+        return; /* force return */
       }
     }
-    metadata->pending_finalizers = TRUE;
-    finref_put_repset(gc);
   }
+  if(!gc_match_kind(gc, MINOR_COLLECTION))
+    finref_put_repset(gc);
+  metadata->pending_finalizers = TRUE;
   
-  finref_add_repset_from_pool(gc, obj_with_fin_pool);
-  /* fianlizable objects have been added to collector repset pool */
-  //finref_add_repset_from_pool(collector, finalizable_obj_pool);
+  /* fianlizable objs have been added to finref repset pool or updated by tracing */
 }
 
 static void identify_dead_refs(GC *gc, Pool *pool)
 {
-  finref_reset_repset(gc);
+  if(!gc_match_kind(gc, MINOR_COLLECTION))
+    finref_reset_repset(gc);
   pool_iterator_init(pool);
   while(Vector_Block *block = pool_iterator_next(pool)){
     POINTER_SIZE_INT *iter = vector_block_iterator_init(block);
     for(; !vector_block_iterator_end(block, iter); iter = vector_block_iterator_advance(block, iter)){
-      Partial_Reveal_Object **p_ref = (Partial_Reveal_Object **)iter;
-      Partial_Reveal_Object *p_obj = *p_ref;
+      REF* p_ref = (REF*)iter;
+      Partial_Reveal_Object *p_obj = read_slot(p_ref);
       assert(p_obj);
-      Partial_Reveal_Object **p_referent_field = obj_get_referent_field(p_obj);
+      REF* p_referent_field = obj_get_referent_field(p_obj);
+      if(IS_FALLBACK_COMPACTION)
       fallback_update_fw_ref(p_referent_field);
-      Partial_Reveal_Object *p_referent = *p_referent_field;
+      Partial_Reveal_Object *p_referent = read_slot(p_referent_field);
       
       if(!p_referent){  // referent field has been cleared
-        *p_ref = NULL;
+        *p_ref = (REF)NULL;
         continue;
       }
       if(!gc_obj_is_dead(gc, p_referent)){  // referent is alive
         if(obj_need_move(gc, p_referent))
-          finref_repset_add_entry(gc, p_referent_field);
-        *p_ref = NULL;
+          if(gc_match_kind(gc, MINOR_COLLECTION)){
+            assert(obj_is_fw_in_oi(p_referent));
+            write_slot(p_referent_field, (obj_get_fw_in_oi(p_referent)));
+          } else {
+            finref_repset_add_entry(gc, p_referent_field);
+          }
+        *p_ref = (REF)NULL;
         continue;
       }
-      *p_referent_field = NULL; /* referent is weakly reachable: clear the referent field */
+      *p_referent_field = (REF)NULL; /* referent is weakly reachable: clear the referent field */
     }
   }
-  finref_put_repset(gc);
-  
-  finref_add_repset_from_pool(gc, pool);
+  if(!gc_match_kind(gc, MINOR_COLLECTION)){
+    finref_put_repset(gc);
+    finref_add_repset_from_pool(gc, pool);
+  }
 }
 
 static void identify_dead_softrefs(Collector *collector)
 {
   GC *gc = collector->gc;
-  if(gc->collect_kind == MINOR_COLLECTION){
+  if(gc_match_kind(gc, MINOR_COLLECTION)){
     assert(softref_pool_is_empty(gc));
     return;
   }
@@ -308,18 +333,20 @@
   Finref_Metadata *metadata = gc->finref_metadata;
   Pool *phanref_pool = metadata->phanref_pool;
   
-  finref_reset_repset(gc);
+  if(!gc_match_kind(gc, MINOR_COLLECTION))
+    finref_reset_repset(gc);
 //  collector_reset_repset(collector);
   pool_iterator_init(phanref_pool);
   while(Vector_Block *block = pool_iterator_next(phanref_pool)){
     POINTER_SIZE_INT *iter = vector_block_iterator_init(block);
     for(; !vector_block_iterator_end(block, iter); iter = vector_block_iterator_advance(block, iter)){
       Partial_Reveal_Object **p_ref = (Partial_Reveal_Object **)iter;
-      Partial_Reveal_Object *p_obj = *p_ref;
+      Partial_Reveal_Object *p_obj = read_slot((REF*)p_ref);
       assert(p_obj);
-      Partial_Reveal_Object **p_referent_field = obj_get_referent_field(p_obj);
+      REF* p_referent_field = obj_get_referent_field(p_obj);
+      if(IS_FALLBACK_COMPACTION)
       fallback_update_fw_ref(p_referent_field);
-      Partial_Reveal_Object *p_referent = *p_referent_field;
+      Partial_Reveal_Object *p_referent = read_slot(p_referent_field);
       
       if(!p_referent){  // referent field has been cleared
         *p_ref = NULL;
@@ -327,14 +354,19 @@
       }
       if(!gc_obj_is_dead(gc, p_referent)){  // referent is alive
         if(obj_need_move(gc, p_referent))
-          finref_repset_add_entry(gc, p_referent_field);
-        *p_ref = NULL;
+           if(gc_match_kind(gc, MINOR_COLLECTION)){
+            assert(obj_is_fw_in_oi(p_referent));
+            write_slot(p_referent_field, (obj_get_fw_in_oi(p_referent)));
+          } else {
+            finref_repset_add_entry(gc, p_referent_field);
+          }
+        *p_ref = (REF)NULL;
         continue;
       }
-      *p_referent_field = NULL;
+      *p_referent_field = (REF)NULL;
       /* Phantom status: for future use
        * if((unsigned int)p_referent & PHANTOM_REF_ENQUEUE_STATUS_MASK){
-       *   // enqueued but not explicitly cleared OR pending for enqueuing
+       *   // enqueued but not explicitly cleared OR pending for enqueueing
        *   *iter = NULL;
        * }
        * resurrect_obj_tree(collector, p_referent_field);
@@ -342,9 +374,10 @@
     }
   }
 //  collector_put_repset(collector);
-  finref_put_repset(gc);
-  
-  finref_add_repset_from_pool(gc, phanref_pool);
+  if(!gc_match_kind(gc, MINOR_COLLECTION)){
+    finref_put_repset(gc);
+    finref_add_repset_from_pool(gc, phanref_pool);
+  }
 }
 
 static void put_finalizable_obj_to_vm(GC *gc)
@@ -356,7 +389,7 @@
     POINTER_SIZE_INT *iter = vector_block_iterator_init(block);
     while(!vector_block_iterator_end(block, iter)){
       assert(*iter);
-      Managed_Object_Handle p_obj = (Managed_Object_Handle)*iter;
+      Managed_Object_Handle p_obj = (Managed_Object_Handle)read_slot((REF*)iter);
       vm_finalize_object(p_obj);
       iter = vector_block_iterator_advance(block, iter);
     }
@@ -365,14 +398,14 @@
   }
 }
 
-static inline void put_dead_weak_refs_to_vm(GC *gc, Pool *reference_pool)
+static inline void put_dead_weak_refs_to_vm(GC *gc, Pool *ref_pool)
 {
   Pool *free_pool = gc->finref_metadata->free_pool;
   
-  while(Vector_Block *block = pool_get_entry(reference_pool)){
+  while(Vector_Block *block = pool_get_entry(ref_pool)){
     POINTER_SIZE_INT *iter = vector_block_iterator_init(block);
     while(!vector_block_iterator_end(block, iter)){
-      Managed_Object_Handle p_obj = (Managed_Object_Handle)*iter;
+      Managed_Object_Handle p_obj = (Managed_Object_Handle)read_slot((REF*)iter);
       if(p_obj)
         vm_enqueue_reference(p_obj);
       iter = vector_block_iterator_advance(block, iter);
@@ -384,23 +417,113 @@
 
 static void put_dead_refs_to_vm(GC *gc)
 {
+  Finref_Metadata *metadata = gc->finref_metadata;
+  
   if(softref_pool_is_empty(gc)
       && weakref_pool_is_empty(gc)
-      && phanref_pool_is_empty(gc)){
+      && phanref_pool_is_empty(gc)
+      && pool_is_empty(metadata->fallback_ref_pool)){
     gc_clear_weakref_pools(gc);
     return;
   }
   
-  gc->finref_metadata->pending_weakrefs = TRUE;
+  put_dead_weak_refs_to_vm(gc, metadata->softref_pool);
+  put_dead_weak_refs_to_vm(gc, metadata->weakref_pool);
+  put_dead_weak_refs_to_vm(gc, metadata->phanref_pool);
   
-  Pool *softref_pool = gc->finref_metadata->softref_pool;
-  Pool *weakref_pool = gc->finref_metadata->weakref_pool;
-  Pool *phanref_pool = gc->finref_metadata->phanref_pool;
-  Pool *free_pool = gc->finref_metadata->free_pool;
+  if(/*IS_FALLBACK_COMPACTION && */!pool_is_empty(metadata->fallback_ref_pool))
+    put_dead_weak_refs_to_vm(gc, metadata->fallback_ref_pool);
+  metadata->pending_weakrefs = TRUE;
+}
+
+/* Finalizable objs falls back to objs with fin when resurrection fallback happens */
+static void finalizable_objs_fallback(GC *gc)
+{
+  Finref_Metadata *metadata = gc->finref_metadata;
+  Pool *finalizable_obj_pool = metadata->finalizable_obj_pool;
+  Pool *obj_with_fin_pool = metadata->obj_with_fin_pool;
+  Vector_Block *obj_with_fin_block = pool_get_entry(obj_with_fin_pool);
+  assert(obj_with_fin_block);
+  
+  Boolean pending_finalizers = FALSE;
+  
+  while(Vector_Block *block = pool_get_entry(finalizable_obj_pool)){
+    POINTER_SIZE_INT *iter = vector_block_iterator_init(block);
+    for(; !vector_block_iterator_end(block, iter); iter = vector_block_iterator_advance(block, iter)){
+      REF* p_ref = (REF*)iter;
+      Partial_Reveal_Object *p_obj = read_slot(p_ref);
+      assert(p_obj);
+      /* Perhaps obj has been resurrected by previous resurrections */
+      if(!gc_obj_is_dead(gc, p_obj) && obj_belongs_to_nos(p_obj)){
+        if(!gc_is_gen_mode() || fspace_obj_to_be_forwarded(p_obj)){
+          write_slot(p_ref , obj_get_fw_in_oi(p_obj));
+          p_obj = read_slot(p_ref);
+        }
+      }
+      gc_add_finalizer(gc, obj_with_fin_block, p_obj);  // Perhaps p_obj has been forwarded, so we use *p_ref rather than p_obj
+    }
+  }
+  
+  pool_put_entry(obj_with_fin_pool, obj_with_fin_block);
+  metadata->pending_finalizers = pending_finalizers;
+}
+
+static void dead_weak_refs_fallback(GC *gc, Pool *ref_pool)
+{
+  Finref_Metadata *metadata = gc->finref_metadata;
+  Pool *free_pool = metadata->free_pool;
+  Pool *fallback_ref_pool = metadata->fallback_ref_pool;
+  
+  Vector_Block *fallback_ref_block = finref_get_free_block(gc);
+  while(Vector_Block *block = pool_get_entry(ref_pool)){
+    POINTER_SIZE_INT *iter = vector_block_iterator_init(block);
+    while(!vector_block_iterator_end(block, iter)){
+      Partial_Reveal_Object *p_obj = read_slot((REF*)iter);
+      if(p_obj)
+        finref_add_fallback_ref(gc, fallback_ref_block, p_obj);
+      iter = vector_block_iterator_advance(block, iter);
+    }
+    vector_block_clear(block);
+    pool_put_entry(free_pool, block);
+  }
+  
+  pool_put_entry(fallback_ref_pool, fallback_ref_block);
+}
+
+/* Record softrefs and weakrefs whose referents are dead.
+ * In fallback collection these refs will not be considered for enqueueing again,
+ * since their referent fields have been cleared by identify_dead_refs().
+ */
+static void dead_refs_fallback(GC *gc)
+{
+  Finref_Metadata *metadata = gc->finref_metadata;
+  
+  if(!softref_pool_is_empty(gc) || !weakref_pool_is_empty(gc))
+    metadata->pending_weakrefs = TRUE;
+  
+  dead_weak_refs_fallback(gc, metadata->softref_pool);
+  dead_weak_refs_fallback(gc, metadata->weakref_pool);
+  
+  gc_clear_weakref_pools(gc);
+}
+
+static void resurrection_fallback_handler(GC *gc)
+{
+  Finref_Metadata *metadata = gc->finref_metadata;
+  
+  /* Repset pool should be empty, because we don't add anthing to this pool in Minor Collection. */
+  assert(pool_is_empty(metadata->repset_pool));
   
-  put_dead_weak_refs_to_vm(gc, softref_pool);
-  put_dead_weak_refs_to_vm(gc, weakref_pool);
-  put_dead_weak_refs_to_vm(gc, phanref_pool);
+  finalizable_objs_fallback(gc);
+  dead_refs_fallback(gc);
+  
+  assert(pool_is_empty(metadata->finalizable_obj_pool));
+  assert(pool_is_empty(metadata->softref_pool));
+  assert(pool_is_empty(metadata->weakref_pool));
+  assert(pool_is_empty(metadata->phanref_pool));
+  
+  assert(metadata->finalizable_obj_set == NULL);
+  assert(metadata->repset == NULL);
 }
 
 void collector_identify_finref(Collector *collector)
@@ -412,9 +535,20 @@
   identify_dead_weakrefs(collector);
   identify_finalizable_objects(collector);
   resurrect_finalizable_objects(collector);
+  gc->collect_result = gc_collection_result(gc);
+  if(!gc->collect_result){
+    assert(gc_match_kind(gc, MINOR_COLLECTION));
+    resurrection_fallback_handler(gc);
+    return;
+  }
   identify_dead_phanrefs(collector);
 }
 
+void fallback_finref_cleanup(GC *gc)
+{
+  gc_set_weakref_sets(gc);
+  gc_clear_weakref_pools(gc);
+}
 void gc_put_finref_to_vm(GC *gc)
 {
   put_dead_refs_to_vm(gc);
@@ -438,7 +572,7 @@
   while(Vector_Block *block = pool_get_entry(obj_with_fin_pool)){
     POINTER_SIZE_INT *iter = vector_block_iterator_init(block);
     while(!vector_block_iterator_end(block, iter)){
-      Managed_Object_Handle p_obj = (Managed_Object_Handle)*iter;
+      Managed_Object_Handle p_obj = (Managed_Object_Handle)read_slot((REF*)iter);
       if(p_obj)
         vm_finalize_object(p_obj);
       iter = vector_block_iterator_advance(block, iter);
@@ -454,24 +588,30 @@
   while(Vector_Block *block = pool_get_entry(pool)){
     POINTER_SIZE_INT *iter = vector_block_iterator_init(block);
     for(; !vector_block_iterator_end(block, iter); iter = vector_block_iterator_advance(block, iter)){
-      Partial_Reveal_Object **p_ref = (Partial_Reveal_Object **)iter;
-      Partial_Reveal_Object *p_obj = *p_ref;
+      REF* p_ref = (REF*)iter;
+      Partial_Reveal_Object *p_obj = read_slot(p_ref);
       assert(p_obj);
-      Partial_Reveal_Object **p_referent_field = obj_get_referent_field(p_obj);
+      REF* p_referent_field = obj_get_referent_field(p_obj);
+      if(IS_FALLBACK_COMPACTION)
       fallback_update_fw_ref(p_referent_field);
-      Partial_Reveal_Object *p_referent = *p_referent_field;
+      Partial_Reveal_Object* p_referent = read_slot(p_referent_field);
       
       if(!p_referent){  // referent field has been cleared
-        *p_ref = NULL;
+        *p_ref = (REF)NULL;
         continue;
       }
       if(!gc_obj_is_dead(gc, p_referent)){  // referent is alive
         if(obj_need_move(gc, p_referent))
-          finref_repset_add_entry(gc, p_referent_field);
-        *p_ref = NULL;
+          if(gc_match_kind(gc, MINOR_COLLECTION)){
+            assert(obj_is_fw_in_oi(p_referent));
+            write_slot(p_referent_field , obj_get_fw_in_oi(p_referent));
+          } else {
+            finref_repset_add_entry(gc, p_referent_field);
+          }
+        *p_ref = (REF)NULL;
         continue;
       }
-      *p_referent_field = NULL; /* referent is weakly reachable: clear the referent field */
+      *p_referent_field = (REF)NULL; /* referent is weakly reachable: clear the referent field */
     }
   }
 }
@@ -480,62 +620,103 @@
 {
   Finref_Metadata *metadata = gc->finref_metadata;
   
-  finref_reset_repset(gc);
+  if(!gc_match_kind(gc, MINOR_COLLECTION))
+    finref_reset_repset(gc);
   update_referent_field_ignore_finref(gc, metadata->softref_pool);
   update_referent_field_ignore_finref(gc, metadata->weakref_pool);
   update_referent_field_ignore_finref(gc, metadata->phanref_pool);
-  finref_put_repset(gc);
+  if(!gc_match_kind(gc, MINOR_COLLECTION))
+    finref_put_repset(gc);
 }
 
-static void move_compaction_update_referent_field(GC *gc, Partial_Reveal_Object **p_referent_field)
+static void move_compaction_update_ref(GC *gc, REF* p_ref)
 {
-  if(!address_belongs_to_gc_heap((void *)p_referent_field, gc)){
-    *p_referent_field = obj_get_fw_in_table(*p_referent_field);
-    return;
-  }
-  
-  Space *ref_space = space_of_addr(gc, p_referent_field);
-  if(ref_space->move_object){
+  /* If p_ref belongs to heap, it must be a referent field pointer */
+  if(address_belongs_to_gc_heap((void *)p_ref, gc) && (space_of_addr(gc, p_ref))->move_object){
     unsigned int offset = get_gc_referent_offset();
-    Partial_Reveal_Object *p_old_ref = (Partial_Reveal_Object *)((POINTER_SIZE_INT)p_referent_field - offset);
-    Partial_Reveal_Object *p_new_ref = obj_get_fw_in_table(p_old_ref);
-    p_referent_field = (Partial_Reveal_Object **)((POINTER_SIZE_INT)p_new_ref + offset);
-  }
-  assert(space_of_addr(gc, *p_referent_field)->move_object);
-  *p_referent_field = obj_get_fw_in_table(*p_referent_field);
+    Partial_Reveal_Object *p_old_ref = (Partial_Reveal_Object *)((POINTER_SIZE_INT)p_ref - offset);
+    Partial_Reveal_Object *p_new_ref = uncompress_ref(obj_get_fw_in_table(p_old_ref));
+    p_ref = (REF*)((POINTER_SIZE_INT)p_new_ref + offset);
+  }
+  Partial_Reveal_Object* p_obj = read_slot(p_ref);
+  assert(space_of_addr(gc, (void*)p_obj)->move_object);
+  *p_ref = obj_get_fw_in_table(p_obj);
 }
 
 extern Boolean IS_MOVE_COMPACT;
 
-void gc_update_finref_repointed_refs(GC *gc)
+/* parameter pointer_addr_in_pool means it is p_ref or p_obj in pool */
+static void destructively_fix_finref_pool(GC *gc, Pool *pool, Boolean pointer_addr_in_pool)
 {
-  unsigned int collect_kind = gc->collect_kind;
-  Finref_Metadata* metadata = gc->finref_metadata;
-  Pool *repset_pool = metadata->repset_pool;
+  Finref_Metadata *metadata = gc->finref_metadata;
+  REF* p_ref;
+  Partial_Reveal_Object *p_obj;
   
   /* NOTE:: this is destructive to the root sets. */
-  Vector_Block* repset = pool_get_entry(repset_pool);
-
+  Vector_Block *repset = pool_get_entry(pool);
   while(repset){
     POINTER_SIZE_INT *iter = vector_block_iterator_init(repset);
     for(; !vector_block_iterator_end(repset,iter); iter = vector_block_iterator_advance(repset,iter)){
-      Partial_Reveal_Object **p_ref = (Partial_Reveal_Object** )*iter;
-      Partial_Reveal_Object *p_obj = *p_ref;
+      if(pointer_addr_in_pool)
+        p_ref = (REF*)*iter;
+      else
+        p_ref = (REF*)iter;
+      p_obj = read_slot(p_ref);
       
       if(!IS_MOVE_COMPACT){
+        assert(obj_is_marked_in_vt(p_obj));
         assert(obj_is_fw_in_oi(p_obj));
-        assert(collect_kind == MINOR_COLLECTION || obj_is_marked_in_vt(p_obj));
-        *p_ref = obj_get_fw_in_oi(p_obj);
+        write_slot(p_ref , obj_get_fw_in_oi(p_obj));
       } else {
-        move_compaction_update_referent_field(gc, p_ref);
+        move_compaction_update_ref(gc, p_ref);
       }
     }
     vector_block_clear(repset);
     pool_put_entry(metadata->free_pool, repset);
-    repset = pool_get_entry(repset_pool);
-  } 
+    repset = pool_get_entry(pool);
+  }
+}
+
+/* parameter pointer_addr_in_pool means it is p_ref or p_obj in pool */
+static void nondestructively_fix_finref_pool(GC *gc, Pool *pool, Boolean pointer_addr_in_pool)
+{
+  Finref_Metadata *metadata = gc->finref_metadata;
+  REF* p_ref;
+  Partial_Reveal_Object *p_obj;
+  
+  /* NOTE:: this is nondestructive to the root sets. */
+  pool_iterator_init(pool);
+  while(Vector_Block *repset = pool_iterator_next(pool)){
+    POINTER_SIZE_INT *iter = vector_block_iterator_init(repset);
+    for(; !vector_block_iterator_end(repset,iter); iter = vector_block_iterator_advance(repset,iter)){
+      if(pointer_addr_in_pool)
+        p_ref = (REF*)*iter;
+      else
+        p_ref = (REF*)iter;
+      p_obj = read_slot(p_ref);
+      
+      if(!IS_MOVE_COMPACT){
+        assert(obj_is_marked_in_vt(p_obj));
+        assert(obj_is_fw_in_oi(p_obj));
+        write_slot(p_ref , obj_get_fw_in_oi(p_obj));
+      } else {
+        move_compaction_update_ref(gc, p_ref);
+      }
+    }
+  }
+}
+
+void gc_update_finref_repointed_refs(GC *gc)
+{
+  assert(!gc_match_kind(gc, MINOR_COLLECTION));
+  
+  Finref_Metadata* metadata = gc->finref_metadata;
+  Pool *repset_pool = metadata->repset_pool;
+  Pool *fallback_ref_pool = metadata->fallback_ref_pool;
   
-  return;
+  destructively_fix_finref_pool(gc, repset_pool, TRUE);
+  if(IS_FALLBACK_COMPACTION && !pool_is_empty(fallback_ref_pool))
+    nondestructively_fix_finref_pool(gc, fallback_ref_pool, FALSE);
 }
 
 void gc_activate_finref_threads(GC *gc)

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.h?view=diff&rev=519564&r1=519563&r2=519564
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.h Sat Mar 17 23:02:56 2007
@@ -47,25 +47,24 @@
  * }
  */
 
-inline Partial_Reveal_Object **obj_get_referent_field(Partial_Reveal_Object *p_obj)
+inline REF* obj_get_referent_field(Partial_Reveal_Object *p_obj)
 {
   assert(p_obj);
-  return (Partial_Reveal_Object **)(( Byte*)p_obj+get_gc_referent_offset());
+  return (REF*)(( Byte*)p_obj+get_gc_referent_offset());
 }
 
-typedef void (* Scan_Slot_Func)(Collector *collector, Partial_Reveal_Object **p_ref);
+typedef void (* Scan_Slot_Func)(Collector *collector, REF* p_ref);
 inline void scan_weak_reference(Collector *collector, Partial_Reveal_Object *p_obj, Scan_Slot_Func scan_slot)
 {
   WeakReferenceType type = special_reference_type(p_obj);
   if(type == NOT_REFERENCE)
     return;
-  unsigned int collect_kind = collector->gc->collect_kind;
-  Partial_Reveal_Object **p_referent_field = obj_get_referent_field(p_obj);
-  Partial_Reveal_Object *p_referent = *p_referent_field;
+  REF* p_referent_field = obj_get_referent_field(p_obj);
+  REF p_referent = *p_referent_field;
   if (!p_referent) return;
   switch(type){
     case SOFT_REFERENCE :
-      if(collect_kind==MINOR_COLLECTION)
+      if(gc_match_kind(collector->gc, MINOR_COLLECTION))
         scan_slot(collector, p_referent_field);
       else
         collector_add_softref(collector, p_obj);
@@ -84,6 +83,7 @@
 
 extern void gc_update_weakref_ignore_finref(GC *gc);
 extern void collector_identify_finref(Collector *collector);
+extern void fallback_finref_cleanup(GC *gc);
 extern void gc_put_finref_to_vm(GC *gc);
 extern void put_all_fin_on_exit(GC *gc);
 

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.cpp?view=diff&rev=519564&r1=519563&r2=519564
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.cpp Sat Mar 17 23:02:56 2007
@@ -22,12 +22,11 @@
 #include "../thread/mutator.h"
 #include "../thread/collector.h"
 
-#define FINREF_METADATA_SEG_SIZE_BIT_SHIFT          20
-#define FINREF_METADATA_SEG_SIZE_BYTES                (1 << FINREF_METADATA_SEG_SIZE_BIT_SHIFT)
+#define FINREF_METADATA_SEG_SIZE_BIT_SHIFT 20
+#define FINREF_METADATA_SEG_SIZE_BYTES (1 << FINREF_METADATA_SEG_SIZE_BIT_SHIFT)
 
-//#define FINREF_METADATA_BLOCK_SIZE_BYTES    must be equal to   VECTOR_BLOCK_DATA_SIZE_BYTES
-#define FINREF_METADATA_BLOCK_SIZE_BIT_SHIFT  11
-#define FINREF_METADATA_BLOCK_SIZE_BYTES        (1 << FINREF_METADATA_BLOCK_SIZE_BIT_SHIFT)
+#define FINREF_METADATA_BLOCK_SIZE_BIT_SHIFT 10
+#define FINREF_METADATA_BLOCK_SIZE_BYTES (1 << FINREF_METADATA_BLOCK_SIZE_BIT_SHIFT)
 
 static Finref_Metadata finref_metadata;
 
@@ -59,6 +58,7 @@
   finref_metadata.weakref_pool = sync_pool_create();
   finref_metadata.phanref_pool = sync_pool_create();
   finref_metadata.repset_pool = sync_pool_create();
+  finref_metadata.fallback_ref_pool = sync_pool_create();
   
   finref_metadata.finalizable_obj_set= NULL;
   finref_metadata.repset = NULL;
@@ -194,6 +194,9 @@
 {
   GC *gc = collector->gc;
   
+  assert(collector->softref_set == NULL);
+  assert(collector->weakref_set == NULL);
+  assert(collector->phanref_set == NULL);
   collector->softref_set = finref_get_free_block(gc);
   collector->weakref_set = finref_get_free_block(gc);
   collector->phanref_set= finref_get_free_block(gc);
@@ -249,13 +252,13 @@
 }
 
 
-static inline void finref_metadata_add_entry(GC *gc, Vector_Block* &vector_block_in_use, Pool *pool, Partial_Reveal_Object *ref)
+static inline void finref_metadata_add_entry(GC *gc, Vector_Block* &vector_block_in_use, Pool *pool, POINTER_SIZE_INT value)
 {
   assert(vector_block_in_use);
-  assert(ref);
+  assert(value);
 
   Vector_Block* block = vector_block_in_use;
-  vector_block_add_entry(block, (POINTER_SIZE_INT)ref);
+  vector_block_add_entry(block, value);
   
   if(!vector_block_is_full(block)) return;
   
@@ -263,35 +266,61 @@
   vector_block_in_use = finref_get_free_block(gc);
 }
 
-void mutator_add_finalizer(Mutator *mutator, Partial_Reveal_Object *ref)
+void mutator_add_finalizer(Mutator *mutator, Partial_Reveal_Object *p_obj)
 {
-  finref_metadata_add_entry(mutator->gc, mutator->obj_with_fin, finref_metadata.obj_with_fin_pool, ref);
+  GC *gc = mutator->gc;
+  Finref_Metadata *metadata = gc->finref_metadata;
+  finref_metadata_add_entry(gc, mutator->obj_with_fin, metadata->obj_with_fin_pool, (POINTER_SIZE_INT)compress_ref(p_obj));
+}
+
+/* This function is only used by resurrection fallback */
+void gc_add_finalizer(GC *gc, Vector_Block* &vector_block_in_use, Partial_Reveal_Object *p_obj)
+{
+  Finref_Metadata *metadata = gc->finref_metadata;
+  finref_metadata_add_entry(gc, vector_block_in_use, metadata->obj_with_fin_pool, (POINTER_SIZE_INT)compress_ref(p_obj));
 }
 
-void gc_add_finalizable_obj(GC *gc, Partial_Reveal_Object *ref)
+void gc_add_finalizable_obj(GC *gc, Partial_Reveal_Object *p_obj)
 {
-  finref_metadata_add_entry(gc, finref_metadata.finalizable_obj_set, finref_metadata.finalizable_obj_pool, ref);
+  Finref_Metadata *metadata = gc->finref_metadata;
+  finref_metadata_add_entry(gc, metadata->finalizable_obj_set, metadata->finalizable_obj_pool, (POINTER_SIZE_INT)compress_ref(p_obj));
 }
 
 void collector_add_softref(Collector *collector, Partial_Reveal_Object *ref)
 {
-  finref_metadata_add_entry(collector->gc, collector->softref_set, finref_metadata.softref_pool, ref);
+  GC *gc = collector->gc;
+  Finref_Metadata *metadata = gc->finref_metadata;
+  finref_metadata_add_entry(gc, collector->softref_set, metadata->softref_pool, (POINTER_SIZE_INT)compress_ref(ref));
 }
 
 void collector_add_weakref(Collector *collector, Partial_Reveal_Object *ref)
 {
-  finref_metadata_add_entry(collector->gc, collector->weakref_set, finref_metadata.weakref_pool, ref);
+  GC *gc = collector->gc;
+  Finref_Metadata *metadata = gc->finref_metadata;
+  finref_metadata_add_entry(gc, collector->weakref_set, metadata->weakref_pool, (POINTER_SIZE_INT)compress_ref(ref));
 }
 
 void collector_add_phanref(Collector *collector, Partial_Reveal_Object *ref)
 {
-  finref_metadata_add_entry(collector->gc, collector->phanref_set, finref_metadata.phanref_pool, ref);
+  GC *gc = collector->gc;
+  Finref_Metadata *metadata = gc->finref_metadata;
+  finref_metadata_add_entry(gc, collector->phanref_set, metadata->phanref_pool, (POINTER_SIZE_INT)compress_ref(ref));
 }
 
-void finref_repset_add_entry(GC *gc, Partial_Reveal_Object **p_ref)
+void finref_repset_add_entry(GC *gc, REF* p_ref)
 {
   assert(*p_ref);
-  finref_metadata_add_entry(gc, finref_metadata.repset, finref_metadata.repset_pool, (Partial_Reveal_Object *)p_ref);
+  assert(*(unsigned int*)*p_ref);
+  Finref_Metadata *metadata = gc->finref_metadata;
+  finref_metadata_add_entry(gc, metadata->repset, metadata->repset_pool, (POINTER_SIZE_INT)p_ref);
+}
+
+/* This function is only used by resurrection fallback */
+void finref_add_fallback_ref(GC *gc, Vector_Block* &vector_block_in_use, Partial_Reveal_Object *p_obj)
+{
+  assert(p_obj);
+  Finref_Metadata *metadata = gc->finref_metadata;
+  finref_metadata_add_entry(gc, vector_block_in_use, metadata->fallback_ref_pool, (POINTER_SIZE_INT)compress_ref(p_obj));
 }
 
 static inline Boolean pool_has_no_ref(Pool *pool)
@@ -354,4 +383,9 @@
   finref_metadata_clear_pool(gc->finref_metadata->softref_pool);
   finref_metadata_clear_pool(gc->finref_metadata->weakref_pool);
   finref_metadata_clear_pool(gc->finref_metadata->phanref_pool);
+}
+
+void gc_clear_finref_repset_pool(GC *gc)
+{
+  finref_metadata_clear_pool(gc->finref_metadata->repset_pool);
 }



Mime
View raw message