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
2 changes: 1 addition & 1 deletion src/datatype.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ JL_DLLEXPORT jl_methtable_t *jl_new_method_table(jl_sym_t *name, jl_module_t *mo
mt->cache = mc;
mt->name = name;
mt->module = module;
mt->backedges = (jl_genericmemory_t*)jl_an_empty_memory_any;
JL_GC_POP();
return mt;
}
Expand All @@ -88,7 +89,6 @@ JL_DLLEXPORT jl_typename_t *jl_new_typename_in(jl_sym_t *name, jl_module_t *modu
tn->partial = NULL;
tn->atomicfields = NULL;
tn->constfields = NULL;
tn->backedges = NULL;
tn->max_methods = 0;
jl_atomic_store_relaxed(&tn->max_args, 0);
jl_atomic_store_relaxed(&tn->cache_entry_count, 0);
Expand Down
331 changes: 206 additions & 125 deletions src/gf.c

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -3004,23 +3004,22 @@ void jl_init_types(void) JL_GC_DISABLED
jl_typename_type->name->wrapper = (jl_value_t*)jl_typename_type;
jl_typename_type->super = jl_any_type;
jl_typename_type->parameters = jl_emptysvec;
jl_typename_type->name->n_uninitialized = 19 - 2;
jl_typename_type->name->names = jl_perm_symsvec(19, "name", "module", "singletonname",
jl_typename_type->name->n_uninitialized = 18 - 2;
jl_typename_type->name->names = jl_perm_symsvec(18, "name", "module", "singletonname",
"names", "atomicfields", "constfields",
"wrapper", "Typeofwrapper", "cache", "linearcache",
"backedges", "partial",
"hash", "max_args", "n_uninitialized",
"partial", "hash", "max_args", "n_uninitialized",
"flags", // "abstract", "mutable", "mayinlinealloc",
"cache_entry_count", "max_methods", "constprop_heuristic");
const static uint32_t typename_constfields[1] = { 0b0001101000001001011 }; // TODO: put back atomicfields and constfields in this list
const static uint32_t typename_atomicfields[1] = { 0b0010010001110000000 };
const static uint32_t typename_constfields[1] = { 0b000110100001001011 }; // TODO: put back atomicfields and constfields in this list
const static uint32_t typename_atomicfields[1] = { 0b001001001110000000 };
jl_typename_type->name->constfields = typename_constfields;
jl_typename_type->name->atomicfields = typename_atomicfields;
jl_precompute_memoized_dt(jl_typename_type, 1);
jl_typename_type->types = jl_svec(19, jl_symbol_type, jl_any_type /*jl_module_type*/, jl_symbol_type,
jl_typename_type->types = jl_svec(18, jl_symbol_type, jl_any_type /*jl_module_type*/, jl_symbol_type,
jl_simplevector_type,
jl_any_type/*jl_voidpointer_type*/, jl_any_type/*jl_voidpointer_type*/,
jl_type_type, jl_type_type, jl_simplevector_type, jl_simplevector_type,
jl_type_type, jl_simplevector_type, jl_simplevector_type,
jl_methcache_type, jl_any_type,
jl_any_type /*jl_long_type*/,
jl_any_type /*jl_int32_type*/,
Expand All @@ -3046,13 +3045,13 @@ void jl_init_types(void) JL_GC_DISABLED
jl_methtable_type->super = jl_any_type;
jl_methtable_type->parameters = jl_emptysvec;
jl_methtable_type->name->n_uninitialized = 0;
jl_methtable_type->name->names = jl_perm_symsvec(4, "defs", "cache", "name", "module");
const static uint32_t methtable_constfields[1] = { 0b1110 };
const static uint32_t methtable_atomicfields[1] = { 0b0001 };
jl_methtable_type->name->names = jl_perm_symsvec(5, "defs", "cache", "name", "module", "backedges");
const static uint32_t methtable_constfields[1] = { 0b01110 };
const static uint32_t methtable_atomicfields[1] = { 0b00001 };
jl_methtable_type->name->constfields = methtable_constfields;
jl_methtable_type->name->atomicfields = methtable_atomicfields;
jl_precompute_memoized_dt(jl_methtable_type, 1);
jl_methtable_type->types = jl_svec(4, jl_any_type, jl_methcache_type, jl_symbol_type, jl_any_type /*jl_module_type*/);
jl_methtable_type->types = jl_svec(5, jl_any_type, jl_methcache_type, jl_symbol_type, jl_any_type /*jl_module_type*/, jl_any_type);

jl_symbol_type->name = jl_new_typename_in(jl_symbol("Symbol"), core, 0, 1);
jl_symbol_type->name->wrapper = (jl_value_t*)jl_symbol_type;
Expand Down Expand Up @@ -3378,6 +3377,7 @@ void jl_init_types(void) JL_GC_DISABLED
core = jl_core_module;
jl_method_table->module = core;
jl_atomic_store_relaxed(&jl_method_table->cache->leafcache, (jl_genericmemory_t*)jl_an_empty_memory_any);
jl_method_table->backedges = (jl_genericmemory_t*)jl_an_empty_memory_any;
jl_atomic_store_relaxed(&core->bindingkeyset, (jl_genericmemory_t*)jl_an_empty_memory_any);
// export own name, so "using Foo" makes "Foo" itself visible
jl_set_initial_const(core, core->name, (jl_value_t*)core, 1);
Expand Down Expand Up @@ -3842,13 +3842,13 @@ void jl_init_types(void) JL_GC_DISABLED
jl_svecset(jl_typename_type->types, 5, jl_voidpointer_type);
jl_svecset(jl_typename_type->types, 6, jl_type_type);
jl_svecset(jl_typename_type->types, 7, jl_type_type);
jl_svecset(jl_typename_type->types, 12, jl_long_type);
jl_svecset(jl_typename_type->types, 11, jl_long_type);
jl_svecset(jl_typename_type->types, 12, jl_int32_type);
jl_svecset(jl_typename_type->types, 13, jl_int32_type);
jl_svecset(jl_typename_type->types, 14, jl_int32_type);
jl_svecset(jl_typename_type->types, 14, jl_uint8_type);
jl_svecset(jl_typename_type->types, 15, jl_uint8_type);
jl_svecset(jl_typename_type->types, 16, jl_uint8_type);
jl_svecset(jl_typename_type->types, 17, jl_uint8_type);
jl_svecset(jl_typename_type->types, 18, jl_uint8_type);
jl_svecset(jl_methcache_type->types, 2, jl_long_type); // voidpointer
jl_svecset(jl_methcache_type->types, 3, jl_long_type); // uint32_t plus alignment
jl_svecset(jl_methtable_type->types, 3, jl_module_type);
Expand Down
2 changes: 1 addition & 1 deletion src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,6 @@ typedef struct {
_Atomic(jl_value_t*) Typeofwrapper; // cache for Type{wrapper}
_Atomic(jl_svec_t*) cache; // sorted array
_Atomic(jl_svec_t*) linearcache; // unsorted array
jl_array_t *backedges; // uncovered (sig => caller::CodeInstance) pairs with this type as the function
jl_array_t *partial; // incomplete instantiations of this type
intptr_t hash;
_Atomic(int32_t) max_args; // max # of non-vararg arguments in a signature with this type as the function
Expand Down Expand Up @@ -882,6 +881,7 @@ typedef struct _jl_methtable_t {
jl_methcache_t *cache;
jl_sym_t *name; // sometimes used for debug printing
jl_module_t *module; // sometimes used for debug printing
jl_genericmemory_t *backedges; // IdDict{top typenames, Vector{uncovered (sig => caller::CodeInstance)}}
} jl_methtable_t;

typedef struct {
Expand Down
2 changes: 0 additions & 2 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,6 @@ jl_expr_t *jl_exprn(jl_sym_t *head, size_t n);
jl_function_t *jl_new_generic_function(jl_sym_t *name, jl_module_t *module, size_t new_world);
jl_function_t *jl_new_generic_function_with_supertype(jl_sym_t *name, jl_module_t *module, jl_datatype_t *st, size_t new_world);
int jl_foreach_reachable_mtable(int (*visit)(jl_methtable_t *mt, void *env), jl_array_t *mod_array, void *env);
int foreach_mtable_in_module(jl_module_t *m, int (*visit)(jl_methtable_t *mt, void *env), void *env);
void jl_init_main_module(void);
JL_DLLEXPORT int jl_is_submodule(jl_module_t *child, jl_module_t *parent) JL_NOTSAFEPOINT;
jl_array_t *jl_get_loaded_modules(void);
Expand Down Expand Up @@ -939,7 +938,6 @@ JL_DLLEXPORT jl_methtable_t *jl_method_get_table(
jl_method_t *method JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT;
JL_DLLEXPORT jl_methcache_t *jl_method_get_cache(
jl_method_t *method JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT;
void jl_foreach_top_typename_for(void (*f)(jl_typename_t*, void*), jl_value_t *argtypes JL_PROPAGATES_ROOT, void *env);

JL_DLLEXPORT int jl_pointer_egal(jl_value_t *t);
JL_DLLEXPORT jl_value_t *jl_nth_slot_type(jl_value_t *sig JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT;
Expand Down
38 changes: 0 additions & 38 deletions src/method.c
Original file line number Diff line number Diff line change
Expand Up @@ -1154,39 +1154,6 @@ JL_DLLEXPORT jl_value_t *jl_declare_const_gf(jl_module_t *mod, jl_sym_t *name)
return gf;
}

static void foreach_top_nth_typename(void (*f)(jl_typename_t*, void*), jl_value_t *a JL_PROPAGATES_ROOT, int n, void *env)
{
if (jl_is_datatype(a)) {
if (n == 0) {
jl_datatype_t *dt = ((jl_datatype_t*)a);
jl_typename_t *tn = NULL;
while (1) {
if (dt != jl_any_type && dt != jl_function_type)
tn = dt->name;
if (dt->super == dt)
break;
dt = dt->super;
}
if (tn)
f(tn, env);
}
else if (jl_is_tuple_type(a)) {
if (jl_nparams(a) >= n)
foreach_top_nth_typename(f, jl_tparam(a, n - 1), 0, env);
}
}
else if (jl_is_typevar(a)) {
foreach_top_nth_typename(f, ((jl_tvar_t*)a)->ub, n, env);
}
else if (jl_is_unionall(a)) {
foreach_top_nth_typename(f, ((jl_unionall_t*)a)->body, n, env);
}
else if (jl_is_uniontype(a)) {
jl_uniontype_t *u = (jl_uniontype_t*)a;
foreach_top_nth_typename(f, u->a, n, env);
foreach_top_nth_typename(f, u->b, n, env);
}
}

// get the MethodTable for dispatch, or `nothing` if cannot be determined
JL_DLLEXPORT jl_methtable_t *jl_method_table_for(jl_value_t *argtypes JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT
Expand All @@ -1200,11 +1167,6 @@ JL_DLLEXPORT jl_methcache_t *jl_method_cache_for(jl_value_t *argtypes JL_PROPAGA
return jl_method_table->cache;
}

void jl_foreach_top_typename_for(void (*f)(jl_typename_t*, void*), jl_value_t *argtypes JL_PROPAGATES_ROOT, void *env)
{
foreach_top_nth_typename(f, argtypes, 1, env);
}

jl_methcache_t *jl_kwmethod_cache_for(jl_value_t *argtypes JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT
{
return jl_method_table->cache;
Expand Down
44 changes: 32 additions & 12 deletions src/staticdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -867,20 +867,30 @@ static void jl_insert_into_serialization_queue(jl_serializer_state *s, jl_value_
assert(!jl_object_in_image((jl_value_t*)tn->module));
assert(!jl_object_in_image((jl_value_t*)tn->wrapper));
}
}
if (jl_is_mtable(v)) {
jl_methtable_t *mt = (jl_methtable_t*)v;
// Any back-edges will be re-validated and added by staticdata.jl, so
// drop them from the image here
if (s->incremental || jl_options.trim || jl_options.strip_ir) {
record_field_change((jl_value_t**)&tn->backedges, NULL);
record_field_change((jl_value_t**)&mt->backedges, jl_an_empty_memory_any);
}
else {
// don't recurse into all backedges memory (yet)
jl_value_t *backedges = get_replaceable_field((jl_value_t**)&tn->backedges, 1);
if (backedges) {
jl_queue_for_serialization_(s, (jl_value_t*)((jl_array_t*)backedges)->ref.mem, 0, 1);
for (size_t i = 0, n = jl_array_nrows(backedges); i < n; i += 2) {
jl_value_t *t = jl_array_ptr_ref(backedges, i);
assert(!jl_is_code_instance(t));
jl_queue_for_serialization(s, t);
jl_value_t *allbackedges = get_replaceable_field((jl_value_t**)&mt->backedges, 1);
jl_queue_for_serialization_(s, allbackedges, 0, 1);
for (size_t i = 0, n = ((jl_genericmemory_t*)allbackedges)->length; i < n; i += 2) {
jl_value_t *tn = jl_genericmemory_ptr_ref(allbackedges, i);
jl_queue_for_serialization(s, tn);
jl_value_t *backedges = jl_genericmemory_ptr_ref(allbackedges, i + 1);
if (backedges && backedges != jl_nothing) {
jl_queue_for_serialization_(s, (jl_value_t*)((jl_array_t*)backedges)->ref.mem, 0, 1);
jl_queue_for_serialization(s, backedges);
for (size_t i = 0, n = jl_array_nrows(backedges); i < n; i += 2) {
jl_value_t *t = jl_array_ptr_ref(backedges, i);
assert(!jl_is_code_instance(t));
jl_queue_for_serialization(s, t);
}
}
}
}
Expand Down Expand Up @@ -2573,8 +2583,6 @@ static void jl_prune_mi_backedges(jl_array_t *backedges)

static void jl_prune_tn_backedges(jl_array_t *backedges)
{
if (backedges == NULL)
return;
size_t i = 0, ins = 0, n = jl_array_nrows(backedges);
for (i = 1; i < n; i += 2) {
jl_value_t *ci = jl_array_ptr_ref(backedges, i);
Expand All @@ -2586,6 +2594,15 @@ static void jl_prune_tn_backedges(jl_array_t *backedges)
jl_array_del_end(backedges, n - ins);
}

static void jl_prune_mt_backedges(jl_genericmemory_t *allbackedges)
{
for (size_t i = 0, n = allbackedges->length; i < n; i += 2) {
jl_value_t *tn = jl_genericmemory_ptr_ref(allbackedges, i);
jl_value_t *backedges = jl_genericmemory_ptr_ref(allbackedges, i + 1);
if (tn && tn != jl_nothing && backedges)
jl_prune_tn_backedges((jl_array_t*)backedges);
}
}

static void jl_prune_binding_backedges(jl_array_t *backedges)
{
Expand Down Expand Up @@ -3240,8 +3257,6 @@ static void jl_save_system_image_to_stream(ios_t *f, jl_array_t *mod_array,
jl_prune_type_cache_hash(jl_atomic_load_relaxed(&tn->cache)));
jl_gc_wb(tn, jl_atomic_load_relaxed(&tn->cache));
jl_prune_type_cache_linear(jl_atomic_load_relaxed(&tn->linearcache));
jl_value_t *backedges = get_replaceable_field((jl_value_t**)&tn->backedges, 1);
jl_prune_tn_backedges((jl_array_t*)backedges);
}
else if (jl_is_method_instance(v)) {
jl_method_instance_t *mi = (jl_method_instance_t*)v;
Expand All @@ -3253,6 +3268,11 @@ static void jl_save_system_image_to_stream(ios_t *f, jl_array_t *mod_array,
jl_value_t *backedges = get_replaceable_field((jl_value_t**)&b->backedges, 1);
jl_prune_binding_backedges((jl_array_t*)backedges);
}
else if (jl_is_mtable(v)) {
jl_methtable_t *mt = (jl_methtable_t*)v;
jl_value_t *backedges = get_replaceable_field((jl_value_t**)&mt->backedges, 1);
jl_prune_mt_backedges((jl_genericmemory_t*)backedges);
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions test/misc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1632,10 +1632,10 @@ end
let errs = IOBuffer()
run(`$(Base.julia_cmd()) -e '
using Test
@test isdefined(Type.body.name, :backedges)
@test !isempty(Core.GlobalMethods.backedges)
Base.Experimental.disable_new_worlds()
@test_throws "disable_new_worlds" @eval f() = 1
@test !isdefined(Type.body.name, :backedges)
@test isempty(Core.GlobalMethods.backedges)
@test_throws "disable_new_worlds" Base.delete_method(which(+, (Int, Int)))
@test 1+1 == 2
using Dates
Expand Down