From 31c01878da5d62c97fa22c92da1572124b92042a Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Wed, 17 Aug 2022 10:30:54 +0200 Subject: [PATCH] Fix serialization of code instances. If they are encountered in a Julia object directly, as opposed to e.g. during serialization of a method instance, we'll have first populated the backref table as part of jl_serialize_value, so we need to skip that check during code instance serialization. --- src/dump.c | 14 ++++++++------ test/precompile.jl | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/dump.c b/src/dump.c index 16391e669b14d..a44c51c157be3 100644 --- a/src/dump.c +++ b/src/dump.c @@ -653,13 +653,15 @@ static int jl_serialize_generic(jl_serializer_state *s, jl_value_t *v) JL_GC_DIS return 0; } -static void jl_serialize_code_instance(jl_serializer_state *s, jl_code_instance_t *codeinst, int skip_partial_opaque, int internal) JL_GC_DISABLED +static void jl_serialize_code_instance(jl_serializer_state *s, jl_code_instance_t *codeinst, + int skip_partial_opaque, int internal, + int force) JL_GC_DISABLED { if (internal > 2) { while (codeinst && !codeinst->relocatability) codeinst = codeinst->next; } - if (jl_serialize_generic(s, (jl_value_t*)codeinst)) { + if (!force && jl_serialize_generic(s, (jl_value_t*)codeinst)) { return; } assert(codeinst != NULL); // handle by jl_serialize_generic, but this makes clang-sa happy @@ -680,7 +682,7 @@ static void jl_serialize_code_instance(jl_serializer_state *s, jl_code_instance_ if (write_ret_type && codeinst->rettype_const && jl_typeis(codeinst->rettype_const, jl_partial_opaque_type)) { if (skip_partial_opaque) { - jl_serialize_code_instance(s, codeinst->next, skip_partial_opaque, internal); + jl_serialize_code_instance(s, codeinst->next, skip_partial_opaque, internal, 0); return; } else { @@ -707,7 +709,7 @@ static void jl_serialize_code_instance(jl_serializer_state *s, jl_code_instance_ jl_serialize_value(s, jl_nothing); } write_uint8(s->s, codeinst->relocatability); - jl_serialize_code_instance(s, codeinst->next, skip_partial_opaque, internal); + jl_serialize_code_instance(s, codeinst->next, skip_partial_opaque, internal, 0); } enum METHOD_SERIALIZATION_MODE { @@ -968,10 +970,10 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li } jl_serialize_value(s, (jl_value_t*)backedges); jl_serialize_value(s, (jl_value_t*)NULL); //callbacks - jl_serialize_code_instance(s, mi->cache, 1, internal); + jl_serialize_code_instance(s, mi->cache, 1, internal, 0); } else if (jl_is_code_instance(v)) { - jl_serialize_code_instance(s, (jl_code_instance_t*)v, 0, 2); + jl_serialize_code_instance(s, (jl_code_instance_t*)v, 0, 2, 1); } else if (jl_typeis(v, jl_module_type)) { jl_serialize_module(s, (jl_module_t*)v); diff --git a/test/precompile.jl b/test/precompile.jl index 47d9a1bb7e860..12c04a997a137 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -1488,5 +1488,22 @@ precompile_test_harness("Issue #46558") do load_path @test (@eval $Foo.foo(1)) == 2 end +precompile_test_harness("issue #46296") do load_path + write(joinpath(load_path, "CodeInstancePrecompile.jl"), + """ + module CodeInstancePrecompile + + mi = first(methods(identity)).specializations[1] + ci = Core.CodeInstance(mi, Any, nothing, nothing, zero(Int32), typemin(UInt64), + typemax(UInt64), zero(UInt32), zero(UInt32), nothing, 0x00) + + __init__() = @assert ci isa Core.CodeInstance + + end + """) + Base.compilecache(Base.PkgId("CodeInstancePrecompile")) + (@eval (using CodeInstancePrecompile)) +end + empty!(Base.DEPOT_PATH) append!(Base.DEPOT_PATH, original_depot_path)