Skip to content

Commit dea372b

Browse files
committed
add stack-probes to make stack-overflow detection more reliable
Supported platforms are currently X86, PowerPC, and SystemZ. Fixes #25523 Fixes #36170 Closes #28577 Closes #30892
1 parent d7da2a4 commit dea372b

File tree

1 file changed

+11
-20
lines changed

1 file changed

+11
-20
lines changed

src/codegen.cpp

+11-20
Original file line numberDiff line numberDiff line change
@@ -1719,6 +1719,10 @@ static void jl_init_function(Function *F)
17191719
F->addFnAttr("no-frame-pointer-elim", "true");
17201720
#endif
17211721
#endif
1722+
#if JL_LLVM_VERSION >= 110000 && !defined(JL_ASAN_ENABLED)
1723+
F->addFnAttr("probe-stack", "inline-asm");
1724+
//F->addFnAttr("stack-probe-size", 4096); // can use this to change the default
1725+
#endif
17221726
}
17231727

17241728
static std::pair<bool, bool> uses_specsig(jl_method_instance_t *lam, jl_value_t *rettype, bool prefer_specsig)
@@ -6297,28 +6301,15 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
62976301
}
62986302
}
62996303

6300-
/*
6301-
// step 6. (optional) check for stack overflow (the slower way)
6302-
Value *cur_sp =
6303-
ctx.builder.CreateCall(Intrinsic::getDeclaration(M,
6304-
Intrinsic::frameaddress),
6305-
ConstantInt::get(T_int32, 0));
6306-
Value *sp_ok =
6307-
ctx.builder.CreateICmpUGT(cur_sp,
6308-
ConstantInt::get(T_size,
6309-
(uptrint_t)jl_stack_lo));
6310-
error_unless(ctx, sp_ok, "stack overflow");
6311-
*/
6312-
6313-
// step 7. set up GC frame
6304+
// step 6. set up GC frame
63146305
allocate_gc_frame(ctx, b0);
63156306
Value *last_age = NULL;
63166307
emit_last_age_field(ctx);
63176308
if (toplevel || ctx.is_opaque_closure) {
63186309
last_age = tbaa_decorate(tbaa_gcframe, ctx.builder.CreateAlignedLoad(ctx.world_age_field, Align(sizeof(size_t))));
63196310
}
63206311

6321-
// step 8. allocate local variables slots
6312+
// step 7. allocate local variables slots
63226313
// must be in the first basic block for the llvm mem2reg pass to work
63236314
auto allocate_local = [&](jl_varinfo_t &varinfo, jl_sym_t *s) {
63246315
jl_value_t *jt = varinfo.value.typ;
@@ -6436,7 +6427,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
64366427
}
64376428
}
64386429

6439-
// step 9. move args into local variables
6430+
// step 8. move args into local variables
64406431
Function::arg_iterator AI = f->arg_begin();
64416432

64426433
auto get_specsig_arg = [&](jl_value_t *argType, Type *llvmArgType, bool isboxed) {
@@ -6566,7 +6557,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
65666557
}
65676558
}
65686559

6569-
// step 10. allocate rest argument
6560+
// step 9. allocate rest argument
65706561
CallInst *restTuple = NULL;
65716562
if (va && ctx.vaSlot != -1) {
65726563
jl_varinfo_t &vi = ctx.slots[ctx.vaSlot];
@@ -6608,7 +6599,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
66086599
}
66096600
}
66106601

6611-
// step 11. Compute properties for each statements
6602+
// step 10. Compute properties for each statements
66126603
// This needs to be computed by iterating in the IR order
66136604
// instead of control flow order.
66146605
auto in_user_mod = [] (jl_module_t *mod) {
@@ -6730,7 +6721,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
67306721
Instruction &prologue_end = ctx.builder.GetInsertBlock()->back();
67316722

67326723

6733-
// step 12. Do codegen in control flow order
6724+
// step 11. Do codegen in control flow order
67346725
std::vector<int> workstack;
67356726
std::map<int, BasicBlock*> BB;
67366727
std::map<size_t, BasicBlock*> come_from_bb;
@@ -7288,7 +7279,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
72887279
PN->eraseFromParent();
72897280
}
72907281

7291-
// step 13. Perform any delayed instantiations
7282+
// step 12. Perform any delayed instantiations
72927283
if (ctx.debug_enabled) {
72937284
bool in_prologue = true;
72947285
for (auto &BB : *ctx.f) {

0 commit comments

Comments
 (0)