Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustc: Ensure closures are "split-stack" #13628

Closed
wants to merge 1 commit into from
Closed
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
1 change: 1 addition & 0 deletions src/librustc/lib/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,7 @@ pub mod llvm {
pub fn LLVMSetGC(Fn: ValueRef, Name: *c_char);
pub fn LLVMAddFunctionAttr(Fn: ValueRef, PA: c_uint);
pub fn LLVMAddFunctionAttrString(Fn: ValueRef, Name: *c_char);
pub fn LLVMRemoveFunctionAttrString(Fn: ValueRef, Name: *c_char);
pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_ulonglong;

pub fn LLVMAddReturnAttribute(Fn: ValueRef, PA: c_uint);
Expand Down
11 changes: 9 additions & 2 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv,
lib::llvm::SetFunctionCallConv(llfn, cc);
// Function addresses in Rust are never significant, allowing functions to be merged.
lib::llvm::SetUnnamedAddr(llfn, true);
set_split_stack(llfn);

llfn
}
Expand Down Expand Up @@ -445,8 +446,8 @@ pub fn set_llvm_fn_attrs(attrs: &[ast::Attribute], llfn: ValueRef) {
}

// Add the no-split-stack attribute if requested
if !contains_name(attrs, "no_split_stack") {
set_split_stack(llfn);
if contains_name(attrs, "no_split_stack") {
unset_split_stack(llfn);
}

if contains_name(attrs, "cold") {
Expand All @@ -464,6 +465,12 @@ pub fn set_split_stack(f: ValueRef) {
})
}

pub fn unset_split_stack(f: ValueRef) {
"split-stack".with_c_str(|buf| {
unsafe { llvm::LLVMRemoveFunctionAttrString(f, buf); }
})
}

// Double-check that we never ask LLVM to declare the same symbol twice. It
// silently mangles such symbols, breaking our linkage model.
pub fn note_unique_llvm_symbol(ccx: &CrateContext, sym: ~str) {
Expand Down
12 changes: 12 additions & 0 deletions src/rustllvm/RustWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ extern "C" void LLVMAddFunctionAttrString(LLVMValueRef fn, const char *Name) {
unwrap<Function>(fn)->addFnAttr(Name);
}

extern "C" void LLVMRemoveFunctionAttrString(LLVMValueRef fn, const char *Name) {
Function *f = unwrap<Function>(fn);
LLVMContext &C = f->getContext();
AttrBuilder B;
B.addAttribute(Name);
AttributeSet to_remove = AttributeSet::get(C, AttributeSet::FunctionIndex, B);

AttributeSet attrs = f->getAttributes();
f->setAttributes(attrs.removeAttributes(f->getContext(),
AttributeSet::FunctionIndex,
to_remove));
}

extern "C" void LLVMAddReturnAttribute(LLVMValueRef Fn, LLVMAttribute PA) {
Function *A = unwrap<Function>(Fn);
Expand Down