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 [1/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/...
Author: wjwashburn
Date: Tue Dec 5 14:32:35 2006
New Revision: 482809
URL: http://svn.apache.org/viewvc?view=rev&rev=482809
Log:
Harmony-2398, patch for gcv5 alloc
build and build test run on windowsxp and linux w/ gcc 4.0.2
Added:
harmony/enhanced/drlvm/trunk/vm/gc_gen/javasrc/
harmony/enhanced/drlvm/trunk/vm/gc_gen/javasrc/org/
harmony/enhanced/drlvm/trunk/vm/gc_gen/javasrc/org/apache/
harmony/enhanced/drlvm/trunk/vm/gc_gen/javasrc/org/apache/harmony/
harmony/enhanced/drlvm/trunk/vm/gc_gen/javasrc/org/apache/harmony/drlvm/
harmony/enhanced/drlvm/trunk/vm/gc_gen/javasrc/org/apache/harmony/drlvm/gc_gen/
harmony/enhanced/drlvm/trunk/vm/gc_gen/javasrc/org/apache/harmony/drlvm/gc_gen/GCHelper.java
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/jni/
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/jni/helper.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.h
Modified:
harmony/enhanced/drlvm/trunk/build/make/components/vm/gc_gen.xml
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_vm.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_platform.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/interior_pointer.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/interior_pointer.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan_par.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan_seq.cpp
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/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_sweep/lspace.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector_alloc.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator_alloc.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/thread_alloc.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_collect_copy.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_forward.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_forward_par.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_forward_seq.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/sync_pool.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/sync_stack.h
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/vector_block.h
Modified: harmony/enhanced/drlvm/trunk/build/make/components/vm/gc_gen.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/build/make/components/vm/gc_gen.xml?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/build/make/components/vm/gc_gen.xml (original)
+++ harmony/enhanced/drlvm/trunk/build/make/components/vm/gc_gen.xml Tue Dec 5 14:32:35 2006
@@ -16,7 +16,7 @@
-->
<!--
Author: Marina V. Goldburt, Dmitry B. Yershov
-Version: $Revision: 1.4.2.3 $
+Version: $Revision: 1.2 $
-->
<!--
This is build descriptor for the component "vm.gc_gen".
@@ -60,6 +60,7 @@
<include name="thread/*.cpp" />
<include name="trace_forward/*.cpp" />
<include name="utils/*.cpp" />
+ <include name="jni/*.cpp" />
<include name="verify/*.cpp" />
</select>
@@ -71,6 +72,7 @@
<exclude name="thread/*.cpp" />
<exclude name="trace_forward/*.cpp" />
<exclude name="utils/*.cpp" />
+ <exclude name="jni/*.cpp" />
<exclude name="verify/*.cpp" />
</select>
</fileset>
@@ -113,16 +115,23 @@
<linkerarg value="-Bsymbolic" />
</select>
</linker>
+
+ <!-- Java helpers -->
+ <property name="build.java.depends" value=""/>
+
<path id="java.source">
- <pathelement location="${build.vm.home}/gc_gen/src/tests" />
+ <pathelement location="${build.vm.home}/gc_gen/javasrc" />
</path>
<path id="java.class.path">
<pathelement location="${java.build.dir}"/>
<fileset dir="${external.dep.CLASSLIB.jardir}" includes="*.jar" />
- <fileset dir="${build.ANTLR.home}" includes="antlr-2.7.5.jar" />
+ <pathelement location="${vm.kernel_classes.jardir}/kernel.jar"/>
+ <fileset dir="${build.MMTK.home}" includes="mmtk-20061012.jar" />
</path>
+
+ <property name="jarname" value="gc_gen.jar"/>
</target>
</project>
Added: harmony/enhanced/drlvm/trunk/vm/gc_gen/javasrc/org/apache/harmony/drlvm/gc_gen/GCHelper.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/javasrc/org/apache/harmony/drlvm/gc_gen/GCHelper.java?view=auto&rev=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/javasrc/org/apache/harmony/drlvm/gc_gen/GCHelper.java (added)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/javasrc/org/apache/harmony/drlvm/gc_gen/GCHelper.java Tue Dec 5 14:32:35 2006
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+/**
+ * @author Xiao-Feng Li
+ */
+
+package org.apache.harmony.drlvm.gc_gen;
+
+import org.apache.harmony.drlvm.VMHelper;
+import org.vmmagic.unboxed.*;
+
+public class GCHelper {
+
+ static {System.loadLibrary("gc_gen");}
+
+ public static final int TLS_GC_OFFSET = TLSGCOffset();
+
+ public static Object alloc(int objSize, int allocationHandle) {
+
+ Address TLS_BASE = VMHelper.getTlsBaseAddress();
+
+ Address allocator_addr = TLS_BASE.plus(TLS_GC_OFFSET);
+ Address allocator = allocator_addr.loadAddress();
+ Address free_addr = allocator.plus(0);
+ Address free = free_addr.loadAddress();
+ Address ceiling = allocator.plus(4).loadAddress();
+
+ Address new_free = free.plus(objSize);
+
+ if (new_free.LE(ceiling)) {
+ free_addr.store(new_free);
+ free.store(allocationHandle);
+ return free;
+ }
+
+ return VMHelper.newResolvedUsingAllocHandleAndSize(objSize, allocationHandle);
+ }
+
+ private static native int TLSGCOffset();
+}
+
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp Tue Dec 5 14:32:35 2006
@@ -0,0 +1,191 @@
+/*
+ * 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/12/3
+ */
+
+#include "gc_common.h"
+#include "gc_metadata.h"
+#include "../thread/mutator.h"
+#include "../verify/verify_live_heap.h"
+
+extern Boolean NEED_BARRIER;
+extern unsigned int NUM_COLLECTORS;
+extern Boolean GC_VERIFY;
+extern unsigned int NOS_SIZE;
+extern Boolean NOS_PARTIAL_FORWARD;
+
+unsigned int HEAP_SIZE_DEFAULT = 256 * MB;
+unsigned int min_heap_size_bytes = 32 * MB;
+unsigned int max_heap_size_bytes = 0;
+
+static int get_int_property(const char *property_name)
+{
+ assert(property_name);
+ char *value = get_property(property_name, VM_PROPERTIES);
+ int return_value;
+ if (NULL != value)
+ {
+ return_value = atoi(value);
+ destroy_property_value(value);
+ }else{
+ printf("property value %s is not set\n", property_name);
+ exit(0);
+ }
+
+ return return_value;
+}
+
+static Boolean get_boolean_property(const char *property_name)
+{
+ assert(property_name);
+ char *value = get_property(property_name, VM_PROPERTIES);
+ if (NULL == value){
+ printf("property value %s is not set\n", property_name);
+ exit(0);
+ }
+
+ Boolean return_value;
+ if (0 == strcmp("no", value)
+ || 0 == strcmp("off", value)
+ || 0 == strcmp("false", value)
+ || 0 == strcmp("0", value))
+ {
+ return_value = FALSE;
+ }
+ else if (0 == strcmp("yes", value)
+ || 0 == strcmp("on", value)
+ || 0 == strcmp("true", value)
+ || 0 == strcmp("1", value))
+ {
+ return_value = TRUE;
+ }else{
+ printf("property value %s is not properly set\n", property_name);
+ exit(0);
+ }
+
+ destroy_property_value(value);
+ return return_value;
+}
+
+static size_t get_size_property(const char* name)
+{
+ char* size_string = get_property(name, VM_PROPERTIES);
+ size_t size = atol(size_string);
+ int sizeModifier = tolower(size_string[strlen(size_string) - 1]);
+ destroy_property_value(size_string);
+
+ size_t unit = 1;
+ switch (sizeModifier) {
+ case 'k': unit = 1024; break;
+ case 'm': unit = 1024 * 1024; break;
+ case 'g': unit = 1024 * 1024 * 1024;break;
+ }
+
+ size_t res = size * unit;
+ if (res / unit != size) {
+ /* overflow happened */
+ return 0;
+ }
+ return res;
+}
+
+void gc_parse_options()
+{
+ unsigned int max_heap_size = HEAP_SIZE_DEFAULT;
+ unsigned int min_heap_size = min_heap_size_bytes;
+
+ if (is_property_set("gc.mx", VM_PROPERTIES) == 1) {
+ max_heap_size = get_size_property("gc.mx");
+
+ if (max_heap_size < min_heap_size)
+ max_heap_size = min_heap_size;
+ if (0 == max_heap_size)
+ max_heap_size = HEAP_SIZE_DEFAULT;
+
+ min_heap_size = max_heap_size / 10;
+ if (min_heap_size < min_heap_size_bytes) min_heap_size = min_heap_size_bytes;
+ }
+
+ if (is_property_set("gc.ms", VM_PROPERTIES) == 1) {
+ min_heap_size = get_size_property("gc.ms");
+ if (min_heap_size < min_heap_size_bytes)
+ min_heap_size = min_heap_size_bytes;
+ }
+
+ if (min_heap_size > max_heap_size)
+ max_heap_size = min_heap_size;
+
+ min_heap_size_bytes = min_heap_size;
+ max_heap_size_bytes = max_heap_size;
+
+ if (is_property_set("gc.nos_size", VM_PROPERTIES) == 1) {
+ NOS_SIZE = get_size_property("gc.nos_size");
+ }
+
+ if (is_property_set("gc.num_collectors", VM_PROPERTIES) == 1) {
+ unsigned int num = get_int_property("gc.num_collectors");
+ NUM_COLLECTORS = (num==0)? NUM_COLLECTORS:num;
+ }
+
+ if (is_property_set("gc.gen_mode", VM_PROPERTIES) == 1) {
+ NEED_BARRIER = get_boolean_property("gc.gen_mode");
+ }
+
+ if (is_property_set("gc.nos_partial_forward", VM_PROPERTIES) == 1) {
+ NOS_PARTIAL_FORWARD = get_boolean_property("gc.nos_partial_forward");
+ }
+
+ if (is_property_set("gc.verify", VM_PROPERTIES) == 1) {
+ GC_VERIFY = get_boolean_property("gc.verify");
+ }
+
+ return;
+}
+
+struct GC_Gen;
+void gc_gen_reclaim_heap(GC_Gen* gc);
+unsigned int gc_decide_collection_kind(GC_Gen* gc, unsigned int gc_cause);
+
+void gc_reclaim_heap(GC* gc, unsigned int gc_cause)
+{
+ gc->num_collections++;
+
+ gc->collect_kind = gc_decide_collection_kind((GC_Gen*)gc, gc_cause);
+ //gc->collect_kind = MAJOR_COLLECTION;
+
+ gc_metadata_verify(gc, TRUE);
+
+ /* Stop the threads and collect the roots. */
+ gc_reset_rootset(gc);
+ vm_enumerate_root_set_all_threads();
+ gc_set_rootset(gc);
+
+ if(verify_live_heap) gc_verify_heap(gc, TRUE);
+
+ gc_gen_reclaim_heap((GC_Gen*)gc);
+
+ if(verify_live_heap) gc_verify_heap(gc, FALSE);
+
+ gc_metadata_verify(gc, FALSE);
+
+ gc_reset_mutator_context(gc);
+ vm_resume_threads_after();
+
+ return;
+}
+
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.h?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.h Tue Dec 5 14:32:35 2006
@@ -22,8 +22,6 @@
#define _GC_COMMON_H_
#include <assert.h>
-#include <vector>
-#include <stack>
#include <map>
#include "port_vmem.h"
@@ -62,8 +60,6 @@
typedef void (*TaskType)(void*);
-typedef std::stack<Partial_Reveal_Object *> MarkStack;
-typedef std::stack<Partial_Reveal_Object**> TraceStack;
typedef std::map<Partial_Reveal_Object*, Obj_Info_Type> ObjectMap;
enum Collection_Kind {
@@ -218,7 +214,7 @@
unsigned int num_collectors;
unsigned int num_active_collectors; /* not all collectors are working */
- /* metadata is the pool for rootset, markstack, etc. */
+ /* metadata is the pool for rootset, tracestack, etc. */
GC_Metadata* metadata;
unsigned int collect_kind; /* MAJOR or MINOR */
/* FIXME:: this is wrong! root_set belongs to mutator */
@@ -230,10 +226,16 @@
}GC;
-void mark_scan_heap_par(Collector* collector);
-void mark_scan_heap_seq(Collector* collector);
+void mark_scan_heap(Collector* collector);
inline void* gc_heap_base(GC* gc){ return gc->heap_start; }
inline void* gc_heap_ceiling(GC* gc){ return gc->heap_end; }
+inline Boolean address_belongs_to_gc_heap(void* addr, GC* gc)
+{
+ return (addr >= gc_heap_base(gc) && addr < gc_heap_ceiling(gc));
+}
+
+void gc_parse_options();
+void gc_reclaim_heap(GC* gc, unsigned int gc_cause);
#endif //_GC_COMMON_H_
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.cpp?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.cpp Tue Dec 5 14:32:35 2006
@@ -70,7 +70,7 @@
}
if( num_ref_fields )
- gcvt->gc_object_has_slots = true;
+ gcvt->gc_object_has_ref_field = true;
else
return NULL;
@@ -119,7 +119,7 @@
memset((void *)gcvt, 0, sizeof(GC_VTable_Info));
gcvt->gc_clss = ch;
gcvt->gc_class_properties = 0;
- gcvt->gc_object_has_slots = false;
+ gcvt->gc_object_has_ref_field = false;
gc_set_prop_alignment_mask(gcvt, class_get_alignment(ch));
@@ -133,7 +133,7 @@
if (class_is_non_ref_array (ch)) {
gc_set_prop_non_ref_array(gcvt);
}else{
- gcvt->gc_object_has_slots = true;
+ gcvt->gc_object_has_ref_field = true;
}
}
@@ -151,4 +151,5 @@
assert (gcvt->gc_class_name);
} /* gc_class_prepared */
+
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.h?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_class.h Tue Dec 5 14:32:35 2006
@@ -30,7 +30,7 @@
typedef POINTER_SIZE_INT Obj_Info_Type;
typedef struct GC_VTable_Info {
- unsigned int gc_object_has_slots;
+ unsigned int gc_object_has_ref_field;
unsigned int gc_number_of_ref_fields;
uint32 gc_class_properties; // This is the same as class_properties in VM's VTable.
@@ -105,10 +105,16 @@
return vtable_get_gcvt(vt);
}
-inline Boolean object_has_slots(Partial_Reveal_Object *obj)
+inline Boolean object_has_ref_field(Partial_Reveal_Object *obj)
{
GC_VTable_Info *gcvt = obj_get_gcvt(obj);
- return gcvt->gc_object_has_slots;
+ return gcvt->gc_object_has_ref_field;
+}
+
+inline Boolean object_ref_field_num(Partial_Reveal_Object *obj)
+{
+ GC_VTable_Info *gcvt = obj_get_gcvt(obj);
+ return gcvt->gc_number_of_ref_fields;
}
inline Boolean object_is_array(Partial_Reveal_Object *obj)
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_vm.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_vm.cpp?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_vm.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_for_vm.cpp Tue Dec 5 14:32:35 2006
@@ -23,96 +23,49 @@
#include "../gen/gen.h"
#include "interior_pointer.h"
-
-unsigned int HEAP_SIZE_DEFAULT = 256 * MB;
-
-extern Boolean NEED_BARRIER;
-extern unsigned int NUM_COLLECTORS;
-extern Boolean GC_VERIFY;
-extern unsigned int NOS_SIZE;
-
-/* heap size limit is not interesting. only for manual tuning purpose */
-unsigned int min_heap_size_bytes = 32 * MB;
-unsigned int max_heap_size_bytes = 256 * MB;
-
-static size_t get_size_property(const char* name)
-{
- char* size_string = get_property(name, VM_PROPERTIES);
- size_t size = atol(size_string);
- int sizeModifier = tolower(size_string[strlen(size_string) - 1]);
- destroy_property_value(size_string);
-
- size_t unit = 1;
- switch (sizeModifier) {
- case 'k': unit = 1024; break;
- case 'm': unit = 1024 * 1024; break;
- case 'g': unit = 1024 * 1024 * 1024;break;
- }
-
- size_t res = size * unit;
- if (res / unit != size) {
- /* overflow happened */
- return 0;
- }
- return res;
-}
-
-static void parse_configuration_properties()
-{
- unsigned int max_heap_size = HEAP_SIZE_DEFAULT;
- unsigned int min_heap_size = min_heap_size_bytes;
-
- if (is_property_set("gc.mx", VM_PROPERTIES) == 1) {
- max_heap_size = get_size_property("gc.mx");
-
- if (max_heap_size < min_heap_size)
- max_heap_size = min_heap_size;
- if (0 == max_heap_size)
- max_heap_size = HEAP_SIZE_DEFAULT;
-
- min_heap_size = max_heap_size / 10;
- if (min_heap_size < min_heap_size_bytes) min_heap_size = min_heap_size_bytes;
- }
-
- if (is_property_set("gc.ms", VM_PROPERTIES) == 1) {
- min_heap_size = get_size_property("gc.ms");
- if (min_heap_size < min_heap_size_bytes)
- min_heap_size = min_heap_size_bytes;
- }
-
- if (min_heap_size > max_heap_size)
- max_heap_size = min_heap_size;
-
- min_heap_size_bytes = min_heap_size;
- max_heap_size_bytes = max_heap_size;
-
- if (is_property_set("gc.nos_size", VM_PROPERTIES) == 1) {
- NOS_SIZE = get_size_property("gc.nos_size");
- }
-
- NUM_COLLECTORS = get_int_property("gc.num_collectors", NUM_COLLECTORS, VM_PROPERTIES);
- NEED_BARRIER = get_boolean_property("gc.gen_mode", TRUE, VM_PROPERTIES);
- GC_VERIFY = get_boolean_property("gc.verify", FALSE, VM_PROPERTIES);
-
- return;
-}
+#include "../thread/collector.h"
+#include "../verify/verify_live_heap.h"
static GC* p_global_gc = NULL;
+void gc_tls_init();
+
void gc_init()
{
- parse_configuration_properties();
-
+ gc_parse_options();
+
assert(p_global_gc == NULL);
GC* gc = (GC*)STD_MALLOC(sizeof(GC_Gen));
assert(gc);
memset(gc, 0, sizeof(GC));
p_global_gc = gc;
- gc_gen_initialize((GC_Gen*)gc, min_heap_size_bytes, max_heap_size_bytes);
+ gc_tls_init();
+ gc_gen_initialize((GC_Gen*)gc, min_heap_size_bytes, max_heap_size_bytes);
+
+ gc_metadata_initialize(gc); /* root set and mark stack */
+ collector_initialize(gc);
+ gc_init_heap_verification(gc);
+
return;
}
+void gc_wrapup()
+{
+ GC* gc = p_global_gc;
+ gc_gen_destruct((GC_Gen*)gc);
+ gc_metadata_destruct(gc); /* root set and mark stack */
+ collector_destruct(gc);
+
+ if( verify_live_heap ){
+ gc_terminate_heap_verification(gc);
+ }
+
+ STD_FREE(p_global_gc);
+
+ p_global_gc = NULL;
+}
+
/* this interface need reconsidering. is_pinned is unused. */
void gc_add_root_set_entry(Managed_Object_Handle *ref, Boolean is_pinned)
{
@@ -133,16 +86,10 @@
void gc_force_gc()
{
vm_gc_lock_enum();
- gc_gen_reclaim_heap((GC_Gen*)p_global_gc, GC_CAUSE_RUNTIME_FORCE_GC);
+ gc_reclaim_heap(p_global_gc, GC_CAUSE_RUNTIME_FORCE_GC);
vm_gc_unlock_enum();
}
-void gc_wrapup()
-{
- gc_gen_destruct((GC_Gen*)p_global_gc);
- p_global_gc = NULL;
-}
-
void* gc_heap_base_address()
{ return gc_heap_base(p_global_gc); }
@@ -186,4 +133,5 @@
unsigned int gc_time_since_last_gc()
{ assert(0); return 0; }
+
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.cpp?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_metadata.cpp Tue Dec 5 14:32:35 2006
@@ -21,8 +21,9 @@
#include "gc_metadata.h"
#include "../thread/mutator.h"
#include "../thread/collector.h"
+#include "interior_pointer.h"
-#define GC_METADATA_SIZE_BYTES 32*MB
+#define GC_METADATA_SIZE_BYTES 48*MB
#define METADATA_BLOCK_SIZE_BIT_SHIFT 12
#define METADATA_BLOCK_SIZE_BYTES (1<<METADATA_BLOCK_SIZE_BIT_SHIFT)
@@ -47,23 +48,22 @@
vector_block_init(block, METADATA_BLOCK_SIZE_BYTES);
}
- /* half of the metadata space is used for mark_stack */
- unsigned num_tasks = num_blocks >> 1;
+ /* part of the metadata space is used for trace_stack */
+ unsigned num_tasks = num_blocks >> 2;
gc_metadata.free_task_pool = sync_pool_create();
for(i=0; i<num_tasks; i++){
unsigned int block = (unsigned int)metadata + i*METADATA_BLOCK_SIZE_BYTES;
- assert(vector_block_is_empty((Vector_Block*)block));
+ vector_stack_init((Vector_Block*)block);
pool_put_entry(gc_metadata.free_task_pool, (void*)block);
}
gc_metadata.mark_task_pool = sync_pool_create();
- /* the other half is used for root sets (including rem sets) */
- unsigned num_sets = num_blocks >> 1;
+ /* the other part is used for root sets (including rem sets) */
+ unsigned num_sets = (num_blocks >> 1) + num_tasks;
gc_metadata.free_set_pool = sync_pool_create();
/* initialize free rootset pool so that mutators can use them */
- for(; i<num_sets+num_tasks; i++){
+ for(; i<num_sets; i++){
unsigned int block = (unsigned int)metadata + i*METADATA_BLOCK_SIZE_BYTES;
- assert(vector_block_is_empty((Vector_Block*)block));
pool_put_entry(gc_metadata.free_set_pool, (void*)block);
}
@@ -145,7 +145,7 @@
root_set = pool_get_entry( collector_remset_pool );
}
- }else{ /* MINOR_COLLECTION */
+ }else{ /* generational MINOR_COLLECTION */
/* all the remsets are put into the shared pool */
root_set = pool_get_entry( mutator_remset_pool );
while(root_set){
@@ -177,6 +177,7 @@
pool_put_entry(gc_metadata.mutator_remset_pool, root_set);
mutator->rem_set = pool_get_entry(gc_metadata.free_set_pool);
+ assert(mutator->rem_set);
}
void collector_repset_add_entry(Collector* collector, Partial_Reveal_Object** p_ref)
@@ -190,6 +191,7 @@
pool_put_entry(gc_metadata.collector_repset_pool, root_set);
collector->rep_set = pool_get_entry(gc_metadata.free_set_pool);
+ assert(collector->rep_set);
}
void collector_remset_add_entry(Collector* collector, Partial_Reveal_Object** p_ref)
@@ -203,32 +205,21 @@
pool_put_entry(gc_metadata.collector_remset_pool, root_set);
collector->rem_set = pool_get_entry(gc_metadata.free_set_pool);
+ assert(collector->rem_set);
}
-void collector_marktask_add_entry(Collector* collector, Partial_Reveal_Object* p_obj)
+void collector_tracestack_push(Collector* collector, void* p_task)
{
- assert( p_obj>= gc_heap_base_address() && p_obj < gc_heap_ceiling_address());
-
- Vector_Block* mark_task = (Vector_Block*)collector->mark_stack;
- vector_block_add_entry(mark_task, (unsigned int)p_obj);
-
- if( !vector_block_is_full(mark_task)) return;
-
- pool_put_entry(gc_metadata.mark_task_pool, mark_task);
- collector->mark_stack = (MarkStack*)pool_get_entry(gc_metadata.free_task_pool);
-}
-
-void collector_tracetask_add_entry(Collector* collector, Partial_Reveal_Object** p_ref)
-{
- assert( p_ref >= gc_heap_base_address() && p_ref < gc_heap_ceiling_address());
-
+ /* we don't have assert as others because p_task is a p_obj for marking,
+ or a p_ref for trace forwarding. The latter can be a root set pointer */
Vector_Block* trace_task = (Vector_Block*)collector->trace_stack;
- vector_block_add_entry(trace_task, (unsigned int)p_ref);
+ vector_stack_push(trace_task, (unsigned int)p_task);
- if( !vector_block_is_full(trace_task)) return;
+ if( !vector_stack_is_full(trace_task)) return;
- pool_put_entry(gc_metadata.gc_rootset_pool, trace_task);
- collector->trace_stack = (TraceStack*)pool_get_entry(gc_metadata.free_set_pool);
+ pool_put_entry(gc_metadata.mark_task_pool, trace_task);
+ collector->trace_stack = pool_get_entry(gc_metadata.free_task_pool);
+ assert(collector->trace_stack);
}
void gc_rootset_add_entry(GC* gc, Partial_Reveal_Object** p_ref)
@@ -242,6 +233,7 @@
pool_put_entry(gc_metadata.gc_rootset_pool, root_set);
gc->root_set = pool_get_entry(gc_metadata.free_set_pool);
+ assert(gc->root_set);
}
@@ -279,16 +271,19 @@
return;
}
-void update_rootset_interior_pointer();
-
void gc_update_repointed_refs(Collector* collector)
{
- GC* gc = collector->gc;
+ GC* gc = collector->gc;
GC_Metadata* metadata = gc->metadata;
- gc_update_repointed_sets(gc, metadata->gc_rootset_pool);
- gc_update_repointed_sets(gc, metadata->collector_repset_pool);
- update_rootset_interior_pointer();
+
+ /* generational MINOR_COLLECTION doesn't need rootset update */
+ if( !gc_requires_barriers() || gc->collect_kind == MAJOR_COLLECTION ){
+ gc_update_repointed_sets(gc, metadata->gc_rootset_pool);
+ gc_update_repointed_sets(gc, metadata->collector_repset_pool);
+ }
+ update_rootset_interior_pointer();
+
return;
}
@@ -318,3 +313,4 @@
return;
}
+
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?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- 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 Tue Dec 5 14:32:35 2006
@@ -48,8 +48,7 @@
void gc_reset_rootset(GC* gc);
void gc_update_repointed_refs(Collector* collector);
-void collector_marktask_add_entry(Collector* collector, Partial_Reveal_Object* p_obj);
-void collector_tracetask_add_entry(Collector* collector, Partial_Reveal_Object** p_ref);
+void collector_tracestack_push(Collector* collector, void* p_task);
void mutator_remset_add_entry(Mutator* mutator, Partial_Reveal_Object** p_slot);
void collector_remset_add_entry(Collector* collector, Partial_Reveal_Object** p_slot);
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?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- 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 Tue Dec 5 14:32:35 2006
@@ -58,6 +58,11 @@
hythread_yield();
}
+inline void* vm_thread_local()
+{
+ return hythread_self();
+}
+
inline int vm_create_thread(int (*func)(void*), void *data)
{
hythread_t* ret_thread = NULL;
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/interior_pointer.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/interior_pointer.cpp?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/interior_pointer.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/interior_pointer.cpp Tue Dec 5 14:32:35 2006
@@ -1,5 +1,27 @@
+/*
+ * 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 "interior_pointer.h"
+#include <vector>
+
void gc_add_root_set_entry(Managed_Object_Handle *ref, Boolean is_pinned);
typedef struct slot_offset_entry_struct{
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/interior_pointer.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/interior_pointer.h?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/interior_pointer.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/interior_pointer.h Tue Dec 5 14:32:35 2006
@@ -1,3 +1,23 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Xiao-Feng Li, 2006/10/05
+ */
+
#ifndef INTERIOR_POINTER_H
#define INTERIOR_POINTER_H
Added: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan.cpp?view=auto&rev=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan.cpp Tue Dec 5 14:32:35 2006
@@ -0,0 +1,179 @@
+/*
+ * 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 "gc_metadata.h"
+#include "../thread/collector.h"
+#include "../gen/gen.h"
+
+static void scan_slot(Collector* collector, Partial_Reveal_Object** p_ref)
+{
+ Partial_Reveal_Object* p_obj = *p_ref;
+ if(p_obj==NULL) return;
+
+ Space* obj_space = space_of_addr(collector->gc, p_obj);
+
+ /* if obj to be moved, its ref slot needs remembering for later update */
+ if(obj_space->move_object)
+ collector_repset_add_entry(collector, p_ref);
+
+ if(obj_space->mark_object_func(obj_space, p_obj))
+ collector_tracestack_push(collector, p_obj);
+
+ return;
+}
+
+static void scan_object(Collector* collector, Partial_Reveal_Object *p_obj)
+{
+ if( !object_has_ref_field(p_obj) ) return;
+
+ /* 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++) {
+ Partial_Reveal_Object** p_ref = (Partial_Reveal_Object**)vector_get_element_address_ref((Vector_Handle) array, i);
+ scan_slot(collector, p_ref);
+ }
+ return;
+ }
+
+ /* scan non-array object */
+ int *offset_scanner = init_object_scanner(p_obj);
+ while (true) {
+ Partial_Reveal_Object** p_ref = (Partial_Reveal_Object**)offset_get_ref(offset_scanner, p_obj);
+ if (p_ref == NULL) break; /* terminating ref slot */
+
+ scan_slot(collector, p_ref);
+ offset_scanner = offset_next_ref(offset_scanner);
+ }
+
+ return;
+}
+
+
+static void trace_object(Collector* collector, Partial_Reveal_Object *p_obj)
+{
+ scan_object(collector, p_obj);
+
+ Vector_Block* trace_stack = collector->trace_stack;
+ while( !vector_stack_is_empty(trace_stack)){
+ p_obj = (Partial_Reveal_Object *)vector_stack_pop(trace_stack);
+ scan_object(collector, p_obj);
+ trace_stack = collector->trace_stack;
+ }
+
+ return;
+}
+
+/* for marking phase termination detection */
+static volatile unsigned int num_finished_collectors = 0;
+
+/* NOTE:: Only marking in object header is idempotent */
+void mark_scan_heap(Collector* collector)
+{
+ GC* gc = collector->gc;
+ GC_Metadata* metadata = gc->metadata;
+
+ /* reset the num_finished_collectors to be 0 by one collector. This is necessary for the barrier later. */
+ unsigned int num_active_collectors = gc->num_active_collectors;
+ atomic_cas32( &num_finished_collectors, 0, num_active_collectors);
+
+ collector->trace_stack = pool_get_entry(metadata->free_task_pool);
+
+ Vector_Block* root_set = pool_iterator_next(metadata->gc_rootset_pool);
+
+ /* first step: copy all root objects to mark tasks.
+ FIXME:: can be done sequentially before coming here to eliminate atomic ops */
+ while(root_set){
+ unsigned int* iter = vector_block_iterator_init(root_set);
+ while(!vector_block_iterator_end(root_set,iter)){
+ Partial_Reveal_Object** p_ref = (Partial_Reveal_Object** )*iter;
+ iter = vector_block_iterator_advance(root_set,iter);
+
+ Partial_Reveal_Object* p_obj = *p_ref;
+ /* root ref can't be NULL, (remset may have NULL ref entry, but this function is only for MAJOR_COLLECTION */
+ assert( (gc->collect_kind==MINOR_COLLECTION && !gc_requires_barriers()) || (gc->collect_kind==MAJOR_COLLECTION) && (p_obj!= NULL));
+ if(p_obj==NULL) continue;
+ /* we have to mark the object before put it into marktask, because
+ it is possible to have two slots containing a same object. They will
+ be scanned twice and their ref slots will be recorded twice. Problem
+ occurs after the ref slot is updated first time with new position
+ and the second time the value is the ref slot is the old position as expected.
+ This can be worked around if we want.
+ */
+ Space* space = space_of_addr(gc, p_obj);
+ if( !space->mark_object_func(space, p_obj) ) continue;
+
+ collector_tracestack_push(collector, p_obj);
+ }
+ root_set = pool_iterator_next(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 mark tasks and scan objects */
+ /* get a task buf for the mark stack */
+ collector->trace_stack = pool_get_entry(metadata->free_task_pool);
+
+retry:
+ Vector_Block* mark_task = pool_get_entry(metadata->mark_task_pool);
+
+ while(mark_task){
+ unsigned int* iter = vector_block_iterator_init(mark_task);
+ while(!vector_block_iterator_end(mark_task,iter)){
+ Partial_Reveal_Object* p_obj = (Partial_Reveal_Object*)*iter;
+ iter = vector_block_iterator_advance(mark_task,iter);
+
+ /* FIXME:: we should not let mark_task empty during working, , other may want to steal it.
+ degenerate my stack into mark_task, and grab another mark_task */
+ trace_object(collector, p_obj);
+ }
+ /* run out one task, put back to the pool and grab another task */
+ vector_stack_clear(mark_task);
+ pool_put_entry(metadata->free_task_pool, mark_task);
+ mark_task = pool_get_entry(metadata->mark_task_pool);
+ }
+
+ /* termination detection. This is also a barrier.
+ NOTE:: We can simply spin waiting for num_finished_collectors, because each
+ generated new task would surely be processed by its generating collector eventually.
+ So code below is only for load balance optimization. */
+ atomic_inc32(&num_finished_collectors);
+ while(num_finished_collectors != num_active_collectors){
+ if( !pool_is_empty(metadata->mark_task_pool)){
+ atomic_dec32(&num_finished_collectors);
+ goto retry;
+ }
+ }
+
+ /* put back the last mark stack to the free pool */
+ mark_task = (Vector_Block*)collector->trace_stack;
+ vector_stack_clear(mark_task);
+ pool_put_entry(metadata->free_task_pool, mark_task);
+ collector->trace_stack = NULL;
+
+ /* put back last repointed refs set recorded during marking */
+ pool_put_entry(metadata->collector_repset_pool, collector->rep_set);
+ collector->rep_set = NULL;
+
+ return;
+}
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan_par.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan_par.cpp?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan_par.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan_par.cpp Tue Dec 5 14:32:35 2006
@@ -1,194 +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 "gc_metadata.h"
-#include "../thread/collector.h"
-#include "../gen/gen.h"
-
-static void scan_slot_par(Collector* collector, Partial_Reveal_Object** p_ref)
-{
- Partial_Reveal_Object* p_obj = *p_ref;
- if(p_obj==NULL) return;
-
- Space* obj_space = space_of_addr(collector->gc, p_obj);
-
- /* if obj to be moved, its ref slot needs remembering for later update */
- if(obj_space->move_object)
- collector_repset_add_entry(collector, p_ref);
-
- if(obj_space->mark_object_func(obj_space, p_obj))
- collector_marktask_add_entry(collector, p_obj);
-
- return;
-}
-
-static void scan_object_par(Collector* collector, Partial_Reveal_Object *p_obj)
-{
- if( !object_has_slots(p_obj) ) return;
-
- /* 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++) {
- Partial_Reveal_Object** p_ref = (Partial_Reveal_Object**)vector_get_element_address_ref((Vector_Handle) array, i);
- scan_slot_par(collector, p_ref);
- }
- return;
- }
-
- /* scan non-array object */
- int *offset_scanner = init_object_scanner(p_obj);
- while (true) {
- Partial_Reveal_Object** p_ref = (Partial_Reveal_Object**)offset_get_ref(offset_scanner, p_obj);
- if (p_ref == NULL) break; /* terminating ref slot */
-
- scan_slot_par(collector, p_ref);
- offset_scanner = offset_next_ref(offset_scanner);
- }
-
- return;
-}
-
-extern void scan_object_seq(Collector*, Partial_Reveal_Object *);
-
-/* for marking phase termination detection */
-static volatile unsigned int num_finished_collectors = 0;
-
-/* NOTE:: Only marking in object header is idempotent */
-void mark_scan_heap_par(Collector* collector)
-{
- GC* gc = collector->gc;
- /* reset the num_finished_collectors to be 0 by one collector. This is necessary for the barrier later. */
- unsigned int num_active_collectors = gc->num_active_collectors;
- atomic_cas32( &num_finished_collectors, 0, num_active_collectors);
-
- GC_Metadata* metadata = gc->metadata;
-
- collector->mark_stack = (MarkStack*)pool_get_entry(metadata->free_task_pool);
-
- Vector_Block* root_set = pool_iterator_next(metadata->gc_rootset_pool);
-
- /* first step: copy all root objects to mark tasks.
- FIXME:: can be done sequentially before coming here to eliminate atomic ops */
- while(root_set){
- unsigned int* iter = vector_block_iterator_init(root_set);
- while(!vector_block_iterator_end(root_set,iter)){
- Partial_Reveal_Object** p_ref = (Partial_Reveal_Object** )*iter;
- iter = vector_block_iterator_advance(root_set,iter);
-
- Partial_Reveal_Object* p_obj = *p_ref;
- /* root ref can't be NULL, (remset may have NULL ref entry, but this function is only for MAJOR_COLLECTION */
- assert((gc->collect_kind==MAJOR_COLLECTION) && (p_obj!= NULL));
- /* we have to mark the object before put it into marktask, because
- it is possible to have two slots containing a same object. They will
- be scanned twice and their ref slots will be recorded twice. Problem
- occurs after the ref slot is updated first time with new position
- and the second time the value is the ref slot is the old position as expected.
- This can be worked around if we want.
- */
- Space* space = space_of_addr(gc, p_obj);
- if( !space->mark_object_func(space, p_obj) ) continue;
-
- collector_marktask_add_entry(collector, p_obj);
- }
- root_set = pool_iterator_next(metadata->gc_rootset_pool);
- }
-
- pool_put_entry(metadata->mark_task_pool, collector->mark_stack);
-
- /* second step: iterate over the mark tasks and scan objects */
- /* get a task buf to push new tasks */
- collector->mark_stack = (MarkStack*)pool_get_entry(metadata->free_task_pool);
-
-retry:
- Vector_Block* mark_task = pool_get_entry(metadata->mark_task_pool);
- while(mark_task){
- unsigned int* iter = vector_block_iterator_init(mark_task);
- while(!vector_block_iterator_end(mark_task,iter)){
- Partial_Reveal_Object* p_obj = (Partial_Reveal_Object*)*iter;
- iter = vector_block_iterator_advance(mark_task,iter);
-
- scan_object_par(collector, p_obj);
- }
- /* run out one task, put back to the pool and grab another task */
- vector_block_clear(mark_task);
- pool_put_entry(metadata->free_task_pool, mark_task);
- mark_task = pool_get_entry(metadata->mark_task_pool);
- }
-
- /* termination detection. This is also a barrier.
- NOTE:: actually we don't need this complexity. We can simply
- spin waiting for num_finished_collectors, because each generated new
- task would surely be processed by its generating collector eventually.
- So code below is for load balance. */
- atomic_inc32(&num_finished_collectors);
- while(num_finished_collectors != num_active_collectors){
- if( !pool_is_empty(metadata->mark_task_pool)){
- atomic_dec32(&num_finished_collectors);
- goto retry;
- }
- }
-
- /* up to now, we donot have any tasks in task_pool, but
- each collector has remaining tasks in its local mark_stack. */
-
- /* Lets process remaining tasks.
- NOTE:: this is the key difference from work-stealing, which uses
- same stack for both working and sharing. So it has no problem
- with remaining tasks in the shared stack. */
-
- /* to simplify the processing, we turn back to use a single stack for
- the remaining objects scanning. The assumption is, there are only limited
- tasks for processing, no need to share the tasks.
- FIXME:: a better way is to reduce the task block size into half till
- the size becomes one, then the collectors actually share a same stack */
-
- mark_task = (Vector_Block*)collector->mark_stack;
- MarkStack* mark_stack = new MarkStack();
-
- unsigned int* iter = vector_block_iterator_init(mark_task);
- while(!vector_block_iterator_end(mark_task,iter)){
- Partial_Reveal_Object* p_obj = (Partial_Reveal_Object*)*iter;
- iter = vector_block_iterator_advance(mark_task,iter);
- mark_stack->push(p_obj);
- }
- /* put back the last task to the free pool */
- vector_block_clear(mark_task);
- pool_put_entry(metadata->free_task_pool, mark_task);
-
- collector->mark_stack = mark_stack;
- while(!mark_stack->empty()){
- Partial_Reveal_Object* p_obj = mark_stack->top();
- mark_stack->pop();
- scan_object_seq(collector, p_obj);
- }
-
- delete mark_stack;
- collector->mark_stack = NULL;
-
- /* put back last repointed refs set recorded during marking */
- pool_put_entry(metadata->collector_repset_pool, collector->rep_set);
- collector->rep_set = NULL;
-
- return;
-}
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan_seq.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan_seq.cpp?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan_seq.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan_seq.cpp Tue Dec 5 14:32:35 2006
@@ -1,108 +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 "gc_metadata.h"
-#include "../thread/collector.h"
-#include "../gen/gen.h"
-
-static void scan_slot_seq(Collector* collector, Partial_Reveal_Object** p_ref)
-{
- Partial_Reveal_Object* p_obj = *p_ref;
- if(p_obj==NULL) return;
-
- MarkStack* mark_stack = (MarkStack*)collector->mark_stack;
- Space* obj_space = space_of_addr(collector->gc, p_obj);
-
- /* if obj to be moved, its ref slot needs remembering for later update */
- if(obj_space->move_object)
- collector_repset_add_entry(collector, p_ref);
-
- if(obj_space->mark_object_func(obj_space, p_obj))
- mark_stack->push(p_obj);
-
- return;
-}
-
-void scan_object_seq(Collector* collector, Partial_Reveal_Object *p_obj)
-{
- if( !object_has_slots(p_obj) ) return;
-
- /* 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++) {
- Partial_Reveal_Object** p_ref = (Partial_Reveal_Object**)vector_get_element_address_ref((Vector_Handle) array, i);
- scan_slot_seq(collector, p_ref);
- }
- return;
- }
-
- /* scan non-array object */
- int *offset_scanner = init_object_scanner(p_obj);
- while (true) {
- Partial_Reveal_Object** p_ref = (Partial_Reveal_Object**)offset_get_ref(offset_scanner, p_obj);
- if (p_ref == NULL) break; /* terminating ref slot */
-
- scan_slot_seq(collector, p_ref);
- offset_scanner = offset_next_ref(offset_scanner);
- }
-
- return;
-}
-
-/* NOTE:: Only marking in object header is idempotent */
-void mark_scan_heap_seq(Collector* collector)
-{
- GC* gc = collector->gc;
- MarkStack* mark_stack = new MarkStack();
- collector->mark_stack = mark_stack;
-
- GC_Metadata* metadata = gc->metadata;
-
- pool_iterator_init(metadata->gc_rootset_pool);
- Vector_Block* root_set = pool_iterator_next(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);
-
- Partial_Reveal_Object* p_obj = *p_ref;
- assert(p_obj != 0); /* root ref can't be NULL */
-
- Space* space = space_of_addr(collector->gc, p_obj);
- if( !space->mark_object_func(space, p_obj) ) continue;
- mark_stack->push(p_obj);
- }
- root_set = pool_iterator_next(metadata->gc_rootset_pool);
- }
-
- while(!mark_stack->empty()){
- Partial_Reveal_Object* p_obj = mark_stack->top();
- mark_stack->pop();
- scan_object_seq(collector, p_obj);
- }
-
- return;
-}
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?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- 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 Tue Dec 5 14:32:35 2006
@@ -33,7 +33,7 @@
static void gc_slot_write_barrier(Managed_Object_Handle *p_slot,
Managed_Object_Handle p_target)
{
- Mutator *mutator = (Mutator *)vm_get_gc_thread_local();
+ Mutator *mutator = (Mutator *)gc_get_tls();
GC_Gen* gc = (GC_Gen*)mutator->gc;
if( address_belongs_to_nursery((void *)p_target, gc) &&
!address_belongs_to_nursery((void *)p_slot, gc))
@@ -44,7 +44,7 @@
static void gc_object_write_barrier(Managed_Object_Handle p_object)
{
- Mutator *mutator = (Mutator *)vm_get_gc_thread_local();
+ Mutator *mutator = (Mutator *)gc_get_tls();
GC_Gen* gc = (GC_Gen*)mutator->gc;
if( address_belongs_to_nursery((void *)p_object, gc)) return;
@@ -82,7 +82,7 @@
void gc_heap_wrote_object (Managed_Object_Handle p_obj_written)
{
if( !NEED_BARRIER ) return;
- if( object_has_slots((Partial_Reveal_Object*)p_obj_written)){
+ if( object_has_ref_field((Partial_Reveal_Object*)p_obj_written)){
/* for array copy and object clone */
gc_object_write_barrier(p_obj_written);
}
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp Tue Dec 5 14:32:35 2006
@@ -21,10 +21,6 @@
#include "port_sysinfo.h"
#include "gen.h"
-#include "../thread/mutator.h"
-#include "../thread/collector.h"
-#include "../verify/verify_live_heap.h"
-
/* fspace size limit is not interesting. only for manual tuning purpose */
unsigned int min_nos_size_bytes = 2 * MB;
@@ -104,12 +100,6 @@
gc_gen->committed_heap_size = space_committed_size((Space*)gc_gen->nos) +
space_committed_size((Space*)gc_gen->mos) +
space_committed_size((Space*)gc_gen->los);
-
- gc_metadata_initialize((GC*)gc_gen); /* root set and mark stack */
- collector_initialize((GC*)gc_gen);
-
- gc_init_heap_verification((GC*)gc_gen);
-
return;
}
@@ -123,20 +113,8 @@
gc_los_destruct(gc_gen);
gc_gen->los = NULL;
-
- gc_metadata_destruct((GC*)gc_gen); /* root set and mark stack */
- collector_destruct((GC*)gc_gen);
-
- if( verify_live_heap ){
- gc_terminate_heap_verification((GC*)gc_gen);
- }
-
- STD_FREE(gc_gen);
-}
-Boolean major_collection_needed(GC_Gen* gc)
-{
- return mspace_free_memory_size(gc->mos) < fspace_used_memory_size(gc->nos);
+ return;
}
void* mos_alloc(unsigned size, Allocator *allocator){return mspace_alloc(size, allocator);}
@@ -150,7 +128,12 @@
void gc_set_los(GC_Gen* gc, Space* los){ gc->los = (Lspace*)los;}
unsigned int gc_get_processor_num(GC_Gen* gc){ return gc->_num_processors;}
-static unsigned int gc_decide_collection_kind(GC_Gen* gc, unsigned int cause)
+static Boolean major_collection_needed(GC_Gen* gc)
+{
+ return mspace_free_memory_size(gc->mos) < fspace_used_memory_size(gc->nos);
+}
+
+unsigned int gc_decide_collection_kind(GC_Gen* gc, unsigned int cause)
{
if(major_collection_needed(gc) || cause== GC_CAUSE_LOS_IS_FULL)
return MAJOR_COLLECTION;
@@ -158,22 +141,8 @@
return MINOR_COLLECTION;
}
-void gc_gen_reclaim_heap(GC_Gen* gc, unsigned int cause)
+void gc_gen_reclaim_heap(GC_Gen* gc)
{
- gc->num_collections++;
-
- gc->collect_kind = gc_decide_collection_kind(gc, cause);
- //gc->collect_kind = MAJOR_COLLECTION;
-
- gc_metadata_verify((GC*)gc, TRUE);
-
- /* Stop the threads and collect the roots. */
- gc_reset_rootset((GC*)gc);
- vm_enumerate_root_set_all_threads();
- gc_set_rootset((GC*)gc);
-
- if(verify_live_heap) gc_verify_heap((GC*)gc, TRUE);
-
if(gc->collect_kind == MINOR_COLLECTION){
if( gc_requires_barriers()) /* normal gen gc nos collection */
fspace_collection(gc->nos);
@@ -199,12 +168,5 @@
lspace_collection(gc->los);
}
- if(verify_live_heap) gc_verify_heap((GC*)gc, FALSE);
-
- gc_metadata_verify((GC*)gc, FALSE);
-
- gc_reset_mutator_context((GC*)gc);
- vm_resume_threads_after();
-
return;
}
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h Tue Dec 5 14:32:35 2006
@@ -22,7 +22,7 @@
#define _GC_GEN_H_
#include "../common/gc_common.h"
-#include "../thread/thread_alloc.h"
+#include "../thread/gc_thread.h"
#include "../trace_forward/fspace.h"
#include "../mark_compact/mspace.h"
#include "../mark_sweep/lspace.h"
@@ -94,8 +94,6 @@
mspace_free_memory_size(gc->mos) +
lspace_free_memory_size(gc->los); }
-void gc_gen_reclaim_heap(GC_Gen* gc, unsigned int cause);
-
/////////////////////////////////////////////////////////////////////////////////////////
inline void gc_nos_initialize(GC_Gen* gc, void* start, unsigned int nos_size)
@@ -124,6 +122,7 @@
inline Space* space_of_addr(GC* gc, void* addr)
{
+ assert(address_belongs_to_gc_heap(addr, gc));
if( addr > nos_boundary) return (Space*)((GC_Gen*)gc)->nos;
if( addr > los_boundary) return (Space*)((GC_Gen*)gc)->mos;
return (Space*)((GC_Gen*)gc)->los;
@@ -139,6 +138,9 @@
void gc_set_mos(GC_Gen* gc, Space* mos);
void gc_set_los(GC_Gen* gc, Space* los);
unsigned int gc_get_processor_num(GC_Gen* gc);
+
+unsigned int gc_decide_collection_kind(GC_Gen* gc, unsigned int cause);
+void gc_gen_reclaim_heap(GC_Gen* gc);
#endif /* ifndef _GC_GEN_H_ */
Added: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/jni/helper.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/jni/helper.cpp?view=auto&rev=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/jni/helper.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/jni/helper.cpp Tue Dec 5 14:32:35 2006
@@ -0,0 +1,22 @@
+#include <open/vm_gc.h>
+#include <jni.h>
+#include "../thread/gc_thread.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Class: org_apache_harmony_drlvm_gc_gen_GCHelper
+ * Method: TLSFreeOffset
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_org_apache_harmony_drlvm_gc_1gen_GCHelper_TLSGCOffset(JNIEnv *e, jclass c)
+{
+ return (jint)tls_gc_offset;
+}
+
+#ifdef __cplusplus
+}
+#endif
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace.h?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace.h Tue Dec 5 14:32:35 2006
@@ -22,7 +22,7 @@
#define _MSC_SPACE_H_
#include "../common/gc_block.h"
-#include "../thread/thread_alloc.h"
+#include "../thread/gc_thread.h"
/* Mark-compaction space is orgnized into blocks*/
typedef struct Mspace{
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect_compact.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect_compact.cpp?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect_compact.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_collect_compact.cpp Tue Dec 5 14:32:35 2006
@@ -60,7 +60,7 @@
static void gc_reset_block_for_collectors(GC* gc, Mspace* mspace)
{
- unsigned int free_blk_idx = mspace->free_block_idx;
+ unsigned int free_blk_idx = mspace->first_block_idx;
for(unsigned int i=0; i<gc->num_active_collectors; i++){
Collector* collector = gc->collectors[i];
unsigned int collector_target_idx = collector->cur_target_block->block_idx;
@@ -324,7 +324,7 @@
have references that are going to be repointed */
unsigned int old_num = atomic_cas32( &num_marking_collectors, 0, num_active_collectors+1);
- mark_scan_heap_par(collector);
+ mark_scan_heap(collector);
old_num = atomic_inc32(&num_marking_collectors);
if( ++old_num == num_active_collectors ){
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.cpp?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.cpp Tue Dec 5 14:32:35 2006
@@ -72,7 +72,7 @@
lspace->heap_end = (void *)((unsigned int)reserved_base + committed_size);
lspace->alloc_free = reserved_base;
- unsigned int num_bits = lspace_size >> BIT_SHIFT_TO_KILO;
+ unsigned int num_bits = (lspace_size >> BIT_SHIFT_TO_KILO) + 1;
unsigned int num_words = (num_bits >> BIT_SHIFT_TO_BITS_PER_WORD)+1;
lspace->mark_table = (unsigned int*)STD_MALLOC( num_words*BYTES_PER_WORD );
memset(lspace->mark_table, 0, num_words*BYTES_PER_WORD);
@@ -101,7 +101,7 @@
{
/* FIXME:: collection */
unsigned int used_size = (unsigned int)lspace->alloc_free - (unsigned int)lspace->heap_start;
- memset(lspace->mark_table, 0, (used_size>>BIT_SHIFT_TO_KILO)>>BIT_SHIFT_TO_BITS_PER_BYTE );
+ memset(lspace->mark_table, 0, (((used_size>>BIT_SHIFT_TO_KILO) + 1)>>BIT_SHIFT_TO_BITS_PER_BYTE) + 1);
return;
}
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h Tue Dec 5 14:32:35 2006
@@ -22,7 +22,7 @@
#define _LSPACE_H_
#include "../common/gc_common.h"
-#include "../thread/thread_alloc.h"
+#include "../thread/gc_thread.h"
typedef struct Lspace{
/* <-- first couple of fields are overloadded as Space */
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector.h?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector.h Tue Dec 5 14:32:35 2006
@@ -37,8 +37,7 @@
/* FIXME:: for testing */
Space* collect_space;
- TraceStack *trace_stack;
- MarkStack* mark_stack;
+ Vector_Block *trace_stack;
Vector_Block* rep_set; /* repointed set */
Vector_Block* rem_set;
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector_alloc.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector_alloc.cpp?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector_alloc.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/collector_alloc.cpp Tue Dec 5 14:32:35 2006
@@ -18,7 +18,7 @@
* @author Xiao-Feng Li, 2006/10/05
*/
-#include "thread_alloc.h"
+#include "gc_thread.h"
void* mos_alloc(unsigned size, Allocator *allocator);
@@ -32,17 +32,18 @@
assert(!obj_is_marked_in_vt(p_obj));
return NULL;
}
+ /* otherwise, get the obj size firstly. The work below will destroy its vtable. */
+ unsigned int size = vm_object_size(p_obj);
/* else, take the obj by setting the forwarding flag atomically
we don't put a simple bit in vt because we need compute obj size later. */
- if ((unsigned int)vt != atomic_cas32((unsigned int*)obj_get_vtraw_addr(p_obj), ((unsigned int)vt|FORWARDING_BIT_MASK), (unsigned int)vt)) {
+ if ((unsigned int)vt != atomic_cas32((unsigned int*)obj_get_vtraw_addr(p_obj), ((unsigned int)FORWARDING_BIT_MASK), (unsigned int)vt)) {
/* forwarded by other */
assert( obj_is_forwarded_in_vt(p_obj) && !obj_is_marked_in_vt(p_obj));
return NULL;
}
/* we hold the object, now forward it */
- unsigned int size = vm_object_size(p_obj);
Partial_Reveal_Object* p_targ_obj = (Partial_Reveal_Object*)mos_alloc(size, (Allocator*)collector);
/* mos should always has enough space to hold nos during collection */
assert(p_targ_obj);
Added: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.cpp?view=auto&rev=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.cpp Tue Dec 5 14:32:35 2006
@@ -0,0 +1,32 @@
+/*
+ * 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 "gc_thread.h"
+
+static hythread_tls_key_t tls_gc_key;
+unsigned int tls_gc_offset;
+
+void gc_tls_init()
+{
+ hythread_tls_alloc(&tls_gc_key);
+ tls_gc_offset = hythread_tls_get_offset(tls_gc_key);
+
+ return;
+}
Added: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.h?view=auto&rev=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.h Tue Dec 5 14:32:35 2006
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Xiao-Feng Li, 2006/10/05
+ */
+
+#ifndef _GC_THREAD_H_
+#define _GC_THREAD_H_
+
+#include "../common/gc_block.h"
+#include "../common/gc_metadata.h"
+
+extern unsigned int tls_gc_offset;
+
+inline void* gc_get_tls()
+{
+ void* tls_base = vm_thread_local();
+ return (void*)*(unsigned int*)((char*)tls_base + tls_gc_offset);
+}
+
+inline void gc_set_tls(void* gc_tls_info)
+{
+ void* tls_base = vm_thread_local();
+ *(unsigned int*)((char*)tls_base + tls_gc_offset) = (unsigned int)gc_tls_info;
+}
+
+/* NOTE:: don't change the position of free/ceiling, because the offsets are constants for inlining */
+typedef struct Allocator{
+ void *free;
+ void *ceiling;
+ Block *alloc_block;
+ Space* alloc_space;
+ GC *gc;
+ VmThreadHandle thread_handle; /* This thread; */
+}Allocator;
+
+inline Partial_Reveal_Object* thread_local_alloc(unsigned int size, Allocator* allocator)
+{
+ void* free = allocator->free;
+ void* ceiling = allocator->ceiling;
+
+ void* new_free = (void*)((unsigned int)free + size);
+
+ if (new_free <= ceiling){
+ allocator->free= new_free;
+ return (Partial_Reveal_Object*)free;
+ }
+
+ return NULL;
+}
+
+inline void alloc_context_reset(Allocator* allocator)
+{
+ allocator->free = NULL;
+ allocator->ceiling = NULL;
+ allocator->alloc_block = NULL;
+
+ return;
+}
+
+#endif /* #ifndef _GC_THREAD_H_ */
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator.cpp?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator.cpp Tue Dec 5 14:32:35 2006
@@ -23,10 +23,10 @@
struct GC_Gen;
Space* gc_get_nos(GC_Gen* gc);
-void mutator_initialize(GC* gc, void *gc_information)
+void mutator_initialize(GC* gc, void *unused_gc_information)
{
/* FIXME:: make sure gc_info is cleared */
- Mutator *mutator = (Mutator *) gc_information;
+ Mutator *mutator = (Mutator *)STD_MALLOC(sizeof(Mutator));
mutator->free = NULL;
mutator->ceiling = NULL;
mutator->alloc_block = NULL;
@@ -46,13 +46,16 @@
unlock(gc->mutator_list_lock); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
gc->num_mutators++;
+
+ gc_set_tls(mutator);
+
return;
}
-void mutator_destruct(GC* gc, void *gc_information)
+void mutator_destruct(GC* gc, void *unused_gc_information)
{
- Mutator *mutator = (Mutator *)gc_information;
+ Mutator *mutator = (Mutator *)gc_get_tls();
if(gc_requires_barriers()){ /* put back the remset when a mutator exits */
pool_put_entry(gc->metadata->mutator_remset_pool, mutator->rem_set);
@@ -75,6 +78,9 @@
unlock(gc->mutator_list_lock); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
gc->num_mutators--;
+
+ //gc_set_tls(NULL);
+
return;
}
@@ -87,4 +93,5 @@
mutator = mutator->next;
}
return;
-}
\ No newline at end of file
+}
+
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator_alloc.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator_alloc.cpp?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator_alloc.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/mutator_alloc.cpp Tue Dec 5 14:32:35 2006
@@ -18,23 +18,31 @@
* @author Xiao-Feng Li, 2006/10/05
*/
-#include "thread_alloc.h"
+#include "gc_thread.h"
#include "../gen/gen.h"
-Managed_Object_Handle gc_alloc(unsigned size, Allocation_Handle ah, void *gc_tls)
+/* classloader sometimes sets the bit for finalizible objects (?) */
+inline unsigned int get_instance_data_size (unsigned int encoded_size)
+{ return (encoded_size & NEXT_TO_HIGH_BIT_CLEAR_MASK); }
+
+Managed_Object_Handle gc_alloc(unsigned size, Allocation_Handle ah, void *unused_gc_tls)
{
Managed_Object_Handle p_obj = NULL;
/* All requests for space should be multiples of 4 (IA32) or 8(IPF) */
assert((size % GC_OBJECT_ALIGNMENT) == 0);
- assert(gc_tls == vm_get_gc_thread_local());
assert(ah);
+ /* FIXME:: this is outdated actually */
+ size = get_instance_data_size(size);
+
+ Allocator* allocator = (Allocator*)gc_get_tls();
+
if ( size > GC_OBJ_SIZE_THRESHOLD )
- p_obj = (Managed_Object_Handle)los_alloc(size, (Allocator*)gc_tls);
+ p_obj = (Managed_Object_Handle)los_alloc(size, allocator);
else
- p_obj = (Managed_Object_Handle)nos_alloc(size, (Allocator*)gc_tls);
+ p_obj = (Managed_Object_Handle)nos_alloc(size, allocator);
assert(p_obj);
obj_set_vt((Partial_Reveal_Object*)p_obj, ah);
@@ -43,19 +51,20 @@
}
-Managed_Object_Handle gc_alloc_fast (unsigned size, Allocation_Handle ah, void *gc_tls)
+Managed_Object_Handle gc_alloc_fast (unsigned size, Allocation_Handle ah, void *unused_gc_tls)
{
/* All requests for space should be multiples of 4 (IA32) or 8(IPF) */
assert((size % GC_OBJECT_ALIGNMENT) == 0);
- assert(gc_tls == vm_get_gc_thread_local());
assert(ah);
/* object shoud be handled specially */
if ( size > GC_OBJ_SIZE_THRESHOLD ) return NULL;
-
+
+ Allocator* allocator = (Allocator*)gc_get_tls();
+
/* Try to allocate an object from the current Thread Local Block */
- Managed_Object_Handle p_obj = NULL;
- p_obj = (Managed_Object_Handle)thread_local_alloc(size, (Allocator*)gc_tls);
+ Managed_Object_Handle p_obj;
+ p_obj = (Managed_Object_Handle)thread_local_alloc(size, allocator);
if(p_obj == NULL) return NULL;
obj_set_vt((Partial_Reveal_Object*)p_obj, ah);
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/thread_alloc.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/thread_alloc.h?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/thread_alloc.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/thread_alloc.h Tue Dec 5 14:32:35 2006
@@ -1,58 +0,0 @@
-/*
- * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @author Xiao-Feng Li, 2006/10/05
- */
-
-#ifndef _THREAD_ALLOC_H_
-#define _THREAD_ALLOC_H_
-
-#include "../common/gc_block.h"
-#include "../common/gc_metadata.h"
-
-typedef struct Allocator{
- void *free;
- void *ceiling;
- Block *alloc_block;
- Space* alloc_space;
- GC *gc;
- VmThreadHandle thread_handle; /* This thread; */
-}Allocator;
-
-inline Partial_Reveal_Object* thread_local_alloc(unsigned int size, Allocator* allocator)
-{
- Partial_Reveal_Object* p_return_obj=(Partial_Reveal_Object*)allocator->free;
- unsigned int new_free = size+(unsigned int)p_return_obj;
-
- if (new_free <= (unsigned int)allocator->ceiling){
- allocator->free=(void*)new_free;
- return p_return_obj;
- }
-
- return NULL;
-}
-
-inline void alloc_context_reset(Allocator* allocator)
-{
- allocator->free = NULL;
- allocator->ceiling = NULL;
- allocator->alloc_block = NULL;
-
- return;
-}
-
-#endif /* #ifndef _THREAD_ALLOC_H_ */
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace.cpp?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace.cpp Tue Dec 5 14:32:35 2006
@@ -22,12 +22,11 @@
#include "fspace.h"
-float NURSERY_OBJECT_FORWARDING_RATIO = FORWARD_ALL;
-//float NURSERY_OBJECT_FORWARDING_RATIO = FORWARD_HALF;
+Boolean NOS_PARTIAL_FORWARD = TRUE;
void* nos_boundary = null; /* this is only for speeding up write barrier */
-Boolean forward_first_half;;
+Boolean forward_first_half;
void* object_forwarding_boundary=NULL;
Boolean fspace_mark_object(Fspace* fspace, Partial_Reveal_Object *p_obj)
@@ -119,7 +118,10 @@
nos_boundary = fspace->heap_start;
forward_first_half = TRUE;
- object_forwarding_boundary = (void*)&fspace->blocks[fspace->first_block_idx + (unsigned int)(fspace->num_managed_blocks * NURSERY_OBJECT_FORWARDING_RATIO)];
+ if( NOS_PARTIAL_FORWARD )
+ object_forwarding_boundary = (void*)&fspace->blocks[fspace->num_managed_blocks >>1 ];
+ else
+ object_forwarding_boundary = (void*)&fspace->blocks[fspace->num_managed_blocks];
return;
}
@@ -134,35 +136,52 @@
void reset_fspace_for_allocation(Fspace* fspace)
{
- if( NURSERY_OBJECT_FORWARDING_RATIO == FORWARD_ALL ||
- fspace->gc->collect_kind == MAJOR_COLLECTION )
+ unsigned int first_idx = fspace->first_block_idx;
+ unsigned int marked_start_idx = 0;
+ unsigned int marked_last_idx = 0;
+
+ if( fspace->gc->collect_kind == MAJOR_COLLECTION ||
+ NOS_PARTIAL_FORWARD == FALSE || !gc_requires_barriers())
{
- fspace->free_block_idx = fspace->first_block_idx;
- fspace->ceiling_block_idx = fspace->first_block_idx + fspace->num_managed_blocks - 1;
+ fspace->free_block_idx = first_idx;
+ fspace->ceiling_block_idx = first_idx + fspace->num_managed_blocks - 1;
forward_first_half = TRUE; /* only useful for not-FORWARD_ALL*/
}else{
if(forward_first_half){
- fspace->free_block_idx = fspace->first_block_idx;
+ fspace->free_block_idx = first_idx;
fspace->ceiling_block_idx = ((Block_Header*)object_forwarding_boundary)->block_idx - 1;
+ marked_start_idx = ((Block_Header*)object_forwarding_boundary)->block_idx - first_idx;
+ marked_last_idx = fspace->num_managed_blocks - 1;
}else{
fspace->free_block_idx = ((Block_Header*)object_forwarding_boundary)->block_idx;
- fspace->ceiling_block_idx = fspace->first_block_idx + fspace->num_managed_blocks - 1;
+ fspace->ceiling_block_idx = first_idx + fspace->num_managed_blocks - 1;
+ marked_start_idx = 0;
+ marked_last_idx = ((Block_Header*)object_forwarding_boundary)->block_idx - 1 - first_idx;
}
- forward_first_half = ~forward_first_half;
+ forward_first_half = forward_first_half^1;
}
- unsigned int first_idx = fspace->free_block_idx;
- unsigned int last_idx = fspace->ceiling_block_idx;
+
Block* blocks = fspace->blocks;
unsigned int num_freed = 0;
- for(unsigned int i = 0; i <= last_idx-first_idx; i++){
+ unsigned int new_start_idx = fspace->free_block_idx - first_idx;
+ unsigned int new_last_idx = fspace->ceiling_block_idx - first_idx;
+ for(unsigned int i = new_start_idx; i <= new_last_idx; i++){
Block_Header* block = (Block_Header*)&(blocks[i]);
if(block->status == BLOCK_FREE) continue;
- block_clear_mark_table(block);
block->status = BLOCK_FREE;
block->free = GC_BLOCK_BODY(block);
+ if( !gc_requires_barriers() || fspace->gc->collect_kind == MAJOR_COLLECTION )
+ block_clear_mark_table(block);
+
num_freed ++;
}
+
+ for(unsigned int i = marked_start_idx; i <= marked_last_idx; i++){
+ Block_Header* block = (Block_Header*)&(blocks[i]);
+ if(block->status == BLOCK_FREE) continue;
+ block_clear_markbits(block);
+ }
fspace->num_used_blocks = fspace->num_used_blocks - num_freed;
}
@@ -177,7 +196,7 @@
GC* gc = fspace->gc;
if(gc_requires_barriers()){
- /* generational GC. Only trace (mark) nos */
+ /* generational GC. Only trace nos */
collector_execute_task(gc, (TaskType)trace_forward_fspace, (Space*)fspace);
}else{
/* non-generational GC. Mark the whole heap (nos, mos, and los) */
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace.h?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace.h Tue Dec 5 14:32:35 2006
@@ -21,18 +21,16 @@
#ifndef _FROM_SPACE_H_
#define _FROM_SPACE_H_
-#include "../thread/thread_alloc.h"
+#include "../thread/gc_thread.h"
/*
* In our Gen GC, not all live objects are copied to tspace space, the newer baby will
- * still be preserved in fspace, that means give them time to die.
+ * still be preserved in fspace, that means to give them time to die.
*/
-#define FORWARD_ALL 1.0
-#define FORWARD_HALF 0.5
-extern float NURSERY_OBJECT_FORWARDING_RATIO;
extern Boolean forward_first_half;
-extern void* object_forwarding_boundary; //objects allocated before this boundary remain in fspace
+/* boundary spliting fspace into forwarding part and remaining part */
+extern void* object_forwarding_boundary;
typedef struct Fspace {
/* <-- first couple of fields are overloadded as Space */
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_alloc.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_alloc.cpp?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_alloc.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_alloc.cpp Tue Dec 5 14:32:35 2006
@@ -60,9 +60,6 @@
}
/* FIXME:: the collection should be seperated from the alloation */
-struct GC_Gen;
-void gc_gen_reclaim_heap(GC_Gen* gc, unsigned int cause);
-
void* fspace_alloc(unsigned size, Allocator *allocator)
{
void* p_return = NULL;
@@ -77,7 +74,7 @@
vm_gc_lock_enum();
/* after holding lock, try if other thread collected already */
if ( !fspace_has_free_block(fspace) ) {
- gc_gen_reclaim_heap((GC_Gen*)allocator->gc, GC_CAUSE_NOS_IS_FULL);
+ gc_reclaim_heap(allocator->gc, GC_CAUSE_NOS_IS_FULL);
}
vm_gc_unlock_enum();
}
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_copy.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_copy.cpp?view=diff&rev=482809&r1=482808&r2=482809
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_copy.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_collect_copy.cpp Tue Dec 5 14:32:35 2006
@@ -172,7 +172,7 @@
have references that are going to be repointed */
atomic_cas32( &num_marking_collectors, 0, num_active_collectors+1);
- mark_scan_heap_par(collector);
+ mark_scan_heap(collector);
unsigned int old_num = atomic_inc32(&num_marking_collectors);
if( ++old_num == num_active_collectors ){