Skip to content

Commit

Permalink
add stack-probes to make stack-overflow detection more reliable (Juli…
Browse files Browse the repository at this point in the history
…aLang#40068)

Supported platforms are currently X86, PowerPC, and SystemZ.

Fixes JuliaLang#25523
Fixes JuliaLang#36170
Closes JuliaLang#28577
Closes JuliaLang#30892
  • Loading branch information
vtjnash authored and antoine-levitt committed May 9, 2021
1 parent 5d85d46 commit 3a5b652
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 21 deletions.
35 changes: 15 additions & 20 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1719,6 +1719,14 @@ static void jl_init_function(Function *F)
F->addFnAttr("no-frame-pointer-elim", "true");
#endif
#endif
#if JL_LLVM_VERSION >= 110000 && !defined(JL_ASAN_ENABLED) && !defined(_OS_WINDOWS_)
// ASAN won't like us accessing undefined memory causing spurious issues,
// and Windows has platform-specific handling which causes it to mishandle
// this annotation. Other platforms should just ignore this if they don't
// implement it.
F->addFnAttr("probe-stack", "inline-asm");
//F->addFnAttr("stack-probe-size", 4096); // can use this to change the default
#endif
}

static std::pair<bool, bool> uses_specsig(jl_method_instance_t *lam, jl_value_t *rettype, bool prefer_specsig)
Expand Down Expand Up @@ -6297,28 +6305,15 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
}
}

/*
// step 6. (optional) check for stack overflow (the slower way)
Value *cur_sp =
ctx.builder.CreateCall(Intrinsic::getDeclaration(M,
Intrinsic::frameaddress),
ConstantInt::get(T_int32, 0));
Value *sp_ok =
ctx.builder.CreateICmpUGT(cur_sp,
ConstantInt::get(T_size,
(uptrint_t)jl_stack_lo));
error_unless(ctx, sp_ok, "stack overflow");
*/

// step 7. set up GC frame
// step 6. set up GC frame
allocate_gc_frame(ctx, b0);
Value *last_age = NULL;
emit_last_age_field(ctx);
if (toplevel || ctx.is_opaque_closure) {
last_age = tbaa_decorate(tbaa_gcframe, ctx.builder.CreateAlignedLoad(ctx.world_age_field, Align(sizeof(size_t))));
}

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

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

auto get_specsig_arg = [&](jl_value_t *argType, Type *llvmArgType, bool isboxed) {
Expand Down Expand Up @@ -6566,7 +6561,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
}
}

// step 10. allocate rest argument
// step 9. allocate rest argument
CallInst *restTuple = NULL;
if (va && ctx.vaSlot != -1) {
jl_varinfo_t &vi = ctx.slots[ctx.vaSlot];
Expand Down Expand Up @@ -6608,7 +6603,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
}
}

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


// step 12. Do codegen in control flow order
// step 11. Do codegen in control flow order
std::vector<int> workstack;
std::map<int, BasicBlock*> BB;
std::map<size_t, BasicBlock*> come_from_bb;
Expand Down Expand Up @@ -7288,7 +7283,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
PN->eraseFromParent();
}

// step 13. Perform any delayed instantiations
// step 12. Perform any delayed instantiations
if (ctx.debug_enabled) {
bool in_prologue = true;
for (auto &BB : *ctx.f) {
Expand Down
2 changes: 1 addition & 1 deletion test/llvmpasses/noinline.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ include(joinpath("..", "testhelpers", "llvmpasses.jl"))
return A + B
end

# CHECK: attributes #{{[0-9]+}} = {{{([a-z]+ )*}} noinline {{([a-z]+ )*}}}
# CHECK: attributes #{{[0-9]+}} = {{{[^}]*}} noinline {{[^}]*}}}
emit(simple_noinline, Float64, Float64)

0 comments on commit 3a5b652

Please sign in to comment.