commit
3d6dc0fa64
3
Changes
3
Changes
|
@ -568,6 +568,9 @@ OCaml 4.12.0
|
|||
- #7538, #9669: Check for misplaced attributes on module aliases
|
||||
(Leo White, report by Thomas Leonard, review by Florian Angeletti)
|
||||
|
||||
- #7813, #9955: make sure the major GC cycle doesn't get stuck in Idle state
|
||||
(Damien Doligez, report by Anders Fugmann, review by Jacques-Henri Jourdan)
|
||||
|
||||
- #7902, #9556: Type-checker infers recursive type, even though -rectypes is
|
||||
off.
|
||||
(Jacques Garrigue, report by Francois Pottier, review by Leo White)
|
||||
|
|
|
@ -603,10 +603,21 @@ cleanup:
|
|||
|
||||
CAMLprim value caml_gc_major_slice (value v)
|
||||
{
|
||||
value exn = Val_unit;
|
||||
CAML_EV_BEGIN(EV_EXPLICIT_GC_MAJOR_SLICE);
|
||||
CAMLassert (Is_long (v));
|
||||
caml_major_collection_slice (Long_val (v));
|
||||
if (caml_gc_phase == Phase_idle){
|
||||
/* We need to start a new major GC cycle. Go through the pending_action
|
||||
machinery. */
|
||||
caml_request_major_slice ();
|
||||
exn = caml_process_pending_actions_exn ();
|
||||
/* Calls the major GC without passing [v] but the initial slice
|
||||
ignores this parameter anyway. */
|
||||
}else{
|
||||
caml_major_collection_slice (Long_val (v));
|
||||
}
|
||||
CAML_EV_END(EV_EXPLICIT_GC_MAJOR_SLICE);
|
||||
caml_raise_if_exception (exn);
|
||||
return Val_long (0);
|
||||
}
|
||||
|
||||
|
|
|
@ -460,34 +460,39 @@ extern uintnat caml_instr_alloc_jump;
|
|||
*/
|
||||
void caml_gc_dispatch (void)
|
||||
{
|
||||
value *trigger = Caml_state->young_trigger; /* save old value of trigger */
|
||||
|
||||
CAML_EVENTLOG_DO({
|
||||
CAML_EV_COUNTER(EV_C_ALLOC_JUMP, caml_instr_alloc_jump);
|
||||
caml_instr_alloc_jump = 0;
|
||||
});
|
||||
|
||||
if (trigger == Caml_state->young_alloc_start
|
||||
|| Caml_state->requested_minor_gc) {
|
||||
if (Caml_state->young_trigger == Caml_state->young_alloc_start){
|
||||
/* The minor heap is full, we must do a minor collection. */
|
||||
Caml_state->requested_minor_gc = 1;
|
||||
}else{
|
||||
/* The minor heap is half-full, do a major GC slice. */
|
||||
Caml_state->requested_major_slice = 1;
|
||||
}
|
||||
if (caml_gc_phase == Phase_idle){
|
||||
/* The major GC needs an empty minor heap in order to start a new cycle.
|
||||
If a major slice was requested, we need to do a minor collection
|
||||
before we can do the major slice that starts a new major GC cycle.
|
||||
If a minor collection was requested, we take the opportunity to start
|
||||
a new major GC cycle.
|
||||
In either case, we have to do a minor cycle followed by a major slice.
|
||||
*/
|
||||
Caml_state->requested_minor_gc = 1;
|
||||
Caml_state->requested_major_slice = 1;
|
||||
}
|
||||
if (Caml_state->requested_minor_gc) {
|
||||
/* reset the pointers first because the end hooks might allocate */
|
||||
CAML_EV_BEGIN(EV_MINOR);
|
||||
Caml_state->requested_minor_gc = 0;
|
||||
Caml_state->young_trigger = Caml_state->young_alloc_mid;
|
||||
caml_update_young_limit();
|
||||
caml_empty_minor_heap ();
|
||||
/* The minor heap is empty, we can start a major collection. */
|
||||
CAML_EV_END(EV_MINOR);
|
||||
if (caml_gc_phase == Phase_idle)
|
||||
{
|
||||
CAML_EV_BEGIN(EV_MAJOR);
|
||||
caml_major_collection_slice (-1);
|
||||
CAML_EV_END(EV_MAJOR);
|
||||
}
|
||||
}
|
||||
if (trigger != Caml_state->young_alloc_start
|
||||
|| Caml_state->requested_major_slice) {
|
||||
/* The minor heap is half-full, do a major GC slice. */
|
||||
if (Caml_state->requested_major_slice) {
|
||||
Caml_state->requested_major_slice = 0;
|
||||
Caml_state->young_trigger = Caml_state->young_alloc_start;
|
||||
caml_update_young_limit();
|
||||
|
|
Loading…
Reference in New Issue