You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by wj...@apache.org on 2006/12/12 16:59:18 UTC

svn commit: r486200 [1/2] - in /harmony/enhanced/drlvm/trunk: build/make/components/vm/ vm/gc_gen/src/common/ vm/gc_gen/src/finalizer_weakref/ vm/gc_gen/src/gen/ vm/gc_gen/src/mark_compact/ vm/gc_gen/src/mark_sweep/ vm/gc_gen/src/thread/ vm/gc_gen/src/...

Author: wjwashburn
Date: Tue Dec 12 07:59:15 2006
New Revision: 486200

URL: http://svn.apache.org/viewvc?view=rev&rev=486200
Log:
Harmony-2509, Harmony-2560  ---- GCV5 finalizer and weak ref support, LOS implementation
build and build test pass on win32 and lin32 w/ gcc 4.0.2


Added:
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/
    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/mark_sweep/free_area_pool.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_alloc_collect.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/bidir_list.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/bit_ops.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/finalizer_thread.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/ref_enqueue_thread.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/finalizer_thread.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/ref_enqueue_thread.cpp
Modified:
    harmony/enhanced/drlvm/trunk/build/make/components/vm/gc_gen.xml
    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/mark_scan.cpp
    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/mark_compact/mspace_collect_compact.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector_alloc.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator_alloc.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_copy.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_forward.cpp
    harmony/enhanced/drlvm/trunk/vm/include/open/vm_gc.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/finalize.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/finalize.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/FinalizerThread.java
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/java_lang_FinalizerThread.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/java_lang_FinalizerThread.h

Modified: harmony/enhanced/drlvm/trunk/build/make/components/vm/gc_gen.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/build/make/components/vm/gc_gen.xml?view=diff&rev=486200&r1=486199&r2=486200
==============================================================================
--- harmony/enhanced/drlvm/trunk/build/make/components/vm/gc_gen.xml (original)
+++ harmony/enhanced/drlvm/trunk/build/make/components/vm/gc_gen.xml Tue Dec 12 07:59:15 2006
@@ -61,7 +61,8 @@
                 <include name="trace_forward/*.cpp" />            
                 <include name="utils/*.cpp" /> 
                 <include name="jni/*.cpp" /> 
-                <include name="verify/*.cpp" />            
+                <include name="verify/*.cpp" />             
+                <include name="finalizer_weakref/*.cpp" />
                 </select>
 
                 <select arch="em64t,ipf">
@@ -74,6 +75,7 @@
                 <exclude name="utils/*.cpp" /> 
                 <exclude name="jni/*.cpp" /> 
                 <exclude name="verify/*.cpp" />            
+                <exclude name="finalizer_weakref/*.cpp" />
                 </select>
             </fileset>
 

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=486200&r1=486199&r2=486200
==============================================================================
--- 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 Tue Dec 12 07:59:15 2006
@@ -22,6 +22,7 @@
 #include "gc_metadata.h"
 #include "../thread/mutator.h"
 #include "../verify/verify_live_heap.h"
+#include "../finalizer_weakref/finalizer_weakref.h"
 
 extern Boolean NEED_BARRIER;
 extern unsigned int NUM_COLLECTORS;
@@ -169,12 +170,15 @@
   //gc->collect_kind = MAJOR_COLLECTION;
 
   gc_metadata_verify(gc, TRUE);
+  gc_finalizer_weakref_metadata_verify((GC*)gc, TRUE);
   
   /* Stop the threads and collect the roots. */
   gc_reset_rootset(gc);  
   vm_enumerate_root_set_all_threads();
   gc_set_rootset(gc); 
-    
+  
+  gc_set_objects_with_finalizer(gc);
+  
   if(verify_live_heap) gc_verify_heap(gc, TRUE);
 
   gc_gen_reclaim_heap((GC_Gen*)gc);  
@@ -182,8 +186,12 @@
   if(verify_live_heap) gc_verify_heap(gc, FALSE);
   
   gc_metadata_verify(gc, FALSE);
-    
+  gc_finalizer_weakref_metadata_verify(gc, FALSE);
+  
+  gc_reset_finalizer_weakref_metadata(gc);
   gc_reset_mutator_context(gc);
+  
+  gc_activate_finalizer_weakref_threads((GC*)gc);
   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=486200&r1=486199&r2=486200
==============================================================================
--- 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 Tue Dec 12 07:59:15 2006
@@ -196,6 +196,7 @@
 struct Mutator;
 struct Collector;
 struct GC_Metadata;
+struct Finalizer_Weakref_Metadata;
 struct Vector_Block;
 typedef struct GC{
   void* heap_start;
@@ -216,6 +217,7 @@
   
   /* metadata is the pool for rootset, tracestack, etc. */  
   GC_Metadata* metadata;
+  Finalizer_Weakref_Metadata *finalizer_weakref_metadata;
   unsigned int collect_kind; /* MAJOR or MINOR */
   /* FIXME:: this is wrong! root_set belongs to mutator */
   Vector_Block* root_set;

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=486200&r1=486199&r2=486200
==============================================================================
--- 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 Tue Dec 12 07:59:15 2006
@@ -19,6 +19,7 @@
  */
 
 #include "gc_common.h"
+#include "../finalizer_weakref/finalizer_weakref_metadata.h"
 
 /* Setter functions for the gc class property field. */
 void gc_set_prop_alignment_mask (GC_VTable_Info *gcvt, unsigned int the_mask)
@@ -41,6 +42,10 @@
 {
   gcvt->gc_class_properties |= CL_PROP_FINALIZABLE_MASK;
 }
+void gc_set_prop_reference(Partial_Reveal_VTable *vt, WeakReferenceType type)
+{
+  vtable_get_gcvt(vt)->gc_class_properties |= (unsigned int)type << CL_PROP_REFERENCE_TYPE_SHIFT;
+}
 
 
 /* A comparison function for qsort() called below to order offset slots. */
@@ -56,7 +61,7 @@
   return 0;
 }
 
-static int *build_ref_offset_array(Class_Handle ch, GC_VTable_Info *gcvt)
+static int *build_ref_offset_array(Class_Handle ch, GC_VTable_Info *gcvt, WeakReferenceType type)
 {
   unsigned num_ref_fields = 0;
   unsigned num_fields = class_num_instance_fields_recursive(ch);
@@ -69,11 +74,25 @@
     }
   }
 
+  int skip = -1; // not skip any reference
+  if (type != NOT_REFERENCE) {
+    int offset = class_get_referent_offset(ch);
+    unsigned int gc_referent_offset = get_gc_referent_offset();
+    if (gc_referent_offset == 0) {
+      set_gc_referent_offset(offset);
+    } else {
+      assert(gc_referent_offset == offset);
+    }
+
+    skip = offset; // skip global referent offset
+    num_ref_fields--;
+  }
+  
   if( num_ref_fields )   
     gcvt->gc_object_has_ref_field = true;
   else 
     return NULL;
-     
+   
   /* add a null-termination slot */
   unsigned int size = (num_ref_fields+1) * sizeof (unsigned int);
 
@@ -85,6 +104,8 @@
   for(idx = 0; idx < num_fields; idx++) {
     Field_Handle fh = class_get_instance_field_recursive(ch, idx);
     if(field_is_reference(fh)) {
+      int offset = field_get_offset(fh);
+      if (offset == skip) continue;
       *new_ref_array = field_get_offset(fh);
       new_ref_array++;
     }
@@ -141,11 +162,14 @@
     gc_set_prop_finalizable(gcvt);
   }
 
+  WeakReferenceType type = class_is_reference(ch);
+  gc_set_prop_reference(vt, type);
+  
   unsigned int size = class_get_boxed_data_size(ch);
   gcvt->gc_allocated_size = size;
   
   /* Build the offset array */
-  build_ref_offset_array(ch, gcvt);
+  build_ref_offset_array(ch, gcvt, type);
 
   gcvt->gc_class_name = class_get_name(ch);
   assert (gcvt->gc_class_name);

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=486200&r1=486199&r2=486200
==============================================================================
--- 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 Tue Dec 12 07:59:15 2006
@@ -142,5 +142,20 @@
   return gcvt->gc_allocated_size;
 }
 
+#define CL_PROP_REFERENCE_TYPE_SHIFT 16
+#define CL_PROP_REFERENCE_TYPE_MASK 0x00030000
+
+inline WeakReferenceType special_reference_type(Partial_Reveal_Object *p_reference)
+{
+  GC_VTable_Info *gcvt = obj_get_gcvt(p_reference);
+  return (WeakReferenceType)((gcvt->gc_class_properties & CL_PROP_REFERENCE_TYPE_MASK) >> CL_PROP_REFERENCE_TYPE_SHIFT);
+}
+
+inline Boolean type_has_finalizer(Partial_Reveal_VTable *vt)
+{
+  GC_VTable_Info *gcvt = vtable_get_gcvt(vt);
+  return gcvt->gc_class_properties & CL_PROP_FINALIZABLE_MASK;
+}
+
 #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=486200&r1=486199&r2=486200
==============================================================================
--- 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 Tue Dec 12 07:59:15 2006
@@ -25,6 +25,7 @@
 #include "interior_pointer.h"
 #include "../thread/collector.h"
 #include "../verify/verify_live_heap.h"
+#include "../finalizer_weakref/finalizer_weakref.h"
 
 static GC* p_global_gc = NULL;
 
@@ -44,6 +45,7 @@
   gc_gen_initialize((GC_Gen*)gc, min_heap_size_bytes, max_heap_size_bytes);
 
   gc_metadata_initialize(gc); /* root set and mark stack */
+  gc_finalizer_weakref_metadata_initialize(gc);
   collector_initialize(gc);
   gc_init_heap_verification(gc);
 
@@ -55,6 +57,7 @@
   GC* gc =  p_global_gc;
   gc_gen_destruct((GC_Gen*)gc);
   gc_metadata_destruct(gc); /* root set and mark stack */
