Skip to content

Commit df91352

Browse files
authored
atomics: avoid iterator invalidation in C++ (#58347)
Observed causing segfaults in CI.
2 parents 9b63fd9 + 6165395 commit df91352

File tree

1 file changed

+47
-46
lines changed

1 file changed

+47
-46
lines changed

src/codegen.cpp

Lines changed: 47 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9874,56 +9874,57 @@ void linkFunctionBody(Function &Dst, Function &Src)
98749874

98759875
void emit_always_inline(orc::ThreadSafeModule &result_m, jl_codegen_params_t &params) JL_NOTSAFEPOINT_LEAVE JL_NOTSAFEPOINT_ENTER
98769876
{
9877-
jl_workqueue_t &edges = params.workqueue;
9878-
bool always_inline = false;
9879-
for (auto &it : edges) {
9880-
if (it.second.private_linkage)
9881-
always_inline = true;
9882-
}
9883-
if (!always_inline)
9884-
return;
9885-
jl_task_t *ct = jl_current_task;
9886-
int8_t gc_state = jl_gc_unsafe_enter(ct->ptls); // codegen may contain safepoints (such as jl_subtype calls)
9887-
jl_code_info_t *src = nullptr;
9888-
params.safepoint_on_entry = false;
9889-
params.temporary_roots = jl_alloc_array_1d(jl_array_any_type, 0);
9890-
JL_GC_PUSH2(&params.temporary_roots, &src);
9891-
for (auto &it : edges) {
9892-
jl_code_instance_t *codeinst = it.first;
9893-
auto &proto = it.second;
9894-
if (!proto.private_linkage)
9895-
continue;
9896-
if (proto.decl->isDeclaration()) {
9897-
src = (jl_code_info_t*)jl_atomic_load_relaxed(&codeinst->inferred);
9898-
jl_method_instance_t *mi = jl_get_ci_mi(codeinst);
9899-
jl_method_t *def = mi->def.method;
9900-
if (src && (jl_value_t*)src != jl_nothing && jl_is_method(def) && jl_ir_inlining_cost((jl_value_t*)src) < UINT16_MAX)
9901-
src = jl_uncompress_ir(def, codeinst, (jl_value_t*)src);
9902-
if (src && jl_is_code_info(src) && jl_ir_inlining_cost((jl_value_t*)src) < UINT16_MAX) {
9903-
jl_llvm_functions_t decls = jl_emit_codeinst(result_m, codeinst, src, params); // contains safepoints
9904-
if (!result_m)
9905-
break;
9906-
// TODO: jl_optimize_roots(params, mi, *result_m.getModuleUnlocked()); // contains safepoints
9907-
Module &M = *result_m.getModuleUnlocked();
9908-
if (decls.functionObject != "jl_fptr_args" &&
9909-
decls.functionObject != "jl_fptr_sparam" &&
9910-
decls.functionObject != "jl_f_opaque_closure_call") {
9911-
Function *F = M.getFunction(decls.functionObject);
9912-
F->eraseFromParent();
9913-
}
9914-
if (!decls.specFunctionObject.empty()) {
9915-
Function *specF = M.getFunction(decls.specFunctionObject);
9916-
linkFunctionBody(*proto.decl, *specF);
9917-
proto.decl->addFnAttr(Attribute::InlineHint);
9918-
proto.decl->setLinkage(proto.external_linkage ? GlobalValue::AvailableExternallyLinkage : GlobalValue::PrivateLinkage);
9919-
specF->eraseFromParent();
9877+
while (true) {
9878+
SmallVector<jl_workqueue_t::value_type> always_inline;
9879+
for (auto &it : params.workqueue) {
9880+
if (it.second.private_linkage && it.second.decl->isDeclaration())
9881+
always_inline.push_back(it);
9882+
it.second.private_linkage = false;
9883+
}
9884+
if (always_inline.empty())
9885+
return;
9886+
jl_task_t *ct = jl_current_task;
9887+
int8_t gc_state = jl_gc_unsafe_enter(ct->ptls); // codegen may contain safepoints (such as jl_subtype calls)
9888+
jl_code_info_t *src = nullptr;
9889+
params.safepoint_on_entry = false;
9890+
params.temporary_roots = jl_alloc_array_1d(jl_array_any_type, 0);
9891+
JL_GC_PUSH2(&params.temporary_roots, &src);
9892+
for (auto &it : always_inline) {
9893+
jl_code_instance_t *codeinst = it.first;
9894+
auto &proto = it.second;
9895+
Function *decl = proto.decl;
9896+
if (decl->isDeclaration()) {
9897+
src = (jl_code_info_t*)jl_atomic_load_relaxed(&codeinst->inferred);
9898+
jl_method_instance_t *mi = jl_get_ci_mi(codeinst);
9899+
jl_method_t *def = mi->def.method;
9900+
if (src && (jl_value_t*)src != jl_nothing && jl_is_method(def) && jl_ir_inlining_cost((jl_value_t*)src) < UINT16_MAX)
9901+
src = jl_uncompress_ir(def, codeinst, (jl_value_t*)src);
9902+
if (src && jl_is_code_info(src) && jl_ir_inlining_cost((jl_value_t*)src) < UINT16_MAX) {
9903+
jl_llvm_functions_t decls = jl_emit_codeinst(result_m, codeinst, src, params); // contains safepoints
9904+
if (!result_m)
9905+
break;
9906+
// TODO: jl_optimize_roots(params, mi, *result_m.getModuleUnlocked()); // contains safepoints
9907+
Module &M = *result_m.getModuleUnlocked();
9908+
if (decls.functionObject != "jl_fptr_args" &&
9909+
decls.functionObject != "jl_fptr_sparam" &&
9910+
decls.functionObject != "jl_f_opaque_closure_call") {
9911+
Function *F = M.getFunction(decls.functionObject);
9912+
F->eraseFromParent();
9913+
}
9914+
if (!decls.specFunctionObject.empty()) {
9915+
Function *specF = M.getFunction(decls.specFunctionObject);
9916+
linkFunctionBody(*decl, *specF);
9917+
decl->addFnAttr(Attribute::InlineHint);
9918+
decl->setLinkage(proto.external_linkage ? GlobalValue::AvailableExternallyLinkage : GlobalValue::PrivateLinkage);
9919+
specF->eraseFromParent();
9920+
}
99209921
}
99219922
}
99229923
}
9924+
params.temporary_roots = nullptr;
9925+
JL_GC_POP();
9926+
jl_gc_unsafe_leave(ct->ptls, gc_state);
99239927
}
9924-
params.temporary_roots = nullptr;
9925-
JL_GC_POP();
9926-
jl_gc_unsafe_leave(ct->ptls, gc_state);
99279928
}
99289929

99299930
// --- initialization ---

0 commit comments

Comments
 (0)