You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by wj...@apache.org on 2006/12/05 23:32:39 UTC
svn commit: r482809 [2/2] - in /harmony/enhanced/drlvm/trunk:
build/make/components/vm/ vm/gc_gen/javasrc/ vm/gc_gen/javasrc/org/
vm/gc_gen/javasrc/org/apache/ vm/gc_gen/javasrc/org/apache/harmony/
vm/gc_gen/javasrc/org/apache/harmony/drlvm/ vm/gc_gen/...
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_forward.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_forward.cpp?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_forward.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_forward.cpp Tue Dec 5 14:32:35 2006
@@ -0,0 +1,252 @@
+
+/*
+ * 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 "fspace.h"
+#include "../thread/collector.h"
+#include "../common/gc_metadata.h"
+
+static Boolean fspace_object_to_be_forwarded(Partial_Reveal_Object *p_obj, Fspace *fspace)
+{
+ assert(obj_belongs_to_space(p_obj, (Space*)fspace));
+ return forward_first_half? (p_obj < object_forwarding_boundary):(p_obj>=object_forwarding_boundary);
+}
+
+static void scan_slot(Collector* collector, Partial_Reveal_Object **p_ref)
+{
+ Partial_Reveal_Object *p_obj = *p_ref;
+ if (p_obj == NULL) return;
+
+ /* the slot can be in tspace or fspace, we don't care.
+ we care only if the reference in the slot is pointing to fspace */
+ if (obj_belongs_to_space(p_obj, collector->collect_space))
+ collector_tracestack_push(collector, p_ref);
+
+ return;
+}
+
+static void scan_object(Collector* collector, Partial_Reveal_Object *p_obj)
+{
+ if (!object_has_ref_field(p_obj)) return;
+
+ void *slot;
+
+ /* scan array object */
+ if (object_is_array(p_obj)) {
+ Partial_Reveal_Object* array = p_obj;
+ assert(!obj_is_primitive_array(array));
+
+ int32 array_length = vector_get_length((Vector_Handle) array);
+ for (int i = 0; i < array_length; i++) {
+ slot = vector_get_element_address_ref((Vector_Handle) array, i);
+ scan_slot(collector, (Partial_Reveal_Object **)slot);
+ }
+ return;
+ }
+
+ /* scan non-array object */
+ int *offset_scanner = init_object_scanner(p_obj);
+ while (true) {
+ slot = offset_get_ref(offset_scanner, p_obj);
+ if (slot == NULL) break;
+
+ scan_slot(collector, (Partial_Reveal_Object **)slot);
+ offset_scanner = offset_next_ref(offset_scanner);
+ }
+
+ return;
+}
+
+/* NOTE:: At this point, p_ref can be in anywhere like root, and other spaces, but *p_ref must be in fspace,
+ since only slot which points to object in fspace could be added into TraceStack.
+ The problem is the *p_ref may be forwarded already so that, when we come here we find it's pointing to tospace.
+ We will simply return for that case. It might be forwarded due to:
+ 1. two difference slots containing same reference;
+ 2. duplicate slots in remset ( we use SSB for remset, no duplication filtering.)
+ The same object can be traced by the thread itself, or by other thread.
+*/
+
+#include "../verify/verify_live_heap.h"
+
+static void forward_object(Collector* collector, Partial_Reveal_Object **p_ref)
+{
+ Space* space = collector->collect_space;
+ GC* gc = collector->gc;
+ Partial_Reveal_Object *p_obj = *p_ref;
+
+ if(!obj_belongs_to_space(p_obj, space)) return;
+
+ /* Fastpath: object has already been forwarded, update the ref slot */
+ if(obj_is_forwarded_in_vt(p_obj)) {
+ *p_ref = obj_get_forwarding_pointer_in_vt(p_obj);
+ return;
+ }
+
+ /* only mark the objects that will remain in fspace */
+ if(!fspace_object_to_be_forwarded(p_obj, (Fspace*)space)) {
+ assert(!obj_is_forwarded_in_vt(p_obj));
+ /* this obj remains in fspace, remember its ref slot for next GC if p_ref is not root */
+ if( !address_belongs_to_space(p_ref, space) && address_belongs_to_gc_heap(p_ref, gc))
+ collector_remset_add_entry(collector, p_ref);
+
+ if(fspace_mark_object((Fspace*)space, p_obj))
+ scan_object(collector, p_obj);
+
+ return;
+ }
+
+ /* following is the logic for forwarding */
+ Partial_Reveal_Object* p_target_obj = collector_forward_object(collector, p_obj);
+
+ /* if p_target_obj is NULL, it is forwarded by other thread.
+ Note: a race condition here, it might be forwarded by other, but not set the
+ forwarding pointer yet. We need spin here to get the forwarding pointer.
+ We can implement the collector_forward_object() so that the forwarding pointer
+ is set in the atomic instruction, which requires to roll back the mos_alloced
+ space. That is easy for thread local block allocation cancellation. */
+ if( p_target_obj == NULL ){
+ Partial_Reveal_Object *forward_ptr = obj_get_forwarding_pointer_in_vt(p_obj);
+ while(forward_ptr == NULL)
+ forward_ptr = obj_get_forwarding_pointer_in_vt(p_obj);
+
+ *p_ref = forward_ptr;
+ return;
+ }
+ /* otherwise, we successfully forwarded */
+ *p_ref = p_target_obj;
+
+ /* we forwarded it, we need remember it for verification. */
+ if(verify_live_heap) {
+ event_collector_move_obj(p_obj, p_target_obj, collector);
+ }
+
+ scan_object(collector, p_target_obj);
+ return;
+}
+
+static void trace_object(Collector* collector, Partial_Reveal_Object **p_ref)
+{
+ forward_object(collector, p_ref);
+
+ Vector_Block* trace_stack = (Vector_Block*)collector->trace_stack;
+ while( !vector_stack_is_empty(trace_stack)){
+ p_ref = (Partial_Reveal_Object **)vector_stack_pop(trace_stack);
+ forward_object(collector, p_ref);
+ trace_stack = (Vector_Block*)collector->trace_stack;
+ }
+
+ return;
+}
+
+/* for tracing phase termination detection */
+static volatile unsigned int num_finished_collectors = 0;
+
+static void collector_trace_rootsets(Collector* collector)
+{
+ GC* gc = collector->gc;
+ GC_Metadata* metadata = gc->metadata;
+
+ unsigned int num_active_collectors = gc->num_active_collectors;
+ atomic_cas32( &num_finished_collectors, 0, num_active_collectors);
+
+ Space* space = collector->collect_space;
+ collector->trace_stack = pool_get_entry(metadata->free_task_pool);
+
+ /* find root slots saved by 1. active mutators, 2. exited mutators, 3. last cycle collectors */
+ Vector_Block* root_set = pool_get_entry(metadata->gc_rootset_pool);
+
+ /* first step: copy all root objects to trace tasks. */
+ while(root_set){
+ unsigned int* iter = vector_block_iterator_init(root_set);
+ while(!vector_block_iterator_end(root_set,iter)){
+ Partial_Reveal_Object** p_ref = (Partial_Reveal_Object** )*iter;
+ iter = vector_block_iterator_advance(root_set,iter);
+ if(*p_ref == NULL) continue; /* root ref cann't be NULL, but remset can be */
+ if(obj_belongs_to_space(*p_ref, space)){
+ collector_tracestack_push(collector, p_ref);
+ }
+ }
+ vector_block_clear(root_set);
+ pool_put_entry(metadata->free_set_pool, root_set);
+ root_set = pool_get_entry(metadata->gc_rootset_pool);
+ }
+ /* put back the last trace_stack task */
+ pool_put_entry(metadata->mark_task_pool, collector->trace_stack);
+
+ /* second step: iterate over the trace tasks and forward objects */
+ collector->trace_stack = pool_get_entry(metadata->free_task_pool);
+
+retry:
+ Vector_Block* trace_task = pool_get_entry(metadata->mark_task_pool);
+
+ while(trace_task){
+ unsigned int* iter = vector_block_iterator_init(trace_task);
+ while(!vector_block_iterator_end(trace_task,iter)){
+ Partial_Reveal_Object** p_ref = (Partial_Reveal_Object** )*iter;
+ iter = vector_block_iterator_advance(trace_task,iter);
+ assert(*p_ref); /* a task can't be NULL, it was checked before put into the task stack */
+ /* in sequential version, we only trace same object once, but we were using a local hashset for that,
+ which couldn't catch the repetition between multiple collectors. This is subject to more study. */
+
+ /* FIXME:: we should not let root_set empty during working, other may want to steal it.
+ degenerate my stack into root_set, and grab another stack */
+
+ /* a task has to belong to collected space, it was checked before put into the stack */
+ trace_object(collector, p_ref);
+ }
+ vector_stack_clear(trace_task);
+ pool_put_entry(metadata->free_task_pool, trace_task);
+ trace_task = pool_get_entry(metadata->mark_task_pool);
+ }
+
+ atomic_inc32(&num_finished_collectors);
+ while(num_finished_collectors != num_active_collectors){
+ if( pool_is_empty(metadata->mark_task_pool)) continue;
+ /* we can't grab the task here, because of a race condition. If we grab the task,
+ and the pool is empty, other threads may fall to this barrier and then pass. */
+ atomic_dec32(&num_finished_collectors);
+ goto retry;
+ }
+
+ /* now we are done, but each collector has a private stack that is empty */
+ trace_task = (Vector_Block*)collector->trace_stack;
+ vector_stack_clear(trace_task);
+ pool_put_entry(metadata->free_task_pool, trace_task);
+ collector->trace_stack = NULL;
+
+ return;
+}
+
+void trace_forward_fspace(Collector* collector)
+{
+ GC* gc = collector->gc;
+ Fspace* space = (Fspace*)collector->collect_space;
+
+ collector_trace_rootsets(collector);
+
+ /* the rest work is not enough for parallelization, so let only one thread go */
+ if( collector->thread_handle != 0 ) return;
+
+ gc_update_repointed_refs(collector);
+ reset_fspace_for_allocation(space);
+
+ return;
+
+}
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_forward_par.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_forward_par.cpp?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_forward_par.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_forward_par.cpp Tue Dec 5 14:32:35 2006
@@ -1,247 +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 "fspace.h"
-#include "../thread/collector.h"
-#include "../common/gc_metadata.h"
-
-static Boolean fspace_object_to_be_forwarded(Partial_Reveal_Object *p_obj, Fspace *fspace)
-{
- assert(obj_belongs_to_space(p_obj, (Space*)fspace));
- return forward_first_half? (p_obj < object_forwarding_boundary):(p_obj>=object_forwarding_boundary);
-}
-
-static void scan_slot(Collector* collector, Partial_Reveal_Object **p_ref)
-{
- Partial_Reveal_Object *p_obj = *p_ref;
- if (p_obj == NULL) return;
-
- /* the slot can be in tspace or fspace, we don't care.
- we care only if the reference in the slot is pointing to fspace */
- if (obj_belongs_to_space(p_obj, collector->collect_space))
- collector_tracetask_add_entry(collector, p_ref);
-
- return;
-}
-
-static void scan_object(Collector* collector, Partial_Reveal_Object *p_obj)
-{
- if (!object_has_slots(p_obj)) return;
-
- void *slot;
-
- /* scan array object */
- if (object_is_array(p_obj)) {
- Partial_Reveal_Object* array = p_obj;
- assert(!obj_is_primitive_array(array));
-
- int32 array_length = vector_get_length((Vector_Handle) array);
- for (int i = 0; i < array_length; i++) {
- slot = vector_get_element_address_ref((Vector_Handle) array, i);
- scan_slot(collector, (Partial_Reveal_Object **)slot);
- }
- return;
- }
-
- /* scan non-array object */
- int *offset_scanner = init_object_scanner(p_obj);
- while (true) {
- slot = offset_get_ref(offset_scanner, p_obj);
- if (slot == NULL) break;
-
- scan_slot(collector, (Partial_Reveal_Object **)slot);
- offset_scanner = offset_next_ref(offset_scanner);
- }
-
- return;
-}
-
-/* At this point, p_ref can be in anywhere like root, and other spaces,
- * but *p_ref must be in fspace, since only slot which points to
- * object in fspace could be added into TraceStack */
-#include "../verify/verify_live_heap.h"
-
-static void trace_object(Collector* collector, Partial_Reveal_Object **p_ref)
-{
- Space* space = collector->collect_space;
- Partial_Reveal_Object *p_obj = *p_ref;
-
- assert(p_obj);
- /* this assert is no longer valid for parallel forwarding, because remset may have duplicate p_refs that
- are traced by difference collectors, and right after both check the p_obj is in fspace, and put into
- trace_stack, one thread forwards it quickly before the other runs to this assert.
- assert(obj_belongs_to_space(p_obj, space)); */
-
- /* Fastpath: object has already been forwarded, update the ref slot */
- if(obj_is_forwarded_in_vt(p_obj)) {
- assert(!obj_is_marked_in_vt(p_obj));
- *p_ref = obj_get_forwarding_pointer_in_vt(p_obj);
- return;
- }
-
- /* only mark the objects that will remain in fspace */
- if (!fspace_object_to_be_forwarded(p_obj, (Fspace*)space)) {
- assert(!obj_is_forwarded_in_vt(p_obj));
- /* this obj remains in fspace, remember its ref slot for next GC. */
- if( !address_belongs_to_space(p_ref, space) )
- collector_remset_add_entry(collector, p_ref);
-
- if(fspace_mark_object((Fspace*)space, p_obj))
- scan_object(collector, p_obj);
-
- return;
- }
-
- /* following is the logic for forwarding */
- Partial_Reveal_Object* p_target_obj = collector_forward_object(collector, p_obj);
-
- /* if it is forwarded by other already, it is ok */
- if( p_target_obj == NULL ){
- *p_ref = obj_get_forwarding_pointer_in_vt(p_obj);
- return;
- }
- /* otherwise, we successfully forwarded */
- *p_ref = p_target_obj;
-
- /* we forwarded it, we need remember it for verification. FIXME:: thread id */
- if(verify_live_heap) {
- event_collector_move_obj(p_obj, p_target_obj, collector);
- }
-
- scan_object(collector, p_target_obj);
- return;
-}
-
-void trace_object_seq(Collector* collector, Partial_Reveal_Object **p_ref);
-
-/* for tracing phase termination detection */
-static volatile unsigned int num_finished_collectors = 0;
-
-static void collector_trace_rootsets(Collector* collector)
-{
- GC* gc = collector->gc;
- GC_Metadata* metadata = gc->metadata;
-
- Space* space = collector->collect_space;
- collector->trace_stack = (TraceStack*)pool_get_entry(metadata->free_set_pool);
- //collector->trace_stack = new TraceStack();
-
- unsigned int num_active_collectors = gc->num_active_collectors;
- atomic_cas32( &num_finished_collectors, 0, num_active_collectors);
-
-retry:
- /* find root slots saved by 1. active mutators, 2. exited mutators, 3. last cycle collectors */
- Vector_Block* root_set = pool_get_entry(metadata->gc_rootset_pool);
-
- while(root_set){
- unsigned int* iter = vector_block_iterator_init(root_set);
- while(!vector_block_iterator_end(root_set,iter)){
- Partial_Reveal_Object** p_ref = (Partial_Reveal_Object** )*iter;
- iter = vector_block_iterator_advance(root_set,iter);
-
- assert(p_ref);
- if(*p_ref == NULL) continue;
- /* in sequential version, we only trace same object once, but we were using a local hashset,
- which couldn't catch the repetition between multiple collectors. This is subject to more study. */
- if (obj_belongs_to_space(*p_ref, space))
- trace_object(collector, p_ref);
- }
- vector_block_clear(root_set);
- pool_put_entry(metadata->free_set_pool, root_set);
- root_set = pool_get_entry(metadata->gc_rootset_pool);
-
- }
-
- atomic_inc32(&num_finished_collectors);
- while(num_finished_collectors != num_active_collectors){
- if( !pool_is_empty(metadata->gc_rootset_pool)){
- atomic_dec32(&num_finished_collectors);
- goto retry;
- }
- }
-
-
- /* now we are done, but each collector has a private task block to deal with */
- Vector_Block* trace_task = (Vector_Block*)collector->trace_stack;
- TraceStack* trace_stack = new TraceStack();
-
- unsigned int* iter = vector_block_iterator_init(trace_task);
- while(!vector_block_iterator_end(trace_task,iter)){
- Partial_Reveal_Object** p_ref = (Partial_Reveal_Object**)*iter;
- iter = vector_block_iterator_advance(trace_task,iter);
- trace_stack->push(p_ref);
- }
-
- /* put back the last task to the free pool */
- vector_block_clear(trace_task);
- pool_put_entry(metadata->free_set_pool, trace_task);
-
- collector->trace_stack = trace_stack;
- while(!trace_stack->empty()){
- Partial_Reveal_Object** p_ref = trace_stack->top();
- trace_stack->pop();
- trace_object_seq(collector, p_ref);
- }
-
- delete trace_stack;
- collector->trace_stack = NULL;
-
- return;
-}
-
-void update_rootset_interior_pointer();
-
-static void update_relocated_refs(Collector* collector)
-{
- update_rootset_interior_pointer();
-}
-
-static volatile unsigned int num_marking_collectors = 0;
-
-void trace_forward_fspace(Collector* collector)
-{
- GC* gc = collector->gc;
- Fspace* space = (Fspace*)collector->collect_space;
-
- unsigned int num_active_collectors = gc->num_active_collectors;
- unsigned int old_num = atomic_cas32( &num_marking_collectors, 0, num_active_collectors+1);
-
- collector_trace_rootsets(collector);
-
- old_num = atomic_inc32(&num_marking_collectors);
- if( ++old_num == num_active_collectors ){
- /* last collector's world here */
- /* prepare for next phase */ /* let other collectors go */
- num_marking_collectors++;
- }
- while(num_marking_collectors != num_active_collectors + 1);
-
- /* the rest work is not enough for parallelization, so let only one thread go */
- if( collector->thread_handle != 0 ) return;
-
- update_relocated_refs(collector);
- reset_fspace_for_allocation(space);
-
- return;
-
-}
-
-
-
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_forward_seq.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_forward_seq.cpp?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_forward_seq.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_forward_seq.cpp Tue Dec 5 14:32:35 2006
@@ -1,205 +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 "fspace.h"
-#include "../thread/collector.h"
-#include "../common/gc_metadata.h"
-
-static Boolean fspace_object_to_be_forwarded(Partial_Reveal_Object *p_obj, Fspace *fspace)
-{
- assert(obj_belongs_to_space(p_obj, (Space*)fspace));
- return forward_first_half? (p_obj < object_forwarding_boundary):(p_obj>=object_forwarding_boundary);
-}
-
-static void scan_slot(Collector* collector, Partial_Reveal_Object **p_ref)
-{
- Partial_Reveal_Object *p_obj = *p_ref;
- TraceStack *ts = collector->trace_stack;
-
- if (p_obj == NULL) return;
-
- /* the slot can be in tspace or fspace, we don't care.
- we care only if the reference in the slot is pointing to fspace */
- if (obj_belongs_to_space(p_obj, collector->collect_space)) {
- ts->push(p_ref);
- }
-
- return;
-}
-
-static void scan_object(Collector* collector, Partial_Reveal_Object *p_obj)
-{
- if (!object_has_slots(p_obj)) return;
-
- void *slot;
-
- /* scan array object */
- if (object_is_array(p_obj)) {
- Partial_Reveal_Object* array = p_obj;
- assert(!obj_is_primitive_array(array));
-
- int32 array_length = vector_get_length((Vector_Handle) array);
- for (int i = 0; i < array_length; i++) {
- slot = vector_get_element_address_ref((Vector_Handle) array, i);
- scan_slot(collector, (Partial_Reveal_Object **)slot);
- }
- return;
- }
-
- /* scan non-array object */
- int *offset_scanner = init_object_scanner(p_obj);
- while (true) {
- slot = offset_get_ref(offset_scanner, p_obj);
- if (slot == NULL) break;
-
- scan_slot(collector, (Partial_Reveal_Object **)slot);
- offset_scanner = offset_next_ref(offset_scanner);
- }
-
- return;
-}
-
-/* At this point, p_ref can be in anywhere like root, and other spaces,
- * but *p_ref must be in fspace, since only slot which points to
- * object in fspace could be added into TraceStack */
-#include "../verify/verify_live_heap.h"
-
-void trace_object_seq(Collector* collector, Partial_Reveal_Object **p_ref)
-{
- Space* space = collector->collect_space;
- Partial_Reveal_Object *p_obj = *p_ref;
-
- assert(p_obj);
- assert(obj_belongs_to_space(p_obj, space));
-
- /* Fastpath: object has already been forwarded, update the ref slot */
- if(obj_is_forwarded_in_vt(p_obj)) {
- assert(!obj_is_marked_in_vt(p_obj));
- *p_ref = obj_get_forwarding_pointer_in_vt(p_obj);
- return;
- }
-
- /* only mark the objects that will remain in fspace */
- if (!fspace_object_to_be_forwarded(p_obj, (Fspace*)space)) {
- assert(!obj_is_forwarded_in_vt(p_obj));
- /* this obj remains in fspace, remember its ref slot for next GC. */
- if( !address_belongs_to_space(p_ref, space) ){
- collector_remset_add_entry(collector, p_ref);
- }
-
- if(fspace_mark_object((Fspace*)space, p_obj))
- scan_object(collector, p_obj);
-
- return;
- }
-
- /* following is the logic for forwarding */
- Partial_Reveal_Object* p_target_obj = collector_forward_object(collector, p_obj);
-
- /* if it is forwarded by other already, it is ok */
- if(!p_target_obj){
- *p_ref = obj_get_forwarding_pointer_in_vt(p_obj);
- return;
- }
- /* otherwise, we successfully forwarded */
- *p_ref = p_target_obj;
-
- /* we forwarded it, we need remember it for verification. FIXME:: thread id */
- if(verify_live_heap) {
- event_collector_move_obj(p_obj, p_target_obj, collector);
- }
-
- scan_object(collector, p_target_obj);
- return;
-}
-
-/* trace the root references from root set and remember sets */
-static void trace_root(Collector* collector, Partial_Reveal_Object **ref)
-{
- assert(*ref);
- assert(obj_belongs_to_space(*ref, collector->collect_space));
-
- TraceStack *ts = collector->trace_stack;
- ts->push(ref);
-
- while(!ts->empty()) {
- Partial_Reveal_Object **p_ref = ts->top();
- ts->pop();
- assert(p_ref);
- trace_object_seq(collector, p_ref);
- }
-}
-
-static void collector_trace_rootsets(Collector* collector)
-{
- GC_Metadata* metadata = collector->gc->metadata;
-
- Space* space = collector->collect_space;
- collector->trace_stack = new TraceStack();
-
- /* find root slots saved by 1. active mutators, 2. exited mutators, 3. last cycle collectors */
- Vector_Block* root_set = pool_get_entry(metadata->gc_rootset_pool);
-
- while(root_set){
- unsigned int* iter = vector_block_iterator_init(root_set);
- while(!vector_block_iterator_end(root_set,iter)){
- Partial_Reveal_Object** p_ref = (Partial_Reveal_Object** )*iter;
- iter = vector_block_iterator_advance(root_set,iter);
-
- assert(p_ref);
- if(*p_ref == NULL) continue;
- if (obj_belongs_to_space(*p_ref, space))
- trace_root(collector, p_ref);
- }
- vector_block_clear(root_set);
- pool_put_entry(metadata->free_set_pool, root_set);
- root_set = pool_get_entry(metadata->gc_rootset_pool);
- }
-
- delete collector->trace_stack;
-
- return;
-}
-
-void update_rootset_interior_pointer();
-
-static void update_relocated_refs(Collector* collector)
-{
- update_rootset_interior_pointer();
-}
-
-void trace_forward_fspace_seq(Collector* collector)
-{
- GC* gc = collector->gc;
- Fspace* space = (Fspace*)collector->collect_space;
-
- /* FIXME:: Single-threaded trace-forwarding for fspace currently */
-
- collector_trace_rootsets(collector);
-
- update_relocated_refs(collector);
- reset_fspace_for_allocation(space);
-
- return;
-
-}
-
-
-
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/sync_pool.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/sync_pool.h?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/sync_pool.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/sync_pool.h Tue Dec 5 14:32:35 2006
@@ -29,10 +29,22 @@
inline void sync_pool_destruct(Pool* pool){ sync_stack_destruct(pool); }
inline Boolean pool_is_empty(Pool* pool){ return stack_is_empty(pool);}
-inline Vector_Block* pool_get_entry(Pool* pool){ return (Vector_Block*)sync_stack_pop(pool); }
-inline void pool_put_entry(Pool* pool, void* value){ assert(value); Boolean ok = sync_stack_push(pool, (Node*)value); assert(ok);}
+inline Vector_Block* pool_get_entry(Pool* pool)
+{
+ Vector_Block* block = (Vector_Block*)sync_stack_pop(pool);
+ return block;
+}
+
+inline void pool_put_entry(Pool* pool, void* value)
+{
+ assert(value);
+ Boolean ok = sync_stack_push(pool, (Node*)value);
+ assert(ok);
+}
+
inline void pool_iterator_init(Pool* pool){ sync_stack_iterate_init(pool);}
inline Vector_Block* pool_iterator_next(Pool* pool){ return (Vector_Block*)sync_stack_iterate_next(pool);}
#endif /* #ifndef _SYNC_POOL_H_ */
+
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/sync_stack.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/sync_stack.h?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/sync_stack.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/sync_stack.h Tue Dec 5 14:32:35 2006
@@ -73,6 +73,7 @@
Node* new_entry = entry->next;
Node* temp = (Node*)atomic_casptr((volatile void**)&stack->top, new_entry, entry);
if(temp == entry){ /* got it */
+ entry->next = NULL;
return entry;
}
entry = stack->top;
@@ -93,6 +94,7 @@
entry = stack->top;
node->next = entry;
}
+ /* never comes here */
return FALSE;
}
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/vector_block.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/vector_block.h?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/vector_block.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/vector_block.h Tue Dec 5 14:32:35 2006
@@ -25,24 +25,24 @@
void* next; /* point to next block */
unsigned int* head; /* point to the first filled entry */
unsigned int* tail; /* point to the entry after the last filled one */
- unsigned int* end; /* point to end of the block (right after the last entry) */
+ unsigned int* heap_end; /* point to heap_end of the block (right after the last entry) */
unsigned int* entries[1];
}Vector_Block;
inline void vector_block_init(Vector_Block* block, unsigned int size)
{
- block->end = (unsigned int*)((unsigned int)block + size);
- block->head = (unsigned int*)block->entries;
- block->tail = (unsigned int*)block->entries;
- memset(block->head, 0, (block->end - block->head)*BYTES_PER_WORD);
- return;
+ block->heap_end = (unsigned int*)((unsigned int)block + size);
+ block->head = (unsigned int*)block->entries;
+ block->tail = (unsigned int*)block->entries;
+ memset(block->entries, 0, (block->heap_end - (unsigned int*)block->entries)*BYTES_PER_WORD);
+ return;
}
inline unsigned int vector_block_entry_count(Vector_Block* block)
{ return (unsigned int)(block->tail - block->head); }
inline Boolean vector_block_is_full(Vector_Block* block)
-{ return block->tail == block->end; }
+{ return block->tail == block->heap_end; }
inline Boolean vector_block_is_empty(Vector_Block* block)
{ return block->tail == block->head; }
@@ -55,11 +55,11 @@
inline void vector_block_clear(Vector_Block* block)
{
+ block->head = (unsigned int*)block->entries;
+ block->tail = (unsigned int*)block->entries;
#ifdef _DEBUG
- memset(block->entries, 0, (block->end - (unsigned int*)block->entries)*BYTES_PER_WORD);
+ memset(block->entries, 0, (block->heap_end - (unsigned int*)block->entries)*BYTES_PER_WORD);
#endif
-
- block->tail = block->head;
}
/* Below is for sequential local access */
@@ -71,5 +71,54 @@
inline Boolean vector_block_iterator_end(Vector_Block* block, unsigned int* iter)
{ return iter == block->tail; }
+
+
+/* Below is to use Vector_Block as stack (for trace-forwarding DFS order ) */
+inline void vector_stack_init(Vector_Block* block)
+{
+ block->tail = block->heap_end;
+ block->head = block->heap_end;
+}
+
+inline void vector_stack_clear(Vector_Block* block)
+{
+ vector_stack_init(block);
+#ifdef _DEBUG
+ memset(block->entries, 0, (block->heap_end - (unsigned int*)block->entries)*BYTES_PER_WORD);
+#endif
+}
+
+inline Boolean vector_stack_is_empty(Vector_Block* block)
+{ return (block->head == block->tail); }
+
+inline Boolean vector_stack_is_full(Vector_Block* block)
+{ return (block->head == (unsigned int*)block->entries); }
+
+inline void vector_stack_push(Vector_Block* block, unsigned int value)
+{
+ block->head--;
+ assert(value && !*(block->head));
+ *(block->head) = value;
+}
+
+inline unsigned int vector_stack_pop(Vector_Block* block)
+{
+ unsigned int value = *block->head;
+#ifdef _DEBUG
+ *block->head = 0;
+#endif
+ block->head++;
+ return value;
+}
+
+inline void vector_block_integrity_check(Vector_Block* block)
+{
+ unsigned int* iter = vector_block_iterator_init(block);
+ while(!vector_block_iterator_end(block, iter)){
+ assert(*iter);
+ iter = vector_block_iterator_advance(block, iter);
+ }
+ return;
+}
#endif /* #ifndef _VECTOR_BLOCK_H_ */