#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"
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;
InterlockedExchangeAdd (°raded_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;
}
/*
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 ();
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);
/* 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) {
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) {
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);
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);
}
if (nursery_clear_policy == CLEAR_AT_TLAB_CREATION)
memset (new_next, 0, alloc_size);
+
+ MONO_GC_NURSERY_TLAB_ALLOC (new_next, alloc_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);
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);
}
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);
}