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;
+}