[dtrace] Pass namespace and class name to probes where appropriate.
[mono.git] / mono / metadata / sgen-alloc.c
index 74db26c184773c72f96e37e0ec09b9a055085c72..0f70797931c479e33b443c5c42e9ffe2037a7399 100644 (file)
@@ -46,6 +46,7 @@
 
 #include "metadata/sgen-gc.h"
 #include "metadata/sgen-protocol.h"
+#include "metadata/sgen-memory-governor.h"
 #include "metadata/profiler-private.h"
 #include "metadata/marshal.h"
 #include "metadata/method-builder.h"
@@ -116,6 +117,8 @@ alloc_degraded (MonoVTable *vtable, size_t size, gboolean for_mature)
        static int last_major_gc_warned = -1;
        static int num_degraded = 0;
 
+       void *p;
+
        if (!for_mature) {
                if (last_major_gc_warned < stat_major_gcs) {
                        ++num_degraded;
@@ -128,11 +131,18 @@ alloc_degraded (MonoVTable *vtable, size_t size, gboolean for_mature)
                InterlockedExchangeAdd (&degraded_mode, size);
        }
 
-       if (sgen_need_major_collection (0)) {
-               sgen_collect_major_no_lock ("degraded overflow");
+       sgen_ensure_free_space (size);
+
+       p = major_collector.alloc_degraded (vtable, size);
+
+       if (for_mature) {
+               MONO_GC_MAJOR_OBJ_ALLOC_MATURE (p, size, vtable->klass->name_space, vtable->klass->name);
+       } else {
+               binary_protocol_alloc_degraded (p, vtable, size);
+               MONO_GC_MAJOR_OBJ_ALLOC_DEGRADED (p, size, vtable->klass->name_space, vtable->klass->name);
        }
 
-       return major_collector.alloc_degraded (vtable, size);
+       return p;
 }
 
 /*
@@ -167,7 +177,7 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size)
 
                if (collect_before_allocs) {
                        if (((current_alloc % collect_before_allocs) == 0) && nursery_section) {
-                               sgen_collect_nursery_no_lock (0);
+                               sgen_perform_collection (0, GENERATION_NURSERY, "collect-before-alloc-triggered");
                                if (!degraded_mode && sgen_can_alloc_size (size) && size <= SGEN_MAX_SMALL_OBJ_SIZE) {
                                        // FIXME:
                                        g_assert_not_reached ();
@@ -210,6 +220,8 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size)
 
                        DEBUG (6, fprintf (gc_debug_file, "Allocated object %p, vtable: %p (%s), size: %zd\n", p, vtable, vtable->klass->name, size));
                        binary_protocol_alloc (p , vtable, size);
+                       if (MONO_GC_NURSERY_OBJ_ALLOC_ENABLED ())
+                               MONO_GC_NURSERY_OBJ_ALLOC (p, size, vtable->klass->name_space, vtable->klass->name);
                        g_assert (*p == NULL);
                        mono_atomic_store_seq (p, vtable);
 
@@ -240,11 +252,8 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size)
                        /* when running in degraded mode, we continue allocing that way
                         * for a while, to decrease the number of useless nursery collections.
                         */
-                       if (degraded_mode && degraded_mode < DEFAULT_NURSERY_SIZE) {
-                               p = alloc_degraded (vtable, size, FALSE);
-                               binary_protocol_alloc_degraded (p, vtable, size);
-                               return p;
-                       }
+                       if (degraded_mode && degraded_mode < DEFAULT_NURSERY_SIZE)
+                               return alloc_degraded (vtable, size, FALSE);
 
                        available_in_tlab = TLAB_REAL_END - TLAB_NEXT;
                        if (size > tlab_size || available_in_tlab > SGEN_MAX_NURSERY_WASTE) {
@@ -252,14 +261,11 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size)
                                do {
                                        p = sgen_nursery_alloc (size);
                                        if (!p) {
-                                               sgen_minor_collect_or_expand_inner (size);
-                                               if (degraded_mode) {
-                                                       p = alloc_degraded (vtable, size, FALSE);
-                                                       binary_protocol_alloc_degraded (p, vtable, size);
-                                                       return p;
-                                               } else {
+                                               sgen_ensure_free_space (size);
+                                               if (degraded_mode)
+                                                       return alloc_degraded (vtable, size, FALSE);
+                                               else
                                                        p = sgen_nursery_alloc (size);
-                                               }
                                        }
                                } while (!p);
                                if (!p) {
@@ -279,14 +285,11 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size)
                                do {
                                        p = sgen_nursery_alloc_range (tlab_size, size, &alloc_size);
                                        if (!p) {
-                                               sgen_minor_collect_or_expand_inner (tlab_size);
-                                               if (degraded_mode) {
-                                                       p = alloc_degraded (vtable, size, FALSE);
-                                                       binary_protocol_alloc_degraded (p, vtable, size);
-                                                       return p;
-                                               } else {
+                                               sgen_ensure_free_space (tlab_size);
+                                               if (degraded_mode)
+                                                       return alloc_degraded (vtable, size, FALSE);
+                                               else
                                                        p = sgen_nursery_alloc_range (tlab_size, size, &alloc_size);
-                                               }               
                                        }
                                } while (!p);
                                        
@@ -324,6 +327,12 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size)
        if (G_LIKELY (p)) {
                DEBUG (6, fprintf (gc_debug_file, "Allocated object %p, vtable: %p (%s), size: %zd\n", p, vtable, vtable->klass->name, size));
                binary_protocol_alloc (p, vtable, size);
+               if (MONO_GC_MAJOR_OBJ_ALLOC_LARGE_ENABLED () || MONO_GC_NURSERY_OBJ_ALLOC_ENABLED ()) {
+                       if (size > SGEN_MAX_SMALL_OBJ_SIZE)
+                               MONO_GC_MAJOR_OBJ_ALLOC_LARGE (p, size, vtable->klass->name_space, vtable->klass->name);
+                       else
+                               MONO_GC_NURSERY_OBJ_ALLOC (p, size, vtable->klass->name_space, vtable->klass->name);
+               }
                mono_atomic_store_seq (p, vtable);
        }
 