+  gc_finalizer_weakref_metadata_destruct(gc);
   collector_destruct(gc);
 
   if( verify_live_heap ){
@@ -135,3 +138,17 @@
 {  assert(0); return 0; }
 
 
+void gc_finalize_on_exit()
+{
+  process_objects_with_finalizer_on_exit(p_global_gc);
+}
+
+/* for future use
+ * void gc_phantom_ref_enqueue_hook(void *p_reference)
+ * {
+ *   if(special_reference_type((Partial_Reveal_Object *)p_reference) == PHANTOM_REFERENCE){
+ *     Partial_Reveal_Object **p_referent_field = obj_get_referent_field(p_reference);
+ *     *p_referent_field = (Partial_Reveal_Object *)((unsigned int)*p_referent_field | PHANTOM_REF_ENQUEUED_MASK | ~PHANTOM_REF_PENDING_MASK);
+ *   }
+ * }
+ */

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=486200&r1=486199&r2=486200
==============================================================================
--- 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 Tue Dec 12 07:59:15 2006
@@ -22,6 +22,7 @@
 #include "../thread/mutator.h"
 #include "../thread/collector.h"
 #include "interior_pointer.h"
+#include "../finalizer_weakref/finalizer_weakref.h"
 
 #define GC_METADATA_SIZE_BYTES 48*MB
 
@@ -182,7 +183,7 @@
 
 void collector_repset_add_entry(Collector* collector, Partial_Reveal_Object** p_ref)
 {
-  assert( p_ref >= gc_heap_base_address() && p_ref < gc_heap_ceiling_address()); 
+//  assert( p_ref >= gc_heap_base_address() && p_ref < gc_heap_ceiling_address()); 
 
   Vector_Block* root_set = collector->rep_set;  
   vector_block_add_entry(root_set, (unsigned int)p_ref);
@@ -260,8 +261,7 @@
       else
 #endif
       if(!obj_is_forwarded_in_obj_info(p_obj)) continue;
-      Partial_Reveal_Object* p_target_obj = get_forwarding_pointer_in_obj_info(p_obj);
-      *p_ref = p_target_obj; 
+      *p_ref = get_forwarding_pointer_in_obj_info(p_obj);
     }
     vector_block_clear(root_set);
     pool_put_entry(metadata->free_set_pool, root_set);
@@ -282,6 +282,7 @@
     gc_update_repointed_sets(gc, metadata->collector_repset_pool);   
   }
   
+  gc_update_finalizer_weakref_repointed_refs(gc);
   update_rootset_interior_pointer();
     
   return;

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan.cpp?view=diff&rev=486200&r1=486199&r2=486200
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan.cpp Tue Dec 12 07:59:15 2006
@@ -22,6 +22,8 @@
 #include "../thread/collector.h"
 #include "../gen/gen.h"
 
+#include "../finalizer_weakref/finalizer_weakref.h"
+
 static void scan_slot(Collector* collector, Partial_Reveal_Object** p_ref)
 {
   Partial_Reveal_Object* p_obj = *p_ref;
@@ -66,6 +68,8 @@
     offset_scanner = offset_next_ref(offset_scanner);
   }
 
+  scan_weak_reference(collector, p_obj, scan_slot);
+  
   return;
 }
 
