@@ -22,6 +22,7 @@ static void check_heap_dirty_msg PROTO((char *msg, ptr *x));
2222static IBOOL dirty_listedp PROTO ((seginfo * x , IGEN from_g , IGEN to_g ));
2323static void check_dirty_space PROTO ((ISPC s ));
2424static void check_dirty PROTO ((void ));
25+ static void check_locked_object PROTO ((ptr p , IBOOL locked , IGEN g , IBOOL aftergc , IGEN mcg ));
2526
2627static IBOOL checkheap_noisy ;
2728
@@ -510,6 +511,8 @@ static void segment_tell(seg) uptr seg; {
510511 else {
511512 printf (" space-%s" , spacename [s1 ]);
512513 if (si -> old_space ) printf (" oldspace" );
514+ if (si -> must_mark ) printf (" mustmark" );
515+ if (si -> marked_mask ) printf (" marked" );
513516 }
514517 printf ("\n" );
515518 }
@@ -534,7 +537,7 @@ static void check_heap_dirty_msg(msg, x) char *msg; ptr *x; {
534537 printf ("to " ); segment_tell (addr_get_segment (* x ));
535538}
536539
537- void S_check_heap (aftergc ) IBOOL aftergc ; {
540+ void S_check_heap (aftergc , mcg ) IBOOL aftergc ; IGEN mcg ; {
538541 uptr seg ; INT d ; ISPC s ; IGEN g ; IDIRTYBYTE dirty ; IBOOL found_eos ; IGEN pg ;
539542 ptr p , * pp1 , * pp2 , * nl ;
540543 iptr i ;
@@ -573,6 +576,10 @@ void S_check_heap(aftergc) IBOOL aftergc; {
573576 seginfo * si ;
574577 for (g = 0 ; g <= S_G .max_nonstatic_generation ; INCRGEN (g )) {
575578 for (si = S_G .occupied_segments [s ][g ]; si != NULL ; si = si -> next ) {
579+ if (si -> generation != g ) {
580+ S_checkheap_errors += 1 ;
581+ printf ("!!! segment in wrong occupied_segments list\n" );
582+ }
576583 nonstatic_segments += 1 ;
577584 }
578585 }
@@ -619,8 +626,11 @@ void S_check_heap(aftergc) IBOOL aftergc; {
619626 s = si -> space ;
620627 g = si -> generation ;
621628
629+ if (si -> use_marks )
630+ printf ("!!! use_marks set on generation %d segment %#tx\n" , g , (ptrdiff_t )seg );
631+
622632 if (s == space_new ) {
623- if (g != 0 ) {
633+ if (g != 0 && ! si -> marked_mask ) {
624634 S_checkheap_errors += 1 ;
625635 printf ("!!! unexpected generation %d segment %#tx in space_new\n" , g , (ptrdiff_t )seg );
626636 }
@@ -654,9 +664,18 @@ void S_check_heap(aftergc) IBOOL aftergc; {
654664 || psi -> old_space
655665 || (psi -> marked_mask && !(psi -> marked_mask [segment_bitmap_byte (p )] & segment_bitmap_bit (p )))) {
656666 S_checkheap_errors += 1 ;
657- printf ("!!! dangling reference at %#tx to %#tx\n" , (ptrdiff_t )pp1 , (ptrdiff_t )p );
667+ printf ("!!! dangling reference at %#tx to %#tx%s \n" , (ptrdiff_t )pp1 , (ptrdiff_t )p , ( aftergc ? " after gc" : "" ) );
658668 printf ("from: " ); segment_tell (seg );
659669 printf ("to: " ); segment_tell (ptr_get_segment (p ));
670+ {
671+ ptr l ;
672+ for (l = S_G .locked_objects [psi -> generation ]; l != Snil ; l = Scdr (l ))
673+ if (Scar (l ) == p )
674+ printf (" in locked\n" );
675+ for (l = S_G .unlocked_objects [psi -> generation ]; l != Snil ; l = Scdr (l ))
676+ if (Scar (l ) == p )
677+ printf (" in unlocked\n" );
678+ }
660679 }
661680 }
662681 }
@@ -745,8 +764,9 @@ void S_check_heap(aftergc) IBOOL aftergc; {
745764 if (aftergc
746765 && (s != space_empty )
747766 && (g == 0
748- || (s != space_impure && s != space_symbol && s != space_port && s != space_weakpair && s != space_ephemeron
749- && s != space_impure_record && s != space_immobile_impure && s != space_count_impure && s != space_closure ))) {
767+ || (s != space_new && s != space_impure && s != space_symbol && s != space_port && s != space_weakpair && s != space_ephemeron
768+ && s != space_impure_record && s != space_impure_typed_object
769+ && s != space_immobile_impure && s != space_count_impure && s != space_closure ))) {
750770 for (d = 0 ; d < cards_per_segment ; d += 1 ) {
751771 if (si -> dirty_bytes [d ] != 0xff ) {
752772 S_checkheap_errors += 1 ;
@@ -760,6 +780,21 @@ void S_check_heap(aftergc) IBOOL aftergc; {
760780 chunk = chunk -> next ;
761781 }
762782 }
783+
784+ {
785+ for (g = 0 ; g <= S_G .max_nonstatic_generation ; INCRGEN (g )) {
786+ ptr l ;
787+ for (l = S_G .locked_objects [g ]; l != Snil ; l = Scdr (l ))
788+ check_locked_object (Scar (l ), 1 , g , aftergc , mcg );
789+ for (l = S_G .unlocked_objects [g ]; l != Snil ; l = Scdr (l ))
790+ check_locked_object (Scar (l ), 0 , g , aftergc , mcg );
791+ }
792+ }
793+
794+ if (S_checkheap_errors ) {
795+ printf ("heap check failed%s\n" , (aftergc ? " after gc" : "" ));
796+ exit (1 );
797+ }
763798}
764799
765800static IBOOL dirty_listedp (seginfo * x , IGEN from_g , IGEN to_g ) {
@@ -826,7 +861,9 @@ static void check_dirty() {
826861 S_checkheap_errors += 1 ;
827862 printf ("!!! (check_dirty): dirty byte = %d for segment %#tx in %d -> %d dirty list\n" , mingval , (ptrdiff_t )(si -> number ), from_g , to_g );
828863 }
829- if (s != space_new && s != space_impure && s != space_symbol && s != space_port && s != space_impure_record && s != space_weakpair && s != space_ephemeron ) {
864+ if (s != space_new && s != space_impure && s != space_symbol && s != space_port
865+ && s != space_impure_record && s != space_impure_typed_object && s != space_immobile_impure
866+ && s != space_weakpair && s != space_ephemeron ) {
830867 S_checkheap_errors += 1 ;
831868 printf ("!!! (check_dirty): unexpected space %d for dirty segment %#tx\n" , s , (ptrdiff_t )(si -> number ));
832869 }
@@ -842,10 +879,40 @@ static void check_dirty() {
842879 check_dirty_space (space_impure_record );
843880 check_dirty_space (space_weakpair );
844881 check_dirty_space (space_ephemeron );
882+ check_dirty_space (space_immobile_impure );
845883
846884 fflush (stdout );
847885}
848886
887+ static void check_locked_object (ptr p , IBOOL locked , IGEN g , IBOOL aftergc , IGEN mcg )
888+ {
889+ const char * what = (locked ? "locked" : "unlocked" );
890+ seginfo * psi = MaybeSegInfo (ptr_get_segment (p ));
891+ if (!psi ) {
892+ S_checkheap_errors += 1 ;
893+ printf ("!!! generation %d %s object has no segment: %p\n" , g , what , p );
894+ } else {
895+ if (psi -> generation != g ) {
896+ S_checkheap_errors += 1 ;
897+ printf ("!!! generation %d %s object in generation %d segment: %p\n" , g , what , psi -> generation , p );
898+ }
899+ if (!psi -> must_mark && locked ) {
900+ S_checkheap_errors += 1 ;
901+ printf ("!!! generation %d %s object not on must-mark page: %p\n" , g , what , p );
902+ }
903+ if (!psi -> marked_mask ) {
904+ if (aftergc && (psi -> generation <= mcg )) {
905+ S_checkheap_errors += 1 ;
906+ printf ("!!! %s object not in marked segment: %p\n" , what , p );
907+ printf (" in: " ); segment_tell (psi -> number );
908+ }
909+ } else if (!(psi -> marked_mask [segment_bitmap_byte (p )] & segment_bitmap_bit (p ))) {
910+ S_checkheap_errors += 1 ;
911+ printf ("!!! generation %d %s object not marked: %p\n" , g , what , p );
912+ }
913+ }
914+ }
915+
849916void S_fixup_counts (ptr counts ) {
850917 IGEN g ; U64 timestamp ;
851918
0 commit comments