Fix MONO_GC_DEBUG=collect-before-allocs. mono_gc_alloc_obj_nolock () was not called...
authorZoltan Varga <vargaz@gmail.com>
Tue, 16 Jul 2013 16:54:14 +0000 (18:54 +0200)
committerZoltan Varga <vargaz@gmail.com>
Tue, 16 Jul 2013 16:54:14 +0000 (18:54 +0200)
mono/metadata/sgen-alloc.c
mono/metadata/sgen-gc.c

index 61222e2d57e96260d9961c3367e5ceed79c56765..bc7006d8e9a073052964dd74847dbeae9627451b 100644 (file)
@@ -434,6 +434,24 @@ mono_gc_alloc_obj (MonoVTable *vtable, size_t size)
        void *res;
 #ifndef DISABLE_CRITICAL_REGION
        TLAB_ACCESS_INIT;
+
+       if (G_UNLIKELY (has_per_allocation_action)) {
+               static int alloc_count;
+               int current_alloc = InterlockedIncrement (&alloc_count);
+
+               if (verify_before_allocs) {
+                       if ((current_alloc % verify_before_allocs) == 0)
+                               sgen_check_whole_heap_stw ();
+               }
+               if (collect_before_allocs) {
+                       if (((current_alloc % collect_before_allocs) == 0) && nursery_section) {
+                               LOCK_GC;
+                               sgen_perform_collection (0, GENERATION_NURSERY, "collect-before-alloc-triggered", TRUE);
+                               UNLOCK_GC;
+                       }
+               }
+       }
+
        ENTER_CRITICAL_REGION;
        res = mono_gc_try_alloc_obj_nolock (vtable, size);
        if (res) {
@@ -967,7 +985,8 @@ mono_gc_get_managed_allocator (MonoClass *klass, gboolean for_box)
        if (tlab_next_offset == -1 || tlab_temp_end_offset == -1)
                return NULL;
 #endif
-
+       if (collect_before_allocs)
+               return NULL;
        if (!mono_runtime_has_tls_get ())
                return NULL;
        if (klass->instance_size > tlab_size)
@@ -979,8 +998,6 @@ mono_gc_get_managed_allocator (MonoClass *klass, gboolean for_box)
                return NULL;
        if (klass->byval_arg.type == MONO_TYPE_STRING)
                return mono_gc_get_managed_allocator_by_type (ATYPE_STRING);
-       if (collect_before_allocs)
-               return NULL;
        /* Generic classes have dynamic field and can go above MAX_SMALL_OBJ_SIZE. */
        if (ALIGN_TO (klass->instance_size, ALLOC_ALIGN) < MAX_SMALL_OBJ_SIZE && !mono_class_is_open_constructed_type (&klass->byval_arg))
                return mono_gc_get_managed_allocator_by_type (ATYPE_SMALL);
index 6012b34713222efbabd09694c756626c6985cef3..625ecc4fdf25756770cc8af730af092ce3b04d5a 100644 (file)
@@ -3386,6 +3386,9 @@ sgen_ensure_free_space (size_t size)
        sgen_perform_collection (size, generation_to_collect, reason, FALSE);
 }
 
+/*
+ * LOCKING: Assumes the GC lock is held.
+ */
 void
 sgen_perform_collection (size_t requested_size, int generation_to_collect, const char *reason, gboolean wait_to_finish)
 {