diff --git a/base/runtime_internals.jl b/base/runtime_internals.jl index 4471638f49ba1c..0765960c97ab35 100644 --- a/base/runtime_internals.jl +++ b/base/runtime_internals.jl @@ -976,7 +976,7 @@ function morespecific!(m::Method) # check that all Methods in this table are morespecific than m # so we might avoid disabling a table that might get used for more than just subsets of m all(m2 -> m === m2 || morespecific(m2, m), MethodList(mt)) || error("unsupported Method to disable") - setfield!(mt, nfields(mt), 0x1) + setfield!(mt, :frozen, 0x1, :monotonic) end """ diff --git a/src/datatype.c b/src/datatype.c index c78b00fdd22456..44dedce8a3c02d 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -54,7 +54,7 @@ JL_DLLEXPORT jl_methtable_t *jl_new_method_table(jl_sym_t *name, jl_module_t *mo mt->backedges = NULL; JL_MUTEX_INIT(&mt->writelock, "methodtable->writelock"); mt->offs = 0; - mt->frozen = 0; + jl_atomic_store_relaxed(&mt->frozen, 0); return mt; } diff --git a/src/gf.c b/src/gf.c index abdda56730580a..fcf25fb40dd392 100644 --- a/src/gf.c +++ b/src/gf.c @@ -331,7 +331,7 @@ jl_datatype_t *jl_mk_builtin_func(jl_datatype_t *dt, const char *name, jl_fptr_a (jl_value_t*)mi, 1, ~(size_t)0); jl_typemap_insert(&mt->cache, (jl_value_t*)mt, newentry, 0); - mt->frozen = 1; + jl_atomic_store_relaxed(&mt->frozen, 1); JL_GC_POP(); return dt; } @@ -772,7 +772,7 @@ static int reset_mt_caches(jl_methtable_t *mt, void *env) { // removes all method caches // this might not be entirely safe (GC or MT), thus we only do it very early in bootstrapping - if (!mt->frozen) { // make sure not to reset frozen functions + if (!jl_atomic_load_relaxed(&mt->frozen)) { // make sure not to reset frozen functions jl_atomic_store_release(&mt->leafcache, (jl_genericmemory_t*)jl_an_empty_memory_any); jl_atomic_store_release(&mt->cache, jl_nothing); } diff --git a/src/jltypes.c b/src/jltypes.c index 11f1d11a14edc4..8b6e50dffdb8e2 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -3038,9 +3038,9 @@ void jl_init_types(void) JL_GC_DISABLED jl_methtable_type->name->names = jl_perm_symsvec(11, "name", "defs", "leafcache", "cache", "max_args", "module", "backedges", - "", "", "offs", ""); + "", "", "offs", "frozen"); const static uint32_t methtable_constfields[1] = { 0x00000020 }; // (1<<5); - const static uint32_t methtable_atomicfields[1] = { 0x0000001e }; // (1<<1)|(1<<2)|(1<<3)|(1<<4); + const static uint32_t methtable_atomicfields[1] = { 0x00000041e }; // (1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<10); jl_methtable_type->name->constfields = methtable_constfields; jl_methtable_type->name->atomicfields = methtable_atomicfields; jl_precompute_memoized_dt(jl_methtable_type, 1); diff --git a/src/julia.h b/src/julia.h index 7bb5f31eda7088..837724cc5253d2 100644 --- a/src/julia.h +++ b/src/julia.h @@ -791,7 +791,7 @@ typedef struct _jl_methtable_t { jl_array_t *backedges; // (sig, caller::MethodInstance) pairs jl_mutex_t writelock; uint8_t offs; // 0, or 1 to skip splitting typemap on first (function) argument - uint8_t frozen; // whether this accepts adding new methods + _Atomic(uint8_t) frozen; // whether this accepts adding new methods } jl_methtable_t; typedef struct { diff --git a/src/staticdata.c b/src/staticdata.c index af4527cbc143f3..a432dd0ad3cdee 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -975,7 +975,7 @@ static void jl_insert_into_serialization_queue(jl_serializer_state *s, jl_value_ } else if (jl_typetagis(v, jl_typename_type)) { jl_typename_t *tn = (jl_typename_t*)v; - if (tn->mt != NULL && !tn->mt->frozen) { + if (tn->mt != NULL && !jl_atomic_load_relaxed(&tn->mt->frozen)) { jl_methtable_t * new_methtable = (jl_methtable_t *)ptrhash_get(&new_methtables, tn->mt); if (new_methtable != HT_NOTFOUND) record_field_change((jl_value_t **)&tn->mt, (jl_value_t*)new_methtable);