@@ -140,7 +144,7 @@
   while(mark_task){
     unsigned int* iter = vector_block_iterator_init(mark_task);
     while(!vector_block_iterator_end(mark_task,iter)){
-      Partial_Reveal_Object* p_obj = (Partial_Reveal_Object*)*iter;
+      Partial_Reveal_Object* p_obj = (Partial_Reveal_Object *)*iter;
       iter = vector_block_iterator_advance(mark_task,iter);
 
       /* FIXME:: we should not let mark_task empty during working, , other may want to steal it. 
@@ -176,4 +180,40 @@
   collector->rep_set = NULL;
 
   return;
+}
+
+void resurrect_obj_tree_after_mark(Collector *collector, Partial_Reveal_Object *p_obj)
+{
+  GC *gc = collector->gc;
+  GC_Metadata* metadata = gc->metadata;
+  
+  Space* space = space_of_addr(gc, p_obj);
+//  if(!space->mark_object_func(space, p_obj)) { assert(0); }
+  space->mark_object_func(space, p_obj);
+  collector->trace_stack = pool_get_entry(metadata->free_task_pool);
+  collector_tracestack_push(collector, p_obj);
+  pool_put_entry(metadata->mark_task_pool, collector->trace_stack);
+  
+//collector->rep_set = pool_get_entry(metadata->free_set_pool); /* has got collector->rep_set in caller */
+  collector->trace_stack = pool_get_entry(metadata->free_task_pool);
+  Vector_Block* mark_task = pool_get_entry(metadata->mark_task_pool);
+  while(mark_task){
+    unsigned int* iter = vector_block_iterator_init(mark_task);
+    while(!vector_block_iterator_end(mark_task,iter)){
+      Partial_Reveal_Object* p_obj = (Partial_Reveal_Object *)*iter;
+      trace_object(collector, p_obj);
+      iter = vector_block_iterator_advance(mark_task, iter);
+    } 
+    /* run out one task, put back to the pool and grab another task */
+    vector_stack_clear(mark_task);
+    pool_put_entry(metadata->free_task_pool, mark_task);
+    mark_task = pool_get_entry(metadata->mark_task_pool);      
+  }
+  
+  mark_task = (Vector_Block*)collector->trace_stack;
+  vector_stack_clear(mark_task);
+  pool_put_entry(metadata->free_task_pool, mark_task);   
+  collector->trace_stack = NULL;
+//pool_put_entry(metadata->collector_repset_pool, collector->rep_set); /* has got collector->rep_set in caller */
+//collector->rep_set = NULL; /* has got collector->rep_set in caller */
 }

Added: 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=auto&rev=486200
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.cpp Tue Dec 12 07:59:15 2006
@@ -0,0 +1,532 @@
+/*
+ *  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 Li-Gang Wang, 2006/11/29
+ */
+
+#include "open/types.h"
+#include "open/vm_gc.h"
+#include "finalizer_weakref.h"
+#include "../thread/mutator.h"
+#include "../common/gc_metadata.h"
+#include "../trace_forward/fspace.h"
+#include "../mark_sweep/lspace.h"
+#include "../gen/gen.h"
+
+/* reset objects_with_finalizer vector block of each mutator */
+void mutator_reset_objects_with_finalizer(Mutator *mutator)
+{
+  mutator->objects_with_finalizer = finalizer_weakref_get_free_block();
+}
+
+void gc_set_objects_with_finalizer(GC *gc)
+{
+  Finalizer_Weakref_Metadata *metadata = gc->finalizer_weakref_metadata;
+  Pool *objects_with_finalizer_pool = metadata->objects_with_finalizer_pool;
+
+  /* put back last objects_with_finalizer block of each mutator */
+  Mutator *mutator = gc->mutator_list;
+  while(mutator){
+    pool_put_entry(objects_with_finalizer_pool, mutator->objects_with_finalizer);
+    mutator->objects_with_finalizer = NULL;
+    mutator = mutator->next;
+  }
+  return;
+}
+
+/* reset weak references vetctor block of each collector */
+void collector_reset_weakref_sets(Collector *collector)
+{
+  collector->softref_set = finalizer_weakref_get_free_block();
+  collector->weakref_set = finalizer_weakref_get_free_block();
+  collector->phanref_set= finalizer_weakref_get_free_block();
+}
+
+static void gc_set_weakref_sets(GC *gc)
+{
+  Finalizer_Weakref_Metadata *metadata = gc->finalizer_weakref_metadata;
+  
+  /* put back last weak references block of each collector */
+  unsigned int num_active_collectors = gc->num_active_collectors;
+  for(unsigned int i = 0; i < num_active_collectors; i++)
+  {
+    Collector* collector = gc->collectors[i];
+    pool_put_entry(metadata->softref_set_pool, collector->softref_set);
+    pool_put_entry(metadata->weakref_set_pool, collector->weakref_set);
+    pool_put_entry(metadata->phanref_set_pool, collector->phanref_set);
+    collector->softref_set = NULL;
+    collector->weakref_set= NULL;
+    collector->phanref_set= NULL;
+  }
+  return;
+}
+
+
+extern Boolean obj_is_dead_in_minor_forward_collection(Collector *collector, Partial_Reveal_Object *p_obj);
+static inline Boolean obj_is_dead_in_minor_copy_collection(Collector *collector, Partial_Reveal_Object *p_obj)
+{
+  GC *gc = collector->gc;
+  Lspace *los = ((GC_Gen *)gc)->los;
+  
+  if(space_of_addr(gc, p_obj) != (Space *)los)
+    return !obj_is_marked_in_vt(p_obj);
+  else
+    return !lspace_object_is_marked(los, p_obj);
+}
+static inline Boolean obj_is_dead_in_major_collection(Collector *collector, Partial_Reveal_Object *p_obj)
+{
+  GC *gc = collector->gc;
+  Lspace *los = ((GC_Gen *)gc)->los;
+  
+  if(space_of_addr(gc, p_obj) != (Space *)los)
+    return !obj_is_marked_in_vt(p_obj);
+  else
+    return !lspace_object_is_marked(los, p_obj);
+}
+// clear the two least significant bits of p_obj first
+static inline Boolean obj_is_dead(Collector *collector, Partial_Reveal_Object *p_obj)
+{
+  GC *gc = collector->gc;
+  
+  assert(p_obj);
+  if(gc->collect_kind == MINOR_COLLECTION){
+    if( gc_requires_barriers())
+      return obj_is_dead_in_minor_forward_collection(collector, p_obj);
+    else
+      return obj_is_dead_in_minor_copy_collection(collector, p_obj);
+  } else {
+    return obj_is_dead_in_major_collection(collector, p_obj);
+  }
+}
+
+
+static inline Boolean fspace_object_to_be_forwarded(Partial_Reveal_Object *p_obj, Space *space)
+{
+  if(!obj_belongs_to_space(p_obj, (Space*)space)) return FALSE;
+  return forward_first_half? (p_obj < object_forwarding_boundary):(p_obj>=object_forwarding_boundary);
+}
+static inline Boolean obj_need_move(Collector *collector, Partial_Reveal_Object *p_obj)
+{
+  assert(!obj_is_dead(collector, p_obj));
+  GC *gc = collector->gc;
+  
+  if(gc_requires_barriers() && gc->collect_kind == MINOR_COLLECTION)
+    return fspace_object_to_be_forwarded(p_obj, collector->collect_space);
+  
+  Space *space = space_of_addr(gc, p_obj);
+  return space->move_object;
+}
+
+
+extern void resurrect_obj_tree_after_trace(Collector *collector, Partial_Reveal_Object **p_ref);
+extern void resurrect_obj_tree_after_mark(Collector *collector, Partial_Reveal_Object *p_obj);
+static inline void resurrect_obj_tree_in_minor_copy_collection(Collector *collector, Partial_Reveal_Object *p_obj)
+{
+  resurrect_obj_tree_after_mark(collector, p_obj);
+}
+static inline void resurrect_obj_tree_in_major_collection(Collector *collector, Partial_Reveal_Object *p_obj)
+{
+  resurrect_obj_tree_after_mark(collector, p_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)
+{
+  GC *gc = collector->gc;
+  
+  if(!gc_requires_barriers() || !(gc->collect_kind == MINOR_COLLECTION))
+    collector_repset_add_entry(collector, p_ref);
+  if(!obj_is_dead(collector, *p_ref)){
+    if(gc_requires_barriers() && gc->collect_kind == MINOR_COLLECTION && obj_need_move(collector, *p_ref))
+      *p_ref = obj_get_forwarding_pointer_in_vt(*p_ref);
+    return;
+  }
+  Partial_Reveal_Object* p_obj = *p_ref;
+  assert(p_obj);
+  
+  if(gc->collect_kind == MINOR_COLLECTION){
+    if( gc_requires_barriers())
+      resurrect_obj_tree_after_trace(collector, p_ref);
+    else
+      resurrect_obj_tree_in_minor_copy_collection(collector, p_obj);
+  } else {
+    resurrect_obj_tree_in_major_collection(collector, p_obj);
+  }
+}
+
+
+/* called before loop of resurrect_obj_tree() */
+static inline void collector_reset_repset(Collector *collector)
+{
+  GC *gc = collector->gc;
+  
+  assert(!collector->rep_set);
+  if(gc_requires_barriers() && gc->collect_kind == MINOR_COLLECTION)
+    return;
+  collector->rep_set = pool_get_entry(gc->metadata->free_set_pool);
+}
+/* called after loop of resurrect_obj_tree() */
+static inline void collector_put_repset(Collector *collector)
+{
+  GC *gc = collector->gc;
+  
+  if(gc_requires_barriers() && gc->collect_kind == MINOR_COLLECTION)
+    return;
+  pool_put_entry(gc->metadata->collector_repset_pool, collector->rep_set);
+  collector->rep_set = NULL;
+}
+
+
+void finalizer_weakref_repset_add_entry_from_pool(Collector *collector, Pool *pool)
+{
+  GC *gc = collector->gc;
+  
+  finalizer_weakref_reset_repset(gc);
+
+  pool_iterator_init(pool);
+  while(Vector_Block *block = pool_iterator_next(pool)){
+    unsigned int *iter = vector_block_iterator_init(block);
+    
+    while(!vector_block_iterator_end(block, iter)){
+      Partial_Reveal_Object **p_ref = (Partial_Reveal_Object **)iter;
+      iter = vector_block_iterator_advance(block, iter);
+	  
+      if(*p_ref && obj_need_move(collector, *p_ref))
+        finalizer_weakref_repset_add_entry(gc, p_ref);
+    }
+  }
+  finalizer_weakref_put_repset(gc);
+}
+
+
+static void process_objects_with_finalizer(Collector *collector)
+{
+  GC *gc = collector->gc;
+  Finalizer_Weakref_Metadata *metadata = gc->finalizer_weakref_metadata;
+  Pool *objects_with_finalizer_pool = metadata->objects_with_finalizer_pool;
+  Pool *finalizable_objects_pool = metadata->finalizable_objects_pool;
+  
+  gc_reset_finalizable_objects(gc);
+  pool_iterator_init(objects_with_finalizer_pool);
+  while(Vector_Block *block = pool_iterator_next(objects_with_finalizer_pool)){
+    unsigned int block_has_ref = 0;
+    unsigned 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_obj = (Partial_Reveal_Object *)*iter;
+      if(!p_obj)
+        continue;
+      if(obj_is_dead(collector, p_obj)){
+        gc_finalizable_objects_add_entry(gc, p_obj);
+        *iter = NULL;
+      } else {
+        ++block_has_ref;
+      }
+    }
+    if(!block_has_ref)
+      vector_block_clear(block);
+  }
+  gc_put_finalizable_objects(gc);
+  
+  collector_reset_repset(collector);
+  if(!finalizable_objects_pool_is_empty(gc)){
+    pool_iterator_init(finalizable_objects_pool);
+    while(Vector_Block *block = pool_iterator_next(finalizable_objects_pool)){
+      unsigned int *iter = vector_block_iterator_init(block);
+      while(!vector_block_iterator_end(block, iter)){
+        assert(*iter);
+        resurrect_obj_tree(collector, (Partial_Reveal_Object **)iter);
+        iter = vector_block_iterator_advance(block, iter);
+      }
+    }
+    metadata->pending_finalizers = TRUE;
+  }
+  collector_put_repset(collector);
+  
+  finalizer_weakref_repset_add_entry_from_pool(collector, objects_with_finalizer_pool);
+  /* fianlizable objects have been added to collector repset pool */
+  //finalizer_weakref_repset_add_entry_from_pool(collector, finalizable_objects_pool);
+}
+
+static void post_process_finalizable_objects(GC *gc)
+{
+  Pool *finalizable_objects_pool = gc->finalizer_weakref_metadata->finalizable_objects_pool;
+  Pool *free_pool = gc->finalizer_weakref_metadata->free_pool;
+  
+  while(Vector_Block *block = pool_get_entry(finalizable_objects_pool)){
+    unsigned 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;
+      vm_finalize_object(p_obj);
+      iter = vector_block_iterator_advance(block, iter);
+    }
+    vector_block_clear(block);
+    pool_put_entry(free_pool, block);
+  }
+}
+
+static void process_soft_references(Collector *collector)
+{
+  GC *gc = collector->gc;
+  if(gc->collect_kind == MINOR_COLLECTION){
+    assert(softref_set_pool_is_empty(gc));
+    return;
+  }
+  
+  Finalizer_Weakref_Metadata *metadata = gc->finalizer_weakref_metadata;
+  Pool *softref_set_pool = metadata->softref_set_pool;
+  
+  finalizer_weakref_reset_repset(gc);
+  pool_iterator_init(softref_set_pool);
+  while(Vector_Block *block = pool_iterator_next(softref_set_pool)){
+    unsigned 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_obj = (Partial_Reveal_Object *)*iter;
+      assert(p_obj);
+      Partial_Reveal_Object **p_referent_field = obj_get_referent_field(p_obj);
+      Partial_Reveal_Object *p_referent = *p_referent_field;
+      
+      if(!p_referent){  // referent field has been cleared
+        *iter = NULL;
+        continue;
+      }
+      if(!obj_is_dead(collector, p_referent)){  // referent is alive
+        if(obj_need_move(collector, p_referent))
+          finalizer_weakref_repset_add_entry(gc, p_referent_field);
+        *iter = NULL;
+        continue;
+      }
+      *p_referent_field = NULL; /* referent is softly reachable: clear the referent field */
+    }
+  }
+  finalizer_weakref_put_repset(gc);
+  
+  finalizer_weakref_repset_add_entry_from_pool(collector, softref_set_pool);
+  return;
+}
+
+static void process_weak_references(Collector *collector)
+{
+  GC *gc = collector->gc;
+  Finalizer_Weakref_Metadata *metadata = gc->finalizer_weakref_metadata;
+  Pool *weakref_set_pool = metadata->weakref_set_pool;
+  
+  finalizer_weakref_reset_repset(gc);
+  pool_iterator_init(weakref_set_pool);
+  while(Vector_Block *block = pool_iterator_next(weakref_set_pool)){
+    unsigned 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_obj = (Partial_Reveal_Object *)*iter;
+      assert(p_obj);
+      Partial_Reveal_Object **p_referent_field = obj_get_referent_field(p_obj);
+      Partial_Reveal_Object *p_referent = *p_referent_field;
+      
+      if(!p_referent){  // referent field has been cleared
+        *iter = NULL;
+        continue;
+      }
+      if(!obj_is_dead(collector, p_referent)){  // referent is alive
+        if(obj_need_move(collector, p_referent))
+          finalizer_weakref_repset_add_entry(gc, p_referent_field);
+        *iter = NULL;
+        continue;
+      }
+      *p_referent_field = NULL; /* referent is weakly reachable: clear the referent field */
+    }
+  }
+  finalizer_weakref_put_repset(gc);
+  
+  finalizer_weakref_repset_add_entry_from_pool(collector, weakref_set_pool);
+  return;
+}
+
+static void process_phantom_references(Collector *collector)
+{
+  GC *gc = collector->gc;
+  Finalizer_Weakref_Metadata *metadata = gc->finalizer_weakref_metadata;
+  Pool *phanref_set_pool = metadata->phanref_set_pool;
+  
+  finalizer_weakref_reset_repset(gc);
+//  collector_reset_repset(collector);
+  pool_iterator_init(phanref_set_pool);
+  while(Vector_Block *block = pool_iterator_next(phanref_set_pool)){
+    unsigned 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_obj = (Partial_Reveal_Object *)*iter;
+      assert(p_obj);
+      Partial_Reveal_Object **p_referent_field = obj_get_referent_field(p_obj);
+      Partial_Reveal_Object *p_referent = *p_referent_field;
+      
+      if(!p_referent){  // referent field has been cleared
+        *iter = NULL;
+        continue;
+      }
+      if(!obj_is_dead(collector, p_referent)){  // referent is alive
+        if(obj_need_move(collector, p_referent))
+          finalizer_weakref_repset_add_entry(gc, p_referent_field);
+        *iter = NULL;
+        continue;
+      }
+      *p_referent_field = NULL;
+      /* Phantom status: for future use
+       * if((unsigned int)p_referent & PHANTOM_REF_ENQUEUE_STATUS_MASK){
+       *   // enqueued but not explicitly cleared OR pending for enqueueing
+       *   *iter = NULL;
+       * }
+       * resurrect_obj_tree(collector, p_referent_field);
+       */
+    }
+  }
+//  collector_put_repset(collector);
+  finalizer_weakref_put_repset(gc);
+  
+  finalizer_weakref_repset_add_entry_from_pool(collector, phanref_set_pool);
+  return;
+}
+
+static inline void post_process_special_reference_pool(GC *gc, Pool *reference_pool)
+{
+  Pool *free_pool = gc->finalizer_weakref_metadata->free_pool;
+  
+  while(Vector_Block *block = pool_get_entry(reference_pool)){
+    unsigned int *iter = vector_block_iterator_init(block);
+    while(!vector_block_iterator_end(block, iter)){
+      Managed_Object_Handle p_obj = (Managed_Object_Handle)*iter;
+      if(p_obj)
+        vm_enqueue_reference(p_obj);
+      iter = vector_block_iterator_advance(block, iter);
+    }
+    vector_block_clear(block);
+    pool_put_entry(free_pool, block);
+  }
+}
+
+static void post_process_special_references(GC *gc)
+{
+  if(softref_set_pool_is_empty(gc)
+      && weakref_set_pool_is_empty(gc)
+      && phanref_set_pool_is_empty(gc)){
+    gc_clear_special_reference_pools(gc);
+    return;
+  }
+  
+  gc->finalizer_weakref_metadata->pending_weak_references = TRUE;
+  
+  Pool *softref_set_pool = gc->finalizer_weakref_metadata->softref_set_pool;
+  Pool *weakref_set_pool = gc->finalizer_weakref_metadata->weakref_set_pool;
+  Pool *phanref_set_pool = gc->finalizer_weakref_metadata->phanref_set_pool;
+  Pool *free_pool = gc->finalizer_weakref_metadata->free_pool;
+  
+  post_process_special_reference_pool(gc, softref_set_pool);
+  post_process_special_reference_pool(gc, weakref_set_pool);
+  post_process_special_reference_pool(gc, phanref_set_pool);
+}
+
+void collector_process_finalizer_weakref(Collector *collector)
+{
+  GC *gc = collector->gc;
+  
+  gc_set_weakref_sets(gc);
+  process_soft_references(collector);
+  process_weak_references(collector);
+  process_objects_with_finalizer(collector);
+  process_phantom_references(collector);
+}
+
+void gc_post_process_finalizer_weakref(GC *gc)
+{
+  post_process_special_references(gc);
+  post_process_finalizable_objects(gc);
+}
+
+void process_objects_with_finalizer_on_exit(GC *gc)
+{
+  Pool *objects_with_finalizer_pool = gc->finalizer_weakref_metadata->objects_with_finalizer_pool;
+  Pool *free_pool = gc->finalizer_weakref_metadata->free_pool;
+  
+  vm_gc_lock_enum();
+  /* FIXME: holding gc lock is not enough, perhaps there are mutators that are allocating objects with finalizer
+   * could be fixed as this:
+   * in fspace_alloc() and lspace_alloc() hold gc lock through
+   * allocating mem and adding the objects with finalizer to the pool
+   */
+  lock(gc->mutator_list_lock);
+  gc_set_objects_with_finalizer(gc);
+  unlock(gc->mutator_list_lock);
+  while(Vector_Block *block = pool_get_entry(objects_with_finalizer_pool)){
+    unsigned int *iter = vector_block_iterator_init(block);
+    while(!vector_block_iterator_end(block, iter)){
+      Managed_Object_Handle p_obj = (Managed_Object_Handle)*iter;
+      if(p_obj)
+        vm_finalize_object(p_obj);
+      iter = vector_block_iterator_advance(block, iter);
+    }
+    vector_block_clear(block);
+    pool_put_entry(free_pool, block);
+  }
+  vm_gc_unlock_enum();
+}
+
+void gc_update_finalizer_weakref_repointed_refs(GC* gc)
+{
+  Finalizer_Weakref_Metadata* metadata = gc->finalizer_weakref_metadata;
+  Pool *repset_pool = metadata->repset_pool;
+  
+  /* NOTE:: this is destructive to the root sets. */
+  Vector_Block* root_set = pool_get_entry(repset_pool);
+
+  while(root_set){
+    unsigned 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;
+      iter = vector_block_iterator_advance(root_set,iter);
+
+      Partial_Reveal_Object* p_obj = *p_ref;
+      /* For repset, this check is unnecessary, since all slots are repointed; otherwise
+         they will not be recorded. For root set, it is possible to point to LOS or other
+         non-moved space.  */
+#ifdef _DEBUG
+      if( !gc_requires_barriers() || gc->collect_kind == MAJOR_COLLECTION ){
+        assert(obj_is_forwarded_in_obj_info(p_obj));
+      } else
+        assert(obj_is_forwarded_in_vt(p_obj));
+#endif
+      Partial_Reveal_Object* p_target_obj;
+      if( !gc_requires_barriers() || gc->collect_kind == MAJOR_COLLECTION )
+        p_target_obj = get_forwarding_pointer_in_obj_info(p_obj);
+      else
+        p_target_obj = obj_get_forwarding_pointer_in_vt(p_obj);
+      *p_ref = p_target_obj;
+    }
+    vector_block_clear(root_set);
+    pool_put_entry(metadata->free_pool, root_set);
+    root_set = pool_get_entry(repset_pool);
+  } 
+  
+  return;
+}
+
+void gc_activate_finalizer_weakref_threads(GC *gc)
+{
+  Finalizer_Weakref_Metadata* metadata = gc->finalizer_weakref_metadata;
+  
+  if(metadata->pending_finalizers || metadata->pending_weak_references){
+	  metadata->pending_finalizers = FALSE;
+    metadata->pending_weak_references = FALSE;
+    vm_hint_finalize();
+  }
+}

