From af946a0aa77e05976337424f8fa016d958075a6b Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 29 May 2024 18:47:45 +0000 Subject: [PATCH] record all invoke targets as edges as test --- base/boot.jl | 6 +-- base/compiler/typeinfer.jl | 19 ++++---- base/expr.jl | 2 +- src/common_symbols1.inc | 2 - src/common_symbols2.inc | 4 +- src/gf.c | 45 +++++++++++-------- src/ircode.c | 60 ++++++++++++++++++++++++- src/julia_internal.h | 5 ++- src/opaque_closure.c | 12 +++-- src/serialize.h | 90 +++++++++++++++++++------------------- src/toplevel.c | 2 +- 11 files changed, 159 insertions(+), 88 deletions(-) diff --git a/base/boot.jl b/base/boot.jl index 3d19e46bf5d5d8..432b6061cb358b 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -510,11 +510,11 @@ function CodeInstance( mi::MethodInstance, owner, @nospecialize(rettype), @nospecialize(exctype), @nospecialize(inferred_const), @nospecialize(inferred), const_flags::Int32, min_world::UInt, max_world::UInt, effects::UInt32, @nospecialize(analysis_results), - relocatability::UInt8, edges::Union{DebugInfo,Nothing}) + relocatability::UInt8, di::Union{DebugInfo,Nothing}, edges::SimpleVector) return ccall(:jl_new_codeinst, Ref{CodeInstance}, - (Any, Any, Any, Any, Any, Any, Int32, UInt, UInt, UInt32, Any, UInt8, Any), + (Any, Any, Any, Any, Any, Any, Int32, UInt, UInt, UInt32, Any, UInt8, Any, Any), mi, owner, rettype, exctype, inferred_const, inferred, const_flags, min_world, max_world, - effects, analysis_results, relocatability, edges) + effects, analysis_results, relocatability, di, edges) end GlobalRef(m::Module, s::Symbol) = ccall(:jl_module_globalref, Ref{GlobalRef}, (Any, Any), m, s) Module(name::Symbol=:anonymous, std_imports::Bool=true, default_names::Bool=true) = ccall(:jl_f_new_module, Ref{Module}, (Any, Bool, Bool), name, std_imports, default_names) diff --git a/base/compiler/typeinfer.jl b/base/compiler/typeinfer.jl index f0e2b9b1045001..bab3e9a944268c 100644 --- a/base/compiler/typeinfer.jl +++ b/base/compiler/typeinfer.jl @@ -224,13 +224,16 @@ function finish!(interp::AbstractInterpreter, caller::InferenceState; if isdefined(result, :ci) ci = result.ci inferred_result = nothing + edges = Core.svec() # This should be a computed input, for now it is approximated (badly) here relocatability = 0x1 const_flag = is_result_constabi_eligible(result) if !can_discard_trees || (is_cached(caller) && !const_flag) inferred_result = transform_result_for_cache(interp, result.linfo, result.valid_worlds, result, can_discard_trees) relocatability = 0x0 if inferred_result isa CodeInfo - edges = inferred_result.debuginfo + edges = ccall(:jl_ir_edges_legacy, Any, (Any,), inferred_result.code) + inferred_result.edges = edges + di = inferred_result.debuginfo uncompressed = inferred_result inferred_result = maybe_compress_codeinfo(interp, result.linfo, inferred_result, can_discard_trees) result.is_src_volatile |= uncompressed !== inferred_result @@ -245,14 +248,14 @@ function finish!(interp::AbstractInterpreter, caller::InferenceState; end end # n.b. relocatability = isa(inferred_result, String) && inferred_result[end] - if !@isdefined edges - edges = DebugInfo(result.linfo) + if !@isdefined di + di = DebugInfo(result.linfo) end - ccall(:jl_update_codeinst, Cvoid, (Any, Any, Int32, UInt, UInt, UInt32, Any, UInt8, Any), + ccall(:jl_update_codeinst, Cvoid, (Any, Any, Int32, UInt, UInt, UInt32, Any, UInt8, Any, Any), ci, inferred_result, const_flag, first(result.valid_worlds), last(result.valid_worlds), encode_effects(result.ipo_effects), result.analysis_results, - relocatability, edges) + relocatability, di, edges) engine_reject(interp, ci) end return nothing @@ -334,7 +337,6 @@ function is_result_constabi_eligible(result::InferenceResult) return isa(result_type, Const) && is_foldable_nothrow(result.ipo_effects) && is_inlineable_constant(result_type.val) end - function transform_result_for_cache(interp::AbstractInterpreter, ::MethodInstance, valid_worlds::WorldRange, result::InferenceResult, can_discard_trees::Bool=may_discard_trees(interp)) @@ -991,6 +993,7 @@ function codeinfo_for_const(interp::AbstractInterpreter, mi::MethodInstance, @no tree.debuginfo = DebugInfo(mi) tree.ssaflags = UInt32[0] tree.rettype = Core.Typeof(val) + tree.edges = Core.svec() set_inlineable!(tree, true) tree.parent = mi return tree @@ -1008,7 +1011,7 @@ function codeinstance_for_const_with_code(interp::AbstractInterpreter, code::Cod return CodeInstance(code.def, cache_owner(interp), code.rettype, code.exctype, code.rettype_const, src, Int32(0x3), code.min_world, code.max_world, code.ipo_purity_bits, code.analysis_results, - code.relocatability, src.debuginfo) + code.relocatability, src.debuginfo, src.edges) end result_is_constabi(interp::AbstractInterpreter, result::InferenceResult, @@ -1170,7 +1173,7 @@ function typeinf_ext(interp::AbstractInterpreter, mi::MethodInstance, source_mod src isa CodeInfo || return nothing return CodeInstance(mi, cache_owner(interp), Any, Any, nothing, src, Int32(0), get_inference_world(interp), get_inference_world(interp), - UInt32(0), nothing, UInt8(0), src.debuginfo) + UInt32(0), nothing, UInt8(0), src.debuginfo, src.edges) end end ci = engine_reserve(interp, mi) diff --git a/base/expr.jl b/base/expr.jl index 37a7330004b9ba..e19aba275569f8 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -79,7 +79,7 @@ function copy(c::CodeInfo) cnew.slottypes = copy(cnew.slottypes::Vector{Any}) end cnew.ssaflags = copy(cnew.ssaflags) - cnew.edges = cnew.edges === nothing || cnew.edges === Core.svec() ? cnew.edges : copy(cnew.edges::Vector) + cnew.edges = cnew.edges === nothing || cnew.edges isa Core.SimpleVector ? cnew.edges : copy(cnew.edges::Vector) ssavaluetypes = cnew.ssavaluetypes ssavaluetypes isa Vector{Any} && (cnew.ssavaluetypes = copy(ssavaluetypes)) return cnew diff --git a/src/common_symbols1.inc b/src/common_symbols1.inc index f54be52729a4f4..3dfcf17a07b5c2 100644 --- a/src/common_symbols1.inc +++ b/src/common_symbols1.inc @@ -88,5 +88,3 @@ jl_symbol("ifelse"), jl_symbol("Array"), jl_symbol("eq_int"), jl_symbol("throw_inexacterror"), -jl_symbol("|"), -jl_symbol("setproperty!"), diff --git a/src/common_symbols2.inc b/src/common_symbols2.inc index ee2a0e2edd9fe4..2a6990bac52fff 100644 --- a/src/common_symbols2.inc +++ b/src/common_symbols2.inc @@ -1,3 +1,5 @@ +jl_symbol("|"), +jl_symbol("setproperty!"), jl_symbol("sext_int"), jl_symbol("String"), jl_symbol("Int"), @@ -244,5 +246,3 @@ jl_symbol("invokelatest"), jl_symbol("jl_array_del_end"), jl_symbol("_mod64"), jl_symbol("parameters"), -jl_symbol("monotonic"), -jl_symbol("regex.jl"), diff --git a/src/gf.c b/src/gf.c index c310f86077527e..3732e8d432329c 100644 --- a/src/gf.c +++ b/src/gf.c @@ -322,7 +322,7 @@ jl_datatype_t *jl_mk_builtin_func(jl_datatype_t *dt, const char *name, jl_fptr_a jl_code_instance_t *codeinst = jl_new_codeinst(mi, jl_nothing, (jl_value_t*)jl_any_type, (jl_value_t*)jl_any_type, jl_nothing, jl_nothing, - 0, 1, ~(size_t)0, 0, jl_nothing, 0, NULL); + 0, 1, ~(size_t)0, 0, jl_nothing, 0, NULL, NULL); jl_mi_cache_insert(mi, codeinst); jl_atomic_store_relaxed(&codeinst->specptr.fptr1, fptr); jl_atomic_store_relaxed(&codeinst->invoke, jl_fptr_args); @@ -480,7 +480,7 @@ JL_DLLEXPORT jl_value_t *jl_call_in_typeinf_world(jl_value_t **args, int nargs) JL_DLLEXPORT jl_code_instance_t *jl_get_method_inferred( jl_method_instance_t *mi JL_PROPAGATES_ROOT, jl_value_t *rettype, - size_t min_world, size_t max_world, jl_debuginfo_t *di /*jl_svec_t *edges*/) + size_t min_world, size_t max_world, jl_debuginfo_t *di, jl_svec_t *edges) { jl_value_t *owner = jl_nothing; // TODO: owner should be arg jl_code_instance_t *codeinst = jl_atomic_load_relaxed(&mi->cache); @@ -492,24 +492,27 @@ JL_DLLEXPORT jl_code_instance_t *jl_get_method_inferred( if (di == NULL) return codeinst; jl_debuginfo_t *debuginfo = jl_atomic_load_relaxed(&codeinst->debuginfo); - if (di == debuginfo) - return codeinst; - if (debuginfo == NULL && jl_atomic_cmpswap_relaxed(&codeinst->debuginfo, &debuginfo, di)) - return codeinst; - if (debuginfo && jl_egal((jl_value_t*)debuginfo, (jl_value_t*)di)) + if (di != debuginfo) { + if (!(debuginfo == NULL && jl_atomic_cmpswap_relaxed(&codeinst->debuginfo, &debuginfo, di))) + if (!(debuginfo && jl_egal((jl_value_t*)debuginfo, (jl_value_t*)di))) + continue; + } + // TODO: this is implied by the matching worlds, since it is intrinsic, so do we really need to verify it? + jl_svec_t *e = jl_atomic_load_relaxed(&codeinst->edges); + if (e && jl_egal((jl_value_t*)e, (jl_value_t*)edges)) return codeinst; } codeinst = jl_atomic_load_relaxed(&codeinst->next); } codeinst = jl_new_codeinst( mi, owner, rettype, (jl_value_t*)jl_any_type, NULL, NULL, - 0, min_world, max_world, 0, jl_nothing, 0, di); + 0, min_world, max_world, 0, jl_nothing, 0, di, edges); jl_mi_cache_insert(mi, codeinst); return codeinst; } JL_DLLEXPORT int jl_mi_cache_has_ci(jl_method_instance_t *mi, - jl_code_instance_t *ci) + jl_code_instance_t *ci) { jl_code_instance_t *codeinst = jl_atomic_load_relaxed(&mi->cache); while (codeinst) { @@ -527,7 +530,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( int32_t const_flags, size_t min_world, size_t max_world, uint32_t effects, jl_value_t *analysis_results, uint8_t relocatability, - jl_debuginfo_t *di /*, jl_svec_t *edges, int absolute_max*/) + jl_debuginfo_t *di, jl_svec_t *edges /*, int absolute_max*/) { jl_task_t *ct = jl_current_task; assert(min_world <= max_world && "attempting to set invalid world constraints"); @@ -535,7 +538,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( jl_code_instance_type); codeinst->def = mi; codeinst->owner = owner; - codeinst->edges = jl_emptysvec; + codeinst->edges = edges; jl_atomic_store_relaxed(&codeinst->min_world, min_world); jl_atomic_store_relaxed(&codeinst->max_world, max_world); codeinst->rettype = rettype; @@ -564,13 +567,15 @@ JL_DLLEXPORT void jl_update_codeinst( jl_code_instance_t *codeinst, jl_value_t *inferred, int32_t const_flags, size_t min_world, size_t max_world, uint32_t effects, jl_value_t *analysis_results, - uint8_t relocatability, jl_debuginfo_t *edges /* , int absolute_max*/) + uint8_t relocatability, jl_debuginfo_t *di, jl_svec_t *edges /* , int absolute_max*/) { codeinst->relocatability = relocatability; codeinst->analysis_results = analysis_results; jl_gc_wb(codeinst, analysis_results); jl_atomic_store_relaxed(&codeinst->ipo_purity_bits, effects); - jl_atomic_store_relaxed(&codeinst->debuginfo, edges); + jl_atomic_store_relaxed(&codeinst->debuginfo, di); + jl_gc_wb(codeinst, di); + jl_atomic_store_relaxed(&codeinst->edges, edges); jl_gc_wb(codeinst, edges); if ((const_flags & 1) != 0) { assert(codeinst->rettype_const); @@ -2564,8 +2569,10 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t jl_code_instance_t *codeinst2 = jl_compile_method_internal(mi2, world); jl_code_instance_t *codeinst = jl_get_method_inferred( mi, codeinst2->rettype, - jl_atomic_load_relaxed(&codeinst2->min_world), jl_atomic_load_relaxed(&codeinst2->max_world), - jl_atomic_load_relaxed(&codeinst2->debuginfo)); + jl_atomic_load_relaxed(&codeinst2->min_world), + jl_atomic_load_relaxed(&codeinst2->max_world), + jl_atomic_load_relaxed(&codeinst2->debuginfo), + jl_atomic_load_relaxed(&codeinst2->edges)); if (jl_atomic_load_relaxed(&codeinst->invoke) == NULL) { codeinst->rettype_const = codeinst2->rettype_const; jl_gc_wb(codeinst, codeinst->rettype_const); @@ -2624,7 +2631,7 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t if (unspec && (unspec_invoke = jl_atomic_load_acquire(&unspec->invoke))) { jl_code_instance_t *codeinst = jl_new_codeinst(mi, jl_nothing, (jl_value_t*)jl_any_type, (jl_value_t*)jl_any_type, NULL, NULL, - 0, 1, ~(size_t)0, 0, jl_nothing, 0, NULL); + 0, 1, ~(size_t)0, 0, jl_nothing, 0, NULL, NULL); void *unspec_fptr = jl_atomic_load_relaxed(&unspec->specptr.fptr); if (unspec_fptr) { // wait until invoke and specsigflags are properly set @@ -2651,7 +2658,7 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t if (!jl_code_requires_compiler(src, 0)) { jl_code_instance_t *codeinst = jl_new_codeinst(mi, jl_nothing, (jl_value_t*)jl_any_type, (jl_value_t*)jl_any_type, NULL, NULL, - 0, 1, ~(size_t)0, 0, jl_nothing, 0, NULL); + 0, 1, ~(size_t)0, 0, jl_nothing, 0, NULL, NULL); jl_atomic_store_release(&codeinst->invoke, jl_fptr_interpret_call); jl_mi_cache_insert(mi, codeinst); record_precompile_statement(mi, 0); @@ -2711,7 +2718,7 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t jl_method_instance_t *unspec = jl_get_unspecialized(def); if (unspec == NULL) unspec = mi; - jl_code_instance_t *ucache = jl_get_method_inferred(unspec, (jl_value_t*)jl_any_type, 1, ~(size_t)0, NULL); + jl_code_instance_t *ucache = jl_get_method_inferred(unspec, (jl_value_t*)jl_any_type, 1, ~(size_t)0, NULL, NULL); // ask codegen to make the fptr for unspec jl_callptr_t ucache_invoke = jl_atomic_load_acquire(&ucache->invoke); if (ucache_invoke == NULL) { @@ -2731,7 +2738,7 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t } codeinst = jl_new_codeinst(mi, jl_nothing, (jl_value_t*)jl_any_type, (jl_value_t*)jl_any_type, NULL, NULL, - 0, 1, ~(size_t)0, 0, jl_nothing, 0, NULL); + 0, 1, ~(size_t)0, 0, jl_nothing, 0, NULL, NULL); void *unspec_fptr = jl_atomic_load_relaxed(&ucache->specptr.fptr); if (unspec_fptr) { // wait until invoke and specsigflags are properly set diff --git a/src/ircode.c b/src/ircode.c index c386919e895a40..380bd11d7ded8e 100644 --- a/src/ircode.c +++ b/src/ircode.c @@ -25,6 +25,7 @@ typedef struct { ios_t *s; // method we're compressing for jl_method_t *method; + jl_svec_t *edges; jl_ptls_t ptls; uint8_t relocatability; } jl_ircode_state; @@ -72,7 +73,7 @@ static void literal_val_id(rle_reference *rr, jl_ircode_state *s, jl_value_t *v) { jl_array_t *rs = s->method->roots; int i, l = jl_array_nrows(rs); - if (jl_is_symbol(v) || jl_is_concrete_type(v)) { + if (jl_is_symbol(v) || jl_is_concrete_type(v)) { // TODO: or more generally, any ptr-egal value for (i = 0; i < l; i++) { if (jl_array_ptr_ref(rs, i) == v) return tagged_root(rr, s, i); @@ -84,6 +85,12 @@ static void literal_val_id(rle_reference *rr, jl_ircode_state *s, jl_value_t *v) return tagged_root(rr, s, i); } } + for (size_t i = 0; i < jl_svec_len(s->edges); i++) { + if (jl_svecref(s->edges, i) == v) { + rr->index = i; + return; + } + } jl_add_method_root(s->method, jl_precompile_toplevel_module, v); return tagged_root(rr, s, jl_array_nrows(rs) - 1); } @@ -102,13 +109,24 @@ static void jl_encode_int32(jl_ircode_state *s, int32_t x) static void jl_encode_as_indexed_root(jl_ircode_state *s, jl_value_t *v) { - rle_reference rr; + rle_reference rr = {.key = -1, .index = -1}; if (jl_is_string(v)) v = jl_as_global_root(v, 1); literal_val_id(&rr, s, v); int id = rr.index; assert(id >= 0); + if (rr.key == -1) { + if (id <= UINT8_MAX) { + write_uint8(s->s, TAG_EDGE); + write_uint8(s->s, id); + } + else { + write_uint8(s->s, TAG_LONG_EDGE); + write_uint32(s->s, id); + } + return; + } if (rr.key) { write_uint8(s->s, TAG_RELOC_METHODROOT); write_uint64(s->s, rr.key); @@ -689,6 +707,10 @@ static jl_value_t *jl_decode_value(jl_ircode_state *s) JL_GC_DISABLED return lookup_root(s->method, 0, read_uint8(s->s)); case TAG_LONG_METHODROOT: return lookup_root(s->method, 0, read_uint32(s->s)); + case TAG_EDGE: + return jl_svecref(s->edges, read_uint8(s->s)); + case TAG_LONG_EDGE: + return jl_svecref(s->edges, read_uint32(s->s)); case TAG_SVEC: JL_FALLTHROUGH; case TAG_LONG_SVEC: return jl_decode_value_svec(s, tag); case TAG_COMMONSYM: @@ -846,6 +868,37 @@ typedef enum { #define checked_size(data, macro_size) \ (declaration_context(static_assert(sizeof(data) == macro_size, #macro_size " does not match written size")), data) +// n.b. this does not compute edges correctly, but is just a temporary legacy helper while porting +JL_DLLEXPORT jl_value_t *jl_ir_edges_legacy(jl_array_t *src) +{ + arraylist_t edges; + arraylist_new(&edges, 0); + for (size_t i = 0; i < jl_array_dim0(src); i++) { + jl_value_t *v = jl_array_ptr_ref(src, i); + if (jl_is_expr(v)) { + jl_expr_t *e = (jl_expr_t*)v; + if (e->head == jl_assign_sym && jl_expr_nargs(e) == 2 && jl_is_expr(jl_exprarg(e, 1))) { + e = (jl_expr_t*)jl_exprarg(e, 1); + } + if (e->head == jl_invoke_sym) { + jl_value_t *target = jl_array_ptr_ref(e->args, 0); + if (jl_is_code_instance(target) || jl_is_method_instance(target)) { + size_t j; + for (j = 0; j < edges.len; j++) + if (edges.items[j] == (void*)target) + break; + if (j == edges.len) + arraylist_push(&edges, target); + } + } + } + } + jl_value_t *e = jl_f_svec(NULL, (jl_value_t**)edges.items, edges.len); + arraylist_free(&edges); + return e; +} + + JL_DLLEXPORT jl_string_t *jl_compress_ir(jl_method_t *m, jl_code_info_t *code) { JL_TIMING(AST_COMPRESS, AST_COMPRESS); @@ -865,9 +918,11 @@ JL_DLLEXPORT jl_string_t *jl_compress_ir(jl_method_t *m, jl_code_info_t *code) m->roots = jl_alloc_vec_any(0); jl_gc_wb(m, m->roots); } + jl_value_t *edges = code->edges; jl_ircode_state s = { &dest, m, + (!isdef && jl_is_svec(edges)) ? (jl_svec_t*)edges : jl_emptysvec, jl_current_task->ptls, 1 }; @@ -950,6 +1005,7 @@ JL_DLLEXPORT jl_code_info_t *jl_uncompress_ir(jl_method_t *m, jl_code_instance_t jl_ircode_state s = { &src, m, + metadata == NULL ? NULL : metadata->edges, jl_current_task->ptls, 1 }; diff --git a/src/julia_internal.h b/src/julia_internal.h index 35e0ae384d83a2..4b7098a5339237 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -664,7 +664,7 @@ JL_DLLEXPORT jl_code_info_t *jl_gdbcodetyped1(jl_method_instance_t *mi, size_t w JL_DLLEXPORT jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *meth JL_PROPAGATES_ROOT, size_t world); JL_DLLEXPORT jl_code_instance_t *jl_get_method_inferred( jl_method_instance_t *mi JL_PROPAGATES_ROOT, jl_value_t *rettype, - size_t min_world, size_t max_world, jl_debuginfo_t *edges); + size_t min_world, size_t max_world, jl_debuginfo_t *di, jl_svec_t *edges); jl_method_instance_t *jl_get_unspecialized(jl_method_t *def JL_PROPAGATES_ROOT); JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst_uninit(jl_method_instance_t *mi, jl_value_t *owner); @@ -674,7 +674,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( jl_value_t *inferred_const, jl_value_t *inferred, int32_t const_flags, size_t min_world, size_t max_world, uint32_t effects, jl_value_t *analysis_results, - uint8_t relocatability, jl_debuginfo_t *edges /* , int absolute_max*/); + uint8_t relocatability, jl_debuginfo_t *di, jl_svec_t *edges /* , int absolute_max*/); JL_DLLEXPORT const char *jl_debuginfo_file(jl_debuginfo_t *debuginfo) JL_NOTSAFEPOINT; JL_DLLEXPORT const char *jl_debuginfo_file1(jl_debuginfo_t *debuginfo) JL_NOTSAFEPOINT; @@ -713,6 +713,7 @@ JL_DLLEXPORT void jl_typeassert(jl_value_t *x, jl_value_t *t); #define JL_CALLABLE(name) \ JL_DLLEXPORT jl_value_t *name(jl_value_t *F, jl_value_t **args, uint32_t nargs) +JL_CALLABLE(jl_f_svec); JL_CALLABLE(jl_f_tuple); JL_CALLABLE(jl_f_intrinsic_call); JL_CALLABLE(jl_f_opaque_closure_call); diff --git a/src/opaque_closure.c b/src/opaque_closure.c index 0bf3a729cbcb19..cf0f32458d254f 100644 --- a/src/opaque_closure.c +++ b/src/opaque_closure.c @@ -112,8 +112,8 @@ static jl_opaque_closure_t *new_opaque_closure(jl_tupletype_t *argt, jl_value_t sigtype = jl_argtype_with_function_type((jl_value_t*)oc_type, (jl_value_t*)argt); jl_method_instance_t *mi_generic = jl_specializations_get_linfo(jl_opaque_closure_method, sigtype, jl_emptysvec); - // OC wrapper methods are not world dependent - ci = jl_get_method_inferred(mi_generic, selected_rt, 1, ~(size_t)0, NULL); + // OC wrapper methods are not world dependent and have no edges or other info + ci = jl_get_method_inferred(mi_generic, selected_rt, 1, ~(size_t)0, NULL, NULL); if (!jl_atomic_load_acquire(&ci->invoke)) jl_compile_codeinst(ci); specptr = jl_atomic_load_relaxed(&ci->specptr.fptr); @@ -144,7 +144,8 @@ JL_DLLEXPORT jl_opaque_closure_t *jl_new_opaque_closure_from_code_info(jl_tuplet { jl_value_t *root = NULL, *sigtype = NULL; jl_code_instance_t *inst = NULL; - JL_GC_PUSH3(&root, &sigtype, &inst); + jl_svec_t *edges = NULL; + JL_GC_PUSH4(&root, &sigtype, &inst, &edges); root = jl_box_long(lineno); root = jl_new_struct(jl_linenumbernode_type, root, file); jl_method_t *meth = jl_make_opaque_closure_method(mod, jl_nothing, nargs, root, ci, isva, isinferred); @@ -158,8 +159,11 @@ JL_DLLEXPORT jl_opaque_closure_t *jl_new_opaque_closure_from_code_info(jl_tuplet jl_value_t *argslotty = jl_array_ptr_ref(ci->slottypes, 0); sigtype = jl_argtype_with_function_type(argslotty, (jl_value_t*)argt); jl_method_instance_t *mi = jl_specializations_get_linfo((jl_method_t*)root, sigtype, jl_emptysvec); + edges = (jl_svec_t*)ci->edges; + if (!jl_is_svec(edges)) + edges = jl_emptysvec; // OC doesn't really have edges, so just drop them for now inst = jl_new_codeinst(mi, jl_nothing, rt_ub, (jl_value_t*)jl_any_type, NULL, (jl_value_t*)ci, - 0, world, world, 0, jl_nothing, 0, ci->debuginfo); + 0, world, world, 0, jl_nothing, 0, ci->debuginfo, edges); jl_mi_cache_insert(mi, inst); } diff --git a/src/serialize.h b/src/serialize.h index 3d3eb4df5e8625..3aa82a1d09a9b9 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -23,50 +23,52 @@ extern "C" { #define TAG_LONG_PHINODE 15 #define TAG_LONG_PHICNODE 16 #define TAG_METHODROOT 17 -#define TAG_STRING 18 -#define TAG_SHORT_INT64 19 -#define TAG_SHORT_GENERAL 20 -#define TAG_CNULL 21 -#define TAG_ARRAY1D 22 -#define TAG_SINGLETON 23 -#define TAG_MODULE 24 -#define TAG_TVAR 25 -#define TAG_METHOD_INSTANCE 26 -#define TAG_METHOD 27 -#define TAG_CODE_INSTANCE 28 -#define TAG_COMMONSYM 29 -#define TAG_NEARBYGLOBAL 30 -#define TAG_GLOBALREF 31 -#define TAG_CORE 32 -#define TAG_BASE 33 -#define TAG_BITYPENAME 34 -#define TAG_NEARBYMODULE 35 -#define TAG_INT32 36 -#define TAG_INT64 37 -#define TAG_UINT8 38 -#define TAG_VECTORTY 39 -#define TAG_PTRTY 40 -#define TAG_LONG_SSAVALUE 41 -#define TAG_LONG_METHODROOT 42 -#define TAG_SHORTER_INT64 43 -#define TAG_SHORT_INT32 44 -#define TAG_CALL1 45 -#define TAG_CALL2 46 -#define TAG_SHORT_BACKREF 47 -#define TAG_BACKREF 48 -#define TAG_UNIONALL 49 -#define TAG_GOTONODE 50 -#define TAG_QUOTENODE 51 -#define TAG_GENERAL 52 -#define TAG_GOTOIFNOT 53 -#define TAG_RETURNNODE 54 -#define TAG_ARGUMENT 55 -#define TAG_RELOC_METHODROOT 56 -#define TAG_BINDING 57 -#define TAG_MEMORYT 58 -#define TAG_ENTERNODE 59 - -#define LAST_TAG 59 +#define TAG_EDGE 18 +#define TAG_STRING 19 +#define TAG_SHORT_INT64 20 +#define TAG_SHORT_GENERAL 21 +#define TAG_CNULL 22 +#define TAG_ARRAY1D 23 +#define TAG_SINGLETON 24 +#define TAG_MODULE 25 +#define TAG_TVAR 26 +#define TAG_METHOD_INSTANCE 27 +#define TAG_METHOD 28 +#define TAG_CODE_INSTANCE 29 +#define TAG_COMMONSYM 30 +#define TAG_NEARBYGLOBAL 31 +#define TAG_GLOBALREF 32 +#define TAG_CORE 33 +#define TAG_BASE 34 +#define TAG_BITYPENAME 35 +#define TAG_NEARBYMODULE 36 +#define TAG_INT32 37 +#define TAG_INT64 38 +#define TAG_UINT8 39 +#define TAG_VECTORTY 40 +#define TAG_PTRTY 41 +#define TAG_LONG_SSAVALUE 42 +#define TAG_LONG_METHODROOT 43 +#define TAG_LONG_EDGE 44 +#define TAG_SHORTER_INT64 45 +#define TAG_SHORT_INT32 46 +#define TAG_CALL1 47 +#define TAG_CALL2 48 +#define TAG_SHORT_BACKREF 49 +#define TAG_BACKREF 50 +#define TAG_UNIONALL 51 +#define TAG_GOTONODE 52 +#define TAG_QUOTENODE 53 +#define TAG_GENERAL 54 +#define TAG_GOTOIFNOT 55 +#define TAG_RETURNNODE 56 +#define TAG_ARGUMENT 57 +#define TAG_RELOC_METHODROOT 58 +#define TAG_BINDING 59 +#define TAG_MEMORYT 60 +#define TAG_ENTERNODE 61 + +#define LAST_TAG 61 #define write_uint8(s, n) ios_putc((n), (s)) #define read_uint8(s) ((uint8_t)ios_getc((s))) diff --git a/src/toplevel.c b/src/toplevel.c index 6db7e1b7b53725..4738e9846b0e4a 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -604,7 +604,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst_for_uninferred(jl_method_instan jl_code_instance_t *ci = jl_new_codeinst(mi, (jl_value_t*)jl_uninferred_sym, (jl_value_t*)jl_any_type, (jl_value_t*)jl_any_type, jl_nothing, (jl_value_t*)src, 0, src->min_world, src->max_world, - 0, NULL, 1, NULL); + 0, NULL, 1, NULL, NULL); return ci; }