@@ -476,7 +476,6 @@ void caml_empty_minor_heap_promote(caml_domain_state* domain,
476
476
caml_domain_state * * participating )
477
477
{
478
478
struct caml_minor_tables * self_minor_tables = domain -> minor_tables ;
479
- struct caml_custom_elt * elt ;
480
479
value * young_ptr = domain -> young_ptr ;
481
480
value * young_end = domain -> young_end ;
482
481
uintnat minor_allocated_bytes = (uintnat )young_end - (uintnat )young_ptr ;
@@ -586,20 +585,6 @@ void caml_empty_minor_heap_promote(caml_domain_state* domain,
586
585
}
587
586
#endif
588
587
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
-
603
588
CAML_EV_BEGIN (EV_MINOR_FINALIZERS_OLDIFY );
604
589
/* promote the finalizers unconditionally as we want to avoid barriers */
605
590
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,
623
608
CAMLassert (!Is_block (vnew )
624
609
|| (get_header_val (vnew ) != 0 && !Is_young (vnew )));
625
610
}
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
- }
633
611
#endif
634
612
635
613
CAML_EV_BEGIN (EV_MINOR_LOCAL_ROOTS );
@@ -674,6 +652,28 @@ void caml_empty_minor_heap_promote(caml_domain_state* domain,
674
652
(unsigned )(minor_allocated_bytes + 512 )/1024 );
675
653
}
676
654
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
+
677
677
void caml_do_opportunistic_major_slice
678
678
(caml_domain_state * domain_unused , void * unused )
679
679
{
@@ -733,6 +733,11 @@ caml_stw_empty_minor_heap_no_major_slice(caml_domain_state* domain,
733
733
CAML_EV_END (EV_MINOR_LEAVE_BARRIER );
734
734
}
735
735
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
+
736
741
CAML_EV_BEGIN (EV_MINOR_FINALIZERS_ADMIN );
737
742
caml_gc_log ("running finalizer data structure book-keeping" );
738
743
caml_final_update_last_minor (domain );
0 commit comments