You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by xl...@apache.org on 2007/08/27 10:12:01 UTC
svn commit: r570028 [1/4] - in /harmony/enhanced/drlvm/trunk/vm/gc_gen/src:
common/ finalizer_weakref/ gen/ los/ mark_compact/ mark_sweep/ tests/
thread/ trace_forward/ utils/ verify/
Author: xli
Date: Mon Aug 27 01:11:57 2007
New Revision: 570028
URL: http://svn.apache.org/viewvc?rev=570028&view=rev
Log:
HARMONY-4325 : concurrent marking for Tick project. The patch also enables the generational mode for Tick's mark-sweep GC.
Added:
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/collection_scheduler.cpp (with props)
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/collection_scheduler.h (with props)
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_concurrent.cpp (with props)
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_concurrent.h (with props)
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/object_status.h (with props)
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/sspace_fallback_mark.cpp (with props)
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/sspace_mark_concurrent.cpp (with props)
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/marker.cpp (with props)
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/marker.h (with props)
Removed:
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/tests/
Modified:
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_vm.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_platform.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_space.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/weak_roots.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gc_for_barrier.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen_adapt.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/los/lspace.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/los/lspace.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/los/lspace_alloc_collect.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect_compact.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect_compact.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_extend_compact.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_move_compact.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_slide_compact.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/gc_ms.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/gc_ms.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/sspace.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/sspace.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/sspace_alloc.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/sspace_alloc.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/sspace_chunk.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/sspace_chunk.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/sspace_compact.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/sspace_mark.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/sspace_mark_sweep.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/sspace_mark_sweep.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/sspace_sweep.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/sspace_verify.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector_alloc.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_alloc.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_gen_forward_pool.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_nongen_forward_pool.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/vector_block.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/verify/verifier_common.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/verify/verifier_common.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/verify/verifier_scanner.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/verify/verify_gc_effect.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/verify/verify_live_heap.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/verify/verify_mutator_effect.cpp
Added: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/collection_scheduler.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/collection_scheduler.cpp?rev=570028&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/collection_scheduler.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/collection_scheduler.cpp Mon Aug 27 01:11:57 2007
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+#include "gc_common.h"
+#include "../gen/gen.h"
+#include "../mark_sweep/gc_ms.h"
+#include "../mark_sweep/sspace.h"
+#include "collection_scheduler.h"
+#include "gc_concurrent.h"
+static int64 time_delay_to_start_mark = 0;
+
+void collection_scheduler_initialize(GC* gc)
+{
+
+ Collection_Scheduler* collection_scheduler = (Collection_Scheduler*) STD_MALLOC(sizeof(Collection_Scheduler));
+ assert(collection_scheduler);
+ memset(collection_scheduler, 0, sizeof(Collection_Scheduler));
+
+ collection_scheduler->gc = gc;
+ gc->collection_scheduler = collection_scheduler;
+ time_delay_to_start_mark = 0;
+
+ return;
+}
+void collection_scheduler_destruct(GC* gc)
+{
+ STD_FREE(gc->collection_scheduler);
+}
+
+Boolean gc_need_start_concurrent_mark(GC* gc)
+{
+ if(!USE_CONCURRENT_GC) return FALSE;
+ //FIXME: GEN mode also needs the support of starting mark after thread resume.
+#ifdef USE_MARK_SWEEP_GC
+ if(gc_is_concurrent_mark_phase() ) return FALSE;
+
+ int64 time_current = time_now();
+ if( time_current - get_collection_end_time() > time_delay_to_start_mark)
+ return TRUE;
+ else return FALSE;
+#else
+ /*FIXME: concurrent mark is not support in GC_GEN*/
+ assert(0);
+ if(gc_next_collection_kind((GC_Gen*)gc) == MAJOR_COLLECTION)
+ return TRUE;
+ else
+ return FALSE;
+#endif
+}
+
+
+
+void gc_update_collection_scheduler(GC* gc, int64 mutator_time, int64 mark_time)
+{
+ //FIXME: GEN GC should be supportted.
+#ifdef USE_MARK_SWEEP_GC
+
+ Collection_Scheduler* collection_scheduler = gc->collection_scheduler;
+ Space* space = NULL;
+
+ space = (Space*) gc_get_sspace(gc);
+
+ Space_Statistics* sspace_stat = space->space_statistic;
+
+ unsigned int slot_index = collection_scheduler->last_slot_index_in_window;
+ unsigned int num_slot = collection_scheduler->num_slot_in_window;
+
+ collection_scheduler->num_obj_traced_window[slot_index] = sspace_stat->num_live_obj;
+ collection_scheduler->size_alloced_window[slot_index] = sspace_stat->last_size_free_space;
+
+ int64 time_mutator = mutator_time;
+ int64 time_mark = mark_time;
+
+ collection_scheduler->alloc_rate_window[slot_index]
+ = time_mutator == 0 ? 0 : (float)collection_scheduler->size_alloced_window[slot_index] / time_mutator;
+
+ collection_scheduler->trace_rate_window[slot_index]
+ = time_mark == 0 ? 0 : (float)collection_scheduler->num_obj_traced_window[slot_index] / time_mark;
+
+ collection_scheduler->num_slot_in_window = num_slot >= STATISTICS_SAMPLING_WINDOW_SIZE ? num_slot : (++num_slot);
+ collection_scheduler->last_slot_index_in_window = (++slot_index)% STATISTICS_SAMPLING_WINDOW_SIZE;
+
+ float sum_alloc_rate = 0;
+ float sum_trace_rate = 0;
+
+ unsigned int i;
+ for(i = 0; i < collection_scheduler->num_slot_in_window; i++){
+ sum_alloc_rate += collection_scheduler->alloc_rate_window[i];
+ sum_trace_rate += collection_scheduler->trace_rate_window[i];
+
+ }
+
+ float average_alloc_rate = sum_alloc_rate / collection_scheduler->num_slot_in_window;
+ float average_trace_rate = sum_trace_rate / collection_scheduler->num_slot_in_window;
+
+ if(average_alloc_rate == 0 || average_trace_rate == 0){
+ time_delay_to_start_mark = 0;
+ }else{
+ float expected_time_alloc = sspace_stat->size_free_space / average_alloc_rate;
+ float expected_time_trace = sspace_stat->num_live_obj / average_trace_rate;
+
+
+ if(expected_time_alloc > expected_time_trace)
+ collection_scheduler->time_delay_to_start_mark = (int64)((expected_time_alloc - expected_time_trace)*0.7);
+ else
+ collection_scheduler->time_delay_to_start_mark = 0;
+
+ time_delay_to_start_mark = collection_scheduler->time_delay_to_start_mark;
+ }
+#endif
+ return;
+
+}
+
Propchange: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/collection_scheduler.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/collection_scheduler.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/collection_scheduler.h?rev=570028&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/collection_scheduler.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/collection_scheduler.h Mon Aug 27 01:11:57 2007
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+#ifndef _COLLECTION_SCHEDULER_H_
+#define _COLLECTION_SCHEDULER_H_
+
+#define STATISTICS_SAMPLING_WINDOW_SIZE 5
+
+typedef struct Collection_Scheduler {
+ /*common field*/
+ GC* gc;
+
+ /*mark schedule */
+ int64 time_delay_to_start_mark;
+
+ /**/
+ unsigned int num_slot_in_window;
+ unsigned int last_slot_index_in_window;
+
+ float alloc_rate_window[STATISTICS_SAMPLING_WINDOW_SIZE];
+ float trace_rate_window[STATISTICS_SAMPLING_WINDOW_SIZE];
+ POINTER_SIZE_INT num_obj_traced_window[STATISTICS_SAMPLING_WINDOW_SIZE];
+ POINTER_SIZE_INT size_alloced_window[STATISTICS_SAMPLING_WINDOW_SIZE];
+} Collection_Scheduler;
+
+void collection_scheduler_initialize(GC* gc);
+void collection_scheduler_destruct(GC* gc);
+
+void gc_update_collection_scheduler(GC* gc, int64 mutator_time, int64 mark_time);
+Boolean gc_need_start_concurrent_mark(GC* gc);
+
+
+#endif
+
Propchange: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/collection_scheduler.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp?rev=570028&r1=570027&r2=570028&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp Mon Aug 27 01:11:57 2007
@@ -22,11 +22,14 @@
#include "gc_common.h"
#include "gc_metadata.h"
#include "../thread/mutator.h"
+#include "../thread/marker.h"
#include "../finalizer_weakref/finalizer_weakref.h"
#include "../gen/gen.h"
#include "../mark_sweep/gc_ms.h"
#include "../common/space_tuner.h"
#include "interior_pointer.h"
+#include "collection_scheduler.h"
+#include "gc_concurrent.h"
unsigned int Cur_Mark_Bit = 0x1;
unsigned int Cur_Forward_Bit = 0x2;
@@ -43,6 +46,7 @@
extern Boolean MINOR_ALGORITHM;
extern Boolean MAJOR_ALGORITHM;
+extern unsigned int NUM_MARKERS;
extern unsigned int NUM_COLLECTORS;
extern unsigned int MINOR_COLLECTORS;
extern unsigned int MAJOR_COLLECTORS;
@@ -56,6 +60,7 @@
extern Boolean JVMTI_HEAP_ITERATION ;
extern Boolean IS_MOVE_COMPACT;
+extern Boolean USE_CONCURRENT_GC;
static int get_int_property(const char *property_name)
{
@@ -189,6 +194,11 @@
NUM_COLLECTORS = (num==0)? NUM_COLLECTORS:num;
}
+ if (is_property_set("gc.num_markers", VM_PROPERTIES) == 1) {
+ unsigned int num = get_int_property("gc.num_markers");
+ NUM_MARKERS = (num==0)? NUM_MARKERS:num;
+ }
+
/* GC algorithm decision */
/* Step 1: */
char* minor_algo = NULL;
@@ -265,89 +275,107 @@
large_page_hint = strdup(value);
destroy_property_value(value);
}
+
+ if (is_property_set("gc.concurrent_gc", VM_PROPERTIES) == 1){
+ USE_CONCURRENT_GC= get_boolean_property("gc.concurrent_gc");
+ }
return;
}
void gc_assign_free_area_to_mutators(GC* gc)
{
+#ifndef USE_MARK_SWEEP_GC
gc_gen_assign_free_area_to_mutators((GC_Gen*)gc);
-}
-
-void gc_adjust_heap_size(GC* gc, int64 pause_time)
-{
- gc_gen_adjust_heap_size((GC_Gen*)gc, pause_time);
+#endif
}
void gc_copy_interior_pointer_table_to_rootset();
/*used for computing collection time and mutator time*/
-static int64 collection_start_time = time_now();
+static int64 collection_start_time = time_now();
static int64 collection_end_time = time_now();
-void gc_reclaim_heap(GC* gc, unsigned int gc_cause)
-{
- INFO2("gc.process", "\nGC: GC start ...\n");
- collection_start_time = time_now();
- int64 mutator_time = collection_start_time -collection_end_time;
+int64 get_collection_end_time()
+{ return collection_end_time; }
+void gc_reclaim_heap(GC* gc, unsigned int gc_cause)
+{
+ INFO2("gc.process", "\nGC: GC start ...\n");
+
+ collection_start_time = time_now();
+ int64 mutator_time = collection_start_time - collection_end_time;
+
/* FIXME:: before mutators suspended, the ops below should be very careful
to avoid racing with mutators. */
- gc->num_collections++;
+ gc->num_collections++;
gc->cause = gc_cause;
gc_decide_collection_kind((GC_Gen*)gc, gc_cause);
-#ifndef USE_MARK_SWEEP_GC
- gc_gen_update_space_before_gc((GC_Gen*)gc);
- gc_compute_space_tune_size_before_marking(gc, gc_cause);
-#endif
-
#ifdef MARK_BIT_FLIPPING
if(gc_match_kind(gc, MINOR_COLLECTION)) mark_bit_flip();
#endif
- gc_metadata_verify(gc, TRUE);
+ if(!USE_CONCURRENT_GC){
+ gc_metadata_verify(gc, TRUE);
#ifndef BUILD_IN_REFERENT
- gc_finref_metadata_verify((GC*)gc, TRUE);
+ gc_finref_metadata_verify((GC*)gc, TRUE);
#endif
-
+ }
/* Stop the threads and collect the roots. */
+ lock(gc->enumerate_rootset_lock);
INFO2("gc.process", "GC: stop the threads and enumerate rootset ...\n");
- gc_reset_rootset(gc);
+ gc_clear_rootset(gc);
+ gc_reset_rootset(gc);
vm_enumerate_root_set_all_threads();
gc_copy_interior_pointer_table_to_rootset();
- gc_set_rootset(gc);
+ gc_set_rootset(gc);
+ unlock(gc->enumerate_rootset_lock);
+
+ if(USE_CONCURRENT_GC && gc_mark_is_concurrent()){
+ gc_finish_concurrent_mark(gc);
+ }
/* this has to be done after all mutators are suspended */
gc_reset_mutator_context(gc);
-
+
if(!IGNORE_FINREF ) gc_set_obj_with_fin(gc);
#ifndef USE_MARK_SWEEP_GC
- gc_gen_reclaim_heap((GC_Gen*)gc);
+ gc_gen_reclaim_heap((GC_Gen*)gc, collection_start_time);
#else
gc_ms_reclaim_heap((GC_MS*)gc);
#endif
-
- gc_reset_interior_pointer_table();
- gc_metadata_verify(gc, FALSE);
+ /* FIXME:: clear root set here to support verify. */
+#ifdef COMPRESS_REFERENCE
+ gc_set_pool_clear(gc->metadata->gc_uncompressed_rootset_pool);
+#endif
+ gc_reset_interior_pointer_table();
+
+ gc_metadata_verify(gc, FALSE);
+
collection_end_time = time_now();
- int64 pause_time = collection_end_time - collection_start_time;
- gc->time_collections += pause_time;
-
#ifndef USE_MARK_SWEEP_GC
- gc_gen_collection_verbose_info((GC_Gen*)gc, pause_time, mutator_time);
+ gc_gen_collection_verbose_info((GC_Gen*)gc, collection_end_time - collection_start_time, mutator_time);
gc_gen_space_verbose_info((GC_Gen*)gc);
- gc_adjust_heap_size(gc, pause_time);
-
- gc_gen_adapt((GC_Gen*)gc, pause_time);
#endif
if(gc_is_gen_mode()) gc_prepare_mutator_remset(gc);
+ int64 mark_time = 0;
+ if(USE_CONCURRENT_GC && gc_mark_is_concurrent()){
+ gc_reset_concurrent_mark(gc);
+ mark_time = gc_get_concurrent_mark_time(gc);
+ }
+
+#ifndef USE_MARK_SWEEP_GC
+ if(USE_CONCURRENT_GC && gc_need_start_concurrent_mark(gc))
+ gc_start_concurrent_mark(gc);
+#endif
+
if(!IGNORE_FINREF ){
INFO2("gc.process", "GC: finref process after collection ...\n");
gc_put_finref_to_vm(gc);
@@ -359,18 +387,17 @@
#endif
}
-#ifndef USE_MARK_SWEEP_GC
- gc_space_tuner_reset(gc);
- gc_gen_update_space_after_gc((GC_Gen*)gc);
- gc_assign_free_area_to_mutators(gc);
+#ifdef USE_MARK_SWEEP_GC
+ gc_ms_update_space_statistics((GC_MS*)gc);
#endif
- vm_reclaim_native_objs();
+ gc_assign_free_area_to_mutators(gc);
+
+ if(USE_CONCURRENT_GC) gc_update_collection_scheduler(gc, mutator_time, mark_time);
+
+ vm_reclaim_native_objs();
vm_resume_threads_after();
INFO2("gc.process", "GC: GC end\n");
return;
}
-
-
-
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.h?rev=570028&r1=570027&r2=570028&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.h Mon Aug 27 01:11:57 2007
@@ -92,24 +92,39 @@
/* major collection */
MAJOR_COMPACT_SLIDE,
- MAJOR_COMPACT_MOVE
+ MAJOR_COMPACT_MOVE,
+ MAJOR_MARK_SWEEP
};
/* Possible combinations:
* MINOR_COLLECTION
- * MAJOR_COLLECTION
+ * NORMAL_MAJOR_COLLECTION
* FALLBACK_COLLECTION
- * MAJOR_COLLECTION | EXTEND_COLLECTION
+ * NORMAL_MAJOR_COLLECTION | EXTEND_COLLECTION
* FALLBACK_COLLECTION | EXTEND_COLLECTION
+ * MS_COLLECTION
+ * MS_COMPACT_COLLECTION
*/
enum Collection_Kind {
- MINOR_COLLECTION = 0x1,
- MAJOR_COLLECTION = 0x2,
- FALLBACK_COLLECTION = 0x4,
- EXTEND_COLLECTION = 0x8,
- MARK_SWEEP_GC = 0x10,
- SWEEP_COMPACT_GC = 0x20
+ /* Two main kinds: generational GC and mark-sweep GC; this is decided at compiling time */
+ GEN_GC = 0x1,
+ MARK_SWEEP_GC = 0x2,
+ /* Mask of bits standing for two basic kinds */
+ GC_BASIC_KIND_MASK = ~(unsigned int)0x7,
+
+ /* Sub-kinds of generational GC use the 4~7th LSB */
+ MINOR_COLLECTION = 0x11, /* 0x10 & GEN_GC */
+ MAJOR_COLLECTION = 0x21, /* 0x20 & GEN_GC */
+
+ /* Sub-kinds of major collection use the 8~11th LSB */
+ NORMAL_MAJOR_COLLECTION = 0x121, /* 0x100 & MAJOR_COLLECTION */
+ FALLBACK_COLLECTION = 0x221, /* 0x200 & MAJOR_COLLECTION */
+ EXTEND_COLLECTION = 0x421, /* 0x400 & MAJOR_COLLECTION */
+
+ /* Sub-kinds of mark-sweep GC use the 12~15th LSB */
+ MS_COLLECTION = 0x1002, /* 0x1000 & MARK_SWEEP_GC */
+ MS_COMPACT_COLLECTION = 0x2002 /* 0x2000 & MARK_SWEEP_GC */
};
extern Boolean IS_FALLBACK_COMPACTION; /* only for mark/fw bits debugging purpose */
@@ -118,7 +133,7 @@
GC_CAUSE_NIL,
GC_CAUSE_NOS_IS_FULL,
GC_CAUSE_LOS_IS_FULL,
- GC_CAUSE_POS_IS_FULL,
+ GC_CAUSE_SSPACE_IS_FULL,
GC_CAUSE_RUNTIME_FORCE_GC
};
@@ -356,13 +371,35 @@
#endif /* MARK_BIT_FLIPPING */
+inline Boolean obj_is_dirty_in_oi(Partial_Reveal_Object* p_obj)
+{
+ Obj_Info_Type info = get_obj_info_raw(p_obj);
+ return (Boolean)(info & OBJ_DIRTY_BIT);
+}
+
+inline Boolean obj_dirty_in_oi(Partial_Reveal_Object* p_obj)
+{
+ Obj_Info_Type info = get_obj_info_raw(p_obj);
+ if( info & OBJ_DIRTY_BIT ) return FALSE;
+
+ Obj_Info_Type new_info = info | OBJ_DIRTY_BIT;
+ while(info != atomic_cas32((volatile unsigned int *)get_obj_info_addr(p_obj),new_info, info)){
+ info = get_obj_info_raw(p_obj);
+ if( info & OBJ_DIRTY_BIT ) return FALSE;
+ new_info = info |OBJ_DIRTY_BIT;
+ }
+ return TRUE;
+}
+
/* all GCs inherit this GC structure */
+struct Marker;
struct Mutator;
struct Collector;
struct GC_Metadata;
struct Finref_Metadata;
struct Vector_Block;
struct Space_Tuner;
+struct Collection_Scheduler;
typedef struct GC{
void* heap_start;
@@ -382,6 +419,10 @@
Collector** collectors;
unsigned int num_collectors;
unsigned int num_active_collectors; /* not all collectors are working */
+
+ Marker** markers;
+ unsigned int num_markers;
+ unsigned int num_active_markers;
/* metadata is the pool for rootset, tracestack, etc. */
GC_Metadata* metadata;
@@ -400,6 +441,13 @@
Vector_Block* uncompressed_root_set;
Space_Tuner* tuner;
+
+ unsigned int gc_concurrent_status; /*concurrent GC status: only support CONCURRENT_MARK_PHASE now*/
+ Collection_Scheduler* collection_scheduler;
+
+ SpinLock concurrent_mark_lock;
+ SpinLock enumerate_rootset_lock;
+
/* system info */
unsigned int _system_alloc_unit;
@@ -422,16 +470,28 @@
return (addr >= gc_heap_base(gc) && addr < gc_heap_ceiling(gc));
}
+/* gc must match exactly that kind if returning TRUE */
inline Boolean gc_match_kind(GC *gc, unsigned int kind)
{
assert(gc->collect_kind && kind);
- return gc->collect_kind & kind;
+ return (Boolean)((gc->collect_kind & kind) == kind);
+}
+/* multi_kinds is a combination of multi collect kinds
+ * gc must match one of them.
+ */
+inline Boolean gc_match_either_kind(GC *gc, unsigned int multi_kinds)
+{
+ multi_kinds &= GC_BASIC_KIND_MASK;
+ assert(gc->collect_kind && multi_kinds);
+ return (Boolean)(gc->collect_kind & multi_kinds);
}
inline unsigned int gc_get_processor_num(GC* gc) { return gc->_num_processors; }
void gc_parse_options(GC* gc);
void gc_reclaim_heap(GC* gc, unsigned int gc_cause);
+
+int64 get_collection_end_time();
/* generational GC related */
Added: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_concurrent.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_concurrent.cpp?rev=570028&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_concurrent.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_concurrent.cpp Mon Aug 27 01:11:57 2007
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+#include "gc_common.h"
+#include "gc_metadata.h"
+#include "../thread/mutator.h"
+#include "../thread/marker.h"
+#include "../finalizer_weakref/finalizer_weakref.h"
+#include "../gen/gen.h"
+#include "../mark_sweep/gc_ms.h"
+#include "interior_pointer.h"
+#include "collection_scheduler.h"
+#include "gc_concurrent.h"
+
+Boolean USE_CONCURRENT_GC = FALSE;
+
+volatile Boolean concurrent_mark_phase = FALSE;
+volatile Boolean mark_is_concurrent = FALSE;
+
+
+static void gc_check_concurrent_mark(GC* gc)
+{
+ if(!is_mark_finished(gc)){
+ lock(gc->concurrent_mark_lock);
+#ifndef USE_MARK_SWEEP_GC
+ gc_gen_start_concurrent_mark((GC_Gen*)gc);
+#else
+ gc_ms_start_concurrent_mark((GC_MS*)gc, MAX_NUM_MARKERS);
+#endif
+ unlock(gc->concurrent_mark_lock);
+ }
+}
+
+static void gc_wait_concurrent_mark_finish(GC* gc)
+{
+ wait_mark_finish(gc);
+ gc_set_concurrent_status(gc,GC_CONCURRENT_STATUS_NIL);
+ gc_reset_snaptshot(gc);
+}
+
+void gc_start_concurrent_mark(GC* gc)
+{
+ if(!try_lock(gc->concurrent_mark_lock) || gc_mark_is_concurrent()) return;
+
+ /*prepare rootset*/
+ if(TRUE){
+ lock(gc->enumerate_rootset_lock);
+ gc_metadata_verify(gc, TRUE);
+ gc_reset_rootset(gc);
+ vm_enumerate_root_set_all_threads();
+ gc_copy_interior_pointer_table_to_rootset();
+ gc_set_rootset(gc);
+ }else{
+ gc_clear_remset((GC*)gc);
+ if(!IGNORE_FINREF){
+ gc_copy_finaliable_obj_to_rootset(gc);
+ }
+ gc->root_set = NULL;
+ }
+ gc_set_concurrent_status(gc, GC_CONCURRENT_MARK_PHASE);
+
+ gc_decide_collection_kind((GC_Gen*)gc, GC_CAUSE_NIL);
+
+ /*start concurrent mark*/
+#ifndef USE_MARK_SWEEP_GC
+ gc_gen_start_concurrent_mark((GC_Gen*)gc);
+#else
+ gc_ms_start_concurrent_mark((GC_MS*)gc, MIN_NUM_MARKERS);
+#endif
+
+ if(TRUE){
+ unlock(gc->enumerate_rootset_lock);
+ vm_resume_threads_after();
+ }
+
+ unlock(gc->concurrent_mark_lock);
+}
+
+void gc_finish_concurrent_mark(GC* gc)
+{
+ gc_check_concurrent_mark(gc);
+ gc_wait_concurrent_mark_finish(gc);
+}
+
+void gc_reset_concurrent_mark(GC* gc)
+{
+ gc->num_active_markers = 0;
+ gc_mark_unset_concurrent();
+}
+
+int64 gc_get_concurrent_mark_time(GC* gc)
+{
+ int64 time_mark = 0;
+ Marker** markers = gc->markers;
+ unsigned int i;
+ for(i = 0; i < gc->num_active_markers; i++){
+ Marker* marker = markers[i];
+ if(marker->time_mark > time_mark){
+ time_mark = marker->time_mark;
+ }
+ }
+ return time_mark;
+}
+
+
Propchange: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_concurrent.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_concurrent.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_concurrent.h?rev=570028&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_concurrent.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_concurrent.h Mon Aug 27 01:11:57 2007
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+#ifndef _GC_CONCURRENT_H_
+#define _GC_CONCURRENT_H_
+#include "gc_common.h"
+
+enum GC_CONCURRENT_STATUS{
+ GC_CONCURRENT_STATUS_NIL = 0x00,
+ GC_CONCURRENT_MARK_PHASE = 0x01,
+};
+
+extern volatile Boolean concurrent_mark_phase;
+extern volatile Boolean mark_is_concurrent;
+extern Boolean USE_CONCURRENT_GC;
+
+inline Boolean gc_mark_is_concurrent()
+{
+ return mark_is_concurrent;
+}
+
+inline void gc_mark_set_concurrent()
+{
+ mark_is_concurrent = TRUE;
+}
+
+inline void gc_mark_unset_concurrent()
+{
+ mark_is_concurrent = FALSE;
+}
+
+inline Boolean gc_is_concurrent_mark_phase()
+{
+ return concurrent_mark_phase;
+}
+
+inline Boolean gc_is_concurrent_mark_phase(GC* gc)
+{
+ return gc->gc_concurrent_status == GC_CONCURRENT_MARK_PHASE;
+}
+
+inline void gc_set_concurrent_status(GC*gc, unsigned int status)
+{
+ gc->gc_concurrent_status = status;
+ if(status == GC_CONCURRENT_MARK_PHASE){
+ concurrent_mark_phase = TRUE;
+ gc_mark_set_concurrent();
+ }else{
+ concurrent_mark_phase = FALSE;
+ }
+}
+
+void gc_reset_concurrent_mark(GC* gc);
+void gc_start_concurrent_mark(GC* gc);
+void gc_finish_concurrent_mark(GC* gc);
+int64 gc_get_concurrent_mark_time(GC* gc);
+
+
+#endif
Propchange: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_concurrent.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.h?rev=570028&r1=570027&r2=570028&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.h Mon Aug 27 01:11:57 2007
@@ -65,6 +65,8 @@
#endif /* else MARK_BIT_FLIPPING */
+#define OBJ_DIRTY_BIT 0x20
+
/*emt64 related!*/
#define COMPRESS_VTABLE
@@ -306,6 +308,7 @@
}
#endif //#ifndef _GC_TYPES_H_
+
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_vm.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_vm.cpp?rev=570028&r1=570027&r2=570028&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_vm.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_vm.cpp Mon Aug 27 01:11:57 2007
@@ -27,9 +27,12 @@
#include "../gen/gen.h"
#include "../mark_sweep/gc_ms.h"
#include "interior_pointer.h"
+#include "../thread/marker.h"
#include "../thread/collector.h"
#include "../verify/verify_live_heap.h"
#include "../finalizer_weakref/finalizer_weakref.h"
+#include "collection_scheduler.h"
+#include "gc_concurrent.h"
#ifdef USE_32BITS_HASHCODE
#include "hashcode.h"
#endif
@@ -51,7 +54,7 @@
}
int gc_init()
-{
+{
INFO2("gc.process", "GC: call GC init...\n");
assert(p_global_gc == NULL);
@@ -85,7 +88,13 @@
#ifndef BUILD_IN_REFERENT
gc_finref_metadata_initialize(gc);
#endif
+ if(USE_CONCURRENT_GC){
+ collection_scheduler_initialize(gc);
+ marker_initialize(gc);
+ }
+
collector_initialize(gc);
+
gc_init_heap_verification(gc);
mutator_need_block = FALSE;
@@ -111,6 +120,7 @@
gc_finref_metadata_destruct(gc);
#endif
collector_destruct(gc);
+ marker_destruct(gc);
if( verify_live_heap ){
gc_terminate_heap_verification(gc);
@@ -173,19 +183,19 @@
return VTABLE_TRACING;
}
-void gc_add_weak_root_set_entry(Managed_Object_Handle *ref, Boolean is_pinned, Boolean is_short_weak)
+void gc_add_weak_root_set_entry(Managed_Object_Handle *ref, Boolean is_pinned, Boolean is_short_weak)
{
//assert(is_short_weak == FALSE); //Currently no need for short_weak_roots
Partial_Reveal_Object** p_ref = (Partial_Reveal_Object**)ref;
Partial_Reveal_Object* p_obj = *p_ref;
/* we don't enumerate NULL reference and nos_boundary
- FIXME:: nos_boundary is a static field in GCHelper.java for fast write barrier, not a real object reference
+ FIXME:: nos_boundary is a static field in GCHelper.java for fast write barrier, not a real object reference
this should be fixed that magic Address field should not be enumerated. */
#ifdef COMPRESS_REFERENCE
if (p_obj == (Partial_Reveal_Object*)HEAP_NULL || p_obj == NULL || p_obj == nos_boundary ) return;
#else
if (p_obj == NULL || p_obj == nos_boundary ) return;
-#endif
+#endif
assert( !obj_is_marked_in_vt(p_obj));
assert( address_belongs_to_gc_heap(p_obj, p_global_gc));
gc_weak_rootset_add_entry(p_global_gc, p_ref, is_short_weak);
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.cpp?rev=570028&r1=570027&r2=570028&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.cpp Mon Aug 27 01:11:57 2007
@@ -76,6 +76,7 @@
gc_metadata.mutator_remset_pool = sync_pool_create();
gc_metadata.collector_remset_pool = sync_pool_create();
gc_metadata.collector_repset_pool = sync_pool_create();
+ gc_metadata.dirty_obj_snaptshot_pool = sync_pool_create();
gc_metadata.weak_roots_pool = sync_pool_create();
#ifdef USE_32BITS_HASHCODE
gc_metadata.collector_hashcode_pool = sync_pool_create();
@@ -98,6 +99,7 @@
sync_pool_destruct(metadata->mutator_remset_pool);
sync_pool_destruct(metadata->collector_remset_pool);
sync_pool_destruct(metadata->collector_repset_pool);
+ sync_pool_destruct(metadata->dirty_obj_snaptshot_pool);
sync_pool_destruct(metadata->weak_roots_pool);
#ifdef USE_32BITS_HASHCODE
sync_pool_destruct(metadata->collector_hashcode_pool);
@@ -234,7 +236,7 @@
update_rootset_interior_pointer();
/* it was pointing to the last root_set entry in gc_rootset_pool (before rem_sets). */
- gc->root_set = NULL;
+ //gc->root_set = NULL;
return;
}
@@ -262,9 +264,9 @@
// gc->root_set = NULL;
if(vector_block_is_empty(gc->weak_root_set))
- pool_put_entry(free_set_pool, gc->weak_root_set);
- else
- pool_put_entry(metadata->weak_roots_pool, gc->weak_root_set);
+ pool_put_entry(free_set_pool, gc->weak_root_set);
+ else
+ pool_put_entry(metadata->weak_roots_pool, gc->weak_root_set);
gc->weak_root_set = NULL;
if(!gc_is_gen_mode()) return;
@@ -287,8 +289,9 @@
pool_put_entry(metadata->collector_remset_pool, collector->rem_set);
collector->rem_set = NULL;
}
-
- if( !gc_match_kind(gc, MINOR_COLLECTION )){
+
+ assert(gc_match_either_kind(gc, MINOR_COLLECTION|NORMAL_MAJOR_COLLECTION));
+ if( gc_match_kind(gc, NORMAL_MAJOR_COLLECTION )){
/* all the remsets are useless now */
/* clean and put back mutator remsets */
root_set = pool_get_entry( mutator_remset_pool );
@@ -330,7 +333,8 @@
void gc_reset_rootset(GC* gc)
{
assert(pool_is_empty(gc_metadata.gc_rootset_pool));
- assert(gc->root_set == NULL);
+ ///TODO: check the statements below assert(gc->root_set == NULL);
+ if(gc->root_set != NULL) gc->root_set = NULL;
gc->root_set = free_set_pool_get_entry(&gc_metadata);
assert(vector_block_is_empty(gc->root_set));
@@ -349,6 +353,17 @@
return;
}
+void gc_clear_rootset(GC* gc)
+{
+ gc_reset_interior_pointer_table();
+ gc_set_pool_clear(gc->metadata->gc_rootset_pool);
+#ifdef COMPRESS_REFERENCE
+ gc_set_pool_clear(gc->metadata->gc_uncompressed_rootset_pool);
+#endif
+ gc->root_set = NULL;
+}
+
+
void gc_clear_remset(GC* gc)
{
assert(gc->root_set != NULL);
@@ -389,6 +404,63 @@
}
return;
+}
+
+#ifdef _DEBUG
+Boolean obj_is_mark_black_in_table(Partial_Reveal_Object* p_obj);
+#endif
+
+void gc_reset_snaptshot(GC* gc)
+{
+ GC_Metadata* metadata = gc->metadata;
+
+ /*reset mutator local snapshot block*/
+ Mutator *mutator = gc->mutator_list;
+ while (mutator) {
+ Vector_Block* local_snapshot = mutator->dirty_obj_snapshot;
+ assert(local_snapshot);
+ if(!vector_block_is_empty(local_snapshot)){
+#ifdef _DEBUG
+ POINTER_SIZE_INT* iter = vector_block_iterator_init(local_snapshot);
+ while(!vector_block_iterator_end(local_snapshot,iter)){
+ Partial_Reveal_Object* p_obj = (Partial_Reveal_Object*) *iter;
+ iter = vector_block_iterator_advance(local_snapshot, iter);
+#ifdef USE_MARK_SWEEP_GC
+ assert(obj_is_mark_black_in_table(p_obj));
+#endif
+ }
+#endif
+ vector_block_clear(mutator->dirty_obj_snapshot);
+ }
+ mutator = mutator->next;
+ }
+
+ /*reset global snapshot pool*/
+ Pool* global_snapshot = metadata->dirty_obj_snaptshot_pool;
+
+ if(!pool_is_empty(global_snapshot)){
+ Vector_Block* snapshot_block = pool_get_entry(global_snapshot);
+ while(snapshot_block != NULL){
+ if(!vector_block_is_empty(snapshot_block)){
+#ifdef _DEBUG
+ POINTER_SIZE_INT* iter = vector_block_iterator_init(snapshot_block);
+ while(!vector_block_iterator_end(snapshot_block,iter)){
+ Partial_Reveal_Object* p_obj = (Partial_Reveal_Object*) *iter;
+ iter = vector_block_iterator_advance(snapshot_block, iter);
+#ifdef USE_MARK_SWEEP_GC
+ assert(obj_is_mark_black_in_table(p_obj));
+#endif
+ }
+#endif
+ }
+ vector_block_clear(snapshot_block);
+ pool_put_entry(metadata->free_set_pool,snapshot_block);
+ snapshot_block = pool_get_entry(global_snapshot);
+ }
+ }
+
+
+
}
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.h?rev=570028&r1=570027&r2=570028&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.h Mon Aug 27 01:11:57 2007
@@ -48,7 +48,9 @@
#ifdef USE_32BITS_HASHCODE
Pool* collector_hashcode_pool;
#endif
-
+
+ Pool* dirty_obj_snaptshot_pool;
+
}GC_Metadata;
extern GC_Metadata gc_metadata;
@@ -59,12 +61,16 @@
void gc_set_rootset(GC* gc);
void gc_reset_rootset(GC* gc);
+void gc_clear_rootset(GC* gc);
void gc_fix_rootset(Collector* collector);
+void gc_clear_remset(GC* gc);
+void gc_reset_snaptshot(GC* gc);
void identify_dead_weak_roots(GC *gc, Pool *pool);
void gc_update_weak_roots_pool(GC *gc);
void gc_clear_remset(GC* gc);
+
inline void gc_task_pool_clear(Pool* task_pool)
{
Vector_Block* task = pool_get_entry(task_pool);
@@ -128,6 +134,23 @@
pool_put_entry(gc_metadata.mutator_remset_pool, root_set);
mutator->rem_set = free_set_pool_get_entry(&gc_metadata);
assert(mutator->rem_set);
+}
+
+inline void mutator_snapshotset_add_entry(Mutator* mutator, Partial_Reveal_Object* p_obj)
+{
+ Vector_Block* dirty_obj_snapshot = mutator->dirty_obj_snapshot;
+ vector_block_add_entry(dirty_obj_snapshot, (POINTER_SIZE_INT)p_obj);
+
+ if( !vector_block_is_full(dirty_obj_snapshot) ) return;
+
+ vector_block_set_full(dirty_obj_snapshot);
+
+ if(vector_block_set_exclusive(dirty_obj_snapshot)){
+ //?vector_block_set_full(dirty_obj_snapshot); //ynhe
+ pool_put_entry(gc_metadata.dirty_obj_snaptshot_pool, dirty_obj_snapshot);
+ }
+
+ mutator->dirty_obj_snapshot = free_set_pool_get_entry(&gc_metadata);
}
inline void collector_repset_add_entry(Collector* collector, Partial_Reveal_Object** p_ref)
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_platform.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_platform.h?rev=570028&r1=570027&r2=570028&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_platform.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_platform.h Mon Aug 27 01:11:57 2007
@@ -24,6 +24,7 @@
#include "port_vmem.h"
#include "port_atomic.h"
+#include "port_malloc.h"
#include <assert.h>
@@ -64,6 +65,18 @@
#define VmThreadHandle void*
#define VmEventHandle hysem_t
#define THREAD_OK TM_ERROR_NONE
+#define THREAD_GROUP hythread_group_t
+
+extern THREAD_GROUP gc_thread_group;
+
+inline THREAD_GROUP get_gc_thread_group () {
+ if (!gc_thread_group) {
+ IDATA UNUSED stat = hythread_group_create(&gc_thread_group);
+ assert(stat == TM_ERROR_NONE);
+ }
+ return gc_thread_group;
+}
+
inline int vm_wait_event(VmEventHandle event)
{ int stat = (int)hysem_wait(event);
@@ -91,13 +104,12 @@
inline int vm_create_thread(int (*func)(void*), void *data)
{
- hythread_t* ret_thread = NULL;
+ hythread_t ret_thread = (hythread_t)STD_CALLOC(1,hythread_get_struct_size());;
UDATA stacksize = 0;
- UDATA priority = 0;
- UDATA suspend = 0;
+ UDATA priority = 5;
- return (int)hythread_create(ret_thread, stacksize, priority, suspend,
- (hythread_entrypoint_t)func, data);
+ return (int)hythread_create_with_group(ret_thread, get_gc_thread_group(), stacksize, priority,
+ (hythread_entrypoint_t)func, data);
}
inline void *atomic_casptr(volatile void **mem, void *with, const void *cmp)
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_space.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_space.h?rev=570028&r1=570027&r2=570028&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_space.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_space.h Mon Aug 27 01:11:57 2007
@@ -26,6 +26,13 @@
extern unsigned int SPACE_ALLOC_UNIT;
+typedef struct Space_Statistics{
+ POINTER_SIZE_INT num_live_obj;
+ POINTER_SIZE_INT size_live_obj;
+ POINTER_SIZE_INT size_free_space;
+ POINTER_SIZE_INT last_size_free_space;
+}Space_Statistics;
+
struct GC;
/* all Spaces inherit this Space structure */
typedef struct Space{
@@ -40,6 +47,8 @@
GC* gc;
Boolean move_object;
+ Space_Statistics* space_statistic;
+
/* Size allocted since last minor collection. */
volatile uint64 last_alloced_size;
/* Size allocted since last major collection. */
@@ -53,6 +62,9 @@
uint64 period_surviving_size;
}Space;
+struct Allocator;
+typedef void *(*Space_Alloc_Func)(unsigned, Allocator *);
+
inline POINTER_SIZE_INT space_committed_size(Space* space){ return space->committed_heap_size;}
inline void* space_heap_start(Space* space){ return space->heap_start; }
inline void* space_heap_end(Space* space){ return space->heap_end; }
@@ -81,6 +93,8 @@
GC* gc;
Boolean move_object;
+ Space_Statistics* space_statistic;
+
/* Size allocted since last minor collection. */
volatile uint64 last_alloced_size;
/* Size allocted since last major collection. */
@@ -105,12 +119,14 @@
unsigned int num_used_blocks;
unsigned int num_managed_blocks;
unsigned int num_total_blocks;
+
+ volatile Block_Header* block_iterator;
/* END of Blocked_Space --> */
}Blocked_Space;
-inline Boolean space_has_free_block(Blocked_Space* space){ return space->free_block_idx <= space->ceiling_block_idx; }
-inline unsigned int space_free_memory_size(Blocked_Space* space){ return GC_BLOCK_SIZE_BYTES * (space->ceiling_block_idx - space->free_block_idx + 1); }
-inline Boolean space_used_memory_size(Blocked_Space* space){ return GC_BLOCK_SIZE_BYTES * (space->free_block_idx - space->first_block_idx); }
+inline Boolean blocked_space_has_free_block(Blocked_Space *space){ return space->free_block_idx <= space->ceiling_block_idx; }
+inline unsigned int blocked_space_free_mem_size(Blocked_Space *space){ return GC_BLOCK_SIZE_BYTES * (space->ceiling_block_idx - space->free_block_idx + 1); }
+inline Boolean blocked_space_used_mem_size(Blocked_Space *space){ return GC_BLOCK_SIZE_BYTES * (space->free_block_idx - space->first_block_idx); }
inline void space_init_blocks(Blocked_Space* space)
{
@@ -196,6 +212,33 @@
last_block->next = NULL;
space->ceiling_block_idx = last_block->block_idx;
space->num_managed_blocks = (unsigned int)(space->committed_heap_size >> GC_BLOCK_SHIFT_COUNT);
+}
+
+inline void blocked_space_block_iterator_init(Blocked_Space *space)
+{ space->block_iterator = (Block_Header*)space->blocks; }
+
+inline void blocked_space_block_iterator_init_free(Blocked_Space *space)
+{ space->block_iterator = (Block_Header*)&space->blocks[space->free_block_idx - space->first_block_idx]; }
+
+inline Block_Header *blocked_space_block_iterator_get(Blocked_Space *space)
+{ return (Block_Header*)space->block_iterator; }
+
+inline Block_Header *blocked_space_block_iterator_next(Blocked_Space *space)
+{
+ Block_Header *cur_block = (Block_Header*)space->block_iterator;
+
+ while(cur_block != NULL){
+ Block_Header *next_block = cur_block->next;
+
+ Block_Header *temp = (Block_Header*)atomic_casptr((volatile void **)&space->block_iterator, next_block, cur_block);
+ if(temp != cur_block){
+ cur_block = (Block_Header*)space->block_iterator;
+ continue;
+ }
+ return cur_block;
+ }
+ /* run out space blocks */
+ return NULL;
}
#endif //#ifndef _GC_SPACE_H_
Added: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/object_status.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/object_status.h?rev=570028&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/object_status.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/object_status.h Mon Aug 27 01:11:57 2007
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+#ifndef _OBJECT_STATUS_H_
+#define _OBJECT_STATUS_H_
+
+#include "../gen/gen.h"
+#include "../mark_sweep/gc_ms.h"
+
+
+inline Boolean obj_is_dead_in_gen_minor_gc(Partial_Reveal_Object *p_obj)
+{
+ /*
+ * The first condition is for supporting switch between nongen and gen minor collection.
+ * With this kind of switch dead objects in MOS & LOS may be set the mark or fw bit in oi.
+ * The second condition is for supporting partially forwarding NOS.
+ * In partially forwarding situation live objects in the non-forwarding half NOS will only be marked but not forwarded.
+ */
+ return obj_belongs_to_nos(p_obj) && !obj_is_marked_or_fw_in_oi(p_obj);
+}
+
+inline Boolean obj_is_dead_in_nongen_minor_gc(Partial_Reveal_Object *p_obj)
+{
+ return (obj_belongs_to_nos(p_obj) && !obj_is_fw_in_oi(p_obj))
+ || (!obj_belongs_to_nos(p_obj) && !obj_is_marked_in_oi(p_obj));
+}
+
+extern Boolean obj_is_mark_black_in_table(Partial_Reveal_Object *obj);
+
+/* The caller must be in places where alloc color and mark color haven't been flipped */
+inline Boolean obj_is_dead_in_sweep_major_gc(Partial_Reveal_Object *p_obj)
+{
+ return (obj_belongs_to_nos(p_obj) && !obj_is_marked_in_vt(p_obj))
+ || (!obj_belongs_to_nos(p_obj) && !obj_is_mark_black_in_table(p_obj));
+}
+
+inline Boolean obj_is_dead_in_compact_major_gc(Partial_Reveal_Object *p_obj)
+{
+ return !obj_is_marked_in_vt(p_obj);
+}
+
+#ifdef USE_MARK_SWEEP_GC
+inline Boolean obj_is_dead_in_mark_sweep_gc(Partial_Reveal_Object *p_obj)
+{
+ return !obj_is_mark_black_in_table(p_obj);
+}
+#endif
+
+inline Boolean gc_obj_is_dead(GC *gc, Partial_Reveal_Object *p_obj)
+{
+ assert(p_obj);
+
+#ifdef USE_MARK_SWEEP_GC
+ return obj_is_dead_in_mark_sweep_gc(p_obj);
+#endif
+
+ if(gc_match_kind(gc, MINOR_COLLECTION)){
+ if(gc_is_gen_mode())
+ return obj_is_dead_in_gen_minor_gc(p_obj);
+ else
+ return obj_is_dead_in_nongen_minor_gc(p_obj);
+ } else if(gc_get_mos((GC_Gen*)gc)->collect_algorithm == MAJOR_MARK_SWEEP){
+ return obj_is_dead_in_sweep_major_gc(p_obj);
+ } else {
+ return obj_is_dead_in_compact_major_gc(p_obj);
+ }
+}
+
+inline Boolean fspace_obj_to_be_forwarded(Partial_Reveal_Object *p_obj)
+{
+ if(!obj_belongs_to_nos(p_obj)) return FALSE;
+ return forward_first_half ? (p_obj < object_forwarding_boundary) : (p_obj>=object_forwarding_boundary);
+}
+inline Boolean obj_need_move(GC *gc, Partial_Reveal_Object *p_obj)
+{
+ /* assert(!gc_obj_is_dead(gc, p_obj)); commented out for weakroot */
+
+#ifdef USE_MARK_SWEEP_GC
+ Sspace *sspace = gc_ms_get_sspace((GC_MS*)gc);
+ return sspace->move_object;
+#endif
+
+ if(gc_is_gen_mode() && gc_match_kind(gc, MINOR_COLLECTION))
+ return fspace_obj_to_be_forwarded(p_obj);
+
+ Space *space = space_of_addr(gc, p_obj);
+ return space->move_object;
+}
+
+
+#endif /* _OBJECT_STATUS_H_ */
Propchange: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/object_status.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.cpp?rev=570028&r1=570027&r2=570028&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.cpp Mon Aug 27 01:11:57 2007
@@ -33,7 +33,7 @@
/* Calculate speed of allocation and waste memory of specific space respectively,
* then decide whether to execute a space tuning according to the infomation.*/
-void gc_decide_space_tune(GC* gc, unsigned int cause)
+static void gc_decide_space_tune(GC* gc)
{
Blocked_Space* mspace = (Blocked_Space*)gc_get_mos((GC_Gen*)gc);
Blocked_Space* fspace = (Blocked_Space*)gc_get_nos((GC_Gen*)gc);
@@ -94,11 +94,11 @@
/* The tuning size computing before marking is not precise. We only estimate the probable direction of space tuning.
* If this function decide to set TRANS_NOTHING, then we just call the normal marking function.
* Else, we call the marking function for space tuning. */
-void gc_compute_space_tune_size_before_marking(GC* gc, unsigned int cause)
+void gc_compute_space_tune_size_before_marking(GC* gc)
{
if(gc_match_kind(gc, MINOR_COLLECTION)) return;
- gc_decide_space_tune(gc, cause);
+ gc_decide_space_tune(gc);
Space_Tuner* tuner = gc->tuner;
assert((tuner->speed_los != 0) && ( tuner->speed_mos != 0)) ;
@@ -440,7 +440,7 @@
void gc_space_tuner_reset(GC* gc)
{
Space_Tuner* tuner = gc->tuner;
- if( !gc_match_kind(gc, MINOR_COLLECTION)){
+ if( gc_match_kind(gc, MAJOR_COLLECTION)){
/*Clear the fields every major collection except the wast area statistic.*/
tuner->tuning_size = 0;
tuner->interim_blocks = NULL;
@@ -538,6 +538,4 @@
STD_FREE(tuner->interim_blocks);
return;
}
-
-
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.h?rev=570028&r1=570027&r2=570028&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.h Mon Aug 27 01:11:57 2007
@@ -75,11 +75,14 @@
POINTER_SIZE_INT min_tuning_size;
}Space_Tuner;
-void gc_compute_space_tune_size_before_marking(GC* gc, unsigned int cause);
+void gc_compute_space_tune_size_before_marking(GC* gc);
void gc_compute_space_tune_size_after_marking(GC *gc);
void gc_space_tuner_reset(GC* gc);
void gc_space_tuner_initialize(GC* gc);
void gc_space_tuner_init_fake_blocks_for_los_shrink(GC* gc);
void gc_space_tuner_release_fake_blocks_for_los_shrink(GC* gc);
+
+inline Boolean gc_has_space_tuner(GC* gc)
+{ return (Boolean)(POINTER_SIZE_INT)gc->tuner; }
#endif /* _SPACE_TUNER_H_ */
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/weak_roots.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/weak_roots.cpp?rev=570028&r1=570027&r2=570028&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/weak_roots.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/weak_roots.cpp Mon Aug 27 01:11:57 2007
@@ -16,7 +16,7 @@
#include "gc_common.h"
#include "gc_metadata.h"
-#include "../gen/gen.h"
+#include "object_status.h"
void identify_dead_weak_roots(GC *gc, Pool *pool)
{
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.cpp?rev=570028&r1=570027&r2=570028&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.cpp Mon Aug 27 01:11:57 2007
@@ -29,6 +29,8 @@
#include "../gen/gen.h"
#include "../mark_sweep/gc_ms.h"
#include "../common/space_tuner.h"
+#include "../common/compressed_ref.h"
+#include "../common/object_status.h"
Boolean IGNORE_FINREF = FALSE;
Boolean DURING_RESURRECTION = FALSE;
@@ -102,7 +104,7 @@
}
gc_put_finalizable_objects(gc);
- if(gc_match_kind(gc, MAJOR_COLLECTION|FALLBACK_COLLECTION|SWEEP_COMPACT_GC))
+ if(gc_match_either_kind(gc, MAJOR_COLLECTION|MS_COMPACT_COLLECTION))
finref_add_repset_from_pool(gc, obj_with_fin_pool);
}
@@ -133,9 +135,9 @@
trace_object = trace_obj_in_gen_fw;
else
trace_object = trace_obj_in_nongen_fw;
- } else if(gc_match_kind(gc, MAJOR_COLLECTION)){
+ } else if(gc_match_kind(gc, NORMAL_MAJOR_COLLECTION)){
p_ref_or_obj = p_obj;
- if(gc->tuner->kind != TRANS_NOTHING){
+ if(gc_has_space_tuner(gc) && (gc->tuner->kind != TRANS_NOTHING)){
trace_object = trace_obj_in_space_tune_marking;
unsigned int obj_size = vm_object_size(p_obj);
#ifdef USE_32BITS_HASHCODE
@@ -147,13 +149,15 @@
} else {
collector->los_live_obj_size += round_up_to_size(obj_size, KB);
}
- }else{
+ } else if(gc_get_mos((GC_Gen*)gc)->collect_algorithm == MAJOR_MARK_SWEEP){
+ trace_object = trace_obj_in_ms_marking;
+ } else {
trace_object = trace_obj_in_normal_marking;
}
} else if(gc_match_kind(gc, FALLBACK_COLLECTION)){
trace_object = trace_obj_in_fallback_marking;
} else {
- assert(gc_match_kind(gc, MARK_SWEEP_GC|SWEEP_COMPACT_GC));
+ assert(gc_match_kind(gc, MARK_SWEEP_GC));
p_ref_or_obj = p_obj;
trace_object = trace_obj_in_ms_marking;
}
@@ -168,9 +172,8 @@
POINTER_SIZE_INT *iter = vector_block_iterator_init(task_block);
while(!vector_block_iterator_end(task_block, iter)){
void *p_ref_or_obj = (void*)*iter;
- assert((gc_match_kind(gc, MINOR_COLLECTION | FALLBACK_COLLECTION) && *(Partial_Reveal_Object **)p_ref_or_obj)
- || (gc_match_kind(gc, MAJOR_COLLECTION) && p_ref_or_obj)
- || (gc_match_kind(gc, MARK_SWEEP_GC|SWEEP_COMPACT_GC) && p_ref_or_obj));
+ assert((gc_match_either_kind(gc, MINOR_COLLECTION|FALLBACK_COLLECTION) && *(Partial_Reveal_Object **)p_ref_or_obj)
+ || (gc_match_either_kind(gc, NORMAL_MAJOR_COLLECTION|MS_COLLECTION|MS_COMPACT_COLLECTION) && p_ref_or_obj));
trace_object(collector, p_ref_or_obj);
if(collector->result == FALSE) break; /* Resurrection fallback happens; force return */
@@ -235,7 +238,7 @@
* Because it is outside heap, we can't update it in ref fixing.
* In minor collection p_ref of the root dead obj is automatically updated while tracing.
*/
- if(gc_match_kind(gc, MAJOR_COLLECTION|FALLBACK_COLLECTION|SWEEP_COMPACT_GC))
+ if(gc_match_either_kind(gc, MAJOR_COLLECTION|MS_COMPACT_COLLECTION))
finref_add_repset_from_pool(gc, finalizable_obj_pool);
metadata->pending_finalizers = TRUE;
@@ -246,7 +249,7 @@
static void identify_dead_refs(GC *gc, Pool *pool)
{
- if(gc_match_kind(gc, MAJOR_COLLECTION|FALLBACK_COLLECTION|SWEEP_COMPACT_GC))
+ if(gc_match_either_kind(gc, MAJOR_COLLECTION|MS_COMPACT_COLLECTION))
finref_reset_repset(gc);
pool_iterator_init(pool);
Vector_Block *block = pool_iterator_next(pool);
@@ -270,7 +273,7 @@
if(gc_match_kind(gc, MINOR_COLLECTION)){
assert(obj_is_fw_in_oi(p_referent));
write_slot(p_referent_field, (obj_get_fw_in_oi(p_referent)));
- } else if(!gc_match_kind(gc, MARK_SWEEP_GC)){
+ } else if(!gc_match_kind(gc, MS_COLLECTION)){
finref_repset_add_entry(gc, p_referent_field);
}
}
@@ -283,7 +286,7 @@
block = pool_iterator_next(pool);
}
- if(gc_match_kind(gc, MAJOR_COLLECTION|FALLBACK_COLLECTION|SWEEP_COMPACT_GC)){
+ if(gc_match_either_kind(gc, MAJOR_COLLECTION|MS_COMPACT_COLLECTION)){
finref_put_repset(gc);
finref_add_repset_from_pool(gc, pool);
}
@@ -319,7 +322,7 @@
Finref_Metadata *metadata = gc->finref_metadata;
Pool *phanref_pool = metadata->phanref_pool;
- if(gc_match_kind(gc, MAJOR_COLLECTION|FALLBACK_COLLECTION|SWEEP_COMPACT_GC))
+ if(gc_match_either_kind(gc, MAJOR_COLLECTION|MS_COMPACT_COLLECTION))
finref_reset_repset(gc);
// collector_reset_repset(collector);
pool_iterator_init(phanref_pool);
@@ -344,7 +347,7 @@
if(gc_match_kind(gc, MINOR_COLLECTION)){
assert(obj_is_fw_in_oi(p_referent));
write_slot(p_referent_field, (obj_get_fw_in_oi(p_referent)));
- } else if(!gc_match_kind(gc, MARK_SWEEP_GC)){
+ } else if(!gc_match_kind(gc, MS_COLLECTION)){
finref_repset_add_entry(gc, p_referent_field);
}
*p_ref = (REF)NULL;
@@ -362,7 +365,7 @@
block = pool_iterator_next(phanref_pool);
}
// collector_put_repset(collector);
- if(gc_match_kind(gc, MAJOR_COLLECTION|FALLBACK_COLLECTION|SWEEP_COMPACT_GC)){
+ if(gc_match_either_kind(gc, MAJOR_COLLECTION|MS_COMPACT_COLLECTION)){
finref_put_repset(gc);
finref_add_repset_from_pool(gc, phanref_pool);
}
@@ -631,14 +634,14 @@
{
Finref_Metadata *metadata = gc->finref_metadata;
- if(gc_match_kind(gc, MAJOR_COLLECTION|FALLBACK_COLLECTION|SWEEP_COMPACT_GC))
+ if(gc_match_either_kind(gc, MAJOR_COLLECTION|MS_COMPACT_COLLECTION))
finref_reset_repset(gc);
- if(!gc_match_kind(gc, MARK_SWEEP_GC)){
+ if(!gc_match_kind(gc, MS_COLLECTION)){
update_referent_field_ignore_finref(gc, metadata->softref_pool);
update_referent_field_ignore_finref(gc, metadata->weakref_pool);
update_referent_field_ignore_finref(gc, metadata->phanref_pool);
}
- if(gc_match_kind(gc, MAJOR_COLLECTION|FALLBACK_COLLECTION|SWEEP_COMPACT_GC))
+ if(gc_match_either_kind(gc, MAJOR_COLLECTION|MS_COMPACT_COLLECTION))
finref_put_repset(gc);
}
@@ -667,7 +670,11 @@
*p_ref = obj_get_fw_in_table(p_obj);
}
-static inline void sweep_compaction_update_ref(GC *gc, REF *p_ref)
+/* In two cases mark-sweep needs fixing repointed refs:
+ * 1. ms with compaction
+ * 2. ms as a mos collection algorithm
+ */
+static inline void moving_mark_sweep_update_ref(GC *gc, REF *p_ref)
{
/* There are only two kinds of p_ref being added into finref_repset_pool:
* 1. p_ref is in a vector block from one finref pool;
@@ -696,40 +703,6 @@
extern Boolean IS_MOVE_COMPACT;
/* parameter pointer_addr_in_pool means it is p_ref or p_obj in pool */
-static void destructively_fix_finref_pool(GC *gc, Pool *pool, Boolean pointer_addr_in_pool)
-{
- Finref_Metadata *metadata = gc->finref_metadata;
- REF *p_ref;
- Partial_Reveal_Object *p_obj;
-
- /* NOTE:: this is destructive to the root sets. */
- Vector_Block *repset = pool_get_entry(pool);
- while(repset){
- POINTER_SIZE_INT *iter = vector_block_iterator_init(repset);
- for(; !vector_block_iterator_end(repset,iter); iter = vector_block_iterator_advance(repset,iter)){
- if(pointer_addr_in_pool)
- p_ref = (REF*)*iter;
- else
- p_ref = (REF*)iter;
- p_obj = read_slot(p_ref);
-
- if(IS_MOVE_COMPACT){
- move_compaction_update_ref(gc, p_ref);
- } else if(gc_match_kind(gc, SWEEP_COMPACT_GC)){
- if(obj_is_fw_in_oi(p_obj))
- sweep_compaction_update_ref(gc, p_ref);
- } else {
- assert((obj_is_marked_in_vt(p_obj) && obj_is_fw_in_oi(p_obj)));
- write_slot(p_ref , obj_get_fw_in_oi(p_obj));
- }
- }
- vector_block_clear(repset);
- pool_put_entry(metadata->free_pool, repset);
- repset = pool_get_entry(pool);
- }
-}
-
-/* parameter pointer_addr_in_pool means it is p_ref or p_obj in pool */
static void nondestructively_fix_finref_pool(GC *gc, Pool *pool, Boolean pointer_addr_in_pool)
{
Finref_Metadata *metadata = gc->finref_metadata;
@@ -748,11 +721,11 @@
p_ref = (REF*)iter;
p_obj = read_slot(p_ref);
- if(!IS_MOVE_COMPACT){
+ if(IS_MOVE_COMPACT){
move_compaction_update_ref(gc, p_ref);
- } else if(gc_match_kind(gc, SWEEP_COMPACT_GC)){
+ } else if(gc_match_kind(gc, MS_COMPACT_COLLECTION) || gc_get_mos((GC_Gen*)gc)->collect_algorithm==MAJOR_MARK_SWEEP){
if(obj_is_fw_in_oi(p_obj))
- sweep_compaction_update_ref(gc, p_ref);
+ moving_mark_sweep_update_ref(gc, p_ref);
} else {
assert((obj_is_marked_in_vt(p_obj) && obj_is_fw_in_oi(p_obj)));
write_slot(p_ref , obj_get_fw_in_oi(p_obj));
@@ -770,7 +743,7 @@
Pool *repset_pool = metadata->repset_pool;
Pool *fallback_ref_pool = metadata->fallback_ref_pool;
- destructively_fix_finref_pool(gc, repset_pool, TRUE);
+ nondestructively_fix_finref_pool(gc, repset_pool, TRUE);
if(!pool_is_empty(fallback_ref_pool)){
assert(IS_FALLBACK_COMPACTION);
nondestructively_fix_finref_pool(gc, fallback_ref_pool, FALSE);
@@ -787,3 +760,26 @@
vm_hint_finalize();
}
}
+
+static void finref_copy_pool_to_rootset(GC *gc, Pool *src_pool)
+{
+ pool_iterator_init(src_pool);
+ while(Vector_Block *root_set = pool_iterator_next(src_pool)){
+ POINTER_SIZE_INT *iter = vector_block_iterator_init(root_set);
+ while(!vector_block_iterator_end(root_set, iter)){
+ gc_compressed_rootset_add_entry(gc, (REF*)iter);
+ iter = vector_block_iterator_advance(root_set, iter);
+ }
+ }
+}
+
+void gc_copy_finaliable_obj_to_rootset(GC *gc)
+{
+ Pool *finalizable_obj_pool = gc->finref_metadata->finalizable_obj_pool;
+ Pool *finalizable_obj_pool_copy = gc->finref_metadata->finalizable_obj_pool_copy;
+ Pool *free_pool = gc->metadata->gc_rootset_pool;
+ finref_metadata_clear_pool(finalizable_obj_pool_copy);
+ finref_copy_pool(finalizable_obj_pool, finalizable_obj_pool_copy, gc);
+ finref_copy_pool_to_rootset(gc, finalizable_obj_pool_copy);
+}
+
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.h?rev=570028&r1=570027&r2=570028&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref.h Mon Aug 27 01:11:57 2007
@@ -93,7 +93,9 @@
extern void gc_put_finref_to_vm(GC *gc);
extern void put_all_fin_on_exit(GC *gc);
-extern void gc_update_finref_repointed_refs(GC* gc);
+extern void gc_update_finref_repointed_refs(GC *gc);
extern void gc_activate_finref_threads(GC *gc);
+
+void gc_copy_finaliable_obj_to_rootset(GC *gc);
#endif // _FINREF_H_
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.cpp?rev=570028&r1=570027&r2=570028&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.cpp Mon Aug 27 01:11:57 2007
@@ -56,6 +56,7 @@
finref_metadata.free_pool = sync_pool_create();
finref_metadata.obj_with_fin_pool = sync_pool_create();
finref_metadata.finalizable_obj_pool = sync_pool_create();
+ finref_metadata.finalizable_obj_pool_copy = sync_pool_create();
finref_metadata.softref_pool = sync_pool_create();
finref_metadata.weakref_pool = sync_pool_create();
finref_metadata.phanref_pool = sync_pool_create();
@@ -89,6 +90,7 @@
sync_pool_destruct(metadata->free_pool);
sync_pool_destruct(metadata->obj_with_fin_pool);
sync_pool_destruct(metadata->finalizable_obj_pool);
+ sync_pool_destruct(metadata->finalizable_obj_pool_copy);
sync_pool_destruct(metadata->softref_pool);
sync_pool_destruct(metadata->weakref_pool);
sync_pool_destruct(metadata->phanref_pool);
@@ -204,6 +206,7 @@
collector->phanref_set= finref_get_free_block(gc);
}
+#include "../common/gc_concurrent.h"
/* put back last weak references block of each collector */
void gc_set_weakref_sets(GC *gc)
{
@@ -220,6 +223,20 @@
collector->weakref_set= NULL;
collector->phanref_set= NULL;
}
+
+ if(gc_mark_is_concurrent()){
+ unsigned int num_active_markers = gc->num_active_markers;
+ for(unsigned int i = 0; i < num_active_markers; i++)
+ {
+ Collector *marker = (Collector*)gc->markers[i];
+ pool_put_entry(metadata->softref_pool, marker->softref_set);
+ pool_put_entry(metadata->weakref_pool, marker->weakref_set);
+ pool_put_entry(metadata->phanref_pool, marker->phanref_set);
+ marker->softref_set = NULL;
+ marker->weakref_set= NULL;
+ marker->phanref_set= NULL;
+ }
+ }
return;
}
@@ -233,10 +250,14 @@
assert(pool_is_empty(metadata->softref_pool));
assert(pool_is_empty(metadata->weakref_pool));
assert(pool_is_empty(metadata->phanref_pool));
- assert(pool_is_empty(metadata->repset_pool));
assert(metadata->finalizable_obj_set == NULL);
assert(metadata->repset == NULL);
+ if(!pool_is_empty(metadata->repset_pool))
+ finref_metadata_clear_pool(metadata->repset_pool);
+ if(!pool_is_empty(metadata->fallback_ref_pool))
+ finref_metadata_clear_pool(metadata->fallback_ref_pool);
+
/* Extract empty blocks in obj_with_fin_pool and put them into free_pool */
Vector_Block *block = pool_get_entry(obj_with_fin_pool);
while(block){
@@ -378,10 +399,9 @@
return pool_has_no_ref(gc->finref_metadata->repset_pool);
}
-static void finref_metadata_clear_pool(Pool *pool)
+void finref_metadata_clear_pool(Pool *pool)
{
- while(Vector_Block* block = pool_get_entry(pool))
- {
+ while(Vector_Block* block = pool_get_entry(pool)){
vector_block_clear(block);
pool_put_entry(finref_metadata.free_pool, block);
}
@@ -393,3 +413,19 @@
finref_metadata_clear_pool(gc->finref_metadata->weakref_pool);
finref_metadata_clear_pool(gc->finref_metadata->phanref_pool);
}
+
+Boolean finref_copy_pool(Pool *src_pool, Pool *dest_pool, GC *gc)
+{
+ Vector_Block *dest_block = finref_get_free_block(gc);
+ pool_iterator_init(src_pool);
+ while(Vector_Block *src_block = pool_iterator_next(src_pool)){
+ POINTER_SIZE_INT *iter = vector_block_iterator_init(src_block);
+ while(!vector_block_iterator_end(src_block, iter)){
+ assert(*iter);
+ finref_metadata_add_entry(gc, dest_block, dest_pool, *iter);
+ iter = vector_block_iterator_advance(src_block, iter);
+ }
+ }
+ return TRUE;
+}
+
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.h?rev=570028&r1=570027&r2=570028&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/finalizer_weakref/finalizer_weakref_metadata.h Mon Aug 27 01:11:57 2007
@@ -38,6 +38,8 @@
Pool *obj_with_fin_pool; // list of objects that have finalizers
// these objects are added in when they are being allocated
Pool *finalizable_obj_pool; // temporary buffer for finalizable objects identified during one single GC
+
+ Pool *finalizable_obj_pool_copy;
Pool *softref_pool; // temporary buffer for soft references identified during one single GC
Pool *weakref_pool; // temporary buffer for weak references identified during one single GC
@@ -83,6 +85,10 @@
extern Boolean weakref_pool_is_empty(GC *gc);
extern Boolean phanref_pool_is_empty(GC *gc);
extern Boolean finref_repset_pool_is_empty(GC *gc);
+
+extern void finref_metadata_clear_pool(Pool *pool);
+extern Boolean finref_copy_pool(Pool* src_pool, Pool* dest_pool, GC* gc);
+
extern void gc_clear_weakref_pools(GC *gc);
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gc_for_barrier.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gc_for_barrier.cpp?rev=570028&r1=570027&r2=570028&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gc_for_barrier.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gc_for_barrier.cpp Mon Aug 27 01:11:57 2007
@@ -22,6 +22,9 @@
#include "../gen/gen.h"
#include "../thread/mutator.h"
#include "gc_for_barrier.h"
+#include "../mark_sweep/sspace_mark_sweep.h"
+#include "../common/gc_concurrent.h"
+
/* All the write barrier interfaces need cleanup */
@@ -81,6 +84,8 @@
void gc_heap_wrote_object (Managed_Object_Handle p_obj_written)
{
+ /*concurrent mark: since object clone and array copy do not modify object slot,
+ we treat it as an new object. It has already been marked when dest object was created.*/
if( !gc_is_gen_mode() ) return;
if( object_has_ref_field((Partial_Reveal_Object*)p_obj_written)){
/* for array copy and object clone */
@@ -92,18 +97,66 @@
void gc_heap_write_ref (Managed_Object_Handle p_obj_holding_ref, unsigned offset, Managed_Object_Handle p_target)
{ assert(0); }
+/*This function is for concurrent mark.*/
+static void gc_dirty_object_write_barrier(Managed_Object_Handle p_obj_holding_ref)
+{
+ Mutator *mutator = (Mutator *)gc_get_tls();
+ REF* p_obj_slot;
+ if(obj_need_take_snaptshot((Partial_Reveal_Object*)p_obj_holding_ref)){
+ if (object_is_array((Partial_Reveal_Object*)p_obj_holding_ref)) {
+ Partial_Reveal_Object* array = (Partial_Reveal_Object*)p_obj_holding_ref;
+ assert(!obj_is_primitive_array(array));
+
+ Partial_Reveal_Object* obj_to_snapshot;
+
+ int32 array_length = vector_get_length((Vector_Handle) array);
+ for (int i = 0; i < array_length; i++) {
+ p_obj_slot = (REF*)vector_get_element_address_ref((Vector_Handle) array, i);
+ obj_to_snapshot = (Partial_Reveal_Object*)read_slot(p_obj_slot);
+ if (obj_to_snapshot != NULL)
+ mutator_snapshotset_add_entry(mutator, obj_to_snapshot);
+ }
+ }else{
+ /* scan non-array object */
+ Partial_Reveal_Object* p_obj = (Partial_Reveal_Object*)p_obj_holding_ref;
+ unsigned int num_refs = object_ref_field_num(p_obj);
+ int *ref_iterator = object_ref_iterator_init(p_obj);
+
+ Partial_Reveal_Object* obj_to_snapshot;
+
+ for(unsigned int i=0; i<num_refs; i++){
+ p_obj_slot = object_ref_iterator_get(ref_iterator+i, p_obj);
+ obj_to_snapshot = (Partial_Reveal_Object*)read_slot(p_obj_slot);
+ if (obj_to_snapshot != NULL)
+ mutator_snapshotset_add_entry(mutator, obj_to_snapshot);
+ }
+ }
+ obj_dirty_in_table((Partial_Reveal_Object *) p_obj_holding_ref);
+ obj_mark_black_in_table((Partial_Reveal_Object *) p_obj_holding_ref);
+ }
+}
+
+
+
/* 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)
{
- *p_slot = p_target;
-
- if( !gc_is_gen_mode() ) return;
- gc_slot_write_barrier(p_slot, p_target);
+ if(!gc_is_concurrent_mark_phase()){
+ *p_slot = p_target;
+
+ if( !gc_is_gen_mode() ) return;
+ gc_slot_write_barrier(p_slot, p_target);
+ }else{
+ gc_dirty_object_write_barrier(p_obj_holding_ref);
+ *p_slot = p_target;
+ }
}
/* this is used for global object update, e.g., strings. */
void gc_heap_write_global_slot(Managed_Object_Handle *p_slot,Managed_Object_Handle p_target)
{
+ /*concurrent mark: global object is enumerated, so the old object has been already marked.*/
+
*p_slot = p_target;
/* Since globals are roots, no barrier here */