void caml_finish_marking () { caml_save_stack_gc(); caml_do_local_roots(&caml_darken, caml_domain_self()); caml_scan_global_roots(&caml_darken); caml_empty_mark_stack(); caml_domain_state->allocated_words = 0; caml_restore_stack_gc(); }
void caml_do_roots (scanning_action f) { /* Global variables */ f(caml_global_data, &caml_global_data); /* The stack and the local C roots */ caml_do_local_roots(f, caml_extern_sp, caml_stack_high, caml_local_roots); /* Global C roots */ caml_scan_global_roots(f); /* Finalised values */ caml_final_do_strong_roots (f); /* Hook */ if (caml_scan_roots_hook != NULL) (*caml_scan_roots_hook)(f); }
static void verify_heap() { caml_save_stack_gc(); caml_do_local_roots(&verify_push, caml_domain_self()); caml_scan_global_roots(&verify_push); while (verify_sp) verify_object(verify_stack[--verify_sp]); caml_gc_log("Verify: %lu objs", verify_objs); caml_addrmap_clear(&verify_seen); verify_objs = 0; caml_stat_free(verify_stack); verify_stack = 0; verify_stack_len = 0; verify_sp = 0; caml_restore_stack_gc(); }
/* Note, in byte-code there is only one global root, so [do_globals] is ignored and [caml_darken_all_roots_slice] does nothing. */ void caml_do_roots (scanning_action f, int do_globals) { CAML_INSTR_SETUP (tmr, "major_roots"); /* Global variables */ f(caml_global_data, &caml_global_data); CAML_INSTR_TIME (tmr, "major_roots/global"); /* The stack and the local C roots */ caml_do_local_roots(f, caml_extern_sp, caml_stack_high, caml_local_roots); CAML_INSTR_TIME (tmr, "major_roots/local"); /* Global C roots */ caml_scan_global_roots(f); CAML_INSTR_TIME (tmr, "major_roots/C"); /* Finalised values */ caml_final_do_strong_roots (f); CAML_INSTR_TIME (tmr, "major_roots/finalised"); /* Hook */ if (caml_scan_roots_hook != NULL) (*caml_scan_roots_hook)(f); CAML_INSTR_TIME (tmr, "major_roots/hook"); }
intnat caml_major_collection_slice(intnat howmuch) { intnat computed_work = howmuch ? howmuch : default_slice_budget(); intnat budget = computed_work; intnat sweep_work, mark_work; uintnat blocks_marked_before = stat_blocks_marked; value v; caml_save_stack_gc(); sweep_work = budget; budget = caml_sweep(caml_domain_self()->shared_heap, budget); sweep_work -= budget; if (gc_phase == Phase_idle) { caml_do_local_roots(&caml_darken, caml_domain_self()); caml_scan_global_roots(&caml_darken); gc_phase = Phase_marking; } mark_work = budget; if (mark_stack_pop(&v)) budget = mark(v, budget); mark_work -= budget; caml_gc_log("Major slice: %lu alloc, %ld work, %ld sweep, %ld mark (%lu blocks)", (unsigned long)caml_domain_state->allocated_words, (long)computed_work, (long)sweep_work, (long)mark_work, (unsigned long)(stat_blocks_marked - blocks_marked_before)); caml_domain_state->allocated_words = 0; caml_restore_stack_gc(); if (budget > 0) { caml_trigger_stw_gc(); caml_handle_gc_interrupt(); } return computed_work; }