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/aotcompile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvm
// if this method is generally visible to the current compilation world,
// and this is either the primary world, or not applicable in the primary world
// then we want to compile and emit this
if (mi->def.method->primary_world <= params.world && params.world <= mi->def.method->deleted_world) {
if (jl_atomic_load_relaxed(&mi->def.method->primary_world) <= params.world && params.world <= jl_atomic_load_relaxed(&mi->def.method->deleted_world)) {
// find and prepare the source code to compile
jl_code_instance_t *codeinst = NULL;
jl_ci_cache_lookup(*cgparams, mi, params.world, &codeinst, &src);
Expand Down
3 changes: 2 additions & 1 deletion src/clangsa/GCChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1444,7 +1444,8 @@ bool GCChecker::evalCall(const CallEvent &Call, CheckerContext &C) const {
} else if (name == "JL_GC_PUSH1" || name == "JL_GC_PUSH2" ||
name == "JL_GC_PUSH3" || name == "JL_GC_PUSH4" ||
name == "JL_GC_PUSH5" || name == "JL_GC_PUSH6" ||
name == "JL_GC_PUSH7" || name == "JL_GC_PUSH8") {
name == "JL_GC_PUSH7" || name == "JL_GC_PUSH8" ||
name == "JL_GC_PUSH9") {
ProgramStateRef State = C.getState();
// Transform slots to roots, transform values to rooted
unsigned NumArgs = CE->getNumArgs();
Expand Down
5 changes: 3 additions & 2 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9324,8 +9324,9 @@ void jl_compile_workqueue(
auto proto = it.second;
params.workqueue.pop_back();
// try to emit code for this item from the workqueue
assert(codeinst->min_world <= params.world && codeinst->max_world >= params.world &&
"invalid world for code-instance");
assert(jl_atomic_load_relaxed(&codeinst->min_world) <= params.world &&
jl_atomic_load_relaxed(&codeinst->max_world) >= params.world &&
"invalid world for code-instance");
StringRef preal_decl = "";
bool preal_specsig = false;
auto invoke = jl_atomic_load_acquire(&codeinst->invoke);
Expand Down
2 changes: 0 additions & 2 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3299,8 +3299,6 @@ static void gc_mark_roots(jl_gc_markqueue_t *mq)
gc_try_claim_and_push(mq, v, NULL);
gc_heap_snapshot_record_array_edge_index((jl_value_t*)jl_anytuple_type_type, (jl_value_t*)v, i);
}
gc_try_claim_and_push(mq, jl_all_methods, NULL);
gc_heap_snapshot_record_gc_roots((jl_value_t*)jl_all_methods, "all_methods");
gc_try_claim_and_push(mq, _jl_debug_method_invalidation, NULL);
gc_heap_snapshot_record_gc_roots((jl_value_t*)_jl_debug_method_invalidation, "debug_method_invalidation");
// constants
Expand Down
163 changes: 106 additions & 57 deletions src/gf.c

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions src/ircode.c
Original file line number Diff line number Diff line change
Expand Up @@ -976,8 +976,9 @@ JL_DLLEXPORT jl_code_info_t *jl_uncompress_ir(jl_method_t *m, jl_code_instance_t
JL_UNLOCK(&m->writelock); // Might GC
JL_GC_POP();
if (metadata) {
code->min_world = metadata->min_world;
code->max_world = metadata->max_world;
code->min_world = jl_atomic_load_relaxed(&metadata->min_world);
// n.b. this should perhaps be capped to jl_world_counter max here, since we don't have backedges on it after return
code->max_world = jl_atomic_load_relaxed(&metadata->max_world);
code->rettype = metadata->rettype;
code->parent = metadata->def;
}
Expand Down
7 changes: 5 additions & 2 deletions src/jitlayers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,11 @@ static jl_callptr_t _jl_compile_codeinst(
start_time = jl_hrtime();

assert(jl_is_code_instance(codeinst));
assert(codeinst->min_world <= world && (codeinst->max_world >= world || codeinst->max_world == 0) &&
#ifndef NDEBUG
size_t max_world = jl_atomic_load_relaxed(&codeinst->max_world);
assert(jl_atomic_load_relaxed(&codeinst->min_world) <= world && (max_world >= world || max_world == 0) &&
"invalid world for method-instance");
#endif

JL_TIMING(CODEINST_COMPILE, CODEINST_COMPILE);
#ifdef USE_TRACY
Expand Down Expand Up @@ -588,7 +591,7 @@ void jl_generate_fptr_for_unspecialized_impl(jl_code_instance_t *unspec)
if (src) {
assert(jl_is_code_info(src));
++UnspecFPtrCount;
_jl_compile_codeinst(unspec, src, unspec->min_world, *jl_ExecutionEngine->getContext(), 0);
_jl_compile_codeinst(unspec, src, jl_atomic_load_relaxed(&unspec->min_world), *jl_ExecutionEngine->getContext(), 0);
}
jl_callptr_t null = nullptr;
// if we hit a codegen bug (or ran into a broken generated function or llvmcall), fall back to the interpreter as a last resort
Expand Down
14 changes: 8 additions & 6 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -2920,8 +2920,8 @@ void jl_init_types(void) JL_GC_DISABLED
jl_bool_type),
jl_emptysvec,
0, 1, 4);
const static uint32_t typemap_entry_constfields[1] = { 0x000003fe }; // (1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)
const static uint32_t typemap_entry_atomicfields[1] = { 0x00000001 }; // (1<<0)
const static uint32_t typemap_entry_constfields[1] = { 0x000003ce }; // (1<<1)|(1<<2)|(1<<3)|(1<<6)|(1<<7)|(1<<8)|(1<<9)
const static uint32_t typemap_entry_atomicfields[1] = { 0x00000031 }; // (1<<0)|(1<<4)|(1<<5)
jl_typemap_entry_type->name->constfields = typemap_entry_constfields;
jl_typemap_entry_type->name->atomicfields = typemap_entry_atomicfields;

Expand Down Expand Up @@ -3195,8 +3195,8 @@ void jl_init_types(void) JL_GC_DISABLED
"module",
"file",
"line",
"primary_world",
"deleted_world", // !const
"primary_world", // atomic
"deleted_world", // atomic
"sig",
"specializations", // !const
"speckeyset", // !const
Expand Down Expand Up @@ -3254,8 +3254,10 @@ void jl_init_types(void) JL_GC_DISABLED
jl_uint16_type),
jl_emptysvec,
0, 1, 10);
//const static uint32_t method_constfields[1] = { 0x03fc065f }; // (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<6)|(1<<9)|(1<<10)|(1<<18)|(1<<19)|(1<<20)|(1<<21)|(1<<22)|(1<<23)|(1<<24)|(1<<25);
//const static uint32_t method_constfields[1] = { 0x03fc065f }; // (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<6)|(1<<9)|(1<<10)|(1<<18)|(1<<19)|(1<<20)|(1<<21)|(1<<22)|(1<<23)|(1<<24)|(1<<25);
//jl_method_type->name->constfields = method_constfields;
const static uint32_t method_atomicfields[1] = { 0x00000030 }; // (1<<4)|(1<<5)
jl_method_type->name->atomicfields = method_atomicfields;

jl_method_instance_type =
jl_new_datatype(jl_symbol("MethodInstance"), core,
Expand Down Expand Up @@ -3330,7 +3332,7 @@ void jl_init_types(void) JL_GC_DISABLED
0, 1, 1);
jl_svecset(jl_code_instance_type->types, 1, jl_code_instance_type);
const static uint32_t code_instance_constfields[1] = { 0b0000010101110001 }; // Set fields 1, 5-7, 9, 11 as const
const static uint32_t code_instance_atomicfields[1] = { 0b1101001010000010 }; // Set fields 2, 8, 10, 13, 15-16 as atomic
const static uint32_t code_instance_atomicfields[1] = { 0b1101001010001110 }; // Set fields 2-4, 8, 10, 13, 15-16 as atomic
//Fields 3-4 are only operated on by construction and deserialization, so are const at runtime
//Fields 11 and 15 must be protected by locks, and thus all operations on jl_code_instance_t are threadsafe
jl_code_instance_type->name->constfields = code_instance_constfields;
Expand Down
19 changes: 12 additions & 7 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,8 +321,8 @@ typedef struct _jl_method_t {
struct _jl_module_t *module;
jl_sym_t *file;
int32_t line;
size_t primary_world;
size_t deleted_world;
_Atomic(size_t) primary_world;
_Atomic(size_t) deleted_world;

// method's type signature. redundant with TypeMapEntry->specTypes
jl_value_t *sig;
Expand Down Expand Up @@ -415,8 +415,8 @@ typedef struct _jl_code_instance_t {
_Atomic(struct _jl_code_instance_t*) next; // pointer to the next cache entry

// world range for which this object is valid to use
size_t min_world;
size_t max_world;
_Atomic(size_t) min_world;
_Atomic(size_t) max_world;

// inference state cache
jl_value_t *rettype; // return type for fptr
Expand Down Expand Up @@ -625,7 +625,6 @@ typedef struct _jl_module_t {
arraylist_t usings; // modules with all bindings potentially imported
jl_uuid_t build_id;
jl_uuid_t uuid;
size_t primary_world;
_Atomic(uint32_t) counter;
int32_t nospecialize; // global bit flags: initialization for new methods
int8_t optlevel;
Expand All @@ -650,8 +649,8 @@ typedef struct _jl_typemap_entry_t {
jl_tupletype_t *sig; // the type signature for this entry
jl_tupletype_t *simplesig; // a simple signature for fast rejection
jl_svec_t *guardsigs;
size_t min_world;
size_t max_world;
_Atomic(size_t) min_world;
_Atomic(size_t) max_world;
union {
jl_value_t *value; // generic accessor
jl_method_instance_t *linfo; // [nullable] for guard entries
Expand Down Expand Up @@ -958,6 +957,7 @@ extern void JL_GC_PUSH5(void *, void *, void *, void *, void *) JL_NOTSAFEPOINT
extern void JL_GC_PUSH6(void *, void *, void *, void *, void *, void *) JL_NOTSAFEPOINT;
extern void JL_GC_PUSH7(void *, void *, void *, void *, void *, void *, void *) JL_NOTSAFEPOINT;
extern void JL_GC_PUSH8(void *, void *, void *, void *, void *, void *, void *, void *) JL_NOTSAFEPOINT;
extern void JL_GC_PUSH9(void *, void *, void *, void *, void *, void *, void *, void *, void *) JL_NOTSAFEPOINT;
extern void _JL_GC_PUSHARGS(jl_value_t **, size_t) JL_NOTSAFEPOINT;
// This is necessary, because otherwise the analyzer considers this undefined
// behavior and terminates the exploration
Expand Down Expand Up @@ -997,10 +997,15 @@ extern void JL_GC_POP() JL_NOTSAFEPOINT;
#define JL_GC_PUSH7(arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
void *__gc_stkf[] = {(void*)JL_GC_ENCODE_PUSH(7), jl_pgcstack, arg1, arg2, arg3, arg4, arg5, arg6, arg7}; \
jl_pgcstack = (jl_gcframe_t*)__gc_stkf;

#define JL_GC_PUSH8(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
void *__gc_stkf[] = {(void*)JL_GC_ENCODE_PUSH(8), jl_pgcstack, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8}; \
jl_pgcstack = (jl_gcframe_t*)__gc_stkf;

#define JL_GC_PUSH9(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \
void *__gc_stkf[] = {(void*)JL_GC_ENCODE_PUSH(9), jl_pgcstack, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9}; \
jl_pgcstack = (jl_gcframe_t*)__gc_stkf;


#define JL_GC_PUSHARGS(rts_var,n) \
rts_var = ((jl_value_t**)alloca(((n)+2)*sizeof(jl_value_t*)))+2; \
Expand Down
3 changes: 2 additions & 1 deletion src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,6 @@ extern JL_DLLEXPORT size_t jl_page_size;
extern jl_function_t *jl_typeinf_func JL_GLOBALLY_ROOTED;
extern JL_DLLEXPORT size_t jl_typeinf_world;
extern _Atomic(jl_typemap_entry_t*) call_cache[N_CALL_CACHE] JL_GLOBALLY_ROOTED;
extern jl_array_t *jl_all_methods JL_GLOBALLY_ROOTED;

JL_DLLEXPORT extern int jl_lineno;
JL_DLLEXPORT extern const char *jl_filename;
Expand Down Expand Up @@ -715,6 +714,8 @@ int jl_has_concrete_subtype(jl_value_t *typ);
jl_tupletype_t *jl_inst_arg_tuple_type(jl_value_t *arg1, jl_value_t **args, size_t nargs, int leaf);
jl_tupletype_t *jl_lookup_arg_tuple_type(jl_value_t *arg1 JL_PROPAGATES_ROOT, jl_value_t **args, size_t nargs, int leaf);
JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method, jl_tupletype_t *simpletype);
void jl_method_table_activate(jl_methtable_t *mt, jl_typemap_entry_t *newentry);
jl_typemap_entry_t *jl_method_table_add(jl_methtable_t *mt, jl_method_t *method, jl_tupletype_t *simpletype);
jl_datatype_t *jl_mk_builtin_func(jl_datatype_t *dt, const char *name, jl_fptr_args_t fptr) JL_GC_DISABLED;
int jl_obviously_unequal(jl_value_t *a, jl_value_t *b);
JL_DLLEXPORT jl_array_t *jl_find_free_typevars(jl_value_t *v);
Expand Down
20 changes: 5 additions & 15 deletions src/method.c
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,9 @@ JL_DLLEXPORT jl_code_info_t *jl_code_for_staged(jl_method_instance_t *linfo, siz

JL_TRY {
ct->ptls->in_pure_callback = 1;
ct->world_age = def->primary_world;
ct->world_age = jl_atomic_load_relaxed(&def->primary_world);
if (ct->world_age > jl_atomic_load_acquire(&jl_world_counter) || jl_atomic_load_relaxed(&def->deleted_world) < ct->world_age)
jl_error("The generator method cannot run until it is added to a method table.");

// invoke code generator
jl_tupletype_t *ttdt = (jl_tupletype_t*)jl_unwrap_unionall(tt);
Expand Down Expand Up @@ -851,8 +853,8 @@ JL_DLLEXPORT jl_method_t *jl_new_method_uninit(jl_module_t *module)
m->recursion_relation = NULL;
m->isva = 0;
m->nargs = 0;
m->primary_world = 1;
m->deleted_world = ~(size_t)0;
jl_atomic_store_relaxed(&m->primary_world, ~(size_t)0);
jl_atomic_store_relaxed(&m->deleted_world, 1);
m->is_for_opaque_closure = 0;
m->nospecializeinfer = 0;
m->constprop = 0;
Expand Down Expand Up @@ -1008,8 +1010,6 @@ JL_DLLEXPORT jl_methtable_t *jl_method_get_table(jl_method_t *method JL_PROPAGAT
return method->external_mt ? (jl_methtable_t*)method->external_mt : jl_method_table_for(method->sig);
}

jl_array_t *jl_all_methods JL_GLOBALLY_ROOTED;

JL_DLLEXPORT jl_method_t* jl_method_def(jl_svec_t *argdata,
jl_methtable_t *mt,
jl_code_info_t *f,
Expand Down Expand Up @@ -1139,16 +1139,6 @@ JL_DLLEXPORT jl_method_t* jl_method_def(jl_svec_t *argdata,
m->line = line;
jl_method_set_source(m, f);

#ifdef RECORD_METHOD_ORDER
if (jl_all_methods == NULL)
jl_all_methods = jl_alloc_vec_any(0);
#endif
if (jl_all_methods != NULL) {
while (jl_array_nrows(jl_all_methods) < m->primary_world)
jl_array_ptr_1d_push(jl_all_methods, NULL);
jl_array_ptr_1d_push(jl_all_methods, (jl_value_t*)m);
}

jl_method_table_insert(mt, m, NULL);
if (jl_newmeth_tracer)
jl_call_tracer(jl_newmeth_tracer, (jl_value_t*)m);
Expand Down
1 change: 0 additions & 1 deletion src/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ JL_DLLEXPORT jl_module_t *jl_new_module_(jl_sym_t *name, jl_module_t *parent, ui
if (!m->build_id.lo)
m->build_id.lo++; // build id 0 is invalid
m->build_id.hi = ~(uint64_t)0;
m->primary_world = 0;
jl_atomic_store_relaxed(&m->counter, 1);
m->nospecialize = 0;
m->optlevel = -1;
Expand Down
7 changes: 5 additions & 2 deletions src/opaque_closure.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,15 @@ JL_DLLEXPORT jl_opaque_closure_t *jl_new_opaque_closure_from_code_info(jl_tuplet
root = jl_new_struct(jl_linenumbernode_type, root, file);
jl_method_t *meth = jl_make_opaque_closure_method(mod, jl_nothing, nargs, root, ci, isva);
root = (jl_value_t*)meth;
meth->primary_world = jl_current_task->world_age;
size_t world = jl_current_task->world_age;
// these are only legal in the current world since they are not in any tables
jl_atomic_store_release(&meth->primary_world, world);
jl_atomic_store_release(&meth->deleted_world, world);

sigtype = jl_argtype_with_function(env, (jl_value_t*)argt);
jl_method_instance_t *mi = jl_specializations_get_linfo((jl_method_t*)root, sigtype, jl_emptysvec);
inst = jl_new_codeinst(mi, rt_ub, (jl_value_t*)jl_any_type, NULL, (jl_value_t*)ci,
0, meth->primary_world, -1, 0, 0, jl_nothing, 0);
0, world, world, 0, 0, jl_nothing, 0);
jl_mi_cache_insert(mi, inst);

jl_opaque_closure_t *oc = new_opaque_closure(argt, rt_lb, rt_ub, root, env, do_compile);
Expand Down
5 changes: 0 additions & 5 deletions src/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,6 @@
// delete julia IR for non-inlineable functions after they're codegen'd
#define JL_DELETE_NON_INLINEABLE 1

// fill in the jl_all_methods in world-counter order
// so that it is possible to map (in a debugger) from
// an inferred world validity range back to the offending definition
// #define RECORD_METHOD_ORDER

// GC options -----------------------------------------------------------------

// debugging options
Expand Down
Loading