Added: 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=auto&rev=486200
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.h Tue Dec 12 07:59:15 2006
@@ -0,0 +1,93 @@
+/*
+ *  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 Li-Gang Wang, 2006/11/30
+ */
+
+#ifndef _FINALIZER_WEAKREF_H_
+#define _FINALIZER_WEAKREF_H_
+
+#include "finalizer_weakref_metadata.h"
+#include "../thread/collector.h"
+
+/* Phantom status: for future use
+ * #define PHANTOM_REF_ENQUEUE_STATUS_MASK 0x3
+ * #define PHANTOM_REF_ENQUEUED_MASK 0x1
+ * #define PHANTOM_REF_PENDING_MASK 0x2
+ *
+ * inline Partial_Reveal_Object *get_reference_pointer(Partial_Reveal_Object *p_obj)
+ * {
+ *   return (Partial_Reveal_Object *)((unsigned int)(p_obj)&(~PHANTOM_REF_ENQUEUE_STATUS_MASK));
+ * }
+ * inline void update_reference_pointer(Partial_Reveal_Object **p_ref, Partial_Reveal_Object *p_target_obj)
+ * {
+ *   unsigned int temp = (unsigned int)*p_ref;
+ * 
+ *   temp &= PHANTOM_REF_ENQUEUE_STATUS_MASK;
+ *   temp |= (unsigned int)p_target_obj;
+ *   *p_ref = (Partial_Reveal_Object *)temp;
+ * }
+ */
+
+inline Partial_Reveal_Object **obj_get_referent_field(Partial_Reveal_Object *p_obj)
+{
+  assert(p_obj);
+  return (Partial_Reveal_Object **)(( Byte*)p_obj+get_gc_referent_offset());
+}
+
+typedef void (* Scan_Slot_Func)(Collector *collector, Partial_Reveal_Object **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;
+  if (!p_referent) return;
+  switch(type){
+    case SOFT_REFERENCE :
+      if(collect_kind==MINOR_COLLECTION)
+        scan_slot(collector, p_referent_field);
+      else
+        collector_softref_set_add_entry(collector, p_obj);
+      break;
+    case WEAK_REFERENCE :
+      collector_weakref_set_add_entry(collector, p_obj);
+      break;
+    case PHANTOM_REFERENCE :
+      collector_phanref_set_add_entry(collector, p_obj);
+      break;
+    default :
+      assert(0);
+      break;
+  }
+}
+
+
+extern void mutator_reset_objects_with_finalizer(Mutator *mutator);
+extern void gc_set_objects_with_finalizer(GC *gc);
+extern void collector_reset_weakref_sets(Collector *collector);
+
+extern void collector_process_finalizer_weakref(Collector *collector);
+extern void gc_post_process_finalizer_weakref(GC *gc);
+extern void process_objects_with_finalizer_on_exit(GC *gc);
+
+extern void gc_update_finalizer_weakref_repointed_refs(GC* gc);
+extern void gc_activate_finalizer_weakref_threads(GC *gc);
+
+#endif // _FINALIZER_WEAKREF_H_

