diff --git a/base/invalidation.jl b/base/invalidation.jl index 0d814b3f31f67..9a3d1ddd912e6 100644 --- a/base/invalidation.jl +++ b/base/invalidation.jl @@ -206,6 +206,10 @@ function scan_new_method!(method::Method, image_backedges_only::Bool) end function scan_new_methods!(extext_methods::Vector{Any}, internal_methods::Vector{Any}, image_backedges_only::Bool) + if image_backedges_only && Base.generating_output(true) + # Replacing image bindings is forbidden during incremental precompilation - skip backedge insertion + return + end for method in internal_methods if isa(method, Method) scan_new_method!(method, image_backedges_only) diff --git a/src/module.c b/src/module.c index 7c83d9329ab50..b0e3efb92fd5d 100644 --- a/src/module.c +++ b/src/module.c @@ -1669,8 +1669,14 @@ JL_DLLEXPORT jl_binding_partition_t *jl_replace_binding_locked2(jl_binding_t *b, // Until the first such replacement, we can fast-path validation. // For these purposes, we consider the `Main` module to be a non-sysimg module. // This is legal, because we special case the `Main` in check_safe_import_from. - if (jl_object_in_image((jl_value_t*)b) && b->globalref->mod != jl_main_module && jl_atomic_load_relaxed(&jl_first_image_replacement_world) == ~(size_t)0) + if (jl_object_in_image((jl_value_t*)b) && b->globalref->mod != jl_main_module && jl_atomic_load_relaxed(&jl_first_image_replacement_world) == ~(size_t)0) { + // During incremental compilation replacement of image bindings is forbidden; + // We use this to avoid inserting backedges while loading pkgimages. + // `check_safe_newbinding` checks an equivalent condition on `b->globalref->mod`, + // but doesn't quite query `jl_object_in_image`, so assert here to be extra sure. + assert(!(jl_options.incremental && jl_generating_output())); jl_atomic_store_relaxed(&jl_first_image_replacement_world, new_world); + } assert(jl_atomic_load_relaxed(&b->partitions) == old_bpart); jl_binding_partition_t *new_bpart = new_binding_partition();