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
/* FIXME: handle OOM */
void **p;
char *new_next;
- TLAB_ACCESS_INIT;
size_t real_size = size;
+ TLAB_ACCESS_INIT;
CANARIFY_SIZE(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 {
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;
{
void **p;
char *new_next;
- TLAB_ACCESS_INIT;
size_t real_size = size;
+ TLAB_ACCESS_INIT;
CANARIFY_SIZE(size);
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);
/*
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);