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/10/27 05:48:44 UTC

svn commit: r468252 [1/2] - in /incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src: common/ gen/ mark_compact/ mark_sweep/ thread/ trace_forward/

Author: wjwashburn
Date: Thu Oct 26 20:48:43 2006
New Revision: 468252

URL: http://svn.apache.org/viewvc?view=rev&rev=468252
Log:
HARMONY-1900 patch to enable GCV5,  to run in non-generational.

Added:
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_block.h
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect_compact.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_copy.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_forward.cpp
Modified:
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.h
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_vm.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gc_for_barrier.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace.h
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_alloc.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect.h
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector.h
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector_alloc.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator.h
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator_alloc.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/thread_alloc.h
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace.h
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_alloc.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_copy.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_forward.cpp

Added: incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_block.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_block.h?view=auto&rev=468252
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_block.h (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_block.h Thu Oct 26 20:48:43 2006
@@ -0,0 +1,169 @@
+/*
+ *  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, 2006/10/05
+ */
+
+#ifndef _BLOCK_H_
+#define _BLOCK_H_
+
+#include "../common/gc_common.h"
+
+#define GC_BLOCK_SHIFT_COUNT 15
+#define GC_BLOCK_SIZE_BYTES (1 << GC_BLOCK_SHIFT_COUNT)
+
+enum Block_Status {
+  BLOCK_NIL,
+  BLOCK_FREE,
+  BLOCK_IN_USE,
+  BLOCK_USED
+};
+
+typedef struct Block_Header {
+  void* base;                       
+  void* free;                       
+  void* ceiling;                    
+  unsigned int block_idx;           
+  unsigned int status;
+  SlotVector* reloc_table;
+  Block_Header* next;
+  unsigned int mark_table[1];  /* entry num == MARKBIT_TABLE_SIZE_WORDS */
+}Block_Header;
+
+typedef union Block{
+    Block_Header header;
+    unsigned char raw_bytes[GC_BLOCK_SIZE_BYTES];
+}Block;
+
+#define GC_BLOCK_HEADER_VARS_SIZE_BYTES (unsigned int)&(((Block_Header*)0)->mark_table)
+
+/* BlockSize - MarkbitTable*32 = HeaderVars + MarkbitTable
+   => MarkbitTable = (BlockSize - HeaderVars)/33 */
+#define MARKBIT_TABLE_COMPUTE_DIVISOR 33
+/* +1 to round up*/
+#define MARKBIT_TABLE_COMPUTED_SIZE_BYTE ((GC_BLOCK_SIZE_BYTES-GC_BLOCK_HEADER_VARS_SIZE_BYTES)/MARKBIT_TABLE_COMPUTE_DIVISOR + 1)
+#define MARKBIT_TABLE_SIZE_WORDS ((MARKBIT_TABLE_COMPUTED_SIZE_BYTE + MASK_OF_BYTES_PER_WORD)&~MASK_OF_BYTES_PER_WORD)
+#define MARKBIT_TABLE_SIZE_BYTES (MARKBIT_TABLE_SIZE_WORDS * BYTES_PER_WORD)
+
+#define GC_BLOCK_HEADER_SIZE_BYTES (MARKBIT_TABLE_SIZE_BYTES + GC_BLOCK_HEADER_VARS_SIZE_BYTES)
+#define GC_BLOCK_BODY_SIZE_BYTES (GC_BLOCK_SIZE_BYTES - GC_BLOCK_HEADER_SIZE_BYTES)
+#define GC_BLOCK_BODY(block) ((void*)((unsigned int)(block) + GC_BLOCK_HEADER_SIZE_BYTES))
+#define GC_BLOCK_END(block) ((void*)((unsigned int)(block) + GC_BLOCK_SIZE_BYTES))
+
+#define GC_BLOCK_LOW_MASK ((unsigned int)(GC_BLOCK_SIZE_BYTES - 1))
+#define GC_BLOCK_HIGH_MASK (~GC_BLOCK_LOW_MASK)
+#define GC_BLOCK_HEADER(addr) ((Block_Header *)((unsigned int)(addr) & GC_BLOCK_HIGH_MASK))
+#define GC_BLOCK_INDEX(addr) ((unsigned int)(GC_BLOCK_HEADER(addr)->block_idx))
+#define GC_BLOCK_INDEX_FROM(heap_start, addr) ((unsigned int)(((unsigned int)(addr)-(unsigned int)(heap_start)) >> GC_BLOCK_SHIFT_COUNT))
+
+#define ADDRESS_OFFSET_TO_BLOCK_HEADER(addr) ((unsigned int)((unsigned int)addr&GC_BLOCK_LOW_MASK))
+#define ADDRESS_OFFSET_IN_BLOCK_BODY(addr) ((unsigned int)(ADDRESS_OFFSET_TO_BLOCK_HEADER(addr)- GC_BLOCK_HEADER_SIZE_BYTES))
+
+#define OBJECT_BIT_INDEX_TO_MARKBIT_TABLE(p_obj)    (ADDRESS_OFFSET_IN_BLOCK_BODY(p_obj) >> 2)
+#define OBJECT_WORD_INDEX_TO_MARKBIT_TABLE(p_obj)   (OBJECT_BIT_INDEX_TO_MARKBIT_TABLE(p_obj) >> BIT_SHIFT_TO_BITS_PER_WORD)
+#define OBJECT_WORD_OFFSET_IN_MARKBIT_TABLE(p_obj)  (OBJECT_BIT_INDEX_TO_MARKBIT_TABLE(p_obj) & BIT_MASK_TO_BITS_PER_WORD)
+
+inline Partial_Reveal_Object* block_get_first_marked_object(Block_Header* block, unsigned int* mark_bit_idx)
+{
+  unsigned int* mark_table = block->mark_table;
+  unsigned int* table_end = mark_table + MARKBIT_TABLE_SIZE_WORDS;
+  
+  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 word_index = (j<<BIT_SHIFT_TO_BITS_PER_WORD) + k;
+        Partial_Reveal_Object* p_obj = (Partial_Reveal_Object*)((unsigned int*)GC_BLOCK_BODY(block) + word_index);
+        /* only valid before compaction: assert(obj_is_marked_in_vt(p_obj)); */
+        
+        *mark_bit_idx = word_index;
+      return p_obj;
+    }
+    j++;
+    k=0;
+  }          
+  *mark_bit_idx = 0;
+  return NULL;   
+}
+
+inline Partial_Reveal_Object* block_get_next_marked_object(Block_Header* block, unsigned int* mark_bit_idx)
+{
+  unsigned int* mark_table = block->mark_table;
+  unsigned int* table_end = mark_table + MARKBIT_TABLE_SIZE_WORDS;
+  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 word_index = (j<<BIT_SHIFT_TO_BITS_PER_WORD) + k;
+      Partial_Reveal_Object* p_obj = (Partial_Reveal_Object*)((unsigned int*)GC_BLOCK_BODY(block) + word_index);      
+      /* only valid before compaction: assert(obj_is_marked_in_vt(p_obj)); */
+      
+      *mark_bit_idx = word_index;
+      return p_obj;
+    }
+    j++;
+    k=0;
+  }        
+  
+  *mark_bit_idx = 0;
+  return NULL;   
+
+}
+
+inline void block_clear_mark_table(Block_Header* block)
+{
+  unsigned int* mark_table = block->mark_table;
+  memset(mark_table, 0, MARKBIT_TABLE_SIZE_BYTES);
+  return;
+}
+
+inline void block_clear_markbits(Block_Header* block)
+{
+  unsigned int* mark_table = block->mark_table;
+  unsigned int* table_end = mark_table + MARKBIT_TABLE_SIZE_WORDS;
+  
+  unsigned j=0;
+  while( (mark_table + j) < table_end){
+    unsigned int markbits = *(mark_table+j);
+    if(!markbits){ j++; continue; }
+    unsigned int k=0;
+    while(k<32){
+        if( !(markbits& (1<<k)) ){ k++; continue;}
+        unsigned int word_index = (j<<BIT_SHIFT_TO_BITS_PER_WORD) + k;
+        Partial_Reveal_Object* p_obj = (Partial_Reveal_Object*)((unsigned int*)GC_BLOCK_BODY(block) + word_index);
+        assert(obj_is_marked_in_vt(p_obj));
+        obj_unmark_in_vt(p_obj);
+        k++;
+    }
+    j++;
+  } 
+
+  block_clear_mark_table(block);
+  return;     
+}
+
+#endif //#ifndef _BLOCK_H_

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp?view=diff&rev=468252&r1=468251&r2=468252
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp Thu Oct 26 20:48:43 2006
@@ -88,6 +88,7 @@
   return;
 }
 
+/* NOTE:: Only marking in object header is idempotent */
 void mark_scan_heap(Collector* collector)
 {
   GC* gc = collector->gc;
@@ -102,23 +103,3 @@
   
   return;
 }
-
-void gc_update_rootset(GC* gc)
-{
-  RootSet* root_set = gc->root_set;
-  /* update refs in root set after moving collection */
-  for(unsigned int i=0; i < root_set->size(); i++){
-      Partial_Reveal_Object** p_ref = (*root_set)[i];
-      Partial_Reveal_Object* p_obj = *p_ref;
-      assert(p_obj); /* root ref should never by NULL*/
-      /* FIXME:: this should be reconsidered: forwarded in vt or obj_info */
-      if(!obj_is_forwarded_in_obj_info(p_obj)){
-         assert(obj_belongs_to_space(p_obj, gc_get_los((GC_Gen*)gc)));
-         continue;
-      }
-      Partial_Reveal_Object* p_target_obj = get_forwarding_pointer_in_obj_info(p_obj);
-      *p_ref = p_target_obj; 
-  }
-  
-  return;
-}
\ No newline at end of file

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.h?view=diff&rev=468252&r1=468251&r2=468252
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.h Thu Oct 26 20:48:43 2006
@@ -60,10 +60,7 @@
 
 #define BIT_MASK_TO_BITS_PER_WORD ((1<<BIT_SHIFT_TO_BITS_PER_WORD)-1)
 
-#define GC_BLOCK_SHIFT_COUNT 15
-#define GC_BLOCK_SIZE_BYTES (1 << GC_BLOCK_SHIFT_COUNT)
-
-#define GC_OBJ_SIZE_THRESHOLD (GC_BLOCK_SIZE_BYTES >> 1)
+#define GC_OBJ_SIZE_THRESHOLD (4*KB)
 
 typedef void (*TaskType)(void*);
 
