Skip to content

Commit

Permalink
don't unconditionally promote custom blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
damiendoligez committed Oct 11, 2023
1 parent a6dd90b commit 98f12c3
Showing 1 changed file with 20 additions and 15 deletions.
35 changes: 20 additions & 15 deletions runtime/minor_gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,6 @@ void caml_empty_minor_heap_promote(caml_domain_state* domain,
caml_domain_state** participating)
{
struct caml_minor_tables *self_minor_tables = domain->minor_tables;
struct caml_custom_elt *elt;
value* young_ptr = domain->young_ptr;
value* young_end = domain->young_end;
uintnat minor_allocated_bytes = (uintnat)young_end - (uintnat)young_ptr;
Expand Down Expand Up @@ -577,20 +576,6 @@ void caml_empty_minor_heap_promote(caml_domain_state* domain,
}
#endif

/* unconditionally promote custom blocks so accounting is correct */
for (elt = self_minor_tables->custom.base;
elt < self_minor_tables->custom.ptr; elt++) {
value *v = &elt->block;
if (Is_block(*v) && Is_young(*v)) {
caml_adjust_gc_speed(elt->mem, elt->max);
if (get_header_val(*v) == 0) { /* value copied to major heap */
*v = Field(*v, 0);
} else {
oldify_one(&st, *v, v);
}
}
}

CAML_EV_BEGIN(EV_MINOR_FINALIZERS_OLDIFY);
/* promote the finalizers unconditionally as we want to avoid barriers */
caml_final_do_young_roots (&oldify_one, oldify_scanning_flags, &st,
Expand All @@ -615,6 +600,7 @@ void caml_empty_minor_heap_promote(caml_domain_state* domain,
|| (get_header_val(vnew) != 0 && !Is_young(vnew)));
}

struct caml_custom_elt *elt;
for (elt = self_minor_tables->custom.base;
elt < self_minor_tables->custom.ptr; elt++) {
value vnew = elt->block;
Expand Down Expand Up @@ -741,6 +727,25 @@ caml_stw_empty_minor_heap_no_major_slice(caml_domain_state* domain,
caml_gc_log("running stw empty_minor_heap_promote");
caml_empty_minor_heap_promote(domain, participating_count, participating);

/* Finalize dead custom blocks; do the accounting for the live ones.
This must be done after all domains have finished minor GC, but
before this domain resumes running OCaml code. */
CAML_EV_BEGIN(EV_MINOR_FINALIZED);
struct caml_custom_elt *elt;
for (elt = domain->minor_tables->custom.base;
elt < domain->minor_tables->custom.ptr; elt++) {
value *v = &elt->block;
if (Is_block(*v) && Is_young(*v)) {
if (get_header_val(*v) == 0) { /* value copied to major heap */
caml_adjust_gc_speed(elt->mem, elt->max);
} else {
void (*final_fun)(value) = Custom_ops_val(*v)->finalize;
if (final_fun != NULL) final_fun(*v);
}
}
}
CAML_EV_END(EV_MINOR_FINALIZED);

CAML_EV_BEGIN(EV_MINOR_FINALIZERS_ADMIN);
caml_gc_log("running finalizer data structure book-keeping");
caml_final_update_last_minor(domain);
Expand Down

0 comments on commit 98f12c3

Please sign in to comment.