Added: 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=auto&rev=486200
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.cpp Tue Dec 12 07:59:15 2006
@@ -0,0 +1,297 @@
+/*
+ *  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 Li-Gang Wang, 2006/11/29
+ */
+
+#include "finalizer_weakref_metadata.h"
+#include "../thread/mutator.h"
+#include "../thread/collector.h"
+
+#define POOL_SEGMENT_SIZE_BIT_SHIFT 20
+#define POOL_SEGMENT_SIZE_BYTES (1 << POOL_SEGMENT_SIZE_BIT_SHIFT)
+
+#define METADATA_BLOCK_SIZE_BIT_SHIFT 10
+#define METADATA_BLOCK_SIZE_BYTES (1<<METADATA_BLOCK_SIZE_BIT_SHIFT)
+
+static Finalizer_Weakref_Metadata finalizer_weakref_metadata;
+
+unsigned int get_gc_referent_offset(void)
+{
+  return finalizer_weakref_metadata.gc_referent_offset;
+}
+void set_gc_referent_offset(unsigned int offset)
+{
+  finalizer_weakref_metadata.gc_referent_offset = offset;
+}
+
+void gc_finalizer_weakref_metadata_initialize(GC *gc)
+{
+  void *pool_segment = STD_MALLOC(POOL_SEGMENT_SIZE_BYTES);
+  memset(pool_segment, 0, POOL_SEGMENT_SIZE_BYTES);
+  finalizer_weakref_metadata.next_segment_pos = 0;
+  finalizer_weakref_metadata.pool_segments[finalizer_weakref_metadata.next_segment_pos] = pool_segment;
+  ++finalizer_weakref_metadata.next_segment_pos;
+  
+  finalizer_weakref_metadata.free_pool = sync_pool_create();
+  finalizer_weakref_metadata.objects_with_finalizer_pool = sync_pool_create();
+  finalizer_weakref_metadata.finalizable_objects_pool = sync_pool_create();
+  finalizer_weakref_metadata.softref_set_pool = sync_pool_create();
+  finalizer_weakref_metadata.weakref_set_pool = sync_pool_create();
+  finalizer_weakref_metadata.phanref_set_pool = sync_pool_create();
+  finalizer_weakref_metadata.repset_pool = sync_pool_create();
+  
+  finalizer_weakref_metadata.finalizable_objects = NULL;
+  finalizer_weakref_metadata.repset = NULL;
+  
+  unsigned int num_blocks =  POOL_SEGMENT_SIZE_BYTES >> METADATA_BLOCK_SIZE_BIT_SHIFT;
+  for(unsigned int i=0; i<num_blocks; i++){
+    Vector_Block *block = (Vector_Block *)((unsigned int)pool_segment + i*METADATA_BLOCK_SIZE_BYTES);
+    vector_block_init(block, METADATA_BLOCK_SIZE_BYTES);
+    assert(vector_block_is_empty((Vector_Block *)block));
+    pool_put_entry(finalizer_weakref_metadata.free_pool, (void *)block);
+  }
+  
+  finalizer_weakref_metadata.pending_finalizers = FALSE;
+  finalizer_weakref_metadata.pending_weak_references = FALSE;
+  finalizer_weakref_metadata.gc_referent_offset = 0;
+  
+  gc->finalizer_weakref_metadata = &finalizer_weakref_metadata;
+  return;
+}
+
+void gc_finalizer_weakref_metadata_destruct(GC *gc)
+{
+  Finalizer_Weakref_Metadata *metadata = gc->finalizer_weakref_metadata;
+  
+  sync_pool_destruct(metadata->free_pool);
+  sync_pool_destruct(metadata->objects_with_finalizer_pool);
+  sync_pool_destruct(metadata->finalizable_objects_pool);
+  sync_pool_destruct(metadata->softref_set_pool);
+  sync_pool_destruct(metadata->weakref_set_pool);
+  sync_pool_destruct(metadata->phanref_set_pool);
+  sync_pool_destruct(metadata->repset_pool);
+  
+  metadata->finalizable_objects = NULL;
+  metadata->repset = NULL;
+  
+  for(unsigned int i=0; i<metadata->next_segment_pos; i++){
+    assert(metadata->pool_segments[i]);
+    STD_FREE(metadata->pool_segments[i]);
+  }
+  
+  gc->finalizer_weakref_metadata = NULL;
+}
+
+void gc_finalizer_weakref_metadata_verify(GC *gc, Boolean is_before_gc)
+{
+  Finalizer_Weakref_Metadata *metadata = gc->finalizer_weakref_metadata;
+  
+  assert(pool_is_empty(metadata->finalizable_objects_pool));
+  assert(pool_is_empty(metadata->softref_set_pool));
+  assert(pool_is_empty(metadata->weakref_set_pool));
+  assert(pool_is_empty(metadata->phanref_set_pool));
+  assert(pool_is_empty(metadata->repset_pool));
+  assert(metadata->finalizable_objects == NULL);
+  assert(metadata->repset == NULL);
+  
+  return;
+}
+
+void gc_reset_finalizer_weakref_metadata(GC *gc)
+{
+  Finalizer_Weakref_Metadata *metadata = gc->finalizer_weakref_metadata;
+  Pool *objects_with_finalizer_pool = metadata->objects_with_finalizer_pool;
+  Pool *finalizable_objects_pool = metadata->finalizable_objects_pool;
+  
+  assert(pool_is_empty(finalizable_objects_pool));
+  assert(pool_is_empty(metadata->softref_set_pool));
+  assert(pool_is_empty(metadata->weakref_set_pool));
+  assert(pool_is_empty(metadata->phanref_set_pool));
+  assert(pool_is_empty(metadata->repset_pool));
+  assert(metadata->finalizable_objects == NULL);
+  assert(metadata->repset == NULL);
+  
+  while(Vector_Block *block = pool_get_entry(objects_with_finalizer_pool)){
+    unsigned int *iter = vector_block_iterator_init(block);
+    if(vector_block_iterator_end(block, iter)){
+      vector_block_clear(block);
+      pool_put_entry(metadata->free_pool, block);
+    } else {
+      pool_put_entry(finalizable_objects_pool, block);
+    }
+  }
+  assert(pool_is_empty(objects_with_finalizer_pool));
+  metadata->objects_with_finalizer_pool = finalizable_objects_pool;
+  metadata->finalizable_objects_pool = objects_with_finalizer_pool;
+}
+
+/* called when there is no Vector_Block in finalizer_weakref_metadata->free_pool
+ * extend the pool by a pool segment
+ */
+static void gc_finalizer_weakref_metadata_extend(void)
+{
+  Finalizer_Weakref_Metadata metadata = finalizer_weakref_metadata;
+  
+  unsigned int segment_pos = metadata.next_segment_pos;
+  while(segment_pos < POOL_SEGMENT_NUM){
+    unsigned int next_segment_pos = segment_pos + 1;
+    unsigned int temp = (unsigned int)atomic_cas32((volatile unsigned int *)&metadata.next_segment_pos, next_segment_pos, segment_pos);
+    if(temp == segment_pos)
+      break;
+    segment_pos = metadata.next_segment_pos;
+  }
+  if(segment_pos > POOL_SEGMENT_NUM)
+    return;
+  
+  void *pool_segment = STD_MALLOC(POOL_SEGMENT_SIZE_BYTES);
+  memset(pool_segment, 0, POOL_SEGMENT_SIZE_BYTES);
+  metadata.pool_segments[segment_pos] = pool_segment;
+  
+  unsigned int num_blocks =  POOL_SEGMENT_SIZE_BYTES >> METADATA_BLOCK_SIZE_BIT_SHIFT;
+  for(unsigned int i=0; i<num_blocks; i++){
+    Vector_Block *block = (Vector_Block *)((unsigned int)pool_segment + i*METADATA_BLOCK_SIZE_BYTES);
+    vector_block_init(block, METADATA_BLOCK_SIZE_BYTES);
+    assert(vector_block_is_empty((Vector_Block *)block));
+    pool_put_entry(metadata.free_pool, (void *)block);
+  }
+  
+  return;
+}
+
+Vector_Block *finalizer_weakref_get_free_block(void)
+{
+  Vector_Block *block;
+  
+  while(!(block = pool_get_entry(finalizer_weakref_metadata.free_pool)))
+    gc_finalizer_weakref_metadata_extend();
+  return block;
+}
+
+/* called when GC completes and there is no Vector_Block in the last five pools of gc->finalizer_weakref_metadata
+ * shrink the free pool by half
+ */
+void gc_finalizer_weakref_metadata_shrink(GC *gc)
+{
+}
+
+static inline void finalizer_weakref_metadata_general_add_entry(Vector_Block* &vector_block_in_use, Pool *pool, Partial_Reveal_Object *ref)
+{
+  assert(vector_block_in_use);
+  assert(ref);
+
+  Vector_Block* block = vector_block_in_use;
+  vector_block_add_entry(block, (unsigned int)ref);
+  
+  if(!vector_block_is_full(block)) return;
+  
+  pool_put_entry(pool, block);
+  vector_block_in_use = finalizer_weakref_get_free_block();
+}
+
+void mutator_finalizer_add_entry(Mutator *mutator, Partial_Reveal_Object *ref)
+{
+  finalizer_weakref_metadata_general_add_entry(mutator->objects_with_finalizer, finalizer_weakref_metadata.objects_with_finalizer_pool, ref);
+}
+
+void gc_finalizable_objects_add_entry(GC *gc, Partial_Reveal_Object *ref)
+{
+  finalizer_weakref_metadata_general_add_entry(finalizer_weakref_metadata.finalizable_objects, finalizer_weakref_metadata.finalizable_objects_pool, ref);
+}
+
+void collector_softref_set_add_entry(Collector *collector, Partial_Reveal_Object *ref)
+{
+  finalizer_weakref_metadata_general_add_entry(collector->softref_set, finalizer_weakref_metadata.softref_set_pool, ref);
+}
+
+void collector_weakref_set_add_entry(Collector *collector, Partial_Reveal_Object *ref)
+{
+  finalizer_weakref_metadata_general_add_entry(collector->weakref_set, finalizer_weakref_metadata.weakref_set_pool, ref);
+}
+
+void collector_phanref_set_add_entry(Collector *collector, Partial_Reveal_Object *ref)
+{
+  finalizer_weakref_metadata_general_add_entry(collector->phanref_set, finalizer_weakref_metadata.phanref_set_pool, ref);
+}
+
+void finalizer_weakref_repset_add_entry(GC *gc, Partial_Reveal_Object **p_ref)
+{
+  assert(*p_ref);
+  finalizer_weakref_metadata_general_add_entry(finalizer_weakref_metadata.repset, finalizer_weakref_metadata.repset_pool, (Partial_Reveal_Object *)p_ref);
+}
+
+static inline Boolean pool_has_no_reference(Pool *pool)
+{
+  if(pool_is_empty(pool))
+    return TRUE;
+  pool_iterator_init(pool);
+  while(Vector_Block *block = pool_iterator_next(pool)){
+    unsigned int *iter = vector_block_iterator_init(block);
+    while(!vector_block_iterator_end(block, iter)){
+      if(*iter)
+        return FALSE;
+      iter = vector_block_iterator_advance(block, iter);
+    }
+  }
+  return TRUE;
+}
+
+Boolean objects_with_finalizer_pool_is_empty(GC *gc)
+{
+  return pool_has_no_reference(gc->finalizer_weakref_metadata->objects_with_finalizer_pool);
+}
+
+Boolean finalizable_objects_pool_is_empty(GC *gc)
+{
+  return pool_has_no_reference(gc->finalizer_weakref_metadata->finalizable_objects_pool);
+}
+
+Boolean softref_set_pool_is_empty(GC *gc)
+{
+  return pool_has_no_reference(gc->finalizer_weakref_metadata->softref_set_pool);
+}
+
+Boolean weakref_set_pool_is_empty(GC *gc)
+{
+  return pool_has_no_reference(gc->finalizer_weakref_metadata->weakref_set_pool);
+}
+
+Boolean phanref_set_pool_is_empty(GC *gc)
+{
+  return pool_has_no_reference(gc->finalizer_weakref_metadata->phanref_set_pool);
+}
+
+Boolean finalizer_weakref_repset_pool_is_empty(GC *gc)
+{
+  return pool_has_no_reference(gc->finalizer_weakref_metadata->repset_pool);
+}
+
+static inline void finalizer_weakref_metadata_clear_pool(Pool *pool)
+{
+  while(Vector_Block* block = pool_get_entry(pool))
+  {
+    vector_block_clear(block);
+    pool_put_entry(finalizer_weakref_metadata.free_pool, block);
+  }
+}
+
+void gc_clear_special_reference_pools(GC *gc)
+{
+  finalizer_weakref_metadata_clear_pool(gc->finalizer_weakref_metadata->softref_set_pool);
+  finalizer_weakref_metadata_clear_pool(gc->finalizer_weakref_metadata->weakref_set_pool);
+  finalizer_weakref_metadata_clear_pool(gc->finalizer_weakref_metadata->phanref_set_pool);
+}

