Skip to content

Commit

Permalink
Increase thread safety/constify various globals
Browse files Browse the repository at this point in the history
  • Loading branch information
pchintalapudi authored and DilumAluthge committed Mar 28, 2022
1 parent 89a613b commit 9333986
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 116 deletions.
1 change: 1 addition & 0 deletions doc/src/devdocs/locks.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ The following are definitely leaf locks (level 1), and must not try to acquire a
> * gc_perm_lock
> * flisp
> * jl_in_stackwalk (Win32)
> * PM_mutex[i]
>
> > flisp itself is already threadsafe, this lock only protects the `jl_ast_context_list_t` pool
Expand Down
10 changes: 5 additions & 5 deletions src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ static bool runtime_sym_gvs(jl_codegen_params_t &emission_context, LLVMContext &
else {
std::string name = "ccalllib_";
name += llvm::sys::path::filename(f_lib);
name += std::to_string(globalUnique++);
name += std::to_string(globalUniqueGeneratedNames++);
runtime_lib = true;
auto &libgv = emission_context.libMapGV[f_lib];
if (libgv.first == NULL) {
Expand All @@ -60,7 +60,7 @@ static bool runtime_sym_gvs(jl_codegen_params_t &emission_context, LLVMContext &
std::string name = "ccall_";
name += f_name;
name += "_";
name += std::to_string(globalUnique++);
name += std::to_string(globalUniqueGeneratedNames++);
auto T_pvoidfunc = JuliaType::get_pvoidfunc_ty(M->getContext());
llvmgv = new GlobalVariable(*M, T_pvoidfunc, false,
GlobalVariable::ExternalLinkage,
Expand Down Expand Up @@ -169,7 +169,7 @@ static Value *runtime_sym_lookup(
std::string gvname = "libname_";
gvname += f_name;
gvname += "_";
gvname += std::to_string(globalUnique++);
gvname += std::to_string(globalUniqueGeneratedNames++);
llvmgv = new GlobalVariable(*jl_Module, T_pvoidfunc, false,
GlobalVariable::ExternalLinkage,
Constant::getNullValue(T_pvoidfunc), gvname);
Expand All @@ -196,7 +196,7 @@ static GlobalVariable *emit_plt_thunk(
libptrgv = prepare_global_in(M, libptrgv);
llvmgv = prepare_global_in(M, llvmgv);
std::string fname;
raw_string_ostream(fname) << "jlplt_" << f_name << "_" << globalUnique++;
raw_string_ostream(fname) << "jlplt_" << f_name << "_" << globalUniqueGeneratedNames++;
Function *plt = Function::Create(functype,
GlobalVariable::ExternalLinkage,
fname, M);
Expand Down Expand Up @@ -799,7 +799,7 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar
// Make sure to find a unique name
std::string ir_name;
while (true) {
raw_string_ostream(ir_name) << (ctx.f->getName().str()) << "u" << globalUnique++;
raw_string_ostream(ir_name) << (ctx.f->getName().str()) << "u" << globalUniqueGeneratedNames++;
if (jl_Module->getFunction(ir_name) == NULL)
break;
}
Expand Down
110 changes: 53 additions & 57 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1058,11 +1058,47 @@ static const auto pointer_from_objref_func = new JuliaFunction{
};

static const auto jltuple_func = new JuliaFunction{XSTR(jl_f_tuple), get_func_sig, get_func_attrs};
static std::map<jl_fptr_args_t, JuliaFunction*> builtin_func_map;
static const auto &builtin_func_map() {
static std::map<jl_fptr_args_t, JuliaFunction*> builtins = { { jl_f_is_addr, new JuliaFunction{XSTR(jl_f_is), get_func_sig, get_func_attrs} },
{ jl_f_typeof_addr, new JuliaFunction{XSTR(jl_f_typeof), get_func_sig, get_func_attrs} },
{ jl_f_sizeof_addr, new JuliaFunction{XSTR(jl_f_sizeof), get_func_sig, get_func_attrs} },
{ jl_f_issubtype_addr, new JuliaFunction{XSTR(jl_f_issubtype), get_func_sig, get_func_attrs} },
{ jl_f_isa_addr, new JuliaFunction{XSTR(jl_f_isa), get_func_sig, get_func_attrs} },
{ jl_f_typeassert_addr, new JuliaFunction{XSTR(jl_f_typeassert), get_func_sig, get_func_attrs} },
{ jl_f_ifelse_addr, new JuliaFunction{XSTR(jl_f_ifelse), get_func_sig, get_func_attrs} },
{ jl_f__apply_iterate_addr, new JuliaFunction{XSTR(jl_f__apply_iterate), get_func_sig, get_func_attrs} },
{ jl_f__apply_pure_addr, new JuliaFunction{XSTR(jl_f__apply_pure), get_func_sig, get_func_attrs} },
{ jl_f__call_latest_addr, new JuliaFunction{XSTR(jl_f__call_latest), get_func_sig, get_func_attrs} },
{ jl_f__call_in_world_addr, new JuliaFunction{XSTR(jl_f__call_in_world), get_func_sig, get_func_attrs} },
{ jl_f__call_in_world_total_addr, new JuliaFunction{XSTR(jl_f__call_in_world_total), get_func_sig, get_func_attrs} },
{ jl_f_throw_addr, new JuliaFunction{XSTR(jl_f_throw), get_func_sig, get_func_attrs} },
{ jl_f_tuple_addr, jltuple_func },
{ jl_f_svec_addr, new JuliaFunction{XSTR(jl_f_svec), get_func_sig, get_func_attrs} },
{ jl_f_applicable_addr, new JuliaFunction{XSTR(jl_f_applicable), get_func_sig, get_func_attrs} },
{ jl_f_invoke_addr, new JuliaFunction{XSTR(jl_f_invoke), get_func_sig, get_func_attrs} },
{ jl_f_invoke_kwsorter_addr, new JuliaFunction{XSTR(jl_f_invoke_kwsorter), get_func_sig, get_func_attrs} },
{ jl_f_isdefined_addr, new JuliaFunction{XSTR(jl_f_isdefined), get_func_sig, get_func_attrs} },
{ jl_f_getfield_addr, new JuliaFunction{XSTR(jl_f_getfield), get_func_sig, get_func_attrs} },
{ jl_f_setfield_addr, new JuliaFunction{XSTR(jl_f_setfield), get_func_sig, get_func_attrs} },
{ jl_f_swapfield_addr, new JuliaFunction{XSTR(jl_f_swapfield), get_func_sig, get_func_attrs} },
{ jl_f_modifyfield_addr, new JuliaFunction{XSTR(jl_f_modifyfield), get_func_sig, get_func_attrs} },
{ jl_f_fieldtype_addr, new JuliaFunction{XSTR(jl_f_fieldtype), get_func_sig, get_func_attrs} },
{ jl_f_nfields_addr, new JuliaFunction{XSTR(jl_f_nfields), get_func_sig, get_func_attrs} },
{ jl_f__expr_addr, new JuliaFunction{XSTR(jl_f__expr), get_func_sig, get_func_attrs} },
{ jl_f__typevar_addr, new JuliaFunction{XSTR(jl_f__typevar), get_func_sig, get_func_attrs} },
{ jl_f_arrayref_addr, new JuliaFunction{XSTR(jl_f_arrayref), get_func_sig, get_func_attrs} },
{ jl_f_const_arrayref_addr, new JuliaFunction{XSTR(jl_f_const_arrayref), get_func_sig, get_func_attrs} },
{ jl_f_arrayset_addr, new JuliaFunction{XSTR(jl_f_arrayset), get_func_sig, get_func_attrs} },
{ jl_f_arraysize_addr, new JuliaFunction{XSTR(jl_f_arraysize), get_func_sig, get_func_attrs} },
{ jl_f_apply_type_addr, new JuliaFunction{XSTR(jl_f_apply_type), get_func_sig, get_func_attrs} },
{ jl_f_donotdelete_addr, new JuliaFunction{XSTR(jl_f_donotdelete), get_func_sig, get_donotdelete_func_attrs} }
};
return builtins;
}

static const auto jl_new_opaque_closure_jlcall_func = new JuliaFunction{XSTR(jl_new_opaque_closure_jlcall), get_func_sig, get_func_attrs};

static int globalUnique = 0;
static std::atomic<int> globalUniqueGeneratedNames{0};

// --- code generation ---
extern "C" {
Expand Down Expand Up @@ -3512,8 +3548,8 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
// For now we emit this as a vararg call to the builtin
// (which doesn't look at the arguments). In the future,
// this should be an LLVM builtin.
auto it = builtin_func_map.find(jl_f_donotdelete_addr);
if (it == builtin_func_map.end()) {
auto it = builtin_func_map().find(jl_f_donotdelete_addr);
if (it == builtin_func_map().end()) {
return false;
}

Expand Down Expand Up @@ -3768,7 +3804,7 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, const
}
}
if (need_to_emit) {
raw_string_ostream(name) << (specsig ? "j_" : "j1_") << name_from_method_instance(mi) << "_" << globalUnique++;
raw_string_ostream(name) << (specsig ? "j_" : "j1_") << name_from_method_instance(mi) << "_" << globalUniqueGeneratedNames++;
protoname = StringRef(name);
}
jl_returninfo_t::CallingConv cc = jl_returninfo_t::CallingConv::Boxed;
Expand Down Expand Up @@ -3813,8 +3849,8 @@ static jl_cgval_t emit_invoke_modify(jl_codectx_t &ctx, jl_expr_t *ex, jl_value_
if (f.constant && f.constant == jl_builtin_modifyfield) {
if (emit_f_opfield(ctx, &ret, jl_builtin_modifyfield, argv, nargs - 1, &lival))
return ret;
auto it = builtin_func_map.find(jl_f_modifyfield_addr);
assert(it != builtin_func_map.end());
auto it = builtin_func_map().find(jl_f_modifyfield_addr);
assert(it != builtin_func_map().end());
Value *oldnew = emit_jlcall(ctx, it->second, Constant::getNullValue(ctx.types().T_prjlvalue), &argv[1], nargs - 1, JLCALL_F_CC);
return mark_julia_type(ctx, oldnew, true, rt);
}
Expand Down Expand Up @@ -3867,8 +3903,8 @@ static jl_cgval_t emit_call(jl_codectx_t &ctx, jl_expr_t *ex, jl_value_t *rt)
}

// special case for known builtin not handled by emit_builtin_call
auto it = builtin_func_map.find(jl_get_builtin_fptr(f.constant));
if (it != builtin_func_map.end()) {
auto it = builtin_func_map().find(jl_get_builtin_fptr(f.constant));
if (it != builtin_func_map().end()) {
Value *ret = emit_jlcall(ctx, it->second, Constant::getNullValue(ctx.types().T_prjlvalue), &argv[1], nargs - 1, JLCALL_F_CC);
return mark_julia_type(ctx, ret, true, rt);
}
Expand Down Expand Up @@ -5136,7 +5172,7 @@ static Function *emit_tojlinvoke(jl_code_instance_t *codeinst, Module *M, jl_cod
{
jl_codectx_t ctx(M->getContext(), params);
std::string name;
raw_string_ostream(name) << "tojlinvoke" << globalUnique++;
raw_string_ostream(name) << "tojlinvoke" << globalUniqueGeneratedNames++;
Function *f = Function::Create(ctx.types().T_jlfunc,
GlobalVariable::InternalLinkage,
name, M);
Expand Down Expand Up @@ -5331,7 +5367,7 @@ static Function* gen_cfun_wrapper(
}

std::string funcName;
raw_string_ostream(funcName) << "jlcapi_" << name << "_" << globalUnique++;
raw_string_ostream(funcName) << "jlcapi_" << name << "_" << globalUniqueGeneratedNames++;

Module *M = into;
AttributeList attributes = sig.attributes;
Expand Down Expand Up @@ -6491,7 +6527,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
if (unadorned_name[0] == '@')
unadorned_name++;
#endif
funcName << unadorned_name << "_" << globalUnique++;
funcName << unadorned_name << "_" << globalUniqueGeneratedNames++;
declarations.specFunctionObject = funcName.str();

// allocate Function declarations and wrapper objects
Expand Down Expand Up @@ -6532,7 +6568,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
}();

std::string wrapName;
raw_string_ostream(wrapName) << "jfptr_" << unadorned_name << "_" << globalUnique++;
raw_string_ostream(wrapName) << "jfptr_" << unadorned_name << "_" << globalUniqueGeneratedNames++;
declarations.functionObject = wrapName;
(void)gen_invoke_wrapper(lam, jlrettype, returninfo, retarg, declarations.functionObject, M, ctx.emission_context);
}
Expand Down Expand Up @@ -8094,7 +8130,7 @@ static void init_jit_functions(void)
add_named_global(jldeclareconst_func, &jl_declare_constant);
add_named_global(jlgetbindingorerror_func, &jl_get_binding_or_error);
add_named_global(jlboundp_func, &jl_boundp);
for (auto it : builtin_func_map)
for (auto it : builtin_func_map())
add_named_global(it.second, it.first);
add_named_global(jlapplygeneric_func, &jl_apply_generic);
add_named_global(jlinvoke_func, &jl_invoke);
Expand Down Expand Up @@ -8158,8 +8194,6 @@ static void init_jit_functions(void)
#undef BOX_F
}

char jl_using_gdb_jitevents = 0;

#ifdef JL_USE_INTEL_JITEVENTS
char jl_using_intel_jitevents; // Non-zero if running under Intel VTune Amplifier
#endif
Expand All @@ -8176,42 +8210,6 @@ void jl_init_debuginfo(void);

extern "C" void jl_init_llvm(void)
{
builtin_func_map =
{ { jl_f_is_addr, new JuliaFunction{XSTR(jl_f_is), get_func_sig, get_func_attrs} },
{ jl_f_typeof_addr, new JuliaFunction{XSTR(jl_f_typeof), get_func_sig, get_func_attrs} },
{ jl_f_sizeof_addr, new JuliaFunction{XSTR(jl_f_sizeof), get_func_sig, get_func_attrs} },
{ jl_f_issubtype_addr, new JuliaFunction{XSTR(jl_f_issubtype), get_func_sig, get_func_attrs} },
{ jl_f_isa_addr, new JuliaFunction{XSTR(jl_f_isa), get_func_sig, get_func_attrs} },
{ jl_f_typeassert_addr, new JuliaFunction{XSTR(jl_f_typeassert), get_func_sig, get_func_attrs} },
{ jl_f_ifelse_addr, new JuliaFunction{XSTR(jl_f_ifelse), get_func_sig, get_func_attrs} },
{ jl_f__apply_iterate_addr, new JuliaFunction{XSTR(jl_f__apply_iterate), get_func_sig, get_func_attrs} },
{ jl_f__apply_pure_addr, new JuliaFunction{XSTR(jl_f__apply_pure), get_func_sig, get_func_attrs} },
{ jl_f__call_latest_addr, new JuliaFunction{XSTR(jl_f__call_latest), get_func_sig, get_func_attrs} },
{ jl_f__call_in_world_addr, new JuliaFunction{XSTR(jl_f__call_in_world), get_func_sig, get_func_attrs} },
{ jl_f__call_in_world_total_addr, new JuliaFunction{XSTR(jl_f__call_in_world_total), get_func_sig, get_func_attrs} },
{ jl_f_throw_addr, new JuliaFunction{XSTR(jl_f_throw), get_func_sig, get_func_attrs} },
{ jl_f_tuple_addr, jltuple_func },
{ jl_f_svec_addr, new JuliaFunction{XSTR(jl_f_svec), get_func_sig, get_func_attrs} },
{ jl_f_applicable_addr, new JuliaFunction{XSTR(jl_f_applicable), get_func_sig, get_func_attrs} },
{ jl_f_invoke_addr, new JuliaFunction{XSTR(jl_f_invoke), get_func_sig, get_func_attrs} },
{ jl_f_invoke_kwsorter_addr, new JuliaFunction{XSTR(jl_f_invoke_kwsorter), get_func_sig, get_func_attrs} },
{ jl_f_isdefined_addr, new JuliaFunction{XSTR(jl_f_isdefined), get_func_sig, get_func_attrs} },
{ jl_f_getfield_addr, new JuliaFunction{XSTR(jl_f_getfield), get_func_sig, get_func_attrs} },
{ jl_f_setfield_addr, new JuliaFunction{XSTR(jl_f_setfield), get_func_sig, get_func_attrs} },
{ jl_f_swapfield_addr, new JuliaFunction{XSTR(jl_f_swapfield), get_func_sig, get_func_attrs} },
{ jl_f_modifyfield_addr, new JuliaFunction{XSTR(jl_f_modifyfield), get_func_sig, get_func_attrs} },
{ jl_f_fieldtype_addr, new JuliaFunction{XSTR(jl_f_fieldtype), get_func_sig, get_func_attrs} },
{ jl_f_nfields_addr, new JuliaFunction{XSTR(jl_f_nfields), get_func_sig, get_func_attrs} },
{ jl_f__expr_addr, new JuliaFunction{XSTR(jl_f__expr), get_func_sig, get_func_attrs} },
{ jl_f__typevar_addr, new JuliaFunction{XSTR(jl_f__typevar), get_func_sig, get_func_attrs} },
{ jl_f_arrayref_addr, new JuliaFunction{XSTR(jl_f_arrayref), get_func_sig, get_func_attrs} },
{ jl_f_const_arrayref_addr, new JuliaFunction{XSTR(jl_f_const_arrayref), get_func_sig, get_func_attrs} },
{ jl_f_arrayset_addr, new JuliaFunction{XSTR(jl_f_arrayset), get_func_sig, get_func_attrs} },
{ jl_f_arraysize_addr, new JuliaFunction{XSTR(jl_f_arraysize), get_func_sig, get_func_attrs} },
{ jl_f_apply_type_addr, new JuliaFunction{XSTR(jl_f_apply_type), get_func_sig, get_func_attrs} },
{ jl_f_donotdelete_addr, new JuliaFunction{XSTR(jl_f_donotdelete), get_func_sig, get_donotdelete_func_attrs} }
};

jl_default_debug_info_kind = (int) DICompileUnit::DebugEmissionKind::FullDebug;
imaging_mode = jl_options.image_codegen || (jl_generating_output() && !jl_options.incremental);
jl_default_cgparams.generic_context = jl_nothing;
Expand Down Expand Up @@ -8256,13 +8254,14 @@ extern "C" void jl_init_llvm(void)

jl_ExecutionEngine = new JuliaOJIT(new LLVMContext());

bool jl_using_gdb_jitevents = false;
// Register GDB event listener
#if defined(JL_DEBUG_BUILD)
jl_using_gdb_jitevents = 1;
jl_using_gdb_jitevents = true;
# else
const char *jit_gdb = getenv("ENABLE_GDBLISTENER");
if (jit_gdb && atoi(jit_gdb)) {
jl_using_gdb_jitevents = 1;
jl_using_gdb_jitevents = true;
}
#endif
if (jl_using_gdb_jitevents)
Expand Down Expand Up @@ -8318,10 +8317,7 @@ extern "C" JL_DLLEXPORT void jl_init_codegen_impl(void)
{
jl_init_llvm();
// Now that the execution engine exists, initialize all modules
jl_init_jit();
init_jit_functions();

jl_init_intrinsic_functions_codegen();
}

extern "C" JL_DLLEXPORT void jl_teardown_codegen_impl()
Expand Down
Loading

0 comments on commit 9333986

Please sign in to comment.