[runtime]
[mono.git] / mono / metadata / sgen-alloc.c
index d04f757ec48866d77dbbf8c3850e92f17ecc9b02..aa475bc0d3153a22c91704db91938368c671c661 100644 (file)
@@ -93,7 +93,7 @@ static __thread char *tlab_next;
 static __thread char *tlab_temp_end;
 static __thread char *tlab_real_end;
 /* Used by the managed allocator/wbarrier */
-static __thread char **tlab_next_addr;
+static __thread char **tlab_next_addr MONO_ATTR_USED;
 #endif
 
 #ifdef HAVE_KW_THREAD
@@ -299,21 +299,22 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size)
                                         * object.  The reason will most likely be that we've
                                         * run out of memory, but there is the theoretical
                                         * possibility that other threads might have consumed
-                                        * the freed up memory ahead of us, so doing another
-                                        * collection and trying again might actually help.
-                                        * Of course the same thing might happen again.
+                                        * the freed up memory ahead of us.
                                         *
-                                        * Ideally we'd like to detect that case and loop (if
-                                        * we always loop we will loop endlessly in the case of
-                                        * OOM).  What we do here is give up right away.
+                                        * What we do in this case is allocate degraded, i.e.,
+                                        * from the major heap.
+                                        *
+                                        * Ideally we'd like to detect the case of other
+                                        * threads allocating ahead of us and loop (if we
+                                        * always loop we will loop endlessly in the case of
+                                        * OOM).
                                         */
                                        sgen_ensure_free_space (real_size);
-                                       if (degraded_mode)
-                                               return alloc_degraded (vtable, size, FALSE);
-                                       else
+                                       if (!degraded_mode)
                                                p = sgen_nursery_alloc (size);
                                }
-                               SGEN_ASSERT (0, p, "Out of memory");
+                               if (!p)
+                                       return alloc_degraded (vtable, size, FALSE);
 
                                zero_tlab_if_necessary (p, size);
                        } else {
@@ -326,12 +327,11 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size)
                                if (!p) {
                                        /* See comment above in similar case. */
                                        sgen_ensure_free_space (tlab_size);
-                                       if (degraded_mode)
-                                               return alloc_degraded (vtable, size, FALSE);
-                                       else
+                                       if (!degraded_mode)
                                                p = sgen_nursery_alloc_range (tlab_size, size, &alloc_size);
                                }
-                               SGEN_ASSERT (0, p, "Out of memory");
+                               if (!p)
+                                       return alloc_degraded (vtable, size, FALSE);
 
                                /* Allocate a new TLAB from the current nursery fragment */
                                TLAB_START = (char*)p;
@@ -1010,8 +1010,9 @@ create_allocator (int atype)
        mono_mb_emit_byte (mb, CEE_STIND_I);
 
        /*The tlab store must be visible before the the vtable store. This could be replaced with a DDS but doing it with IL would be tricky. */
-       mono_mb_emit_byte ((mb), MONO_CUSTOM_PREFIX);
-       mono_mb_emit_op (mb, CEE_MONO_MEMORY_BARRIER, (gpointer)StoreStoreBarrier);
+       mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+       mono_mb_emit_byte (mb, CEE_MONO_MEMORY_BARRIER);
+       mono_mb_emit_i4 (mb, MONO_MEMORY_BARRIER_REL);
 
        /* *p = vtable; */
        mono_mb_emit_ldloc (mb, p_var);
@@ -1049,8 +1050,9 @@ create_allocator (int atype)
        /*
        We must make sure both vtable and max_length are globaly visible before returning to managed land.
        */
-       mono_mb_emit_byte ((mb), MONO_CUSTOM_PREFIX);
-       mono_mb_emit_op (mb, CEE_MONO_MEMORY_BARRIER, (gpointer)StoreStoreBarrier);
+       mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+       mono_mb_emit_byte (mb, CEE_MONO_MEMORY_BARRIER);
+       mono_mb_emit_i4 (mb, MONO_MEMORY_BARRIER_REL);
 
        /* return p */
        mono_mb_emit_ldloc (mb, p_var);