@@ -651,6 +651,30 @@ static size_t jl_static_show_x_sym_escaped(JL_STREAM *out, jl_sym_t *name) JL_NO
651651 return n ;
652652}
653653
654+ // `jl_static_show()` cannot call `jl_subtype()`, for the GC reasons
655+ // explained in the comment on `jl_static_show_x_()`, below.
656+ // This function checks if `vt <: Function` without triggering GC.
657+ static int jl_static_is_function_ (jl_datatype_t * vt ) JL_NOTSAFEPOINT {
658+ if (!jl_function_type ) { // Make sure there's a Function type defined.
659+ return 0 ;
660+ }
661+ int _iter_count = 0 ; // To prevent infinite loops from corrupt type objects.
662+ while (vt != jl_any_type ) {
663+ if (vt == NULL ) {
664+ return 0 ;
665+ } else if (_iter_count > 10000 ) {
666+ // We are very likely stuck in a cyclic datastructure, so we assume this is
667+ // _not_ a Function.
668+ return 0 ;
669+ } else if (vt == jl_function_type ) {
670+ return 1 ;
671+ }
672+ vt = vt -> super ;
673+ _iter_count += 1 ;
674+ }
675+ return 0 ;
676+ }
677+
654678// `v` might be pointing to a field inlined in a structure therefore
655679// `jl_typeof(v)` may not be the same with `vt` and only `vt` should be
656680// used to determine the type of the value.
@@ -1006,7 +1030,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
10061030 n += jl_static_show_x (out , * (jl_value_t * * )v , depth );
10071031 n += jl_printf (out , ")" );
10081032 }
1009- else if (jl_function_type && jl_isa ( v , ( jl_value_t * ) jl_function_type )) {
1033+ else if (jl_static_is_function_ ( vt )) {
10101034 // v is function instance (an instance of a Function type).
10111035 jl_datatype_t * dv = (jl_datatype_t * )vt ;
10121036 jl_sym_t * sym = dv -> name -> mt -> name ;
0 commit comments