Skip to content

Commit

Permalink
Turn off segmented stack support and use stack probes instead
Browse files Browse the repository at this point in the history
  • Loading branch information
Zoxc committed Aug 6, 2014
1 parent f5ac411 commit ed8981f
Show file tree
Hide file tree
Showing 9 changed files with 16 additions and 183 deletions.
2 changes: 0 additions & 2 deletions src/librustc/middle/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,4 @@ lets_do_this! {
ManagedItem, "managed_bound", managed_bound;

IteratorItem, "iterator", iterator;

StackExhaustedLangItem, "stack_exhausted", stack_exhausted;
}
33 changes: 9 additions & 24 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,8 @@ fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv,
// Function addresses in Rust are never significant, allowing functions to be merged.
llvm::SetUnnamedAddr(llfn, true);

if ccx.is_split_stack_supported() {
set_split_stack(llfn);
if ccx.is_probe_stack_supported() {
set_probe_stack(llfn);
}

llfn
Expand Down Expand Up @@ -429,11 +429,6 @@ pub fn set_llvm_fn_attrs(attrs: &[ast::Attribute], llfn: ValueRef) {
InlineNone => { /* fallthrough */ }
}

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

if contains_name(attrs, "cold") {
unsafe {
llvm::LLVMAddFunctionAttribute(llfn,
Expand All @@ -447,14 +442,14 @@ pub fn set_always_inline(f: ValueRef) {
llvm::SetFunctionAttribute(f, llvm::AlwaysInlineAttribute)
}

pub fn set_split_stack(f: ValueRef) {
"split-stack".with_c_str(|buf| {
pub fn set_probe_stack(f: ValueRef) {
"probe-stack".with_c_str(|buf| {
unsafe { llvm::LLVMAddFunctionAttrString(f, llvm::FunctionIndex as c_uint, buf); }
})
}

pub fn unset_split_stack(f: ValueRef) {
"split-stack".with_c_str(|buf| {
pub fn unset_probe_stack(f: ValueRef) {
"probe-stack".with_c_str(|buf| {
unsafe { llvm::LLVMRemoveFunctionAttrString(f, llvm::FunctionIndex as c_uint, buf); }
})
}
Expand Down Expand Up @@ -2009,14 +2004,8 @@ fn finish_register_fn(ccx: &CrateContext, sp: Span, sym: String, node_id: ast::N
llvm::SetLinkage(llfn, llvm::InternalLinkage);
}

// The stack exhaustion lang item shouldn't have a split stack because
// otherwise it would continue to be exhausted (bad), and both it and the
// eh_personality functions need to be externally linkable.
// The eh_personality function need to be externally linkable.
let def = ast_util::local_def(node_id);
if ccx.tcx.lang_items.stack_exhausted() == Some(def) {
unset_split_stack(llfn);
llvm::SetLinkage(llfn, llvm::ExternalLinkage);
}
if ccx.tcx.lang_items.eh_personality() == Some(def) {
llvm::SetLinkage(llfn, llvm::ExternalLinkage);
}
Expand Down Expand Up @@ -2729,13 +2718,9 @@ pub fn trans_crate(krate: ast::Crate,
});

// Make sure that some other crucial symbols are not eliminated from the
// module. This includes the main function, the crate map (used for debug
// log settings and I/O), and finally the curious rust_stack_exhausted
// symbol. This symbol is required for use by the libmorestack library that
// we link in, so we must ensure that this symbol is not internalized (if
// defined in the crate).
// module. This includes the main function and the crate map (used for debug
// log settings and I/O)
reachable.push("main".to_string());
reachable.push("rust_stack_exhausted".to_string());

// referenced from .eh_frame section on some platforms
reachable.push("rust_eh_personality".to_string());
Expand Down
13 changes: 2 additions & 11 deletions src/librustc/middle/trans/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ use std::c_str::ToCStr;
use std::ptr;
use std::rc::Rc;
use std::collections::{HashMap, HashSet};
use syntax::abi;
use syntax::ast;
use syntax::parse::token::InternedString;

Expand Down Expand Up @@ -275,16 +274,8 @@ impl CrateContext {
}
}

// Although there is an experimental implementation of LLVM which
// supports SS on armv7 it wasn't approved by Apple, see:
// http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140505/216350.html
// It looks like it might be never accepted to upstream LLVM.
//
// So far the decision was to disable them in default builds
// but it could be enabled (with patched LLVM)
pub fn is_split_stack_supported(&self) -> bool {
let ref cfg = self.sess().targ_cfg;
cfg.os != abi::OsiOS || cfg.arch != abi::Arm
pub fn is_probe_stack_supported(&self) -> bool {
true
}
}

Expand Down
4 changes: 0 additions & 4 deletions src/librustc/middle/weak_lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ pub fn check_crate(krate: &ast::Crate,
// These are never called by user code, they're generated by the compiler.
// They will never implicitly be added to the `missing` array unless we do
// so here.
if items.stack_exhausted().is_none() {
items.missing.push(lang_items::StackExhaustedLangItem);
}
if items.eh_personality().is_none() {
items.missing.push(lang_items::EhPersonalityLangItem);
}
Expand Down Expand Up @@ -119,6 +116,5 @@ impl<'a> Visitor<()> for Context<'a> {

weak_lang_items!(
begin_unwind, BeginUnwindLangItem, rust_begin_unwind;
stack_exhausted, StackExhaustedLangItem, rust_stack_exhausted;
eh_personality, EhPersonalityLangItem, rust_eh_personality;
)
23 changes: 1 addition & 22 deletions src/rt/arch/arm/morestack.S
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,10 @@

#if defined(__APPLE__)
#define MORESTACK ___morestack
#define STACK_EXHAUSTED _rust_stack_exhausted
#else
#define MORESTACK __morestack
#define STACK_EXHAUSTED rust_stack_exhausted
#endif

.global STACK_EXHAUSTED
.global MORESTACK

// Unfortunately LLVM yet doesn't support emitting correct debug
Expand All @@ -48,23 +45,5 @@
// ARMFrameLowering::adjustForSegmentedStacks() implementation.
MORESTACK:
UNWIND .fnstart

// Save frame pointer and return address
UNWIND .save {r4, r5}
UNWIND .save {lr}
UNWIND .save {r6, fp, lr}
push {r6, fp, lr}

UNWIND .movsp r6
mov r6, sp
UNWIND .setfp fp, sp, #4
add fp, sp, #4

// Save argument registers of the original function
push {r0, r1, r2, r3, lr}

// Create new stack
bl STACK_EXHAUSTED@plt

// the above function ensures that it never returns
b MORESTACK
UNWIND .fnend
45 changes: 1 addition & 44 deletions src/rt/arch/i386/morestack.S
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,11 @@

#if defined(__APPLE__)
#define MORESTACK ___morestack
#define EXHAUSTED _rust_stack_exhausted
#else
#if defined(__linux__) || defined(__FreeBSD__)
#define MORESTACK __morestack
#define EXHAUSTED rust_stack_exhausted
#else
#define MORESTACK ___morestack
#define EXHAUSTED _rust_stack_exhausted
#endif
#endif

Expand All @@ -100,45 +97,5 @@

MORESTACK:
.cfi_startproc

// This base pointer setup differs from most in that we are
// telling the unwinder to consider the Canonical Frame
// Address (CFA) for this frame to be the value of the stack
// pointer prior to entry to the original function, whereas
// the CFA would typically be the value of the stack
// pointer prior to entry to this function. This will allow
// the unwinder to understand how to skip the tiny partial
// frame that the original function created by calling
// __morestack.

// In practical terms, our CFA is 12 bytes greater than it
// would normally be, accounting for the two arguments to
// __morestack, and an extra return address.

// FIXME(#9854) these cfi directives don't work on windows.

pushl %ebp

#if defined(__APPLE__)
// The pattern of the return address being saved twice to the same location
// tells the OS X linker that it should not attempt to convert the DWARF
// unwind information to the compact format.
.cfi_offset %eip, -4
.cfi_offset %eip, -4
#endif

// The CFA is 20 bytes above the register that it is
// associated with for this frame (which will be %ebp)
.cfi_def_cfa_offset 20
// %ebp is -20 bytes from the CFA
.cfi_offset %ebp, -20
movl %esp, %ebp
// Calculate the CFA as an offset from %ebp
.cfi_def_cfa_register %ebp

// re-align the stack
subl $12,%esp
calll EXHAUSTED
// the exhaustion function guarantees that it can't return

jmp MORESTACK
.cfi_endproc
20 changes: 1 addition & 19 deletions src/rt/arch/mips/morestack.S
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

.text

.globl rust_stack_exhausted
.globl __morestack

.hidden __morestack
Expand All @@ -19,25 +18,8 @@ __morestack:
.set noreorder
.set nomacro

addiu $29, $29, -4
sw $30, 0($29)

// 16 = 4 (current) + 12 (previous)
.cfi_def_cfa_offset 16
.cfi_offset 31, -4
.cfi_offset 30, -16

move $30, $29
.cfi_def_cfa_register 30

// O32 ABI always reserves 16 bytes for arguments
addiu $29, $29, -16

lw $25, %call16(rust_stack_exhausted)($28)
jalr $25
b __morestack
nop

// the above function make sure that we never get here

.end __morestack
.cfi_endproc
20 changes: 1 addition & 19 deletions src/rt/arch/mipsel/morestack.S
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

.text

.globl rust_stack_exhausted
.globl __morestack

.hidden __morestack
Expand All @@ -19,25 +18,8 @@ __morestack:
.set noreorder
.set nomacro

addiu $29, $29, -4
sw $30, 0($29)

// 16 = 4 (current) + 12 (previous)
.cfi_def_cfa_offset 16
.cfi_offset 31, -4
.cfi_offset 30, -16

move $30, $29
.cfi_def_cfa_register 30

// O32 ABI always reserves 16 bytes for arguments
addiu $29, $29, -16

lw $25, %call16(rust_stack_exhausted)($28)
jalr $25
b __morestack
nop

// the above function make sure that we never get here

.end __morestack
.cfi_endproc
39 changes: 1 addition & 38 deletions src/rt/arch/x86_64/morestack.S
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,6 @@
#define MORESTACK __morestack
#endif

#if defined(__APPLE__)
#define EXHAUSTED _rust_stack_exhausted
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
#define EXHAUSTED rust_stack_exhausted@PLT
#else
#define EXHAUSTED rust_stack_exhausted
#endif

#if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
.hidden MORESTACK
#else
Expand All @@ -36,34 +28,5 @@
.globl MORESTACK
MORESTACK:
.cfi_startproc

pushq %rbp
// The CFA is 24 bytes above the register that it will
// be associated with for this frame (%rbp). That is 8
// bytes greater than a normal frame, to allow the unwinder
// to skip the partial frame of the original function.
.cfi_def_cfa_offset 24

#if defined(__APPLE__)
// The pattern of the return address being saved twice to the same location
// tells the OS X linker that it should not attempt to convert the DWARF
// unwind information to the compact format.
.cfi_offset %rip, -8
.cfi_offset %rip, -8
#endif

// %rbp is -24 bytes from the CFA
.cfi_offset %rbp, -24
movq %rsp, %rbp
// Calculate the CFA as on offset from %ebp
.cfi_def_cfa_register %rbp

// re-align the stack
subq $8, %rsp

// kill this program
call EXHAUSTED

// the exhaustion function guarantees that it can't return

jmp MORESTACK
.cfi_endproc

0 comments on commit ed8981f

Please sign in to comment.