Added: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.h?view=auto&rev=486200
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.h Tue Dec 12 07:59:15 2006
@@ -0,0 +1,116 @@
+/*
+ *  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 Li-Gang Wang, 2006/11/29
+ */
+
+#ifndef _FINALIZER_WEAKREF_METADATA_H_
+#define _FINALIZER_WEAKREF_METADATA_H_
+
+#include "../common/gc_common.h"
+#include "../utils/vector_block.h"
+#include "../utils/sync_pool.h"
+
+#define POOL_SEGMENT_NUM 256
+
+typedef struct Finalizer_Weakref_Metadata{
+  void *pool_segments[POOL_SEGMENT_NUM];  // malloced free pool segments' addresses array
+  unsigned int next_segment_pos;          // next available position in pool_segments array
+  
+  Pool *free_pool;                        // list of free buffers for the five pools below
+  
+  Pool *objects_with_finalizer_pool;      // list of objects that have finalizer;
+                                          // these objects are added in when they are allocated
+  Pool *finalizable_objects_pool;         // temporary buffer for finalizable objects identified during one single GC
+  
+  Pool *softref_set_pool;                 // temporary buffer for soft references identified during one single GC
+  Pool *weakref_set_pool;                 // temporary buffer for weak references identified during one single GC
+  Pool *phanref_set_pool;                 // temporary buffer for phantom references identified during one single GC
+  
+  Pool *repset_pool;                      // repointed reference slot sets
+  
+  Vector_Block *finalizable_objects;      // buffer for finalizable_objects_pool
+  Vector_Block *repset;                   // buffer for repset_pool
+  
+  Boolean pending_finalizers;             // there are objects waiting to be finalized
+  Boolean pending_weak_references;        // there are weak references waiting to be enqueued
+  
+  unsigned int gc_referent_offset;        // the referent field's offset in Reference Class
+}Finalizer_Weakref_Metadata;
+
+extern unsigned int get_gc_referent_offset(void);
+extern void set_gc_referent_offset(unsigned int offset);
+
+extern void gc_finalizer_weakref_metadata_initialize(GC *gc);
+extern void gc_finalizer_weakref_metadata_destruct(GC *gc);
+extern void gc_finalizer_weakref_metadata_verify(GC *gc, Boolean is_before_gc);
+extern void gc_reset_finalizer_weakref_metadata(GC *gc);
+extern Vector_Block *finalizer_weakref_get_free_block(void);
+extern void gc_finalizer_weakref_metadata_shrink(GC *gc);
+
+extern void mutator_finalizer_add_entry(Mutator *mutator, Partial_Reveal_Object *ref);
+extern void gc_finalizable_objects_add_entry(GC *gc, Partial_Reveal_Object *ref);
+extern void collector_softref_set_add_entry(Collector *collector, Partial_Reveal_Object *ref);
+extern void collector_weakref_set_add_entry(Collector *collector, Partial_Reveal_Object *ref);
+extern void collector_phanref_set_add_entry(Collector *collector, Partial_Reveal_Object *ref);
+extern void finalizer_weakref_repset_add_entry(GC *gc, Partial_Reveal_Object **ref);
+
+extern Boolean objects_with_finalizer_pool_is_empty(GC *gc);
+extern Boolean finalizable_objects_pool_is_empty(GC *gc);
+extern Boolean softref_set_pool_is_empty(GC *gc);
+extern Boolean weakref_set_pool_is_empty(GC *gc);
+extern Boolean phanref_set_pool_is_empty(GC *gc);
+extern Boolean finalizer_weakref_repset_pool_is_empty(GC *gc);
+
+extern void gc_clear_special_reference_pools(GC *gc);
+
+
+/* called before loop of recording finalizable objects */
+inline void gc_reset_finalizable_objects(GC *gc)
+{
+  Finalizer_Weakref_Metadata *metadata = gc->finalizer_weakref_metadata;
+  
+  assert(!metadata->finalizable_objects);
+  metadata->finalizable_objects = pool_get_entry(metadata->free_pool);
+}
+/* called after loop of recording finalizable objects */
+inline void gc_put_finalizable_objects(GC *gc)
+{
+  Finalizer_Weakref_Metadata *metadata = gc->finalizer_weakref_metadata;
+  
+  pool_put_entry(metadata->finalizable_objects_pool, metadata->finalizable_objects);
+  metadata->finalizable_objects = NULL;
+}
+
+/* called before loop of recording repointed reference */
+inline void finalizer_weakref_reset_repset(GC *gc)
+{
+  Finalizer_Weakref_Metadata *metadata = gc->finalizer_weakref_metadata;
+  
+  assert(!metadata->repset);
+  metadata->repset = pool_get_entry(metadata->free_pool);
+}
+/* called after loop of recording repointed reference */
+inline void finalizer_weakref_put_repset(GC *gc)
+{
+  Finalizer_Weakref_Metadata *metadata = gc->finalizer_weakref_metadata;
+  
+  pool_put_entry(metadata->repset_pool, metadata->repset);
+  metadata->repset = NULL;
+}
+
+#endif // _FINALIZER_WEAKREF_METADATA_H_

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp?view=diff&rev=486200&r1=486199&r2=486200
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp Tue Dec 12 07:59:15 2006
@@ -100,6 +100,10 @@
   gc_gen->committed_heap_size = space_committed_size((Space*)gc_gen->nos) +
                                 space_committed_size((Space*)gc_gen->mos) +
                                 space_committed_size((Space*)gc_gen->los);
+  
+  set_native_finalizer_thread_flag(TRUE);
+  set_native_ref_enqueue_thread_flag(TRUE);
+  
   return;
 }
 

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h?view=diff&rev=486200&r1=486199&r2=486200
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h Tue Dec 12 07:59:15 2006
@@ -26,6 +26,7 @@
 #include "../trace_forward/fspace.h"
 #include "../mark_compact/mspace.h"
 #include "../mark_sweep/lspace.h"
+#include "../finalizer_weakref/finalizer_weakref_metadata.h"
   
 enum Write_Barrier_Kind{
   WRITE_BARRIER_NIL,  
@@ -64,6 +65,7 @@
 
   /* metadata is the pool for rootset, markstack, etc. */  
   GC_Metadata* metadata;
+  Finalizer_Weakref_Metadata *finalizer_weakref_metadata;
   unsigned int collect_kind; /* MAJOR or MINOR */
   /* FIXME:: this is wrong! root_set belongs to mutator */
   Vector_Block* root_set;

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect_compact.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect_compact.cpp?view=diff&rev=486200&r1=486199&r2=486200
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect_compact.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect_compact.cpp Tue Dec 12 07:59:15 2006
@@ -21,6 +21,7 @@
 #include "mspace.h"
 #include "../thread/collector.h"
 #include "../trace_forward/fspace.h"
+#include "../finalizer_weakref/finalizer_weakref.h"
 
 struct GC_Gen;
 Space* gc_get_nos(GC_Gen* gc);
@@ -331,6 +332,9 @@
     /* last collector's world here */
     /* prepare for next phase */
     gc_init_block_for_collectors(gc, mspace); 
+    
+    collector_process_finalizer_weakref(collector);
+    
     /* let other collectors go */
     num_marking_collectors++; 
   }
@@ -360,6 +364,8 @@
     
   /* Pass 3: update all references whose objects are to be moved */  
   gc_update_repointed_refs(collector);
+  
+  gc_post_process_finalizer_weakref(gc);
     
   /* Pass 4: do the compaction and reset blocks */  
   next_block_for_compact = mspace_get_first_compact_block(mspace);

Added: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/free_area_pool.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/free_area_pool.cpp?view=auto&rev=486200
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/free_area_pool.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/free_area_pool.cpp Tue Dec 12 07:59:15 2006
@@ -0,0 +1,67 @@
+/*
+ *  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 Ji Qi, 2006/10/05
+ */
+
+#include "free_area_pool.h"
+
+void free_area_pool_init(Free_Area_Pool* pool)
+{
+  for(unsigned int i = 0; i < NUM_FREE_LIST; i ++){
+    Bidir_List* list = &pool->sized_area_list[i];
+    list->next = list->prev = list;
+  }
+  
+  memset((void*)pool->list_bit_flag, 0, NUM_FLAG_WORDS << BIT_SHIFT_TO_BYTES_PER_WORD);
+  pool->free_pool_lock = 0;
+  return;
+}
+
+void free_area_pool_reset(Free_Area_Pool* pool)
+{
+  free_area_pool_init(pool);
+}
+
+Free_Area* free_pool_find_size_area(Free_Area_Pool* pool, unsigned int size)
+{
+  assert(size >= GC_OBJ_SIZE_THRESHOLD);
+  
+  size = ALIGN_UP_TO_KILO(size);
+  unsigned int index = pool_list_index_with_size(size);
+  /* Get first list index that is not empty */
+  index = pool_list_get_next_flag(pool, index);
+  assert(index <= NUM_FREE_LIST);
+  
+  /*No free area left*/
+  if(index == NUM_FREE_LIST) 
+  return NULL; 
+  
+  Bidir_List* list = &pool->sized_area_list[index];
+  Free_Area* area = (Free_Area*)list->next;
+  
+  if(index != MAX_LIST_INDEX)
+  return area;
+  
+  /* Else, for last bucket MAX_LIST_INDEX, we must traverse it */
+  while(  area != (Free_Area*)list ){
+    if(area->size >= size)	return area;
+    area = (Free_Area*)(area->next);
+  }
+  
+  return NULL;
+}

Added: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/free_area_pool.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/free_area_pool.h?view=auto&rev=486200
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/free_area_pool.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/free_area_pool.h Tue Dec 12 07:59:15 2006
@@ -0,0 +1,119 @@
+/*
+ *  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 Ji Qi, 2006/10/05
+ */
+
+#ifndef _BUDDY_H_
+#define _BUDDY_H_
+
+#include "../common/gc_common.h"
+#include "../utils/bit_ops.h"
+#include "../utils/bidir_list.h"
+
+#define ADDRESS_IS_KB_ALIGNED(addr) (!(((unsigned int)addr) & ((1 << BIT_SHIFT_TO_KILO)-1)))
+#define ALIGN_UP_TO_KILO(addr) (((unsigned int)(addr) + (KB - 1)) & (~(KB- 1)))
+#define ALIGN_DOWN_TO_KILO(addr) ((unsigned int)(addr) & (~(KB- 1)))
+
+#define NUM_FREE_LIST 128
+
+typedef struct Free_Area{
+  /* <-- First couple of fields overloadded as Bidir_List */
+  Bidir_List* next;
+  Bidir_List* prev;
+  /* END of Bidir_List --> */
+  unsigned int size;
+}Free_Area;
+
+/* this is the only interface for new area creation */
+inline Free_Area* free_area_new(void* start, unsigned int size)
+{
+  assert(ADDRESS_IS_KB_ALIGNED(start));
+  assert(ADDRESS_IS_KB_ALIGNED(size));
+  
+  if( size < GC_OBJ_SIZE_THRESHOLD) return NULL;
+  Free_Area* area = (Free_Area*)start;
+  memset(area, 0, size);
+  area->size = size;
+  return area;
+}
+
+#define NUM_FLAG_WORDS (NUM_FREE_LIST >> BIT_SHIFT_TO_BITS_PER_WORD)
+
+typedef struct Free_Area_Pool{
+  Bidir_List sized_area_list[NUM_FREE_LIST];
+  /* each list corresponds to one bit in below vector */
+  unsigned int list_bit_flag[NUM_FLAG_WORDS];
+  volatile unsigned int free_pool_lock;
+}Free_Area_Pool;
+
+#define MAX_LIST_INDEX (NUM_FREE_LIST - 1)
+
+inline void pool_list_set_flag(Free_Area_Pool* pool, unsigned int index)
+{
+  words_set_bit(pool->list_bit_flag, NUM_FLAG_WORDS, index);
+}
+
+inline void pool_list_clear_flag(Free_Area_Pool* pool, unsigned int index)
+{
+  words_clear_bit(pool->list_bit_flag, NUM_FLAG_WORDS, index);
+}
+
+inline unsigned int pool_list_get_next_flag(Free_Area_Pool* pool, unsigned int start_idx)
+{
+  return words_get_next_set_lsb(pool->list_bit_flag, NUM_FLAG_WORDS, start_idx);
+}
+
+inline unsigned int pool_list_index_with_size(unsigned int size)
+{
+  assert(size >= GC_OBJ_SIZE_THRESHOLD);
+  
+  unsigned int index;
+  index = size >> BIT_SHIFT_TO_KILO;
+  if(index > MAX_LIST_INDEX) index = MAX_LIST_INDEX;
+  return index;
+}
+
+inline Free_Area* free_pool_add_area(Free_Area_Pool* pool, Free_Area* free_area)
+{
+  assert( free_area->size >= GC_OBJ_SIZE_THRESHOLD);
+  
+  unsigned int index = pool_list_index_with_size(free_area->size);
+  bidir_list_add_item(&(pool->sized_area_list[index]), (Bidir_List*)free_area);
+  
+  /* set bit flag of the list */
+  pool_list_set_flag(pool, index);
+  return free_area;
+}
+
+inline void free_pool_remove_area(Free_Area_Pool* pool, Free_Area* free_area)
+{
+  unsigned int index = pool_list_index_with_size(free_area->size);
+  bidir_list_remove_item((Bidir_List*)free_area);
+  
+  /* set bit flag of the list */
+  Bidir_List* list = &(pool->sized_area_list[index]);
+  if(list->next == list){
+  	pool_list_clear_flag(pool, index);		
+  }
+}
+
+void free_area_pool_init(Free_Area_Pool* p_buddy);
+void free_area_pool_reset(Free_Area_Pool* p_buddy);
+Free_Area* free_pool_find_size_area(Free_Area_Pool* pool, unsigned int size);
+
+#endif /*ifdef _BUDDY_H_*/

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.cpp?view=diff&rev=486200&r1=486199&r2=486200
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.cpp Tue Dec 12 07:59:15 2006
@@ -15,76 +15,50 @@
  */
 
 /**
- * @author Xiao-Feng Li, 2006/10/05
+ * @author Ji Qi, 2006/10/05
  */
 
 #include "lspace.h"
 
 void* los_boundary = NULL;
 struct GC_Gen;
