}
*/
-/*
- * Define this to allow the user to change the nursery size by
- * specifying its value in the MONO_GC_PARAMS environmental
- * variable. See mono_gc_base_init for details.
- */
-#define USER_CONFIG 1
-
#define TV_DECLARE SGEN_TV_DECLARE
#define TV_GETTIME SGEN_TV_GETTIME
#define TV_ELAPSED SGEN_TV_ELAPSED
#define pin_object SGEN_PIN_OBJECT
#define unpin_object SGEN_UNPIN_OBJECT
-#define ptr_in_nursery(p) (SGEN_PTR_IN_NURSERY ((p), DEFAULT_NURSERY_BITS, nursery_start, nursery_end))
+#define ptr_in_nursery mono_sgen_ptr_in_nursery
#define LOAD_VTABLE SGEN_LOAD_VTABLE
static gboolean use_cardtable;
-#ifdef USER_CONFIG
-
-/* good sizes are 512KB-1MB: larger ones increase a lot memzeroing time */
-#define DEFAULT_NURSERY_SIZE (default_nursery_size)
-int default_nursery_size = (1 << 22);
-#ifdef SGEN_ALIGN_NURSERY
-/* The number of trailing 0 bits in DEFAULT_NURSERY_SIZE */
-#define DEFAULT_NURSERY_BITS (default_nursery_bits)
-static int default_nursery_bits = 22;
-#endif
-
-#else
-
-#define DEFAULT_NURSERY_SIZE (4*1024*1024)
-#ifdef SGEN_ALIGN_NURSERY
-#define DEFAULT_NURSERY_BITS 22
-#endif
-
-#endif
-
-#ifndef SGEN_ALIGN_NURSERY
-#define DEFAULT_NURSERY_BITS -1
-#endif
-
#define MIN_MINOR_COLLECTION_ALLOWANCE (DEFAULT_NURSERY_SIZE * 4)
#define SCAN_START_SIZE SGEN_SCAN_START_SIZE
report->extra_info [report->count++] = (uintptr_t)((MonoVTable*)LOAD_VTABLE (object))->klass;
}
-/*
- * The current allocation cursors
- * We allocate objects in the nursery.
- * The nursery is the area between nursery_start and nursery_end.
- * nursery_frag_real_end points to the end of the currently used nursery fragment.
- * nursery_first_pinned_start points to the start of the first pinned object in the nursery
- * nursery_last_pinned_end points to the end of the last pinned object in the nursery
- * At the next allocation, the area of the nursery where objects can be present is
- * between MIN(nursery_first_pinned_start, first_fragment_start) and
- * MAX(nursery_last_pinned_end, nursery_frag_real_end)
- */
-static char *nursery_start = NULL;
-static char *nursery_end = NULL;
-static char *nursery_alloc_bound = NULL;
-
MonoNativeTlsKey thread_info_key;
#ifdef HAVE_KW_THREAD
size = ALIGN_UP (safe_object_get_size ((MonoObject*)obj));
- callback (obj, size, data);
+ if (SGEN_LOAD_VTABLE (obj) != array_fill_vtable)
+ callback (obj, size, data);
start += size;
}
if (addr >= (mword)start_nursery && addr < (mword)end_nursery)
mono_sgen_pin_stage_ptr ((void*)addr);
if (G_UNLIKELY (do_pin_stats)) {
- if (ptr_in_nursery (addr))
+ if (ptr_in_nursery ((void*)addr))
mono_sgen_pin_stats_register_address ((char*)addr, pin_type);
}
DEBUG (6, if (count) fprintf (gc_debug_file, "Pinning address %p from %p\n", (void*)addr, start));
#else
data = major_collector.alloc_heap (alloc_size, 0, DEFAULT_NURSERY_BITS);
#endif
- nursery_start = data;
- nursery_end = nursery_start + nursery_size;
- mono_sgen_update_heap_boundaries ((mword)nursery_start, (mword)nursery_end);
+ mono_sgen_update_heap_boundaries ((mword)data, (mword)(data + nursery_size));
DEBUG (4, fprintf (gc_debug_file, "Expanding nursery size (%p-%p): %lu, total: %lu\n", data, data + alloc_size, (unsigned long)nursery_size, (unsigned long)total_alloc));
section->data = section->next_data = data;
section->size = alloc_size;
- section->end_data = nursery_end;
+ section->end_data = data + nursery_size;
scan_starts = (alloc_size + SCAN_START_SIZE - 1) / SCAN_START_SIZE;
section->scan_starts = mono_sgen_alloc_internal_dynamic (sizeof (char*) * scan_starts, INTERNAL_MEM_SCAN_STARTS);
section->num_scan_start = scan_starts;
nursery_section = section;
- mono_sgen_nursery_allocator_set_nursery_bounds (nursery_start, nursery_end);
+ mono_sgen_nursery_allocator_set_nursery_bounds (data, data + nursery_size);
}
void*
#else
*shift_bits = -1;
#endif
- return nursery_start;
+ return mono_sgen_get_nursery_start ();
}
void
mono_sgen_scan_togglerefs (copy_func, start_addr, end_addr, queue);
if (generation == GENERATION_OLD)
- mono_sgen_scan_togglerefs (copy_func, nursery_start, nursery_end, queue);
+ mono_sgen_scan_togglerefs (copy_func, mono_sgen_get_nursery_start (), mono_sgen_get_nursery_end (), queue);
if (mono_sgen_need_bridge_processing ()) {
collect_bridge_objects (copy_func, start_addr, end_addr, generation, queue);
if (generation == GENERATION_OLD)
- collect_bridge_objects (copy_func, nursery_start, nursery_end, GENERATION_NURSERY, queue);
+ collect_bridge_objects (copy_func, mono_sgen_get_nursery_start (), mono_sgen_get_nursery_end (), GENERATION_NURSERY, queue);
mono_sgen_drain_gray_stack (queue, -1);
}
fin_ready = num_ready_finalizers;
finalize_in_range (copy_func, start_addr, end_addr, generation, queue);
if (generation == GENERATION_OLD)
- finalize_in_range (copy_func, nursery_start, nursery_end, GENERATION_NURSERY, queue);
+ finalize_in_range (copy_func, mono_sgen_get_nursery_start (), mono_sgen_get_nursery_end (), GENERATION_NURSERY, queue);
if (fin_ready != num_ready_finalizers)
++num_loops;
/*This cleans up unused fragments */
mono_sgen_nursery_allocator_prepare_for_pinning ();
- hole_start = start = cur = nursery_start;
- end = nursery_end;
+ hole_start = start = cur = mono_sgen_get_nursery_start ();
+ end = mono_sgen_get_nursery_end ();
while (cur < end) {
size_t ss, size;
objects_pinned = 0;
nursery_next = mono_sgen_nursery_alloc_get_upper_alloc_bound ();
/* FIXME: optimize later to use the higher address where an object can be present */
- nursery_next = MAX (nursery_next, nursery_end);
+ nursery_next = MAX (nursery_next, mono_sgen_get_nursery_end ());
- nursery_alloc_bound = nursery_next;
-
- DEBUG (1, fprintf (gc_debug_file, "Start nursery collection %d %p-%p, size: %d\n", stat_minor_gcs, nursery_start, nursery_next, (int)(nursery_next - nursery_start)));
- max_garbage_amount = nursery_next - nursery_start;
+ DEBUG (1, fprintf (gc_debug_file, "Start nursery collection %d %p-%p, size: %d\n", stat_minor_gcs, mono_sgen_get_nursery_start (), nursery_next, (int)(nursery_next - mono_sgen_get_nursery_start ())));
+ max_garbage_amount = nursery_next - mono_sgen_get_nursery_start ();
g_assert (nursery_section->size >= max_garbage_amount);
/* world must be stopped already */
/* pin from pinned handles */
mono_sgen_init_pinning ();
mono_profiler_gc_event (MONO_GC_EVENT_MARK_START, 0);
- pin_from_roots (nursery_start, nursery_next, WORKERS_DISTRIBUTE_GRAY_QUEUE);
+ pin_from_roots (mono_sgen_get_nursery_start (), nursery_next, WORKERS_DISTRIBUTE_GRAY_QUEUE);
/* identify pinned objects */
mono_sgen_optimize_pin_queue (0);
mono_sgen_pinning_setup_section (nursery_section);
* This usually involves scanning global information that might later be produced by evacuation.
*/
if (remset.begin_scan_remsets)
- remset.begin_scan_remsets (nursery_start, nursery_next, WORKERS_DISTRIBUTE_GRAY_QUEUE);
+ remset.begin_scan_remsets (mono_sgen_get_nursery_start (), nursery_next, WORKERS_DISTRIBUTE_GRAY_QUEUE);
mono_sgen_workers_start_marking ();
- frssjd.heap_start = nursery_start;
+ frssjd.heap_start = mono_sgen_get_nursery_start ();
frssjd.heap_end = nursery_next;
mono_sgen_workers_enqueue_job (job_finish_remembered_set_scan, &frssjd);
/* registered roots, this includes static fields */
scrrjd_normal.func = mono_sgen_collection_is_parallel () ? major_collector.copy_object : major_collector.nopar_copy_object;
- scrrjd_normal.heap_start = nursery_start;
+ scrrjd_normal.heap_start = mono_sgen_get_nursery_start ();
scrrjd_normal.heap_end = nursery_next;
scrrjd_normal.root_type = ROOT_TYPE_NORMAL;
mono_sgen_workers_enqueue_job (job_scan_from_registered_roots, &scrrjd_normal);
scrrjd_wbarrier.func = mono_sgen_collection_is_parallel () ? major_collector.copy_object : major_collector.nopar_copy_object;
- scrrjd_wbarrier.heap_start = nursery_start;
+ scrrjd_wbarrier.heap_start = mono_sgen_get_nursery_start ();
scrrjd_wbarrier.heap_end = nursery_next;
scrrjd_wbarrier.root_type = ROOT_TYPE_WBARRIER;
mono_sgen_workers_enqueue_job (job_scan_from_registered_roots, &scrrjd_wbarrier);
time_minor_scan_registered_roots += TV_ELAPSED (atv, btv);
/* thread data */
- stdjd.heap_start = nursery_start;
+ stdjd.heap_start = mono_sgen_get_nursery_start ();
stdjd.heap_end = nursery_next;
mono_sgen_workers_enqueue_job (job_scan_thread_data, &stdjd);
if (mono_sgen_collection_is_parallel ())
g_assert (mono_sgen_gray_object_queue_is_empty (&gray_queue));
- finish_gray_stack (nursery_start, nursery_next, GENERATION_NURSERY, &gray_queue);
+ finish_gray_stack (mono_sgen_get_nursery_start (), nursery_next, GENERATION_NURSERY, &gray_queue);
TV_GETTIME (atv);
time_minor_finish_gray_stack += TV_ELAPSED (btv, atv);
mono_profiler_gc_event (MONO_GC_EVENT_MARK_END, 0);
TV_GETTIME (btv);
time_major_pre_collection_fragment_clear += TV_ELAPSED (atv, btv);
- nursery_section->next_data = nursery_end;
+ nursery_section->next_data = mono_sgen_get_nursery_end ();
/* we should also coalesce scanning from sections close to each other
* and deal with pointers outside of the sections later.
*/
}
reset_heap_boundaries ();
- mono_sgen_update_heap_boundaries ((mword)nursery_start, (mword)nursery_end);
+ mono_sgen_update_heap_boundaries ((mword)mono_sgen_get_nursery_start (), (mword)mono_sgen_get_nursery_end ());
/* sweep the big objects list */
prevbo = NULL;
num_workers = 16;
///* Keep this the default for now */
- //conservative_stack_mark = TRUE;
+#ifdef __APPLE__
+ conservative_stack_mark = TRUE;
+#endif
if (opts) {
for (ptr = opts; *ptr; ++ptr) {
long val;
opt = strchr (opt, '=') + 1;
if (*opt && mono_gc_parse_environment_string_extract_number (opt, &val)) {
- default_nursery_size = val;
+ mono_sgen_nursery_size = val;
#ifdef SGEN_ALIGN_NURSERY
if ((val & (val - 1))) {
fprintf (stderr, "The nursery size must be a power of two.\n");
exit (1);
}
- default_nursery_bits = 0;
- while (1 << (++ default_nursery_bits) != default_nursery_size)
+ mono_sgen_nursery_bits = 0;
+ while (1 << (++ mono_sgen_nursery_bits) != mono_sgen_nursery_size)
;
#endif
} else {
mono_mb_emit_ldarg (mb, 0);
mono_mb_emit_icon (mb, DEFAULT_NURSERY_BITS);
mono_mb_emit_byte (mb, CEE_SHR_UN);
- mono_mb_emit_icon (mb, (mword)nursery_start >> DEFAULT_NURSERY_BITS);
+ mono_mb_emit_icon (mb, (mword)mono_sgen_get_nursery_start () >> DEFAULT_NURSERY_BITS);
nursery_check_return_labels [0] = mono_mb_emit_branch (mb, CEE_BEQ);
// if (!ptr_in_nursery (*ptr)) return;
mono_mb_emit_byte (mb, CEE_LDIND_I);
mono_mb_emit_icon (mb, DEFAULT_NURSERY_BITS);
mono_mb_emit_byte (mb, CEE_SHR_UN);
- mono_mb_emit_icon (mb, (mword)nursery_start >> DEFAULT_NURSERY_BITS);
+ mono_mb_emit_icon (mb, (mword)mono_sgen_get_nursery_start () >> DEFAULT_NURSERY_BITS);
nursery_check_return_labels [1] = mono_mb_emit_branch (mb, CEE_BNE_UN);
#else
int label_continue1, label_continue2;
int dereferenced_var;
- // if (ptr < (nursery_start)) goto continue;
+ // if (ptr < (mono_sgen_get_nursery_start ())) goto continue;
mono_mb_emit_ldarg (mb, 0);
- mono_mb_emit_ptr (mb, (gpointer) nursery_start);
+ mono_mb_emit_ptr (mb, (gpointer) mono_sgen_get_nursery_start ());
label_continue_1 = mono_mb_emit_branch (mb, CEE_BLT);
- // if (ptr >= nursery_end)) goto continue;
+ // if (ptr >= mono_sgen_get_nursery_end ())) goto continue;
mono_mb_emit_ldarg (mb, 0);
- mono_mb_emit_ptr (mb, (gpointer) nursery_end);
+ mono_mb_emit_ptr (mb, (gpointer) mono_sgen_get_nursery_end ());
label_continue_2 = mono_mb_emit_branch (mb, CEE_BGE);
// Otherwise return
mono_mb_emit_byte (mb, CEE_LDIND_I);
mono_mb_emit_stloc (mb, dereferenced_var);
- // if (*ptr < nursery_start) return;
+ // if (*ptr < mono_sgen_get_nursery_start ()) return;
mono_mb_emit_ldloc (mb, dereferenced_var);
- mono_mb_emit_ptr (mb, (gpointer) nursery_start);
+ mono_mb_emit_ptr (mb, (gpointer) mono_sgen_get_nursery_start ());
nursery_check_return_labels [1] = mono_mb_emit_branch (mb, CEE_BLT);
- // if (*ptr >= nursery_end) return;
+ // if (*ptr >= mono_sgen_get_nursery_end ()) return;
mono_mb_emit_ldloc (mb, dereferenced_var);
- mono_mb_emit_ptr (mb, (gpointer) nursery_end);
+ mono_mb_emit_ptr (mb, (gpointer) mono_sgen_get_nursery_end ());
nursery_check_return_labels [2] = mono_mb_emit_branch (mb, CEE_BGE);
#endif
}
major_collector.scan_card_table (queue);
}
-gboolean
-mono_sgen_ptr_in_nursery (void *p)
-{
- return SGEN_PTR_IN_NURSERY ((p), DEFAULT_NURSERY_BITS, nursery_start, nursery_end);
-}
-
SgenMajorCollector*
mono_sgen_get_major_collector (void)
{