@@ -253,7 +250,7 @@
 {
 	gc->root_set->clear();
 }
-void gc_update_rootset(GC* gc);
+
 void mark_scan_heap(Collector* collector);
 
 inline void* gc_heap_base(GC* gc){ return gc->heap_start; }

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_vm.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_vm.cpp?view=diff&rev=468252&r1=468251&r2=468252
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_vm.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_vm.cpp Thu Oct 26 20:48:43 2006
@@ -21,8 +21,7 @@
 #include "vm_threads.h"
 
 #include "../gen/gen.h"
-
-#include "../common/interior_pointer.h"
+#include "interior_pointer.h"
 
 static GC* p_global_gc = NULL;
 
@@ -51,6 +50,11 @@
 	p_global_gc->root_set->push_back(p_ref);
 } 
 
+void gc_add_root_set_entry_interior_pointer (void **slot, int offset, Boolean is_pinned) 
+{  
+  add_root_set_entry_interior_pointer(slot, offset, is_pinned); 
+}
+
 /* VM to force GC */
 void gc_force_gc() 
 {
@@ -109,5 +113,3 @@
 unsigned int gc_time_since_last_gc()
 {  assert(0); return 0; }
 
-void gc_add_root_set_entry_interior_pointer (void **slot, int offset, Boolean is_pinned) 
-{	add_root_set_entry_interior_pointer(slot, offset, is_pinned); }

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gc_for_barrier.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gc_for_barrier.cpp?view=diff&rev=468252&r1=468251&r2=468252
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gc_for_barrier.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gc_for_barrier.cpp Thu Oct 26 20:48:43 2006
@@ -24,59 +24,84 @@
 
 /* All the write barrier interfaces need cleanup */
 
+static Boolean NEED_BARRIER = TRUE;
+
 Boolean gc_requires_barriers() 
-{   return 1; }
+{   return NEED_BARRIER; }
 
 /* The implementations are only temporary */
-static void gc_write_barrier_generic(Managed_Object_Handle p_obj_holding_ref, Managed_Object_Handle *p_slot, 
-                      Managed_Object_Handle p_target, unsigned int kind) 
+static void gc_slot_write_barrier(Managed_Object_Handle *p_slot, 
+                      Managed_Object_Handle p_target) 
 {
   Mutator *mutator = (Mutator *)vm_get_gc_thread_local();
   GC_Gen* gc = (GC_Gen*)mutator->gc;
-  if(kind == WRITE_BARRIER_SLOT ){
-    if( address_belongs_to_nursery((void *)p_target, gc) && 
-         !address_belongs_to_nursery((void *)p_slot, gc)) 
-    {
-      mutator->remslot->push_back((Partial_Reveal_Object **)p_slot);
-    }
-  }else if( kind == WRITE_BARRIER_OBJECT ){
-    if( !address_belongs_to_nursery((void *)p_obj_holding_ref, gc) ) {
-      mutator->remobj->push_back((Partial_Reveal_Object *)p_obj_holding_ref);
-    }    
-  }else{  
-    assert(kind == WRITE_BARRIER_UPDATE ); 
-    *p_slot = p_target;
-    if( address_belongs_to_nursery((void *)p_target, gc) && 
-         !address_belongs_to_nursery((void *)p_slot, gc)) 
-    {
-      mutator->remslot->push_back((Partial_Reveal_Object **)p_slot);
-    }      
+  if( address_belongs_to_nursery((void *)p_target, gc) && 
+       !address_belongs_to_nursery((void *)p_slot, gc)) 
+  {
+    mutator->remslot->push_back((Partial_Reveal_Object **)p_slot);
   }
 }
 
-/* temporary write barriers, need reconsidering */
-void gc_write_barrier(Managed_Object_Handle p_obj_holding_ref)
+static void gc_object_write_barrier(Managed_Object_Handle p_object) 
 {
-  gc_write_barrier_generic(p_obj_holding_ref, NULL, NULL, WRITE_BARRIER_OBJECT); 
+  Mutator *mutator = (Mutator *)vm_get_gc_thread_local();
+  GC_Gen* gc = (GC_Gen*)mutator->gc;
+  if( !address_belongs_to_nursery((void *)p_object, gc)) return;
+  
+  Partial_Reveal_Object **p_slot; 
+  /* scan array object */
+  if (object_is_array((Partial_Reveal_Object*)p_object)) {
+    Partial_Reveal_Object* array = (Partial_Reveal_Object*)p_object;
+    assert(!obj_is_primitive_array(array));
+    
+    int32 array_length = vector_get_length((Vector_Handle) array);
+    for (int i = 0; i < array_length; i++) {
+      p_slot = (Partial_Reveal_Object **)vector_get_element_address_ref((Vector_Handle) array, i);
+      if( *p_slot != NULL && address_belongs_to_nursery((void *)*p_slot, gc)){
+        mutator->remslot->push_back(p_slot);
+      }
+    }   
+    return;
+  }
+
+  /* scan non-array object */
+  Partial_Reveal_Object* p_obj =  (Partial_Reveal_Object*)p_object;   
+  int *offset_scanner = init_object_scanner(p_obj);
+  while (true) {
+    p_slot = (Partial_Reveal_Object**)offset_get_ref(offset_scanner, p_obj);
+    if (p_slot == NULL) break;  
+    if( address_belongs_to_nursery((void *)*p_slot, gc)){
+      mutator->remslot->push_back(p_slot);
+    }
+    offset_scanner = offset_next_ref(offset_scanner);
+  }
+
+  return;
 }
 
-/* for array copy and object clone */
-void gc_heap_wrote_object (Managed_Object_Handle p_obj_holding_ref)
+void gc_heap_wrote_object (Managed_Object_Handle p_obj_written)
 {
-  gc_write_barrier_generic(p_obj_holding_ref, NULL, NULL, WRITE_BARRIER_OBJECT); 
+  if( !NEED_BARRIER ) return;
+  if( object_has_slots((Partial_Reveal_Object*)p_obj_written)){
+    /* for array copy and object clone */
+    gc_object_write_barrier(p_obj_written); 
+  }
 }
 
 /* The following routines were supposed to be the only way to alter any value in gc heap. */
 void gc_heap_write_ref (Managed_Object_Handle p_obj_holding_ref, unsigned offset, Managed_Object_Handle p_target) 
 {  assert(0); }
 
+/* FIXME:: this is not the right interface for write barrier */
 void gc_heap_slot_write_ref (Managed_Object_Handle p_obj_holding_ref,Managed_Object_Handle *p_slot, Managed_Object_Handle p_target)
 {  
-  gc_write_barrier_generic(NULL, p_slot, p_target, WRITE_BARRIER_UPDATE); 
+  *p_slot = p_target;
+  if( !NEED_BARRIER ) return;
+  gc_slot_write_barrier(p_slot, p_target); 
 }
 
 /* this is used for global object update, e.g., strings. Since globals are roots, no barrier here */
 void gc_heap_write_global_slot(Managed_Object_Handle *p_slot,Managed_Object_Handle p_target)
 {
   *p_slot = p_target;
-}
\ No newline at end of file
+}

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp?view=diff&rev=468252&r1=468251&r2=468252
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp Thu Oct 26 20:48:43 2006
@@ -27,7 +27,7 @@
 
 /* heap size limit is not interesting. only for manual tuning purpose */
 unsigned int min_heap_size_bytes = 32 * MB;
-unsigned int max_heap_size_bytes = 64 * MB;
+unsigned int max_heap_size_bytes = 128 * MB;
 
 /* fspace size limit is not interesting. only for manual tuning purpose */
 unsigned int min_nos_size_bytes = 2 * MB;
@@ -76,17 +76,18 @@
   gc_gen->reserved_heap_size = max_heap_size;
   gc_gen->heap_start = reserved_base;
   gc_gen->heap_end = (void*)((unsigned int)reserved_base + max_heap_size);
+  gc_gen->blocks = (Block*)reserved_base;
   gc_gen->num_collections = 0;
 
   /* heuristic nos + mos + LOS */
-  unsigned int nos_size =  max_heap_size >> 4; 
+  unsigned int nos_size =  max_heap_size >> 2; 
   assert(nos_size > min_nos_size_bytes);
 	gc_nos_initialize(gc_gen, reserved_base, nos_size);	
 
 	unsigned int mos_size = max_heap_size >> 1;
 	reserved_base = (void*)((unsigned int)reserved_base + nos_size);
 	gc_mos_initialize(gc_gen, reserved_base, mos_size);
-  
+    
 	unsigned int los_size = max_heap_size >> 2;
 	reserved_base = (void*)((unsigned int)gc_gen->heap_end - los_size);
 	gc_los_initialize(gc_gen, reserved_base, los_size);
@@ -137,9 +138,9 @@
   return mspace_free_memory_size(gc->mos) < fspace_used_memory_size(gc->nos);  
 }
 
-void* mos_alloc(unsigned size, Alloc_Context *alloc_ctx){return mspace_alloc(size, alloc_ctx);}
-void* nos_alloc(unsigned size, Alloc_Context *alloc_ctx){return fspace_alloc(size, alloc_ctx);}
-void* los_alloc(unsigned size, Alloc_Context *alloc_ctx){return lspace_alloc(size, alloc_ctx);}
+void* mos_alloc(unsigned size, Allocator *allocator){return mspace_alloc(size, allocator);}
+void* nos_alloc(unsigned size, Allocator *allocator){return fspace_alloc(size, allocator);}
+void* los_alloc(unsigned size, Allocator *allocator){return lspace_alloc(size, allocator);}
 Space* gc_get_nos(GC_Gen* gc){ return (Space*)gc->nos;}
 Space* gc_get_mos(GC_Gen* gc){ return (Space*)gc->mos;}
 Space* gc_get_los(GC_Gen* gc){ return (Space*)gc->los;}
@@ -148,10 +149,60 @@
 void gc_set_los(GC_Gen* gc, Space* los){ gc->los = (Lspace*)los;}
 unsigned int gc_get_processor_num(GC_Gen* gc){ return gc->_num_processors;}
 
