Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions base/invalidation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -122,23 +122,23 @@ function invalidate_code_for_globalref!(b::Core.Binding, invalidated_bpart::Core
invalidated_any |= invalidate_method_for_globalref!(gr, method, invalidated_bpart, new_max_world)
end
end
if isdefined(b, :backedges)
for edge in b.backedges
if isa(edge, CodeInstance)
ccall(:jl_invalidate_code_instance, Cvoid, (Any, UInt), edge, new_max_world)
invalidated_any = true
elseif isa(edge, Core.Binding)
isdefined(edge, :partitions) || continue
latest_bpart = edge.partitions
latest_bpart.max_world == typemax(UInt) || continue
is_some_imported(binding_kind(latest_bpart)) || continue
if is_some_binding_imported(binding_kind(latest_bpart))
partition_restriction(latest_bpart) === b || continue
end
push!(queued_bindings, (edge, latest_bpart, latest_bpart))
else
invalidated_any |= invalidate_method_for_globalref!(gr, edge::Method, invalidated_bpart, new_max_world)
nbackedges = ccall(:jl_binding_backedges_length, Csize_t, (Any,), b)
for i = 1:nbackedges
edge = ccall(:jl_binding_backedges_getindex, Any, (Any, Csize_t), b, i)
if isa(edge, CodeInstance)
ccall(:jl_invalidate_code_instance, Cvoid, (Any, UInt), edge, new_max_world)
invalidated_any = true
elseif isa(edge, Core.Binding)
isdefined(edge, :partitions) || continue
latest_bpart = edge.partitions
latest_bpart.max_world == typemax(UInt) || continue
is_some_imported(binding_kind(latest_bpart)) || continue
if is_some_binding_imported(binding_kind(latest_bpart))
partition_restriction(latest_bpart) === b || continue
end
push!(queued_bindings, (edge, latest_bpart, latest_bpart))
else
invalidated_any |= invalidate_method_for_globalref!(gr, edge::Method, invalidated_bpart, new_max_world)
end
end
end
Expand All @@ -149,7 +149,7 @@ function invalidate_code_for_globalref!(b::Core.Binding, invalidated_bpart::Core
usings_backedges = ccall(:jl_get_module_usings_backedges, Any, (Any,), gr.mod)
if usings_backedges !== nothing
for user::Module in usings_backedges::Vector{Any}
user_binding = ccall(:jl_get_module_binding_or_nothing, Any, (Any, Any), user, gr.name)
user_binding = ccall(:jl_get_module_binding_or_nothing, Any, (Any, Any), user, gr.name)::Union{Core.Binding, Nothing}
user_binding === nothing && continue
isdefined(user_binding, :partitions) || continue
latest_bpart = user_binding.partitions
Expand Down
24 changes: 24 additions & 0 deletions src/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,25 @@ JL_DLLEXPORT jl_value_t *jl_get_binding_leaf_partitions_value_if_const(jl_bindin
return NULL;
}

JL_DLLEXPORT size_t jl_binding_backedges_length(jl_binding_t *b)
{
JL_LOCK(&b->globalref->mod->lock);
size_t len = 0;
if (b->backedges)
len = jl_array_len(b->backedges);
JL_UNLOCK(&b->globalref->mod->lock);
return len;
}

JL_DLLEXPORT jl_value_t *jl_binding_backedges_getindex(jl_binding_t *b, size_t i)
{
JL_LOCK(&b->globalref->mod->lock);
assert(b->backedges);
jl_value_t *ret = jl_array_ptr_ref(b->backedges, i-1);
JL_UNLOCK(&b->globalref->mod->lock);
return ret;
}

static jl_module_t *jl_new_module__(jl_sym_t *name, jl_module_t *parent)
{
jl_task_t *ct = jl_current_task;
Expand Down Expand Up @@ -527,7 +546,9 @@ jl_module_t *jl_new_module_(jl_sym_t *name, jl_module_t *parent, uint8_t default
{
jl_module_t *m = jl_new_module__(name, parent);
JL_GC_PUSH1(&m);
JL_LOCK(&world_counter_lock);
jl_add_default_names(m, default_using_core, self_name);
JL_UNLOCK(&world_counter_lock);
JL_GC_POP();
return m;
}
Expand Down Expand Up @@ -1620,16 +1641,19 @@ void jl_invalidate_binding_refs(jl_globalref_t *ref, jl_binding_partition_t *inv

JL_DLLEXPORT void jl_add_binding_backedge(jl_binding_t *b, jl_value_t *edge)
{
JL_LOCK(&b->globalref->mod->lock);
if (!b->backedges) {
b->backedges = jl_alloc_vec_any(0);
jl_gc_wb(b, b->backedges);
} else if (jl_array_len(b->backedges) > 0 &&
jl_array_ptr_ref(b->backedges, jl_array_len(b->backedges)-1) == edge) {
// Optimization: Deduplicate repeated insertion of the same edge (e.g. during
// definition of a method that contains many references to the same global)
JL_UNLOCK(&b->globalref->mod->lock);
return;
}
jl_array_ptr_1d_push(b->backedges, edge);
JL_UNLOCK(&b->globalref->mod->lock);
}

// Called for all GlobalRefs found in lowered code. Adds backedges for cross-module
Expand Down
4 changes: 4 additions & 0 deletions src/staticdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -3751,15 +3751,19 @@ static int jl_validate_binding_partition(jl_binding_t *b, jl_binding_partition_t
// We need to go through and re-validate any bindings in the same image that
// may have imported us.
if (b->backedges) {
JL_LOCK(&b->globalref->mod->lock);
for (size_t i = 0; i < jl_array_len(b->backedges); i++) {
jl_value_t *edge = jl_array_ptr_ref(b->backedges, i);
if (!jl_is_binding(edge))
continue;
jl_binding_t *bedge = (jl_binding_t*)edge;
if (!jl_atomic_load_relaxed(&bedge->partitions))
continue;
JL_UNLOCK(&b->globalref->mod->lock);
jl_validate_binding_partition(bedge, jl_atomic_load_relaxed(&bedge->partitions), mod_idx, 0, 0);
JL_LOCK(&b->globalref->mod->lock);
}
JL_UNLOCK(&b->globalref->mod->lock);
}
if (bpart->kind & PARTITION_FLAG_EXPORTED) {
jl_module_t *mod = b->globalref->mod;
Expand Down