Skip to content

Commit dba4687

Browse files
authored
flambda-backend: Ports upstream #12439 (Fix custom block promotion) (#2068)
1 parent 418f1a0 commit dba4687

File tree

1 file changed

+27
-22
lines changed

1 file changed

+27
-22
lines changed

runtime/minor_gc.c

+27-22
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,6 @@ void caml_empty_minor_heap_promote(caml_domain_state* domain,
476476
caml_domain_state** participating)
477477
{
478478
struct caml_minor_tables *self_minor_tables = domain->minor_tables;
479-
struct caml_custom_elt *elt;
480479
value* young_ptr = domain->young_ptr;
481480
value* young_end = domain->young_end;
482481
uintnat minor_allocated_bytes = (uintnat)young_end - (uintnat)young_ptr;
@@ -586,20 +585,6 @@ void caml_empty_minor_heap_promote(caml_domain_state* domain,
586585
}
587586
#endif
588587

589-
/* unconditionally promote custom blocks so accounting is correct */
590-
for (elt = self_minor_tables->custom.base;
591-
elt < self_minor_tables->custom.ptr; elt++) {
592-
value *v = &elt->block;
593-
if (Is_block(*v) && Is_young(*v)) {
594-
caml_adjust_gc_speed(elt->mem, elt->max);
595-
if (get_header_val(*v) == 0) { /* value copied to major heap */
596-
*v = Field(*v, 0);
597-
} else {
598-
oldify_one(&st, *v, v);
599-
}
600-
}
601-
}
602-
603588
CAML_EV_BEGIN(EV_MINOR_FINALIZERS_OLDIFY);
604589
/* promote the finalizers unconditionally as we want to avoid barriers */
605590
caml_final_do_young_roots (&oldify_one, oldify_scanning_flags, &st,
@@ -623,13 +608,6 @@ void caml_empty_minor_heap_promote(caml_domain_state* domain,
623608
CAMLassert (!Is_block(vnew)
624609
|| (get_header_val(vnew) != 0 && !Is_young(vnew)));
625610
}
626-
627-
for (elt = self_minor_tables->custom.base;
628-
elt < self_minor_tables->custom.ptr; elt++) {
629-
value vnew = elt->block;
630-
CAMLassert (!Is_block(vnew)
631-
|| (get_header_val(vnew) != 0 && !Is_young(vnew)));
632-
}
633611
#endif
634612

635613
CAML_EV_BEGIN(EV_MINOR_LOCAL_ROOTS);
@@ -674,6 +652,28 @@ void caml_empty_minor_heap_promote(caml_domain_state* domain,
674652
(unsigned)(minor_allocated_bytes + 512)/1024);
675653
}
676654

655+
/* Finalize dead custom blocks and do the accounting for the live
656+
ones. This must be done right after leaving the barrier. At this
657+
point, all domains have finished minor GC, but this domain hasn't
658+
resumed running OCaml code. Other domains may have resumed OCaml
659+
code, but they cannot have any pointers into our minor heap. */
660+
static void custom_finalize_minor (caml_domain_state * domain)
661+
{
662+
struct caml_custom_elt *elt;
663+
for (elt = domain->minor_tables->custom.base;
664+
elt < domain->minor_tables->custom.ptr; elt++) {
665+
value *v = &elt->block;
666+
if (Is_block(*v) && Is_young(*v)) {
667+
if (get_header_val(*v) == 0) { /* value copied to major heap */
668+
caml_adjust_gc_speed(elt->mem, elt->max);
669+
} else {
670+
void (*final_fun)(value) = Custom_ops_val(*v)->finalize;
671+
if (final_fun != NULL) final_fun(*v);
672+
}
673+
}
674+
}
675+
}
676+
677677
void caml_do_opportunistic_major_slice
678678
(caml_domain_state* domain_unused, void* unused)
679679
{
@@ -733,6 +733,11 @@ caml_stw_empty_minor_heap_no_major_slice(caml_domain_state* domain,
733733
CAML_EV_END(EV_MINOR_LEAVE_BARRIER);
734734
}
735735

736+
CAML_EV_BEGIN(EV_MINOR_FINALIZED);
737+
caml_gc_log("finalizing dead minor custom blocks");
738+
custom_finalize_minor(domain);
739+
CAML_EV_END(EV_MINOR_FINALIZED);
740+
736741
CAML_EV_BEGIN(EV_MINOR_FINALIZERS_ADMIN);
737742
caml_gc_log("running finalizer data structure book-keeping");
738743
caml_final_update_last_minor(domain);

0 commit comments

Comments
 (0)