[sgen] Allow TLABs larger than MAX_SMALL_OBJ_SIZE.
authorMark Probst <mark.probst@gmail.com>
Fri, 15 Jan 2016 02:05:14 +0000 (18:05 -0800)
committerMark Probst <mark.probst@gmail.com>
Fri, 12 Feb 2016 18:03:34 +0000 (10:03 -0800)
`sgen_ensure_free_space()` assumed that if `size` was larger than
`SGEN_MAX_SMALL_OBJ_SIZE`, it should find free space on the major
heap, so it wouldn't consider triggering a nursery allocation.  Making
TLABs larger than that would thus never trigger nursery collections
anymore.

Now we pass in the generation that says where we want space.

mono/sgen/sgen-alloc.c
mono/sgen/sgen-gc.c
mono/sgen/sgen-gc.h
mono/sgen/sgen-los.c

index 349eff5401457757c9757591a398a275d7990aab..2c69c7d932f24a5109cbc92e289676dcb2fc86ca 100644 (file)
@@ -101,7 +101,7 @@ alloc_degraded (GCVTable vtable, size_t size, gboolean for_mature)
        if (!for_mature) {
                sgen_client_degraded_allocation (size);
                SGEN_ATOMIC_ADD_P (degraded_mode, size);
-               sgen_ensure_free_space (size);
+               sgen_ensure_free_space (size, GENERATION_OLD);
        } else {
                if (sgen_need_major_collection (size))
                        sgen_perform_collection (size, GENERATION_OLD, "mature allocation failure", !for_mature);
@@ -271,7 +271,7 @@ sgen_alloc_obj_nolock (GCVTable vtable, size_t size)
                                         * always loop we will loop endlessly in the case of
                                         * OOM).
                                         */
-                                       sgen_ensure_free_space (real_size);
+                                       sgen_ensure_free_space (real_size, GENERATION_NURSERY);
                                        if (!degraded_mode)
                                                p = (void **)sgen_nursery_alloc (size);
                                }
@@ -288,7 +288,7 @@ sgen_alloc_obj_nolock (GCVTable vtable, size_t size)
                                p = (void **)sgen_nursery_alloc_range (tlab_size, size, &alloc_size);
                                if (!p) {
                                        /* See comment above in similar case. */
-                                       sgen_ensure_free_space (tlab_size);
+                                       sgen_ensure_free_space (tlab_size, GENERATION_NURSERY);
                                        if (!degraded_mode)
                                                p = (void **)sgen_nursery_alloc_range (tlab_size, size, &alloc_size);
                                }
index 34da3f15ab339c4b84d83585d4d265832fdc1c24..6d0b151560d5e087e38d23954b2967349ca3b3f5 100644 (file)
@@ -2154,12 +2154,12 @@ major_finish_concurrent_collection (gboolean forced)
  * LOCKING: The GC lock MUST be held.
  */
 void
-sgen_ensure_free_space (size_t size)
+sgen_ensure_free_space (size_t size, int generation)
 {
        int generation_to_collect = -1;
        const char *reason = NULL;
 
-       if (size > SGEN_MAX_SMALL_OBJ_SIZE) {
+       if (generation == GENERATION_OLD) {
                if (sgen_need_major_collection (size)) {
                        reason = "LOS overflow";
                        generation_to_collect = GENERATION_OLD;
index afd5ba5dce858c2721c9a7e53d6113d2205b9c83..4b2f895d890badc5f42157ebe4009f57211ad1b4 100644 (file)
@@ -802,7 +802,7 @@ enum {
 void sgen_pin_object (GCObject *object, SgenGrayQueue *queue);
 void sgen_set_pinned_from_failed_allocation (mword objsize);
 
-void sgen_ensure_free_space (size_t size);
+void sgen_ensure_free_space (size_t size, int generation);
 void sgen_gc_collect (int generation);
 void sgen_perform_collection (size_t requested_size, int generation_to_collect, const char *reason, gboolean wait_to_finish);
 
index 8cc92e34553f5008105bcc16fdc80232c1cb595c..a89ec99fe353517580f0695f6d45e68859a18101 100644 (file)
@@ -380,7 +380,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));