@@ -1777,14 +1777,37 @@ STATIC_INLINE uintptr_t gc_read_stack(void *_addr, uintptr_t offset,
17771777 return * (uintptr_t * )real_addr ;
17781778}
17791779
1780- JL_NORETURN NOINLINE void gc_assert_datatype_fail (jl_ptls_t ptls , jl_datatype_t * vt ,
1781- jl_gc_markqueue_t * mq ) JL_NOTSAFEPOINT
1782- {
1783- jl_safe_printf ("GC error (probable corruption) :\n" );
1784- jl_gc_debug_print_status ();
1785- jl_ (vt );
1786- jl_gc_debug_critical_error ();
1787- abort ();
1780+ STATIC_INLINE void gc_assert_parent_validity (jl_value_t * parent , jl_value_t * child ) JL_NOTSAFEPOINT
1781+ {
1782+ #ifdef GC_ASSERT_PARENT_VALIDITY
1783+ jl_taggedvalue_t * child_astagged = jl_astaggedvalue (child );
1784+ jl_taggedvalue_t * child_vtag = (jl_taggedvalue_t * )(child_astagged -> header & ~(uintptr_t )0xf );
1785+ uintptr_t child_vt = (uintptr_t )child_vtag ;
1786+ if (child_vt == (jl_datatype_tag << 4 ) ||
1787+ child_vt == (jl_unionall_tag << 4 ) ||
1788+ child_vt == (jl_uniontype_tag << 4 ) ||
1789+ child_vt == (jl_tvar_tag << 4 ) ||
1790+ child_vt == (jl_vararg_tag << 4 )) {
1791+ // Skip, since these wouldn't hit the object assert anyway
1792+ return ;
1793+ }
1794+ else if (child_vt < jl_max_tags << 4 ) {
1795+ // Skip, since these wouldn't hit the object assert anyway
1796+ return ;
1797+ }
1798+ if (__unlikely (!jl_is_datatype ((jl_datatype_t * )child_vt ) || ((jl_datatype_t * )child_vt )-> smalltag )) {
1799+ jl_safe_printf ("GC error (probable corruption)\n" );
1800+ jl_gc_debug_print_status ();
1801+ jl_safe_printf ("Parent %p\n" , (void * )parent );
1802+ jl_safe_printf ("of type:\n" );
1803+ jl_ (jl_typeof (parent ));
1804+ jl_safe_printf ("While marking child at %p\n" , (void * )child );
1805+ jl_safe_printf ("of type:\n" );
1806+ jl_ (child_vtag );
1807+ jl_gc_debug_critical_error ();
1808+ abort ();
1809+ }
1810+ #endif
17881811}
17891812
17901813// Check if `nptr` is tagged for `old + refyoung`,
@@ -1884,6 +1907,7 @@ STATIC_INLINE jl_value_t *gc_mark_obj8(jl_ptls_t ptls, char *obj8_parent, uint8_
18841907 if (new_obj != NULL ) {
18851908 verify_parent2 ("object" , obj8_parent , slot , "field(%d)" ,
18861909 gc_slot_to_fieldidx (obj8_parent , slot , (jl_datatype_t * )jl_typeof (obj8_parent )));
1910+ gc_assert_parent_validity ((jl_value_t * )obj8_parent , new_obj );
18871911 if (obj8_begin + 1 != obj8_end ) {
18881912 gc_try_claim_and_push (mq , new_obj , & nptr );
18891913 }
@@ -1915,6 +1939,7 @@ STATIC_INLINE jl_value_t *gc_mark_obj16(jl_ptls_t ptls, char *obj16_parent, uint
19151939 if (new_obj != NULL ) {
19161940 verify_parent2 ("object" , obj16_parent , slot , "field(%d)" ,
19171941 gc_slot_to_fieldidx (obj16_parent , slot , (jl_datatype_t * )jl_typeof (obj16_parent )));
1942+ gc_assert_parent_validity ((jl_value_t * )obj16_parent , new_obj );
19181943 if (obj16_begin + 1 != obj16_end ) {
19191944 gc_try_claim_and_push (mq , new_obj , & nptr );
19201945 }
@@ -1946,6 +1971,7 @@ STATIC_INLINE jl_value_t *gc_mark_obj32(jl_ptls_t ptls, char *obj32_parent, uint
19461971 if (new_obj != NULL ) {
19471972 verify_parent2 ("object" , obj32_parent , slot , "field(%d)" ,
19481973 gc_slot_to_fieldidx (obj32_parent , slot , (jl_datatype_t * )jl_typeof (obj32_parent )));
1974+ gc_assert_parent_validity ((jl_value_t * )obj32_parent , new_obj );
19491975 if (obj32_begin + 1 != obj32_end ) {
19501976 gc_try_claim_and_push (mq , new_obj , & nptr );
19511977 }
@@ -2011,6 +2037,7 @@ STATIC_INLINE void gc_mark_objarray(jl_ptls_t ptls, jl_value_t *obj_parent, jl_v
20112037 if (new_obj != NULL ) {
20122038 verify_parent2 ("obj array" , obj_parent , obj_begin , "elem(%d)" ,
20132039 gc_slot_to_arrayidx (obj_parent , obj_begin ));
2040+ gc_assert_parent_validity (obj_parent , new_obj );
20142041 gc_try_claim_and_push (mq , new_obj , & nptr );
20152042 gc_heap_snapshot_record_array_edge (obj_parent , & new_obj );
20162043 }
@@ -2084,6 +2111,7 @@ STATIC_INLINE void gc_mark_array8(jl_ptls_t ptls, jl_value_t *ary8_parent, jl_va
20842111 if (new_obj != NULL ) {
20852112 verify_parent2 ("array" , ary8_parent , & new_obj , "elem(%d)" ,
20862113 gc_slot_to_arrayidx (ary8_parent , ary8_begin ));
2114+ gc_assert_parent_validity (ary8_parent , new_obj );
20872115 gc_try_claim_and_push (mq , new_obj , & nptr );
20882116 gc_heap_snapshot_record_array_edge (ary8_parent , & new_obj );
20892117 }
@@ -2158,6 +2186,7 @@ STATIC_INLINE void gc_mark_array16(jl_ptls_t ptls, jl_value_t *ary16_parent, jl_
21582186 if (new_obj != NULL ) {
21592187 verify_parent2 ("array" , ary16_parent , & new_obj , "elem(%d)" ,
21602188 gc_slot_to_arrayidx (ary16_parent , ary16_begin ));
2189+ gc_assert_parent_validity (ary16_parent , new_obj );
21612190 gc_try_claim_and_push (mq , new_obj , & nptr );
21622191 gc_heap_snapshot_record_array_edge (ary16_parent , & new_obj );
21632192 }
@@ -2311,12 +2340,16 @@ STATIC_INLINE void gc_mark_module_binding(jl_ptls_t ptls, jl_module_t *mb_parent
23112340 if (b == (jl_binding_t * )jl_nothing )
23122341 continue ;
23132342 verify_parent1 ("module" , mb_parent , mb_begin , "binding_buff" );
2343+ gc_assert_parent_validity ((jl_value_t * )mb_parent , (jl_value_t * )b );
23142344 gc_try_claim_and_push (mq , b , & nptr );
23152345 }
23162346 jl_value_t * bindings = (jl_value_t * )jl_atomic_load_relaxed (& mb_parent -> bindings );
2347+ gc_assert_parent_validity ((jl_value_t * )mb_parent , bindings );
23172348 gc_try_claim_and_push (mq , bindings , & nptr );
23182349 jl_value_t * bindingkeyset = (jl_value_t * )jl_atomic_load_relaxed (& mb_parent -> bindingkeyset );
2350+ gc_assert_parent_validity ((jl_value_t * )mb_parent , bindingkeyset );
23192351 gc_try_claim_and_push (mq , bindingkeyset , & nptr );
2352+ gc_assert_parent_validity ((jl_value_t * )mb_parent , (jl_value_t * )mb_parent -> parent );
23202353 gc_try_claim_and_push (mq , (jl_value_t * )mb_parent -> parent , & nptr );
23212354 size_t nusings = mb_parent -> usings .len ;
23222355 if (nusings > 0 ) {
@@ -2346,7 +2379,7 @@ void gc_mark_finlist_(jl_gc_markqueue_t *mq, jl_value_t **fl_begin, jl_value_t *
23462379 }
23472380 for (; fl_begin < fl_end ; fl_begin ++ ) {
23482381 new_obj = * fl_begin ;
2349- if (__unlikely (! new_obj ))
2382+ if (__unlikely (new_obj == NULL ))
23502383 continue ;
23512384 if (gc_ptr_tag (new_obj , 1 )) {
23522385 new_obj = (jl_value_t * )gc_ptr_clear_tag (new_obj , 1 );
@@ -2535,11 +2568,6 @@ FORCE_INLINE void gc_mark_outrefs(jl_ptls_t ptls, jl_gc_markqueue_t *mq, void *_
25352568 }
25362569 return ;
25372570 }
2538- else {
2539- jl_datatype_t * vt = (jl_datatype_t * )vtag ;
2540- if (__unlikely (!jl_is_datatype (vt ) || vt -> smalltag ))
2541- gc_assert_datatype_fail (ptls , vt , mq );
2542- }
25432571 jl_datatype_t * vt = (jl_datatype_t * )vtag ;
25442572 if (vt -> name == jl_array_typename ) {
25452573 jl_array_t * a = (jl_array_t * )new_obj ;
0 commit comments