commit
3d6dc0fa64
3
Changes
3
Changes
|
@ -568,6 +568,9 @@ OCaml 4.12.0
|
||||||
- #7538, #9669: Check for misplaced attributes on module aliases
|
- #7538, #9669: Check for misplaced attributes on module aliases
|
||||||
(Leo White, report by Thomas Leonard, review by Florian Angeletti)
|
(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
|
- #7902, #9556: Type-checker infers recursive type, even though -rectypes is
|
||||||
off.
|
off.
|
||||||
(Jacques Garrigue, report by Francois Pottier, review by Leo White)
|
(Jacques Garrigue, report by Francois Pottier, review by Leo White)
|
||||||
|
|
|
@ -603,10 +603,21 @@ cleanup:
|
||||||
|
|
||||||
CAMLprim value caml_gc_major_slice (value v)
|
CAMLprim value caml_gc_major_slice (value v)
|
||||||
{
|
{
|
||||||
|
value exn = Val_unit;
|
||||||
CAML_EV_BEGIN(EV_EXPLICIT_GC_MAJOR_SLICE);
|
CAML_EV_BEGIN(EV_EXPLICIT_GC_MAJOR_SLICE);
|
||||||
CAMLassert (Is_long (v));
|
CAMLassert (Is_long (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_major_collection_slice (Long_val (v));
|
||||||
|
}
|
||||||
CAML_EV_END(EV_EXPLICIT_GC_MAJOR_SLICE);
|
CAML_EV_END(EV_EXPLICIT_GC_MAJOR_SLICE);
|
||||||
|
caml_raise_if_exception (exn);
|
||||||
return Val_long (0);
|
return Val_long (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -460,34 +460,39 @@ extern uintnat caml_instr_alloc_jump;
|
||||||
*/
|
*/
|
||||||
void caml_gc_dispatch (void)
|
void caml_gc_dispatch (void)
|
||||||
{
|
{
|
||||||
value *trigger = Caml_state->young_trigger; /* save old value of trigger */
|
|
||||||
|
|
||||||
CAML_EVENTLOG_DO({
|
CAML_EVENTLOG_DO({
|
||||||
CAML_EV_COUNTER(EV_C_ALLOC_JUMP, caml_instr_alloc_jump);
|
CAML_EV_COUNTER(EV_C_ALLOC_JUMP, caml_instr_alloc_jump);
|
||||||
caml_instr_alloc_jump = 0;
|
caml_instr_alloc_jump = 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (trigger == Caml_state->young_alloc_start
|
if (Caml_state->young_trigger == Caml_state->young_alloc_start){
|
||||||
|| Caml_state->requested_minor_gc) {
|
|
||||||
/* The minor heap is full, we must do a minor collection. */
|
/* 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 */
|
/* reset the pointers first because the end hooks might allocate */
|
||||||
CAML_EV_BEGIN(EV_MINOR);
|
CAML_EV_BEGIN(EV_MINOR);
|
||||||
Caml_state->requested_minor_gc = 0;
|
Caml_state->requested_minor_gc = 0;
|
||||||
Caml_state->young_trigger = Caml_state->young_alloc_mid;
|
Caml_state->young_trigger = Caml_state->young_alloc_mid;
|
||||||
caml_update_young_limit();
|
caml_update_young_limit();
|
||||||
caml_empty_minor_heap ();
|
caml_empty_minor_heap ();
|
||||||
/* The minor heap is empty, we can start a major collection. */
|
|
||||||
CAML_EV_END(EV_MINOR);
|
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 (Caml_state->requested_major_slice) {
|
||||||
if (trigger != Caml_state->young_alloc_start
|
|
||||||
|| Caml_state->requested_major_slice) {
|
|
||||||
/* The minor heap is half-full, do a major GC slice. */
|
|
||||||
Caml_state->requested_major_slice = 0;
|
Caml_state->requested_major_slice = 0;
|
||||||
Caml_state->young_trigger = Caml_state->young_alloc_start;
|
Caml_state->young_trigger = Caml_state->young_alloc_start;
|
||||||
caml_update_young_limit();
|
caml_update_young_limit();
|
||||||
|
|
Loading…
Reference in New Issue