@@ -400,6 +409,8 @@ mono_gc_try_alloc_obj_nolock (MonoVTable *vtable, size_t size)
 
                        if (nursery_clear_policy == CLEAR_AT_TLAB_CREATION)
                                memset (new_next, 0, alloc_size);
+
+                       MONO_GC_NURSERY_TLAB_ALLOC (new_next, alloc_size);
                }
        }
 
@@ -408,6 +419,8 @@ mono_gc_try_alloc_obj_nolock (MonoVTable *vtable, size_t size)
 
        DEBUG (6, fprintf (gc_debug_file, "Allocated object %p, vtable: %p (%s), size: %zd\n", p, vtable, vtable->klass->name, size));
        binary_protocol_alloc (p, vtable, size);
+       if (MONO_GC_NURSERY_OBJ_ALLOC_ENABLED ())
+               MONO_GC_NURSERY_OBJ_ALLOC (p, size, vtable->klass->name_space, vtable->klass->name);
        g_assert (*p == NULL); /* FIXME disable this in non debug builds */
 
        mono_atomic_store_seq (p, vtable);
@@ -475,6 +488,22 @@ mono_gc_alloc_array (MonoVTable *vtable, size_t size, uintptr_t max_length, uint
        MonoArray *arr;
        MonoArrayBounds *bounds;
 
+#ifndef DISABLE_CRITICAL_REGION
+       TLAB_ACCESS_INIT;
+       ENTER_CRITICAL_REGION;
+       arr = mono_gc_try_alloc_obj_nolock (vtable, size);
+       if (arr) {
+               /*This doesn't require fencing since EXIT_CRITICAL_REGION already does it for us*/
+               arr->max_length = max_length;
+
+               bounds = (MonoArrayBounds*)((char*)arr + size - bounds_size);
+               arr->bounds = bounds;
+               EXIT_CRITICAL_REGION;
+               return arr;
+       }
+       EXIT_CRITICAL_REGION;
+#endif
+
        LOCK_GC;
 
        arr = mono_gc_alloc_obj_nolock (vtable, size);
@@ -545,6 +574,10 @@ mono_gc_alloc_pinned_obj (MonoVTable *vtable, size_t size)
        }
        if (G_LIKELY (p)) {
                DEBUG (6, fprintf (gc_debug_file, "Allocated pinned object %p, vtable: %p (%s), size: %zd\n", p, vtable, vtable->klass->name, size));
+               if (size > SGEN_MAX_SMALL_OBJ_SIZE)
+                       MONO_GC_MAJOR_OBJ_ALLOC_LARGE (p, size, vtable->klass->name_space, vtable->klass->name);
+               else
+                       MONO_GC_MAJOR_OBJ_ALLOC_PINNED (p, size, vtable->klass->name_space, vtable->klass->name);
                binary_protocol_alloc_pinned (p, vtable, size);
                mono_atomic_store_seq (p, vtable);
        }