-void gc_preprocess_collector(Collector *collector)
+static void gc_gen_update_rootset(GC* gc)
+{
+  RootSet* root_set = gc->root_set;
+  /* update refs in root set after moving collection */
+  for(unsigned int i=0; i < root_set->size(); i++){
+      Partial_Reveal_Object** p_ref = (*root_set)[i];
+      Partial_Reveal_Object* p_obj = *p_ref;
+      assert(p_obj); /* root ref should never by NULL*/
+      /* FIXME:: this should be reconsidered: forwarded in vt or obj_info */
+      if(!obj_is_forwarded_in_obj_info(p_obj)){
+        /* if an obj is not moved, it must be in LOS or otherwise in MOS for MINOR_COLLECTION */
+#ifdef _DEBUG
+        if( gc->collect_kind == MINOR_COLLECTION )
+          assert( !obj_belongs_to_space(p_obj, gc_get_nos((GC_Gen*)gc)) );
+        else
+          assert( obj_belongs_to_space(p_obj, gc_get_los((GC_Gen*)gc)) ); 
+#endif
+        continue;
+      }
+      Partial_Reveal_Object* p_target_obj = get_forwarding_pointer_in_obj_info(p_obj);
+      *p_ref = p_target_obj; 
+  }
+  
+  return;
+}
+
+void update_rootset_interior_pointer();
+
+void gc_gen_update_repointed_refs(Collector* collector)
 {
   GC_Gen* gc = (GC_Gen*)collector->gc;
+  Space* space;
+  space = gc_get_nos(gc);  space->update_reloc_func(space);
+  space = gc_get_mos(gc);  space->update_reloc_func(space);
+  space = gc_get_los(gc);  space->update_reloc_func(space);
+
+  gc_gen_update_rootset((GC*)gc);   
+  update_rootset_interior_pointer();
   
+  return;
+}
+
+void gc_preprocess_collector(Collector *collector)
+{
+  /* for MAJOR_COLLECTION, all the remsets are useless */
+  GC_Gen* gc = (GC_Gen*)collector->gc;
+  if( gc->collect_kind == MAJOR_COLLECTION ){
+    collector->last_cycle_remset->clear();
+    return;
+  }
+
+  Fspace* fspace = (Fspace*)gc_get_nos(gc);
+  fspace->remslot_sets->push_back(collector->last_cycle_remset);
+    
   /* this_cycle_remset is ready to be used */
   assert(collector->this_cycle_remset->empty());
 
@@ -160,11 +211,12 @@
 
 void gc_postprocess_collector(Collector *collector)
 { 
+  /* for MAJOR_COLLECTION we do nothing */
   GC_Gen* gc = (GC_Gen*)collector->gc;
+  if( gc->collect_kind == MAJOR_COLLECTION )
+    return;
       
   /* for MINOR_COLLECTION */
-  Fspace* fspace = (Fspace*)gc_get_nos(gc);
-  
   /* switch its remsets, this_cycle_remset data kept in space->remslot_sets */
   /* last_cycle_remset was in space->remslot_sets and cleared during collection */
   assert(collector->last_cycle_remset->empty());
@@ -173,32 +225,32 @@
   collector->this_cycle_remset = collector->last_cycle_remset;
   collector->last_cycle_remset = temp_set;
   
-  fspace->remslot_sets->push_back(collector->last_cycle_remset);
-  
   return;
 }
 
 void gc_preprocess_mutator(GC_Gen* gc)
-{
+{       
   Mutator *mutator = gc->mutator_list;
   Fspace* fspace = (Fspace*)mutator->alloc_space;
-  
+  /* for MAJOR_COLLECTION, all the remsets are useless */
   while (mutator) {
-    fspace->remslot_sets->push_back(mutator->remslot);
-    fspace->remobj_sets->push_back(mutator->remobj);  
+    if(gc->collect_kind == MAJOR_COLLECTION){
+      mutator->remslot->clear();
+    }else{        
+      fspace->remslot_sets->push_back(mutator->remslot);
+    }
     mutator = mutator->next;
   }
  
   return;
-}
+} /////////FIXME::: need clear space remsets
 
 void gc_postprocess_mutator(GC_Gen* gc)
 {
   Mutator *mutator = gc->mutator_list;
   while (mutator) {
-    assert(mutator->remobj->empty());
     assert(mutator->remslot->empty());
-    alloc_context_reset((Alloc_Context*)mutator);    
+    alloc_context_reset((Allocator*)mutator);    
     mutator = mutator->next;
   }
   
@@ -209,7 +261,7 @@
 {
   if(major_collection_needed(gc) || cause== GC_CAUSE_LOS_IS_FULL)
     return  MAJOR_COLLECTION;
-
+    
   return MINOR_COLLECTION;     
 }
 
@@ -227,9 +279,27 @@
   
   if(verify_live_heap) gc_verify_heap((GC*)gc, TRUE);
 
-  if(gc->collect_kind == MINOR_COLLECTION)
-    fspace_collection(gc->nos);
-  else{
+  if(gc->collect_kind == MINOR_COLLECTION){
+    if( gc_requires_barriers()) /* normal gen gc nos collection */
+      fspace_collection(gc->nos);
+    else{ /* copy nos to mos for non-gen gc */
+      /* we don't move mos objects in MINOR_COLLECTION. This is true for both 
+        gen or non-gen collections, but only meaningful for non-gen GC, because
+        non-gen GC need mark the heap in order to find the refs from mos/los to nos.
+        This can save lots of reloc table space for slots having ref pointing to mos.
+        For gen GC, MINOR_COLLECTION doesn't really mark the heap. It has remsets that
+        have all the refs from mos/los to nos, which are actually the same thing as reloc table */
+      gc->mos->move_object = FALSE;
+      fspace_collection(gc->nos);
+      gc->mos->move_object = TRUE;
+      
+      /* these are only needed for non-gen MINOR_COLLECTION, because 
+        both mos and los will be collected (and reset) in MAJOR_COLLECTION */
+      reset_mspace_after_copy_nursery(gc->mos);
+      reset_lspace_after_copy_nursery(gc->los);
+    }
+  }else{
+    /* process mos and nos together in one compaction */
     mspace_collection(gc->mos); /* fspace collection is included */
     lspace_collection(gc->los);
   }

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h?view=diff&rev=468252&r1=468251&r2=468252
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h Thu Oct 26 20:48:43 2006
@@ -44,8 +44,6 @@
 extern unsigned int min_nos_size_bytes;
 extern unsigned int max_nos_size_bytes;
 
-extern unsigned int block_size_bytes;
-
 typedef struct GC_Gen {
   /* <-- First couple of fields overloadded as GC */
   void* heap_start;
@@ -73,6 +71,7 @@
   port_vmem_t *allocated_memory;
   /* END of GC --> */
   
+  Block* blocks;
   Fspace *nos;
   Mspace *mos;
   Lspace *los;
@@ -94,6 +93,7 @@
          lspace_free_memory_size(gc->los);  }
                         
 void gc_gen_reclaim_heap(GC_Gen* gc, unsigned int cause);
+void gc_gen_update_repointed_refs(Collector* collector);
 
 /////////////////////////////////////////////////////////////////////////////////////////
 
@@ -128,9 +128,9 @@
   return (Space*)((GC_Gen*)gc)->los;
 }
 
-void* mos_alloc(unsigned size, Alloc_Context *alloc_ctx);
-void* nos_alloc(unsigned size, Alloc_Context *alloc_ctx);
-void* los_alloc(unsigned size, Alloc_Context *alloc_ctx);
+void* mos_alloc(unsigned size, Allocator *allocator);
+void* nos_alloc(unsigned size, Allocator *allocator);
+void* los_alloc(unsigned size, Allocator *allocator);
 Space* gc_get_nos(GC_Gen* gc);
 Space* gc_get_mos(GC_Gen* gc);
 Space* gc_get_los(GC_Gen* gc);

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace.cpp?view=diff&rev=468252&r1=468251&r2=468252
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace.cpp Thu Oct 26 20:48:43 2006
@@ -1,91 +1,141 @@
-/*
- *  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, 2006/10/05
- */
-
-#include "mspace.h"
-
-static void mspace_init_blocks(Mspace* mspace)
-{
-  int size = sizeof(Block_Info)* mspace->num_total_blocks;
-  Block_Info* block_info =  (Block_Info*)STD_MALLOC(size);
-  memset(block_info, 0, size);
-  
-  for(unsigned int i=0; i < mspace->num_current_blocks; i++){
-    Block_Header* block = (Block_Header*)((unsigned int)space_heap_start((Space*)mspace) + i*mspace->block_size_bytes);
-    block->free = (void*)((unsigned int)block + GC_BLOCK_HEADER_SIZE_BYTES);
-    block->ceiling = (void*)((unsigned int)block + mspace->block_size_bytes); 
-    block->base = block->free;
-    block->block_idx = i;
-    
-    block_info[i].block = block;
-    block_info[i].status = BLOCK_FREE;  
-    block_info[i].reloc_table = new SlotVector();
-  }
-  
-  mspace->block_info = block_info;
-  
-  return;
-}
-
-struct GC_Gen;
-extern void gc_set_mos(GC_Gen* gc, Space* space);
-void mspace_initialize(GC* gc, void* start, unsigned int mspace_size)
-{
-    Mspace* mspace = (Mspace*)STD_MALLOC( sizeof(Mspace));
-    assert(mspace);
-    memset(mspace, 0, sizeof(Mspace));
-    
-    mspace->block_size_bytes = GC_BLOCK_SIZE_BYTES;
-    mspace->reserved_heap_size = mspace_size;
-    mspace->num_total_blocks = mspace_size/mspace->block_size_bytes;
-
-    mspace_size >>= 1;   
-    void* reserved_base = start;
-    int status = port_vmem_commit(&reserved_base, mspace_size, gc->allocated_memory); 
-    assert(status == APR_SUCCESS && reserved_base == start);
-    
-    memset(reserved_base, 0, mspace_size);
-    mspace->committed_heap_size = mspace_size;
-    mspace->heap_start = reserved_base;
-    mspace->heap_end = (void *)((unsigned int)reserved_base + mspace->reserved_heap_size);
-    mspace->num_current_blocks = mspace_size/mspace->block_size_bytes;
-    
-    mspace->num_used_blocks = 0;
-    mspace->free_block_idx = 0;
-    
-    mspace_init_blocks(mspace);
-    
-    mspace->obj_info_map = new ObjectMap();
-    mspace->mark_object_func = mspace_mark_object;
-    mspace->save_reloc_func = mspace_save_reloc;
-    mspace->update_reloc_func = mspace_update_reloc;
-
-    mspace->move_object = TRUE;
-    mspace->gc = gc;
-    gc_set_mos((GC_Gen*)gc, (Space*)mspace);
-
-    return;
-}
-
-
-void mspace_destruct(Mspace* mspace)
-{
-  /* inverse of initialize */
-}
-
+/*
+ *  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, 2006/10/05
+ */
+
+#include "mspace.h"
+
+static void mspace_destruct_blocks(Mspace* mspace)
+{ 
+  Block* blocks = (Block*)mspace->blocks; 
+  for(unsigned int i=0; i < mspace->num_managed_blocks; i++){
+    Block_Header* block = (Block_Header*)&(blocks[i]);
+    delete block->reloc_table;
+    block->reloc_table = NULL;
+  }
+  
+  return;
+}
+
+static void mspace_init_blocks(Mspace* mspace)
+{ 
+  Block* blocks = (Block*)mspace->heap_start; 
+  Block_Header* last_block = (Block_Header*)blocks;
+  unsigned int start_idx = mspace->first_block_idx;
+  for(unsigned int i=0; i < mspace->num_managed_blocks; i++){
+    Block_Header* block = (Block_Header*)&(blocks[i]);
+    block->free = (void*)((unsigned int)block + GC_BLOCK_HEADER_SIZE_BYTES);
+    block->ceiling = (void*)((unsigned int)block + GC_BLOCK_SIZE_BYTES); 
+    block->base = block->free;
+    block->block_idx = i + start_idx;
+    block->status = BLOCK_FREE;  
+    block->reloc_table = new SlotVector();
+    last_block->next = block;
+    last_block = block;
+  }
+  last_block->next = NULL;
+  mspace->blocks = blocks;
+   
+  return;
+}
+
+struct GC_Gen;
+extern void gc_set_mos(GC_Gen* gc, Space* space);
+void mspace_initialize(GC* gc, void* start, unsigned int mspace_size)
+{
+  Mspace* mspace = (Mspace*)STD_MALLOC( sizeof(Mspace));
+  assert(mspace);
+  memset(mspace, 0, sizeof(Mspace));
+  
+  mspace->reserved_heap_size = mspace_size;
+  mspace->num_total_blocks = mspace_size >> GC_BLOCK_SHIFT_COUNT;
+
+  void* reserved_base = start;
+  int status = port_vmem_commit(&reserved_base, mspace_size, gc->allocated_memory); 
+  assert(status == APR_SUCCESS && reserved_base == start);
+  
+  memset(reserved_base, 0, mspace_size);
+  mspace->committed_heap_size = mspace_size;
+  mspace->heap_start = reserved_base;
+  mspace->heap_end = (void *)((unsigned int)reserved_base + mspace->reserved_heap_size);
+  mspace->num_managed_blocks = mspace_size >> GC_BLOCK_SHIFT_COUNT;
+  
+  mspace->first_block_idx = GC_BLOCK_INDEX_FROM(gc->heap_start, reserved_base);
+  mspace->ceiling_block_idx = mspace->first_block_idx + mspace->num_managed_blocks - 1;
+  
+  mspace->num_used_blocks = 0;
+  mspace->free_block_idx = mspace->first_block_idx;
+  
+  mspace_init_blocks(mspace);
+  
+  mspace->obj_info_map = new ObjectMap();
+  mspace->mark_object_func = mspace_mark_object;
+  mspace->save_reloc_func = mspace_save_reloc;
+  mspace->update_reloc_func = mspace_update_reloc;
+
+  mspace->move_object = TRUE;
+  mspace->gc = gc;
+  gc_set_mos((GC_Gen*)gc, (Space*)mspace);
+
+  return;
+}
+
+
+void mspace_destruct(Mspace* mspace)
+{
+  //FIXME:: when map the to-half, the decommission start address should change
+  mspace_destruct_blocks(mspace);
+  port_vmem_decommit(mspace->heap_start, mspace->committed_heap_size, mspace->gc->allocated_memory);
+  STD_FREE(mspace);  
+}
+
+  /* for non-gen MINOR_COLLECTION, mspace has both obj and marktable to be cleared,
+     because the marking phase will mark them, but then never touch them 
+     
+     FIXME:: the marking choice between header and mark table has to be decided.
+     Obj header marking has advantage of idempotent, while table marking can prefetch 
+     If we choose only one, we will not have the two version clearings: one after
+     MAJOR_COLLECTION, one after non-gen MINOR_COLLECTION */
+     
+void reset_mspace_after_copy_nursery(Mspace* mspace)
+{ 
+  /* for major collection we do nothing, the reset is done there */
+  assert( mspace->gc->collect_kind == MINOR_COLLECTION );
+
+  unsigned int new_num_used = mspace->free_block_idx - mspace->first_block_idx;
+  unsigned int old_num_used = mspace->num_used_blocks;
+
+  /* At the moment, for MINOR_COLLECTION, only non-gen collection does copying.
+     The generational version does forwarding */
+  assert( !gc_requires_barriers());
+  
+  Block* blocks = mspace->blocks;
+  for(unsigned int i=0; i < old_num_used; i++){
+    Block_Header* block = (Block_Header*)&(blocks[i]);
+    block_clear_markbits(block); 
+  }
+
+  for(unsigned int i=old_num_used; i < new_num_used; i++){
+    Block_Header* block = (Block_Header*)&(blocks[i]);
+    block->status = BLOCK_USED;
+  }
+
+  mspace->num_used_blocks = new_num_used;  
+  return;
+}
+

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace.h?view=diff&rev=468252&r1=468251&r2=468252
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace.h Thu Oct 26 20:48:43 2006
@@ -1,125 +1,75 @@
-/*
- *  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, 2006/10/05
- */
-
-#ifndef _MSC_SPACE_H_
-#define _MSC_SPACE_H_
-
-#include "../common/gc_common.h"
-#include "../thread/thread_alloc.h"
-
-typedef struct Block_Header {
-  void* base;                       
-  void* free;                       
-  void* ceiling;                    
-  unsigned int block_idx;           
-  unsigned int mark_table[1];  /* entry num == MARKBIT_TABLE_SIZE_WORDS */
-}Block_Header;
-
-enum Block_Status {
-  BLOCK_NIL,
-  BLOCK_FREE,
-  BLOCK_IN_USE,
-  BLOCK_USED
-};
-
-typedef struct Block_Info{
-  Block_Header* block;
-  Boolean status;
-
-  SlotVector* reloc_table;
-    
-}Block_Info;
-
-/* Mark-compaction space is orgnized into blocks*/
-typedef struct Mspace{
+/*
+ *  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, 2006/10/05
+ */
+
+#ifndef _MSC_SPACE_H_
+#define _MSC_SPACE_H_
+
+#include "../common/gc_block.h"
+#include "../thread/thread_alloc.h"
+
+/* Mark-compaction space is orgnized into blocks*/
+typedef struct Mspace{
   /* <-- first couple of fields are overloadded as Space */
   void* heap_start;
   void* heap_end;
   unsigned int reserved_heap_size;
   unsigned int committed_heap_size;
-  unsigned int num_collections;
-  GC* gc;
-  Boolean move_object;
+  unsigned int num_collections;
+  GC* gc;
+  Boolean move_object;
   Boolean (*mark_object_func)(Mspace* space, Partial_Reveal_Object* p_obj);
   void (*save_reloc_func)(Mspace* space, Partial_Reveal_Object** p_ref);
-  void (*update_reloc_func)(Mspace* space);
-  /* END of Space --> */
-    
-  Block_Info* block_info; /* data structure for all the blocks */
-  
-  volatile unsigned int num_used_blocks;
-  volatile unsigned int free_block_idx;
-  unsigned int compact_block_low_idx;
-  unsigned int compact_block_high_idx;
-
-  unsigned int block_size_bytes;
-  unsigned int num_current_blocks;
-  unsigned int num_total_blocks;
-
-  /* during compaction, save non-zero obj_info who's overwritten by forwarding pointer */
-  ObjectMap*  obj_info_map; 
-    
-}Mspace;
-
-void mspace_initialize(GC* gc, void* reserved_base, unsigned int mspace_size);
-void mspace_destruct(Mspace* mspace);
-
-inline unsigned int mspace_free_memory_size(Mspace* mspace){ return GC_BLOCK_SIZE_BYTES * (mspace->num_current_blocks - mspace->num_used_blocks);  }
-inline Boolean mspace_has_free_block(Mspace* mspace){ return mspace->free_block_idx < mspace->num_current_blocks; }
-
-void* mspace_alloc(unsigned size, Alloc_Context *alloc_ctx);
-void mspace_collection(Mspace* mspace);
-
-#define GC_BLOCK_HEADER_VARS_SIZE_BYTES (unsigned int)&(((Block_Header*)0)->mark_table)
-
-/* BlockSize - MarkbitTable*32 = HeaderVars + MarkbitTable
-   => MarkbitTable = (BlockSize - HeaderVars)/33 */
-#define MARKBIT_TABLE_COMPUTE_DIVISOR 33
-/* +1 to round up*/
-#define MARKBIT_TABLE_COMPUTED_SIZE_BYTE ((GC_BLOCK_SIZE_BYTES-GC_BLOCK_HEADER_VARS_SIZE_BYTES)/MARKBIT_TABLE_COMPUTE_DIVISOR + 1)
-#define MARKBIT_TABLE_SIZE_WORDS ((MARKBIT_TABLE_COMPUTED_SIZE_BYTE + MASK_OF_BYTES_PER_WORD)&~MASK_OF_BYTES_PER_WORD)
-#define MARKBIT_TABLE_SIZE_BYTES (MARKBIT_TABLE_SIZE_WORDS * BYTES_PER_WORD)
-
-#define GC_BLOCK_HEADER_SIZE_BYTES (MARKBIT_TABLE_SIZE_BYTES + GC_BLOCK_HEADER_VARS_SIZE_BYTES)
-#define GC_BLOCK_BODY_SIZE_BYTES (GC_BLOCK_SIZE_BYTES - GC_BLOCK_HEADER_SIZE_BYTES)
-#define GC_BLOCK_BODY(block) ((void*)((unsigned int)block + GC_BLOCK_HEADER_SIZE_BYTES))
-#define GC_BLOCK_END(block) ((void*)((unsigned int)block + GC_BLOCK_SIZE_BYTES))
-
-#define GC_BLOCK_LOW_MASK ((unsigned int)(GC_BLOCK_SIZE_BYTES - 1))
-#define GC_BLOCK_HIGH_MASK (~GC_BLOCK_LOW_MASK)
-#define GC_BLOCK_HEADER(addr) ((Block_Header *)((unsigned int)addr & GC_BLOCK_HIGH_MASK))
-#define GC_BLOCK_INDEX(addr) ((unsigned int)(GC_BLOCK_HEADER(addr)->block_idx))
-#define GC_BLOCK_INFO_ADDRESS(mspace, addr) ((Block_Info *)&(mspace->block_info[GC_BLOCK_INDEX(addr)]))
-#define GC_BLOCK_INFO_BLOCK(mspace, block) ((Block_Info *)&(mspace->block_info[block->block_idx]))
-
-#define ADDRESS_OFFSET_TO_BLOCK_HEADER(addr) ((unsigned int)((unsigned int)addr&GC_BLOCK_LOW_MASK))
-#define ADDRESS_OFFSET_IN_BLOCK_BODY(addr) ((unsigned int)(ADDRESS_OFFSET_TO_BLOCK_HEADER(addr)- GC_BLOCK_HEADER_SIZE_BYTES))
-
-#define OBJECT_BIT_INDEX_TO_MARKBIT_TABLE(p_obj)    (ADDRESS_OFFSET_IN_BLOCK_BODY(p_obj) >> 2)
-#define OBJECT_WORD_INDEX_TO_MARKBIT_TABLE(p_obj)   (OBJECT_BIT_INDEX_TO_MARKBIT_TABLE(p_obj) >> BIT_SHIFT_TO_BITS_PER_WORD)
-#define OBJECT_WORD_OFFSET_IN_MARKBIT_TABLE(p_obj)  (OBJECT_BIT_INDEX_TO_MARKBIT_TABLE(p_obj) & BIT_MASK_TO_BITS_PER_WORD)
-
-#define GC_BLOCK_OBJECT_AT_INDEX(block, idx) (block->mark_table[idx])
-
-Boolean mspace_mark_object(Mspace* mspace, Partial_Reveal_Object *p_obj);
+  void (*update_reloc_func)(Mspace* space);
+  /* END of Space --> */
+    
+  Block* blocks; /* short-cut for mpsace blockheader access, not mandatory */
+  
+  /* FIXME:: the block indices should be replaced with block header addresses */
+  unsigned int first_block_idx;
+  unsigned int ceiling_block_idx;
+  volatile unsigned int free_block_idx;
+   
+  unsigned int num_used_blocks;
+  unsigned int num_managed_blocks;
+  unsigned int num_total_blocks;
+
+  /* during compaction, save non-zero obj_info who's overwritten by forwarding pointer */
+  ObjectMap*  obj_info_map; 
+    
+}Mspace;
+
+void mspace_initialize(GC* gc, void* reserved_base, unsigned int mspace_size);
+void mspace_destruct(Mspace* mspace);
+
+inline Boolean mspace_has_free_block(Mspace* mspace){ return mspace->free_block_idx <= mspace->ceiling_block_idx; }
+inline unsigned int mspace_free_memory_size(Mspace* mspace){ return GC_BLOCK_SIZE_BYTES * (mspace->ceiling_block_idx - mspace->free_block_idx + 1);  }
+inline Boolean mspace_used_memory_size(Mspace* mspace){ return GC_BLOCK_SIZE_BYTES * mspace->num_used_blocks; }
+
+void* mspace_alloc(unsigned size, Allocator *allocator);
+void mspace_collection(Mspace* mspace);
+
+void reset_mspace_after_copy_nursery(Mspace* mspace);
+
+
+Boolean mspace_mark_object(Mspace* mspace, Partial_Reveal_Object *p_obj);
 void mspace_save_reloc(Mspace* mspace, Partial_Reveal_Object** p_ref);
-void mspace_update_reloc(Mspace* mspace);
-
-#endif //#ifdef _MSC_SPACE_H_
\ No newline at end of file
+void mspace_update_reloc(Mspace* mspace);
+
+#endif //#ifdef _MSC_SPACE_H_

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_alloc.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_alloc.cpp?view=diff&rev=468252&r1=468251&r2=468252
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_alloc.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_alloc.cpp Thu Oct 26 20:48:43 2006
@@ -1,89 +1,92 @@
-/*
- *  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, 2006/10/05
- */
-
-#include "mspace_collect.h"
-
-static Boolean mspace_alloc_block(Mspace* mspace, Alloc_Context* alloc_ctx)
-{
-  int old_free_idx = mspace->free_block_idx;
-  int new_free_idx = old_free_idx+1;
-
-  Block_Info* curr_alloc_block = (Block_Info* )alloc_ctx->curr_alloc_block;
-  if(curr_alloc_block != NULL){ /* it is NULL at first time */
-    assert(curr_alloc_block->status == BLOCK_IN_USE);
-    curr_alloc_block->status = BLOCK_USED;
-    curr_alloc_block->block->free = alloc_ctx->free;
-  }
-
-  while( mspace_has_free_block(mspace)){
-    
-    unsigned int allocated_idx = atomic_cas32(&mspace->free_block_idx, new_free_idx, old_free_idx);
-      
-    if(allocated_idx != (POINTER_SIZE_INT)old_free_idx){
-      old_free_idx = mspace->free_block_idx;
-      new_free_idx = old_free_idx+1;
-      continue;
-    }
-  
-    Block_Info* curr_alloc_block = &(mspace->block_info[allocated_idx]);
-
-    assert(curr_alloc_block->status == BLOCK_FREE);
-    curr_alloc_block->status = BLOCK_IN_USE;
-    mspace->num_used_blocks++;
-
-    alloc_ctx->curr_alloc_block = curr_alloc_block; 
-    Block_Header* block = curr_alloc_block->block;
-    memset(block->free, 0, (unsigned int)block->ceiling - (unsigned int)block->free);
-    alloc_ctx->free = block->free;
-    alloc_ctx->ceiling = block->ceiling;
-    
-    return TRUE;
-  }
+/*
+ *  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, 2006/10/05
+ */
+
+#include "mspace.h"
+
+static Boolean mspace_alloc_block(Mspace* mspace, Allocator* allocator)
+{
+  Block_Header* alloc_block = (Block_Header* )allocator->alloc_block;
+  /* put back the used block */
+  if(alloc_block != NULL){ /* it is NULL at first time */
+    assert(alloc_block->status == BLOCK_IN_USE);
+    alloc_block->status = BLOCK_USED;
+    alloc_block->free = allocator->free;
+  }
+
+  /* now try to get a new block */
+  unsigned int old_free_idx = mspace->free_block_idx;
+  unsigned int new_free_idx = old_free_idx+1;
+  while( old_free_idx <= mspace->ceiling_block_idx ){   
+    unsigned int allocated_idx = atomic_cas32(&mspace->free_block_idx, new_free_idx, old_free_idx);
+    if(allocated_idx != old_free_idx){
+      old_free_idx = mspace->free_block_idx;
+      new_free_idx = old_free_idx+1;
+      continue;
+    }
+    /* ok, got one */
+    alloc_block = (Block_Header*)&(mspace->blocks[allocated_idx - mspace->first_block_idx]);
+    assert(alloc_block->status == BLOCK_FREE);
+    alloc_block->status = BLOCK_IN_USE;
+    mspace->num_used_blocks++;
+    memset(alloc_block->free, 0, GC_BLOCK_BODY_SIZE_BYTES);
+    
+    /* set allocation context */
+    allocator->free = alloc_block->free;
+    allocator->ceiling = alloc_block->ceiling;
+    allocator->alloc_block = (Block*)alloc_block; 
+    
+    return TRUE;
+  }
+
+  /* if Mspace is used for mutator allocation, here a collection should be triggered. 
+     else if this is only for collector allocation, when code goes here, it means 
+     Mspace is not enough to hold Nursery live objects, so the invoker of this routine 
+     should throw out-of-memory exception.
+     But because in our design, we don't do any Mspace allocation during collection, this
+     path should never be reached. That's why we assert(0) here. */  
+  assert(0);
+  return FALSE;
   
-  /* FIXME:: collect Mspace if for mutator, else assert(0) */
-  assert(0);
-  return FALSE;
-  
 }
-
-struct GC_Gen;
+
+struct GC_Gen;
 Space* gc_get_mos(GC_Gen* gc);
-void* mspace_alloc(unsigned int size, Alloc_Context* alloc_ctx)
+void* mspace_alloc(unsigned int size, Allocator* allocator)
 {
   void *p_return = NULL;
- 
-  Mspace* mspace = (Mspace*)gc_get_mos((GC_Gen*)alloc_ctx->gc);
+ 
+  Mspace* mspace = (Mspace*)gc_get_mos((GC_Gen*)allocator->gc);
   
   /* All chunks of data requested need to be multiples of GC_OBJECT_ALIGNMENT */
   assert((size % GC_OBJECT_ALIGNMENT) == 0);
   assert( size <= GC_OBJ_SIZE_THRESHOLD );
 
-  /* check if collector local alloc block is ok. If not, grab a new block */
-  p_return = thread_local_alloc(size, alloc_ctx);
+  /* check if collector local alloc block is ok. If not, grab a new block */
+  p_return = thread_local_alloc(size, allocator);
   if(p_return) return p_return;
   
-  /* grab a new block */
-  Boolean ok = mspace_alloc_block(mspace, alloc_ctx);
-  assert(ok);
-  
-  p_return = thread_local_alloc(size, alloc_ctx);
+  /* grab a new block */
+  Boolean ok = mspace_alloc_block(mspace, allocator);
+  assert(ok);
+  
+  p_return = thread_local_alloc(size, allocator);
   assert(p_return);
     
   return p_return;

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect.cpp?view=diff&rev=468252&r1=468251&r2=468252
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect.cpp Thu Oct 26 20:48:43 2006
@@ -1,334 +0,0 @@
-/*
- *  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, 2006/10/05
- */
-
-#include "mspace_collect.h"
-#include "../thread/collector.h"
-#include "../trace_forward/fspace.h"
-#include "../common/interior_pointer.h"
-struct GC_Gen;
-Space* gc_get_nos(GC_Gen* gc);
-Space* gc_get_mos(GC_Gen* gc);
-Space* gc_get_los(GC_Gen* gc);
-
-void mspace_save_reloc(Mspace* mspace, Partial_Reveal_Object** p_ref)
-{
-  Block_Info* block_info = GC_BLOCK_INFO_ADDRESS(mspace, p_ref);
-  block_info->reloc_table->push_back(p_ref);
-  return;
-}
-
-void  mspace_update_reloc(Mspace* mspace)
-{
-  SlotVector* reloc_table;
-  /* update refs in mspace */
-  for(unsigned int i=0; i < mspace->num_used_blocks; i++){
-    Block_Info* block_info = &(mspace->block_info[i]);
-    reloc_table = block_info->reloc_table;
-    for(unsigned int j=0; j < reloc_table->size(); j++){
-      Partial_Reveal_Object** p_ref = (*reloc_table)[j];
-      Partial_Reveal_Object* p_target_obj = get_forwarding_pointer_in_obj_info(*p_ref);
-      *p_ref = p_target_obj;
-    }
-    reloc_table->clear();
-  }
-  
-  return;  
-}  
-
-Boolean mspace_mark_object(Mspace* mspace, Partial_Reveal_Object *p_obj)
-{  
-  obj_mark_in_vt(p_obj);
-
-  unsigned int obj_word_index = OBJECT_WORD_INDEX_TO_MARKBIT_TABLE(p_obj);
-  unsigned int obj_offset_in_word = OBJECT_WORD_OFFSET_IN_MARKBIT_TABLE(p_obj); 	
-	
-  unsigned int *p_word = &(GC_BLOCK_HEADER(p_obj)->mark_table[obj_word_index]);
-  unsigned int word_mask = (1<<obj_offset_in_word);
-	
-  unsigned int result = (*p_word)|word_mask;
-	
-  if( result==(*p_word) ) return FALSE;
-  
-  *p_word = result; 
-  
-   return TRUE;
-}
-
-Boolean mspace_object_is_marked(Partial_Reveal_Object *p_obj, Mspace* mspace)
-{
-  assert(p_obj);
-  
-#ifdef _DEBUG //TODO:: Cleanup
-  unsigned int obj_word_index = OBJECT_WORD_INDEX_TO_MARKBIT_TABLE(p_obj);
-  unsigned int obj_offset_in_word = OBJECT_WORD_OFFSET_IN_MARKBIT_TABLE(p_obj); 	
-	
-  unsigned int *p_word = &(GC_BLOCK_HEADER(p_obj)->mark_table[obj_word_index]);
-  unsigned int word_mask = (1<<obj_offset_in_word);
-	
-  unsigned int result = (*p_word)|word_mask;
-	
-  if( result==(*p_word) )
-    assert( obj_is_marked_in_vt(p_obj));
-  else 
-    assert(!obj_is_marked_in_vt(p_obj));
-    
-#endif
-
-  return (obj_is_marked_in_vt(p_obj));
-    
-}
-
-static Boolean mspace_compute_object_target(Mspace* mspace)
-{  
-  unsigned int target_blk_idx;
-  Block_Header* dest_block = mspace_get_first_target_block(mspace, &target_blk_idx);    
-
-  unsigned int compact_blk_idx;
-  Block_Header* curr_block = mspace_get_first_compact_block(mspace, &compact_blk_idx);
-
-  void* dest_addr = GC_BLOCK_BODY(dest_block);
- 
-  while( curr_block ){
-    unsigned int mark_bit_idx;
-    Partial_Reveal_Object* p_obj = block_get_first_marked_object(curr_block, &mark_bit_idx);
-    
-    while( p_obj ){
-      assert( obj_is_marked_in_vt(p_obj));
-            
-      unsigned int obj_size = vm_object_size(p_obj);
-      
-      if( ((unsigned int)dest_addr + obj_size) > (unsigned int)GC_BLOCK_END(dest_block)){
-        dest_block->free = dest_addr;
-        dest_block = mspace_get_next_target_block(mspace, &target_blk_idx);
-        dest_addr = GC_BLOCK_BODY(dest_block);
-      }
-      assert(((unsigned int)dest_addr + obj_size) <= (unsigned int)GC_BLOCK_END(dest_block));
-      
-      Obj_Info_Type obj_info = get_obj_info(p_obj);
-      if( obj_info != 0 ) {
-        mspace->obj_info_map->insert(ObjectMap::value_type((Partial_Reveal_Object*)dest_addr, obj_info));
-      }
-      
-      //FIXME: should use alloc to handle alignment requirement
-      set_forwarding_pointer_in_obj_info(p_obj, dest_addr);
-
-      dest_addr = (void *) WORD_SIZE_ROUND_UP((unsigned int) dest_addr + obj_size);
-      p_obj = block_get_next_marked_object(curr_block, &mark_bit_idx);
-  
-    }
-    curr_block = mspace_get_next_compact_block(mspace, &compact_blk_idx);
-  }
-
-
-  mspace->free_block_idx = dest_block->block_idx+1;
-
-  /* fail to evacuate any room, FIXME:: do nothing at the moment */
-  if( mspace->free_block_idx == mspace->num_current_blocks) 
-    return FALSE;
-  
-  return TRUE;
-}   
-
-static Boolean fspace_compute_object_target(Collector* collector, Fspace* fspace)
-{  
-  Mspace* mspace = (Mspace*)collector->collect_space;
-  unsigned int target_blk_idx;
-  Block_Header* dest_block = mspace_get_first_block_for_nos(mspace, &target_blk_idx);    
-  void* dest_addr = GC_BLOCK_BODY(dest_block);
-
-  unsigned int* mark_table = fspace->mark_table;
-  unsigned int* table_end = (unsigned int*)((POINTER_SIZE_INT)mark_table + fspace->mark_table_size);
-  unsigned int* fspace_start = (unsigned int*)fspace->heap_start;
-  Partial_Reveal_Object* p_obj = NULL;
-    
-  unsigned j=0;
-  while( (mark_table + j) < table_end){
-    unsigned int markbits = *(mark_table+j);
-    if(!markbits){ j++; continue; }
-    unsigned int k=0;
-    while(k<32){
-      if( !(markbits& (1<<k)) ){ k++; continue;}
-      p_obj = (Partial_Reveal_Object*)(fspace_start + (j<<5) + k);
-      assert( obj_is_marked_in_vt(p_obj));
-      
-      unsigned int obj_size = vm_object_size(p_obj);
-
-      if( ((unsigned int)dest_addr + obj_size) > (unsigned int)GC_BLOCK_END(dest_block)){
-        dest_block->free = dest_addr;
-        dest_block = mspace_get_next_block_for_nos(mspace, &target_blk_idx);
-        
-        if(dest_block == NULL) return FALSE;
-        dest_addr = GC_BLOCK_BODY(dest_block);
-      }
-      assert(((unsigned int)dest_addr + obj_size) <= (unsigned int)GC_BLOCK_END(dest_block));
-      
-      Obj_Info_Type obj_info = get_obj_info(p_obj);
-      if( obj_info != 0 ) {
-        fspace->obj_info_map->insert(ObjectMap::value_type((Partial_Reveal_Object*)dest_addr, obj_info));
-      }
-      
-      //FIXME: should use alloc to handle alignment requirement
-      set_forwarding_pointer_in_obj_info(p_obj, dest_addr);
-
-      dest_addr = (void *) WORD_SIZE_ROUND_UP((unsigned int) dest_addr + obj_size);
-      
-      k++;
-    }   
-    j++;;
-  }
-
-  mspace->free_block_idx = dest_block->block_idx+1;
-  
-  return TRUE;
-}   
-
-static void update_relocated_refs(Collector* collector)
-{
-  GC_Gen* gc = (GC_Gen*)collector->gc;
-  Space* space;
-  space = gc_get_nos(gc);  space->update_reloc_func(space);
-  space = gc_get_mos(gc);  space->update_reloc_func(space);
-  space = gc_get_los(gc);  space->update_reloc_func(space);
-
-  gc_update_rootset((GC*)gc);  
-
-  space_update_remsets((Fspace*)gc_get_nos(gc));
-  
-  /* FIXME:: interior table */
-  update_rootset_interior_pointer();
-  return;
-}
-
-static void mspace_restore_obj_info(Mspace* mspace)
-{
-  ObjectMap* objmap = mspace->obj_info_map;
-  ObjectMap::iterator obj_iter;
-  for( obj_iter=objmap->begin(); obj_iter!=objmap->end(); obj_iter++){
-    Partial_Reveal_Object* p_target_obj = obj_iter->first;
-    Obj_Info_Type obj_info = obj_iter->second;
-    set_obj_info(p_target_obj, obj_info);     
-  }
-  objmap->clear();
-  return;  
-}
-
-static void restore_saved_obj_info(Collector* collector)
-{
-  GC_Gen* gc = (GC_Gen*)collector->gc;
-  Space* space;
-  space = gc_get_nos(gc);  fspace_restore_obj_info((Fspace*)space);
-  space = gc_get_mos(gc);  mspace_restore_obj_info((Mspace*)space);
-
-  return;
-}   
-
-static void reset_mspace_for_allocation(Mspace* mspace)
-{ 
-  unsigned int num_used = mspace->num_used_blocks;
-  unsigned int num_free = mspace->free_block_idx;
-  unsigned int index = num_used>num_free? num_used:num_free;
-  
-  for(unsigned int i=0; i < index; i++){
-    Block_Info* block_info = &(mspace->block_info[i]);
-    block_clear_markbits(block_info->block); /* only needed for i<num_used_blocks */
-    block_info->status = BLOCK_USED;
-
-    if(i >= mspace->free_block_idx){
-      block_info->status = BLOCK_FREE; 
-      block_info->block->free = GC_BLOCK_BODY(block_info->block);
-    }
-  }
-  mspace->num_used_blocks = mspace->free_block_idx;
-}
-
-#include "../verify/verify_live_heap.h"
-
-static void mspace_sliding_compact(Collector* collector, Mspace* mspace)
-{
-  unsigned int compact_blk_idx;
-  Block_Header* curr_block = mspace_get_first_compact_block(mspace, &compact_blk_idx);
-  
-  while( curr_block ){
-    unsigned int mark_bit_idx;
-    Partial_Reveal_Object* p_obj = block_get_first_marked_object(curr_block, &mark_bit_idx);
-    
-    while( p_obj ){
-      assert( obj_is_marked_in_vt(p_obj));
-      obj_unmark_in_vt(p_obj);
-      
-      unsigned int obj_size = vm_object_size(p_obj);
-      Partial_Reveal_Object *p_target_obj = get_forwarding_pointer_in_obj_info(p_obj);
-      if( p_obj != p_target_obj){
-        memmove(p_target_obj, p_obj, obj_size);
-
-        if (verify_live_heap)
-          /* we forwarded it, we need remember it for verification */
-          event_collector_move_obj(p_obj, p_target_obj, collector);
-      }
-     
-      set_obj_info(p_target_obj, 0);
- 
-      p_obj = block_get_next_marked_object(curr_block, &mark_bit_idx);  
-    }
-        
-    curr_block = mspace_get_next_compact_block(mspace, &compact_blk_idx);
-  }
-
-  reset_mspace_for_allocation(mspace);
-  
-  return;
-} 
-
-static void mark_compact_mspace(Collector* collector) 
-{
-  /* Pass 1: mark all live objects in heap, and save all the outgoing pointers */
-  mark_scan_heap(collector);
-  
-  /* Pass 2: assign target addresses for all to-be-moved objects */
-  Boolean ok;
-  ok = mspace_compute_object_target((Mspace*)gc_get_mos((GC_Gen*)collector->gc)); 
-  assert(ok); /* free at least one block */
-
-  ok = fspace_compute_object_target(collector, (Fspace*)gc_get_nos((GC_Gen*)collector->gc)); 
-  assert(ok); /* FIXME:: throw out-of-memory exception if not ok */
-  
-  /* Pass 3: update all references whose objects are to be moved */  
-  update_relocated_refs(collector);
-    
-  /* Pass 4: do the compaction and reset blocks */  
-  mspace_sliding_compact(collector, (Mspace*)collector->collect_space);
-  GC_Gen* gc = (GC_Gen*)collector->gc;
-  fspace_copy_collect(collector, (Fspace*)gc_get_nos(gc));
-  
-  restore_saved_obj_info(collector);
-  
-  return;
-}
-
-void mspace_collection(Mspace* mspace) 
-{
-  mspace->num_collections++;
-
-  GC* gc = mspace->gc;  
-
-  collector_execute_task(gc, (TaskType)mark_compact_mspace, (Space*)mspace);
-  
-  return;  
-} 

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect.h?view=diff&rev=468252&r1=468251&r2=468252
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect.h Thu Oct 26 20:48:43 2006
@@ -1,148 +0,0 @@
-/*
- *  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, 2006/10/05
- */
-
-#ifndef _MSC_COLLECT_H_
-#define _MSC_COLLECT_H_
-
-#include "mspace.h"
-
-inline Block_Header* mspace_get_first_block_for_nos(Mspace* mspace, unsigned int* target_blk_idx)
-{  
-  unsigned int index = mspace->free_block_idx;
-  *target_blk_idx = index;
-  return mspace->block_info[index].block;
-}
-
-inline Block_Header* mspace_get_next_block_for_nos(Mspace* mspace, unsigned int* target_blk_idx)
-{  
-  unsigned int index = *target_blk_idx;
-
-  *target_blk_idx = ++index;
-  
-  if( index >= mspace->num_current_blocks) return NULL;
-  
-  return mspace->block_info[index].block; 
-}
-
-inline void block_clear_markbits(Block_Header* block)
-{
-  unsigned int* mark_table = block->mark_table;
-  memset(mark_table, 0, MARKBIT_TABLE_SIZE_WORDS*BYTES_PER_WORD);
-  return;
-}
-
-inline Block_Header* mspace_get_first_compact_block(Mspace* mspace, unsigned int* compact_blk_idx)
-{  
-  assert( mspace->block_info[0].status != BLOCK_FREE );
-
-  *compact_blk_idx = 0;
-  return mspace->block_info[0].block;
-}
-
-inline Block_Header* mspace_get_next_compact_block(Mspace* mspace, unsigned int* compact_blk_idx)
-{  
-  unsigned int index = *compact_blk_idx;
- 
-  if( ++index == mspace->num_used_blocks ) return NULL;
-
-  *compact_blk_idx = index;
-  assert( mspace->block_info[index].status != BLOCK_FREE );
-
-  return mspace->block_info[index].block; 
-}
-
-inline Block_Header* mspace_get_first_target_block(Mspace* mspace, unsigned int* target_blk_idx)
-{  
-  assert( mspace->block_info[0].status != BLOCK_FREE);
-
-  *target_blk_idx = 0;
-  return mspace->block_info[0].block;
-}
-
-inline Block_Header* mspace_get_next_target_block(Mspace* mspace, unsigned int* target_blk_idx)
-{  
-  unsigned int index = *target_blk_idx;
-
-  *target_blk_idx = ++index;
-  /* trick! free_block_idx is changed after computing target addresses */
-  assert( mspace->block_info[index].status != BLOCK_FREE && (index < mspace->free_block_idx));
-  
-  return mspace->block_info[index].block; 
-  
-}
-
-inline Partial_Reveal_Object* block_get_first_marked_object(Block_Header* block, unsigned int* mark_bit_idx)
-{
-  unsigned int* mark_table = block->mark_table;
-  unsigned int* table_end = mark_table + MARKBIT_TABLE_SIZE_WORDS;
-  
-  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 word_index = (j<<BIT_SHIFT_TO_BITS_PER_WORD) + k;
-        Partial_Reveal_Object* p_obj = (Partial_Reveal_Object*)((unsigned int*)GC_BLOCK_BODY(block) + word_index);
-        /* only valid before compaction: assert(obj_is_marked_in_vt(p_obj)); */
-        
-        *mark_bit_idx = word_index;
-      return p_obj;
-    }
-    j++;
-    k=0;
-  }          
-  *mark_bit_idx = 0;
-  return NULL;   
-}
-
-inline Partial_Reveal_Object* block_get_next_marked_object(Block_Header* block, unsigned int* mark_bit_idx)
-{
-  unsigned int* mark_table = block->mark_table;
-  unsigned int* table_end = mark_table + MARKBIT_TABLE_SIZE_WORDS;
-  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 word_index = (j<<BIT_SHIFT_TO_BITS_PER_WORD) + k;
-      Partial_Reveal_Object* p_obj = (Partial_Reveal_Object*)((unsigned int*)GC_BLOCK_BODY(block) + word_index);      
-      /* only valid before compaction: assert(obj_is_marked_in_vt(p_obj)); */
-      
-      *mark_bit_idx = word_index;
-      return p_obj;
-    }
-    j++;
-    k=0;
-  }        
-  
-  *mark_bit_idx = 0;
-  return NULL;   
-
-}
-
-#endif /* #ifndef _MSC_COLLECT_H_ */
\ No newline at end of file