-Space* gc_get_los(GC_Gen* gc);
 void gc_set_los(GC_Gen* gc, Space* lspace);
-void* lspace_alloc(unsigned int size, Allocator *allocator)
-{  
-  Lspace* lspace = (Lspace*)gc_get_los((GC_Gen*)allocator->gc);
-  
-  unsigned int old_free = (unsigned int)lspace->alloc_free;
-  unsigned int new_free = old_free + size;
-
-  while(new_free <= (unsigned int)lspace->heap_end){
-    unsigned int temp = atomic_cas32((volatile unsigned int *)&lspace->alloc_free, new_free, old_free);
-    if (temp != old_free) {
-      old_free = (unsigned int)lspace->alloc_free;
-      new_free = old_free + size;
-      continue;
-    }
-    /* successfully allocate an object */
-    Partial_Reveal_Object* p_return_object = (Partial_Reveal_Object*)old_free;
-    lspace->alloc_free = (void*)new_free;
-
-    /* TODO: should moved to better location */
-    memset(p_return_object, 0, size);
-    
-    return (void*)old_free;
-  }
-
-  /* FIXME:: trigger collection */
-  assert(0);
-  return NULL;
-
-}
 
 void lspace_initialize(GC* gc, void* start, unsigned int lspace_size)
 {
   Lspace* lspace = (Lspace*)STD_MALLOC( sizeof(Lspace));
   assert(lspace);
   memset(lspace, 0, sizeof(Lspace));
-  
+
   void* reserved_base = start;
   unsigned int committed_size = lspace_size;
   int status = port_vmem_commit(&reserved_base, committed_size, gc->allocated_memory); 
   assert(status == APR_SUCCESS && reserved_base == start);
-  
+
   memset(reserved_base, 0, committed_size);
   lspace->committed_heap_size = committed_size;
   lspace->reserved_heap_size = lspace_size - committed_size;
   lspace->heap_start = reserved_base;
   lspace->heap_end = (void *)((unsigned int)reserved_base + committed_size);
-  lspace->alloc_free = reserved_base;
-  
-  unsigned int num_bits = (lspace_size >> BIT_SHIFT_TO_KILO) + 1;
-  unsigned int num_words = (num_bits >> BIT_SHIFT_TO_BITS_PER_WORD)+1;
+
+  /*Treat with mark bit table*/
+  unsigned int num_words = LSPACE_SIZE_TO_MARKTABLE_SIZE_WORDS(lspace_size);
   lspace->mark_table = (unsigned int*)STD_MALLOC( num_words*BYTES_PER_WORD );
   memset(lspace->mark_table, 0, num_words*BYTES_PER_WORD);
-  
   lspace->mark_object_func = lspace_mark_object;
-  
   lspace->move_object = FALSE;
   lspace->gc = gc;
+
+  /*Treat with free area buddies*/
+  lspace->free_pool = (Free_Area_Pool*)STD_MALLOC(sizeof(Free_Area_Pool));
+  free_area_pool_init(lspace->free_pool);
+  Free_Area* initial_fa = (Free_Area*)lspace->heap_start;
+  initial_fa->size = lspace->committed_heap_size;
+  free_pool_add_area(lspace->free_pool, initial_fa);
+
   gc_set_los((GC_Gen*)gc, (Space*)lspace);
-  
   los_boundary = lspace->heap_end;
-  
+
   return;
 }
 
@@ -97,40 +71,40 @@
   return;
 }
 
-void lspace_collection(Lspace* lspace)
-{
-  /* FIXME:: collection */
-  unsigned int used_size = (unsigned int)lspace->alloc_free - (unsigned int)lspace->heap_start;
-  memset(lspace->mark_table, 0, (((used_size>>BIT_SHIFT_TO_KILO) + 1)>>BIT_SHIFT_TO_BITS_PER_BYTE) + 1);
-  
-  return;
-}
-
-void reset_lspace_after_copy_nursery(Lspace* lspace)
-{
-  unsigned int used_size = (unsigned int)lspace->alloc_free - (unsigned int)lspace->heap_start;
-  memset(lspace->mark_table, 0, (used_size>>BIT_SHIFT_TO_KILO)>>BIT_SHIFT_TO_BITS_PER_BYTE );
-  return;  
-}
-
-
 Boolean lspace_mark_object(Lspace* lspace, Partial_Reveal_Object* p_obj)
 {
   assert( obj_belongs_to_space(p_obj, (Space*)lspace));
   unsigned int word_index = OBJECT_WORD_INDEX_TO_LSPACE_MARKBIT_TABLE(lspace, p_obj);
   unsigned int bit_offset_in_word = OBJECT_WORD_OFFSET_IN_LSPACE_MARKBIT_TABLE(lspace, p_obj);
- 
+
   unsigned int* p_word = &(lspace->mark_table[word_index]);
   unsigned int word_mask = (1<<bit_offset_in_word);
-  
+
   unsigned int old_value = *p_word;
   unsigned int new_value = old_value|word_mask;
-  
+
   while(old_value != new_value){
     unsigned int temp = atomic_cas32(p_word, new_value, old_value);
     if(temp == old_value) return TRUE;
     old_value = *p_word;
     new_value = old_value|word_mask;
   }
+
   return FALSE;
+}
+
+void reset_lspace_after_copy_nursery(Lspace* lspace)
+{
+  unsigned int marktable_size = LSPACE_SIZE_TO_MARKTABLE_SIZE_BYTES(lspace->committed_heap_size);
+  memset(lspace->mark_table, 0, marktable_size); 
+  return;  
+}
+
+void lspace_collection(Lspace* lspace)
+{
+  /* heap is marked already, we need only sweep here. */
+  lspace_sweep(lspace);
+  unsigned int marktable_size = LSPACE_SIZE_TO_MARKTABLE_SIZE_BYTES(lspace->committed_heap_size);
+  memset(lspace->mark_table, 0, marktable_size); 
+  return;
 }

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h?view=diff&rev=486200&r1=486199&r2=486200
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h Tue Dec 12 07:59:15 2006
@@ -15,7 +15,7 @@
  */
 
 /**
- * @author Xiao-Feng Li, 2006/10/05
+ * @author Ji Qi, 2006/10/05
  */
 
 #ifndef _LSPACE_H_
@@ -23,6 +23,7 @@
 
 #include "../common/gc_common.h"
 #include "../thread/gc_thread.h"
+#include "free_area_pool.h"
 
 typedef struct Lspace{
   /* <-- first couple of fields are overloadded as Space */
@@ -36,8 +37,9 @@
   Boolean (*mark_object_func)(Lspace* space, Partial_Reveal_Object* p_obj);
   /* END of Space --> */
 
-  void* alloc_free;
-    
+//  void* alloc_free;
+  Free_Area_Pool* free_pool;
+  
   unsigned int* mark_table;
 
 }Lspace;
@@ -45,10 +47,16 @@
 void lspace_initialize(GC* gc, void* reserved_base, unsigned int lspace_size);
 void lspace_destruct(Lspace* lspace);
 Managed_Object_Handle lspace_alloc(unsigned int size, Allocator* allocator);
+void lspace_sweep(Lspace* lspace);
 void lspace_collection(Lspace* lspace);
 
 inline unsigned int lspace_free_memory_size(Lspace* lspace){ /* FIXME:: */ return 0; }
 
+
+#define LSPACE_SIZE_TO_MARKTABLE_SIZE_BITS(space_size) (((space_size) >> BIT_SHIFT_TO_KILO)+1)
+#define LSPACE_SIZE_TO_MARKTABLE_SIZE_BYTES(space_size) ((LSPACE_SIZE_TO_MARKTABLE_SIZE_BITS(space_size)>> BIT_SHIFT_TO_BITS_PER_BYTE)+1) 
+#define LSPACE_SIZE_TO_MARKTABLE_SIZE_WORDS(space_size) ((LSPACE_SIZE_TO_MARKTABLE_SIZE_BYTES(space_size)>> BIT_SHIFT_TO_BYTES_PER_WORD)+1) 
+
 /* The assumption is the offset below is always aligned at word size, because both numbers are aligned */
 #define ADDRESS_OFFSET_IN_LSPACE_BODY(lspace, p_obj) ((unsigned int)p_obj - (unsigned int)space_heap_start((Space*)lspace))
 #define OBJECT_BIT_INDEX_TO_LSPACE_MARKBIT_TABLE(lspace, p_obj)    (ADDRESS_OFFSET_IN_LSPACE_BODY(lspace, p_obj) >> BIT_SHIFT_TO_KILO)
@@ -65,9 +73,62 @@
   return markbits & (1<<bit_offset_in_word);
 }
 
+
+inline Partial_Reveal_Object* lspace_get_first_marked_object(Lspace* lspace, unsigned int* mark_bit_idx)
+{
+  unsigned int* mark_table = lspace->mark_table;
+  unsigned int* table_end = mark_table + LSPACE_SIZE_TO_MARKTABLE_SIZE_WORDS(lspace->committed_heap_size);
+  
+  unsigned j=0;
+  unsigned int k=0;
+  while( (mark_table + j) < table_end){
+    unsigned int markbits = *(mark_table+j);
+    if(!markbits){ j++; continue; }
+    while(k<32){
+        if( !(markbits& (1<<k)) ){ k++; continue;}
+        unsigned int kilo_bytes_index = (j<<BIT_SHIFT_TO_BITS_PER_WORD) + k;
+        Partial_Reveal_Object* p_obj = (Partial_Reveal_Object*)((char*)lspace->heap_start + kilo_bytes_index * KB);
+        *mark_bit_idx = kilo_bytes_index;
+        return p_obj;
+    }
+    j++;
+    k=0;
+  }          
+  *mark_bit_idx = 0;
+  return NULL;   
+}
+
+
+inline Partial_Reveal_Object* lspace_get_next_marked_object(Lspace* lspace, unsigned int* mark_bit_idx)
+{
+  unsigned int* mark_table = lspace->mark_table;
+  unsigned int* table_end = mark_table + LSPACE_SIZE_TO_MARKTABLE_SIZE_WORDS(lspace->committed_heap_size);
+  unsigned int bit_index = *mark_bit_idx;
+  
+  unsigned int j = bit_index >> BIT_SHIFT_TO_BITS_PER_WORD;
+  unsigned int k = (bit_index & BIT_MASK_TO_BITS_PER_WORD) + 1;  
+     
+  while( (mark_table + j) < table_end){
+    unsigned int markbits = *(mark_table+j);
+    if(!markbits){ j++; continue; }
+    while(k<32){
+      if( !(markbits& (1<<k)) ){ k++; continue;}
+      
+      unsigned int kilo_byte_index = (j<<BIT_SHIFT_TO_BITS_PER_WORD) + k;
+      Partial_Reveal_Object* p_obj = (Partial_Reveal_Object*)((char*)lspace->heap_start + kilo_byte_index *  KB);      
+      *mark_bit_idx = kilo_byte_index;
+      return p_obj;
+    }
+    j++;
+    k=0;
+  }        
+  
+  *mark_bit_idx = 0;
+  return NULL;   
+
+}
+
 Boolean lspace_mark_object(Lspace* lspace, Partial_Reveal_Object* p_obj);
