[sgen] Allow read only access of los object list without taking GC_LOCK
[mono.git] / mono / sgen / sgen-los.c
index c0ea17bb329982efe49392adda5ff15df6bdfe1d..968bd587df5a4ecbccdd8ed8d51fce9e0e34de3b 100644 (file)
@@ -73,6 +73,7 @@ struct _LOSSection {
        unsigned char *free_chunk_map;
 };
 
+/* We allow read only access on the list while sweep is not running */
 LOSObject *los_object_list = NULL;
 mword los_memory_usage = 0;
 
@@ -380,7 +381,7 @@ sgen_los_alloc_large_inner (GCVTable vtable, size_t size)
        los_segment_index += size + sizeof (LOSObject);
        g_assert (los_segment_index <= LOS_SEGMENT_SIZE);
 #else
-       sgen_ensure_free_space (size);
+       sgen_ensure_free_space (size, GENERATION_OLD);
 
 #ifdef USE_MALLOC
        obj = malloc (size + sizeof (LOSObject));
@@ -410,6 +411,11 @@ sgen_los_alloc_large_inner (GCVTable vtable, size_t size)
        *vtslot = vtable;
        sgen_update_heap_boundaries ((mword)obj->data, (mword)obj->data + size);
        obj->next = los_object_list;
+       /*
+        * We need a memory barrier so we don't expose as head of the los object list
+        * a LOSObject that doesn't have its fields initialized.
+        */
+       mono_memory_write_barrier ();
        los_object_list = obj;
        los_memory_usage += size;
        los_num_objects++;
@@ -621,6 +627,7 @@ sgen_los_scan_card_table (gboolean mod_union, ScanCopyContext ctx)
 {
        LOSObject *obj;
 
+       binary_protocol_los_card_table_scan_start (sgen_timestamp (), mod_union);
        for (obj = los_object_list; obj; obj = obj->next) {
                guint8 *cards;
 
@@ -639,6 +646,7 @@ sgen_los_scan_card_table (gboolean mod_union, ScanCopyContext ctx)
 
                sgen_cardtable_scan_object (obj->data, sgen_los_object_size (obj), cards, mod_union, ctx);
        }
+       binary_protocol_los_card_table_scan_end (sgen_timestamp (), mod_union);
 }
 
 void