Added: incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect_compact.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect_compact.cpp?view=auto&rev=468252
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect_compact.cpp (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect_compact.cpp Thu Oct 26 20:48:43 2006
@@ -0,0 +1,270 @@
+/*
+ *  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, 2006/10/05
+ */
+
+#include "mspace.h"
+#include "../thread/collector.h"
+#include "../trace_forward/fspace.h"
+struct GC_Gen;
+Space* gc_get_nos(GC_Gen* gc);
+Space* gc_get_mos(GC_Gen* gc);
+Space* gc_get_los(GC_Gen* gc);
+
+static Block_Header* mspace_get_first_compact_block(Mspace* mspace)
+{ return (Block_Header*)mspace->blocks; }
+
+static Block_Header* mspace_get_next_compact_block(Mspace* mspace, Block_Header* block)
+{ return block->next; }
+
+static Block_Header* mspace_get_first_target_block(Mspace* mspace)
+{ return (Block_Header*)mspace->blocks; }
+
+static Block_Header* mspace_get_next_target_block(Mspace* mspace, Block_Header* block)
+{ return block->next; }
+
+void mspace_save_reloc(Mspace* mspace, Partial_Reveal_Object** p_ref)
+{
+  Block_Header* block = GC_BLOCK_HEADER(p_ref);
+  block->reloc_table->push_back(p_ref);
+  return;
+}
+
+void  mspace_update_reloc(Mspace* mspace)
+{
+  SlotVector* reloc_table;
+  /* update refs in mspace */
+  Block* blocks = mspace->blocks;
+  for(unsigned int i=0; i < mspace->num_used_blocks; i++){
+    Block_Header* block = (Block_Header*)&(blocks[i]);
+    reloc_table = block->reloc_table;
+    for(unsigned int j=0; j < reloc_table->size(); j++){
+      Partial_Reveal_Object** p_ref = (*reloc_table)[j];
+      Partial_Reveal_Object* p_target_obj = get_forwarding_pointer_in_obj_info(*p_ref);
+      *p_ref = p_target_obj;
+    }
+    reloc_table->clear();
+  }
+  
+  return;  
+}  
+
+Boolean mspace_mark_object(Mspace* mspace, Partial_Reveal_Object *p_obj)
+{  
+  obj_mark_in_vt(p_obj);
+
+  unsigned int obj_word_index = OBJECT_WORD_INDEX_TO_MARKBIT_TABLE(p_obj);
+  unsigned int obj_offset_in_word = OBJECT_WORD_OFFSET_IN_MARKBIT_TABLE(p_obj); 	
+	
+  unsigned int *p_word = &(GC_BLOCK_HEADER(p_obj)->mark_table[obj_word_index]);
+  unsigned int word_mask = (1<<obj_offset_in_word);
+	
+  unsigned int result = (*p_word)|word_mask;
+	
+  if( result==(*p_word) ) return FALSE;
+  
+  *p_word = result; 
+  
+   return TRUE;
+}
+
+Boolean mspace_object_is_marked(Partial_Reveal_Object *p_obj, Mspace* mspace)
+{
+  assert(p_obj);
+  
+#ifdef _DEBUG //TODO:: Cleanup
+  unsigned int obj_word_index = OBJECT_WORD_INDEX_TO_MARKBIT_TABLE(p_obj);
+  unsigned int obj_offset_in_word = OBJECT_WORD_OFFSET_IN_MARKBIT_TABLE(p_obj); 	
+	
+  unsigned int *p_word = &(GC_BLOCK_HEADER(p_obj)->mark_table[obj_word_index]);
+  unsigned int word_mask = (1<<obj_offset_in_word);
+	
+  unsigned int result = (*p_word)|word_mask;
+	
+  if( result==(*p_word) )
+    assert( obj_is_marked_in_vt(p_obj));
+  else 
+    assert(!obj_is_marked_in_vt(p_obj));
+    
+#endif
+
+  return (obj_is_marked_in_vt(p_obj));
+    
+}
+
+static Boolean mspace_compute_object_target(Mspace* mspace)
+{  
+  Block_Header* dest_block = mspace_get_first_target_block(mspace);    
+  Block_Header* curr_block = mspace_get_first_compact_block(mspace);
+
+  void* dest_addr = GC_BLOCK_BODY(dest_block);
+ 
+  while( curr_block ){
+    unsigned int mark_bit_idx;
+    Partial_Reveal_Object* p_obj = block_get_first_marked_object(curr_block, &mark_bit_idx);
+    
+    while( p_obj ){
+      assert( obj_is_marked_in_vt(p_obj));
+            
+      unsigned int obj_size = vm_object_size(p_obj);
+      
+      if( ((unsigned int)dest_addr + obj_size) > (unsigned int)GC_BLOCK_END(dest_block)){
+        dest_block->free = dest_addr;
+        dest_block = mspace_get_next_target_block(mspace, dest_block);
+        dest_addr = GC_BLOCK_BODY(dest_block);
+      }
+      assert(((unsigned int)dest_addr + obj_size) <= (unsigned int)GC_BLOCK_END(dest_block));
+      
+      Obj_Info_Type obj_info = get_obj_info(p_obj);
+      if( obj_info != 0 ) {
+        mspace->obj_info_map->insert(ObjectMap::value_type((Partial_Reveal_Object*)dest_addr, obj_info));
+      }
+      
+      assert( (unsigned int) p_obj >= (unsigned int)dest_addr );
+      set_forwarding_pointer_in_obj_info(p_obj, dest_addr);
+
+      /* FIXME: should use alloc to handle alignment requirement */
+      dest_addr = (void *) WORD_SIZE_ROUND_UP((unsigned int) dest_addr + obj_size);
+      p_obj = block_get_next_marked_object(curr_block, &mark_bit_idx);
+  
+    }
+    curr_block = mspace_get_next_compact_block(mspace, curr_block);
+  }
+
+
+  mspace->free_block_idx = dest_block->block_idx+1;
+
+  /* fail to evacuate any room, FIXME:: do nothing at the moment */
+  if( mspace->free_block_idx == mspace->first_block_idx + mspace->num_used_blocks) 
+    return FALSE;
+  
+  return TRUE;
+}   
+
+static void mspace_restore_obj_info(Mspace* mspace)
+{
+  ObjectMap* objmap = mspace->obj_info_map;
+  ObjectMap::iterator obj_iter;
+  for( obj_iter=objmap->begin(); obj_iter!=objmap->end(); obj_iter++){
+    Partial_Reveal_Object* p_target_obj = obj_iter->first;
+    Obj_Info_Type obj_info = obj_iter->second;
+    set_obj_info(p_target_obj, obj_info);     
+  }
+  objmap->clear();
+  return;  
+}
+  
+static void reset_mspace_after_compaction(Mspace* mspace)
+{ 
+  unsigned int old_num_used = mspace->num_used_blocks;
+  unsigned int new_num_used = mspace->free_block_idx - mspace->first_block_idx;
+  unsigned int num_used = old_num_used>new_num_used? old_num_used:new_num_used;
+  
+  Block* blocks = mspace->blocks;
+  for(unsigned int i=0; i < num_used; i++){
+    Block_Header* block = (Block_Header*)&(blocks[i]);
+    block_clear_mark_table(block); 
+    block->status = BLOCK_USED;
+
+    if(i >= new_num_used){
+      block->status = BLOCK_FREE; 
+      block->free = GC_BLOCK_BODY(block);
+    }
+  }
+  mspace->num_used_blocks = new_num_used;
+}
+
+#include "../verify/verify_live_heap.h"
+
+static void mspace_sliding_compact(Collector* collector, Mspace* mspace)
+{
+  Block_Header* curr_block = mspace_get_first_compact_block(mspace);
+  
+  while( curr_block ){
+    unsigned int mark_bit_idx;
+    Partial_Reveal_Object* p_obj = block_get_first_marked_object(curr_block, &mark_bit_idx);
+    
+    while( p_obj ){
+      assert( obj_is_marked_in_vt(p_obj));
+      obj_unmark_in_vt(p_obj);
+      
+      unsigned int obj_size = vm_object_size(p_obj);
+      Partial_Reveal_Object *p_target_obj = get_forwarding_pointer_in_obj_info(p_obj);
+      if( p_obj != p_target_obj){
+        memmove(p_target_obj, p_obj, obj_size);
+
+        if (verify_live_heap)
+          /* we forwarded it, we need remember it for verification */
+          event_collector_move_obj(p_obj, p_target_obj, collector);
+      }
+     
+      set_obj_info(p_target_obj, 0);
+ 
+      p_obj = block_get_next_marked_object(curr_block, &mark_bit_idx);  
+    }
+        
+    curr_block = mspace_get_next_compact_block(mspace, curr_block);
+  }
+
+  mspace_restore_obj_info(mspace);
+  reset_mspace_after_compaction(mspace);
+  
+  return;
+} 
+
+void gc_gen_update_repointed_refs(Collector* collector);
+
+static void mark_compact_mspace(Collector* collector) 
+{
+  GC_Gen* gc = (GC_Gen*)collector->gc;
+  Mspace* mspace = (Mspace*)gc_get_mos(gc);
+  Fspace* fspace = (Fspace*)gc_get_nos(gc);
+
+  /* FIXME:: Single-threaded mark-compaction for mspace currently */
+
+  /* Pass 1: mark all live objects in heap, and save all the slots that 
+             have references  that are going to be repointed */
+  mark_scan_heap(collector);
+  
+  /* Pass 2: assign target addresses for all to-be-moved objects */
+  Boolean ok;
+  ok = mspace_compute_object_target(mspace); 
+  assert(ok); /* free at least one block */
+  ok = fspace_compute_object_target(collector, fspace); 
+  assert(ok); /* FIXME:: throw out-of-memory exception if not ok */
+  
+  /* Pass 3: update all references whose objects are to be moved */  
+  gc_gen_update_repointed_refs(collector);
+    
+  /* Pass 4: do the compaction and reset blocks */  
+  mspace_sliding_compact(collector, mspace);
+  fspace_copy_collect(collector, fspace);
+     
+  return;
+}
+
+void mspace_collection(Mspace* mspace) 
+{
+  mspace->num_collections++;
+
+  GC* gc = mspace->gc;  
+
+  collector_execute_task(gc, (TaskType)mark_compact_mspace, (Space*)mspace);
+  
+  return;  
+} 

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.cpp?view=diff&rev=468252&r1=468251&r2=468252
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.cpp Thu Oct 26 20:48:43 2006
@@ -1,121 +1,129 @@
-/*
- *  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, 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, Alloc_Context *alloc_ctx)
-{  
-  Lspace* lspace = (Lspace*)gc_get_los((GC_Gen*)alloc_ctx->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 >> 1;
-  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;
-  unsigned int num_words = (num_bits >> BIT_SHIFT_TO_BITS_PER_WORD)+1;
-  lspace->mark_table = (unsigned int*)STD_MALLOC( num_words*BYTES_PER_WORD );
-  memset(lspace->mark_table, 0, num_words*BYTES_PER_WORD);
-  
-  lspace->reloc_table = new SlotVector();
-  lspace->mark_object_func = lspace_mark_object;
-  lspace->save_reloc_func = lspace_save_reloc;
-  lspace->update_reloc_func = lspace_update_reloc;
-  
-  lspace->move_object = FALSE;
-  lspace->gc = gc;
-  gc_set_los((GC_Gen*)gc, (Space*)lspace);
-  
-  los_boundary = start;
-  
-  return;
-}
-
-void lspace_destruct(Lspace* lspace)
-{
-  //FIXME:: decommit lspace space
-  STD_FREE(lspace->mark_table);
-  STD_FREE(lspace);
-  lspace = NULL;
-  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)>>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_markbits = &(lspace->mark_table[word_index]);
+/*
+ *  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, 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 >> 1;
+  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;
+  unsigned int num_words = (num_bits >> BIT_SHIFT_TO_BITS_PER_WORD)+1;
+  lspace->mark_table = (unsigned int*)STD_MALLOC( num_words*BYTES_PER_WORD );
+  memset(lspace->mark_table, 0, num_words*BYTES_PER_WORD);
+  
+  lspace->reloc_table = new SlotVector();
+  lspace->mark_object_func = lspace_mark_object;
+  lspace->save_reloc_func = lspace_save_reloc;
+  lspace->update_reloc_func = lspace_update_reloc;
+  
+  lspace->move_object = FALSE;
+  lspace->gc = gc;
+  gc_set_los((GC_Gen*)gc, (Space*)lspace);
+  
+  los_boundary = start;
+  
+  return;
+}
+
+void lspace_destruct(Lspace* lspace)
+{
+  //FIXME:: decommit lspace space
+  STD_FREE(lspace->mark_table);
+  STD_FREE(lspace);
+  lspace = NULL;
+  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)>>BIT_SHIFT_TO_BITS_PER_BYTE );
+  
+  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_markbits = &(lspace->mark_table[word_index]);
   unsigned int word_mask = (1<<bit_offset_in_word);
 	
   unsigned int result = (*p_markbits)|word_mask;
@@ -123,25 +131,25 @@
   if( result==(*p_markbits) ) return FALSE;
   
   *p_markbits = result; 
-      
-  return TRUE;
-}
-
-void lspace_save_reloc(Lspace* lspace, Partial_Reveal_Object** p_ref)
-{
-  lspace->reloc_table->push_back(p_ref);
-}
-
-void lspace_update_reloc(Lspace* lspace)
-{
-  SlotVector* reloc_table;
-  
-  reloc_table = lspace->reloc_table;
-  for(unsigned int j=0; j < reloc_table->size(); j++){
-    Partial_Reveal_Object** p_ref = (*reloc_table)[j];
-    Partial_Reveal_Object* p_target_obj = get_forwarding_pointer_in_obj_info(*p_ref);
-    *p_ref = p_target_obj;
-  }
-  reloc_table->clear();
-  return;
-}
+      
+  return TRUE;
+}
+
+void lspace_save_reloc(Lspace* lspace, Partial_Reveal_Object** p_ref)
+{
+  lspace->reloc_table->push_back(p_ref);
+}
+
+void lspace_update_reloc(Lspace* lspace)
+{
+  SlotVector* reloc_table;
+  
+  reloc_table = lspace->reloc_table;
+  for(unsigned int j=0; j < reloc_table->size(); j++){
+    Partial_Reveal_Object** p_ref = (*reloc_table)[j];
+    Partial_Reveal_Object* p_target_obj = get_forwarding_pointer_in_obj_info(*p_ref);
+    *p_ref = p_target_obj;
+  }
+  reloc_table->clear();
+  return;
+}