-void lspace_save_reloc(Lspace* space, Partial_Reveal_Object** p_ref);
-void lspace_update_reloc(Lspace* lspace);
 
 void reset_lspace_after_copy_nursery(Lspace* lspace);
 

Added: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace_alloc_collect.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace_alloc_collect.cpp?view=auto&rev=486200
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace_alloc_collect.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace_alloc_collect.cpp Tue Dec 12 07:59:15 2006
@@ -0,0 +1,111 @@
+/*
+ *  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 Ji Qi, 2006/10/05
+ */
+
+#include "lspace.h"
+struct GC_Gen;
+Space* gc_get_los(GC_Gen* gc);
+
+void* lspace_alloc(unsigned int size, Allocator *allocator)
+{
+  vm_gc_lock_enum();
+  unsigned int try_count = 0;
+  Lspace* lspace = (Lspace*)gc_get_los((GC_Gen*)allocator->gc);
+  Free_Area_Pool* pool = lspace->free_pool;
+  Free_Area* free_area;
+  Free_Area* remain_area;
+  void* p_return = NULL;
+
+  while( try_count < 2 ){
+    free_area = free_pool_find_size_area(pool, size);
+    
+    /*Got one free area!*/
+    if(free_area != NULL){
+      assert(free_area->size >= size);
+      free_pool_remove_area(pool, free_area);
+      p_return = (void*)free_area;
+      unsigned int old_size = free_area->size;
+      memset(p_return, 0, sizeof(Free_Area));
+
+      /* we need put the remaining area back if it size is ok.*/
+      void* new_start = (Free_Area*)ALIGN_UP_TO_KILO(((unsigned int)free_area + size));
+      unsigned int alloc_size = (unsigned int)new_start - (unsigned int)free_area;
+      unsigned int new_size = old_size - alloc_size;
+      
+      remain_area = free_area_new(new_start, new_size);
+      if( remain_area )
+        free_pool_add_area(pool, remain_area);
+
+      vm_gc_unlock_enum();
+      return p_return;
+    }
+
+    if(try_count++ == 0) 
+      gc_reclaim_heap(allocator->gc, GC_CAUSE_LOS_IS_FULL);
+
+  }
+
+  vm_gc_unlock_enum();
+  return NULL;
+}
+
+void lspace_sweep(Lspace* lspace)
+{
+  /* reset the pool first because its info is useless now. */
+  free_area_pool_reset(lspace->free_pool);
+
+  unsigned int mark_bit_idx, cur_size;
+  void *cur_area_start, *cur_area_end;
+
+
+
+  Partial_Reveal_Object* p_prev_obj = (Partial_Reveal_Object *)lspace->heap_start;
+  Partial_Reveal_Object* p_next_obj = lspace_get_first_marked_object(lspace, &mark_bit_idx);
+
+  cur_area_start = (void*)ALIGN_UP_TO_KILO(p_prev_obj);
+  cur_area_end = (void*)ALIGN_DOWN_TO_KILO(p_next_obj);
+
+
+  while(cur_area_end){
+    cur_size = (unsigned int)cur_area_end - (unsigned int)cur_area_start;
+      
+    Free_Area* cur_area = free_area_new(cur_area_start, cur_size);
+    /* successfully create an area */
+    if( cur_area )
+      free_pool_add_area(lspace->free_pool, cur_area);
+
+    p_prev_obj = p_next_obj;
+    p_next_obj = lspace_get_next_marked_object(lspace, &mark_bit_idx);
+
+    cur_area_start = (void*)ALIGN_UP_TO_KILO((unsigned int)p_prev_obj + vm_object_size(p_prev_obj));
+    cur_area_end = (void*)ALIGN_DOWN_TO_KILO(p_next_obj);
+    
+  }
+
+   /* cur_area_end == NULL */
+  cur_area_end = (void*)ALIGN_DOWN_TO_KILO(lspace->heap_end);
+  cur_size = (unsigned int)cur_area_end - (unsigned int)cur_area_start;
+  Free_Area* cur_area = free_area_new(cur_area_start, cur_size);
+  /* successfully create an area */
+  if( cur_area )
+    free_pool_add_area(lspace->free_pool, cur_area);
+
+   return;
+
+}

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector.cpp?view=diff&rev=486200&r1=486199&r2=486200
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector.cpp Tue Dec 12 07:59:15 2006
@@ -22,6 +22,7 @@
 
 #include "collector.h"
 #include "../mark_compact/mspace.h"
+#include "../finalizer_weakref/finalizer_weakref.h"
 
 
 static void collector_restore_obj_info(Collector* collector)
@@ -70,6 +71,8 @@
     assert(collector->rem_set==NULL);
     collector->rem_set = pool_get_entry(metadata->free_set_pool);
   }
+  
+  collector_reset_weakref_sets(collector);
 
   collector->result = TRUE;
   return;

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector.h?view=diff&rev=486200&r1=486199&r2=486200
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector.h Tue Dec 12 07:59:15 2006
@@ -42,6 +42,10 @@
   Vector_Block* rep_set; /* repointed set */
   Vector_Block* rem_set;
   
+  Vector_Block *softref_set;
+  Vector_Block *weakref_set;
+  Vector_Block *phanref_set;
+  
   VmEventHandle task_assigned_event;
   VmEventHandle task_finished_event;
   

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector_alloc.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector_alloc.cpp?view=diff&rev=486200&r1=486199&r2=486200
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector_alloc.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector_alloc.cpp Tue Dec 12 07:59:15 2006
@@ -32,25 +32,26 @@
      assert(!obj_is_marked_in_vt(p_obj));
      return NULL;
   }
-  /* otherwise, get the obj size firstly. The work below will destroy its vtable. */
+  
+  /* otherwise, try to alloc it. mos should always has enough space to hold nos during collection */
   unsigned int size = vm_object_size(p_obj);
+  Partial_Reveal_Object* p_targ_obj = (Partial_Reveal_Object*)mos_alloc(size, (Allocator*)collector);  
+  assert(p_targ_obj); 
     
   /* 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. */
-  if ((unsigned int)vt != atomic_cas32((unsigned int*)obj_get_vtraw_addr(p_obj), ((unsigned int)FORWARDING_BIT_MASK), (unsigned int)vt)) {
-    /* forwarded by other */
+  if ((unsigned int)vt != atomic_cas32((unsigned int*)obj_get_vtraw_addr(p_obj), ((unsigned int)p_targ_obj|FORWARDING_BIT_MASK), (unsigned int)vt)) {
+    /* 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. */
     assert( obj_is_forwarded_in_vt(p_obj) && !obj_is_marked_in_vt(p_obj));
+    thread_local_unalloc(size, (Allocator*)collector);
     return NULL;
   }
 
-  /* we hold the object, now forward it */
-  Partial_Reveal_Object* p_targ_obj = (Partial_Reveal_Object*)mos_alloc(size, (Allocator*)collector);  
-  /* mos should always has enough space to hold nos during collection */
-  assert(p_targ_obj); 
+  /* we forwarded the object */
   memcpy(p_targ_obj, p_obj, size);
-
-  /* because p_obj has forwarding flag in its vt, we set it here */
-  obj_set_forwarding_pointer_in_vt(p_obj, p_targ_obj);
+  /* because p_obj has forwarding pointer in its vt, we set it seperately here */
   obj_set_vt(p_targ_obj, (Allocation_Handle)vt);
   
   return p_targ_obj;  

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.h?view=diff&rev=486200&r1=486199&r2=486200
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.h Tue Dec 12 07:59:15 2006
@@ -48,6 +48,13 @@
   VmThreadHandle thread_handle;   /* This thread; */
 }Allocator;
 
+inline void thread_local_unalloc(unsigned int size, Allocator* allocator)
+{
+    void* free = allocator->free;    
+    allocator->free = (void*)((unsigned int)free - size);
+    return;
+}
+
 inline Partial_Reveal_Object* thread_local_alloc(unsigned int size, Allocator* allocator)
 {
     void* free = allocator->free;

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator.cpp?view=diff&rev=486200&r1=486199&r2=486200
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator.cpp Tue Dec 12 07:59:15 2006
@@ -20,6 +20,7 @@
 
 #include "mutator.h"
 #include "../trace_forward/fspace.h"
+#include "../finalizer_weakref/finalizer_weakref.h"
 
 struct GC_Gen;
 Space* gc_get_nos(GC_Gen* gc);
@@ -37,6 +38,8 @@
     mutator->rem_set = pool_get_entry(gc->metadata->free_set_pool);
     assert(vector_block_is_empty(mutator->rem_set));
   }
+  
+  mutator->objects_with_finalizer = finalizer_weakref_get_free_block();
        
   lock(gc->mutator_list_lock);     // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
 
@@ -61,6 +64,11 @@
     pool_put_entry(gc->metadata->mutator_remset_pool, mutator->rem_set);
     mutator->rem_set = NULL;
   }
+  
+  if(mutator->objects_with_finalizer){
+    pool_put_entry(gc->finalizer_weakref_metadata->objects_with_finalizer_pool, mutator->objects_with_finalizer);
+    mutator->objects_with_finalizer = NULL;
+  }
 
   lock(gc->mutator_list_lock);     // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
 
@@ -90,6 +98,7 @@
   while (mutator) {
     mutator->rem_set = pool_get_entry(gc->metadata->free_set_pool);
     alloc_context_reset((Allocator*)mutator);    
+    mutator_reset_objects_with_finalizer(mutator);
     mutator = mutator->next;
   }  
   return;

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator.h?view=diff&rev=486200&r1=486199&r2=486200
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator.h Tue Dec 12 07:59:15 2006
@@ -35,6 +35,7 @@
   /* END of Allocator --> */
   
   Vector_Block* rem_set;
+  Vector_Block* objects_with_finalizer;
   Mutator* next;  /* The gc info area associated with the next active thread. */
 } Mutator;