Parcourir la source

2009-07-03 Mark Probst <[email protected]>

        * object.c (handle_enum): Invoke the write barrier when copying
        value type instances.

        * sgen-gc.c: Register remsets for unmanaged write barriers only
        when the address written to is actually on the heap.  This makes
        set_value() in object.c work without requiring that the result be
        on the heap.

svn path=/trunk/mono/; revision=137331
Mark Probst il y a 16 ans
Parent
commit
8bf864880d
3 fichiers modifiés avec 60 ajouts et 11 suppressions
  1. 10 0
      mono/metadata/ChangeLog
  2. 8 4
      mono/metadata/object.c
  3. 42 7
      mono/metadata/sgen-gc.c

+ 10 - 0
mono/metadata/ChangeLog

@@ -1,3 +1,13 @@
+2009-07-03  Mark Probst  <[email protected]>
+
+	* object.c (handle_enum): Invoke the write barrier when copying
+	value type instances.
+
+	* sgen-gc.c: Register remsets for unmanaged write barriers only
+	when the address written to is actually on the heap.  This makes
+	set_value() in object.c work without requiring that the result be
+	on the heap.
+
 2009-07-02 Rodrigo Kumpera  <[email protected]>
 
 	The runtime wrappers are all bound to a given type that must

+ 8 - 4
mono/metadata/object.c

@@ -2591,6 +2591,8 @@ set_value (MonoType *type, void *dest, void *value, int deref_pointer)
 {
 	int t;
 	if (type->byref) {
+		/* object fields cannot be byref, so we don't need a
+		   wbarrier here */
 		gpointer *p = (gpointer*)dest;
 		*p = value;
 		return;
@@ -2661,12 +2663,14 @@ handle_enum:
 			t = mono_class_enum_basetype (type->data.klass)->type;
 			goto handle_enum;
 		} else {
-			int size;
-			size = mono_class_value_size (mono_class_from_mono_type (type), NULL);
-			if (value == NULL)
+			MonoClass *class = mono_class_from_mono_type (type);
+			int size = mono_class_value_size (class, NULL);
+			if (value == NULL) {
 				memset (dest, 0, size);
-			else
+			} else {
 				memcpy (dest, value, size);
+				mono_gc_wbarrier_value_copy (dest, value, size, class);
+			}
 		}
 		return;
 	case MONO_TYPE_GENERICINST:

+ 42 - 7
mono/metadata/sgen-gc.c

@@ -2291,7 +2291,7 @@ alloc_nursery (void)
 	UPDATE_HEAP_BOUNDARIES (nursery_start, nursery_real_end);
 	nursery_next = nursery_start;
 	total_alloc += alloc_size;
-	DEBUG (4, fprintf (gc_debug_file, "Expanding heap size: %zd, total: %zd\n", nursery_size, total_alloc));
+	DEBUG (4, fprintf (gc_debug_file, "Expanding nursery size (%p-%p): %zd, total: %zd\n", data, data + alloc_size, nursery_size, total_alloc));
 	section->data = section->next_data = data;
 	section->size = alloc_size;
 	section->end_data = nursery_real_end;
@@ -2978,7 +2978,7 @@ alloc_section (size_t size)
 	section->end_data = data + new_size;
 	UPDATE_HEAP_BOUNDARIES (data, section->end_data);
 	total_alloc += new_size;
-	DEBUG (2, fprintf (gc_debug_file, "Expanding heap size: %zd, total: %zd\n", new_size, total_alloc));
+	DEBUG (2, fprintf (gc_debug_file, "Expanding heap size: %zd (%p-%p), total: %zd\n", new_size, data, data + new_size, total_alloc));
 	section->data = data;
 	section->size = new_size;
 	scan_starts = new_size / SCAN_START_SIZE;
@@ -4726,15 +4726,51 @@ find_pinning_ref_from_thread (char *obj, size_t size)
 	/* FIXME: check register */
 }
 
+static gboolean
+ptr_on_stack (void *ptr)
+{
+	int rs = 0;
+	int dummy;
+	SgenThreadInfo *info = thread_info_lookup (ARCH_GET_THREAD ());
+
+	update_current_thread_stack (&dummy);
+
+	if (ptr >= (gpointer)info->stack_start && ptr < (gpointer)info->stack_end)
+		return TRUE;
+	return FALSE;
+}
+
 /* return TRUE if ptr points inside the managed heap */
 static gboolean
 ptr_in_heap (void* ptr)
 {
 	mword p = (mword)ptr;
+	LOSObject *bigobj;
+	GCMemSection *section;
+
 	if (p < lowest_heap_address || p >= highest_heap_address)
 		return FALSE;
-	/* FIXME: more checks */
-	return TRUE;
+
+	if (ptr_in_nursery (ptr))
+		return TRUE;
+
+	if (ptr_on_stack (ptr))
+		return FALSE;
+
+	for (section = section_list; section; section = section->next) {
+		if (ptr >= (gpointer)section->data && ptr < (gpointer)(section->data + section->size))
+			return TRUE;
+	}
+
+	if (obj_is_from_pinned_alloc (ptr))
+		return TRUE;
+
+	for (bigobj = los_object_list; bigobj; bigobj = bigobj->next) {
+		if (ptr >= (gpointer)bigobj->data && ptr < (gpointer)(bigobj->data + bigobj->size))
+			return TRUE;
+	}
+
+	return FALSE;
 }
 
 static mword*
@@ -5292,14 +5328,13 @@ mono_gc_wbarrier_generic_store (gpointer ptr, MonoObject* value)
 {
 	RememberedSet *rs;
 	TLAB_ACCESS_INIT;
-	if (ptr_in_nursery (ptr)) {
+	if (ptr_in_nursery (ptr) || !ptr_in_heap (ptr)) {
 		DEBUG (8, fprintf (gc_debug_file, "Skipping remset at %p\n", ptr));
 		*(void**)ptr = value;
 		return;
 	}
 	rs = REMEMBERED_SET;
 	DEBUG (8, fprintf (gc_debug_file, "Adding remset at %p (%s)\n", ptr, value ? safe_name (value) : "null"));
-	/* FIXME: ensure it is on the heap */
 	if (rs->store_next < rs->end_set) {
 		*(rs->store_next++) = (mword)ptr;
 		*(void**)ptr = value;
@@ -5349,7 +5384,7 @@ mono_gc_wbarrier_value_copy (gpointer dest, gpointer src, int count, MonoClass *
 	RememberedSet *rs;
 	TLAB_ACCESS_INIT;
 	rs = REMEMBERED_SET;
-	if (ptr_in_nursery (dest))
+	if (ptr_in_nursery (dest) || !ptr_in_heap (dest))
 		return;
 	DEBUG (8, fprintf (gc_debug_file, "Adding value remset at %p, count %d for class %s\n", dest, count, klass->name));