Skip to content

Commit 31a209c

Browse files
committed
auto merge of #9834 : alexcrichton/rust/morestack, r=brson
This commit re-introduces the functionality of __morestack in a way that it was not originally anticipated. Rust does not currently have segmented stacks, rather just large stack segments. We do not detect when these stack segments are overrun currently, but this commit leverages __morestack in order to check this. This commit purges a lot of the old __morestack and stack limit C++ functionality, migrating the necessary chunks to rust. The stack limit is now entirely maintained in rust, and the "main logic bits" of __morestack are now also implemented in rust as well. I put my best effort into validating that this currently builds and runs successfully on osx and linux 32/64 bit, but I was unable to get this working on windows. We never did have unwinding through __morestack frames, and although I tried poking at it for a bit, I was unable to understand why we don't get unwinding right now. A focus of this commit is to implement as much of the logic in rust as possible. This involved some liberal usage of `no_split_stack` in various locations, along with some use of the `asm!` macro (scary). I modified a bit of C++ to stop calling `record_sp_limit` because this is no longer defined in C++, rather in rust. Another consequence of this commit is that `thread_local_storage::{get, set}` must both be flagged with `#[rust_stack]`. I've briefly looked at the implementations on osx/linux/windows to ensure that they're pretty small stacks, and I'm pretty sure that they're definitely less than 20K stacks, so we probably don't have a lot to worry about. Other things worthy of note: * The default stack size is now 4MB instead of 2MB. This is so that when we request 2MB to call a C function you don't immediately overflow because you have consumed any stack at all. * `asm!` is actually pretty cool, maybe we could actually define context switching with it? * I wanted to add links to the internet about all this jazz of storing information in TLS, but I was only able to find a link for the windows implementation. Otherwise my suggestion is just "disassemble on that arch and see what happens" * I put my best effort forward on arm/mips to tweak __morestack correctly, we have no ability to test this so an extra set of eyes would be useful on these spots. * This is all really tricky stuff, so I tried to put as many comments as I thought were necessary, but if anything is still unclear (or I completely forgot to take something into account), I'm willing to write more!
2 parents 5751794 + 6d8330a commit 31a209c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+500
-1551
lines changed

mk/platform.mk

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,8 @@ define CFG_MAKE_TOOLCHAIN
507507

508508
# For the ARM and MIPS crosses, use the toolchain assembler
509509
# XXX: We should be able to use the LLVM assembler
510-
CFG_ASSEMBLE_$(1)=$$(CC_$(1)) $$(CFG_DEPEND_FLAGS) $$(2) -c -o $$(1)
510+
CFG_ASSEMBLE_$(1)=$$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \
511+
$$(CFG_DEPEND_FLAGS) $$(2) -c -o $$(1)
511512

512513
endif
513514

mk/rt.mk

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,6 @@ RUNTIME_CXXS_$(1)_$(2) := \
9191
rt/miniz.cpp \
9292
rt/memory_region.cpp \
9393
rt/boxed_region.cpp \
94-
rt/arch/$$(HOST_$(1))/context.cpp \
95-
rt/arch/$$(HOST_$(1))/gpr.cpp \
9694
rt/rust_android_dummy.cpp \
9795
rt/rust_test_helpers.cpp
9896

@@ -106,7 +104,6 @@ RUNTIME_CS_$(1)_$(2) := rt/sundown/src/autolink.c \
106104
rt/sundown/html/html.c
107105

108106
RUNTIME_S_$(1)_$(2) := rt/arch/$$(HOST_$(1))/_context.S \
109-
rt/arch/$$(HOST_$(1))/ccall.S \
110107
rt/arch/$$(HOST_$(1))/record_sp.S
111108

112109
RT_BUILD_DIR_$(1)_$(2) := $$(RT_OUTPUT_DIR_$(1))/stage$(2)
@@ -122,7 +119,7 @@ RUNTIME_OBJS_$(1)_$(2) := $$(RUNTIME_CXXS_$(1)_$(2):rt/%.cpp=$$(RT_BUILD_DIR_$(1
122119
$$(RUNTIME_S_$(1)_$(2):rt/%.S=$$(RT_BUILD_DIR_$(1)_$(2))/%.o)
123120
ALL_OBJ_FILES += $$(RUNTIME_OBJS_$(1)_$(2))
124121

125-
MORESTACK_OBJ_$(1)_$(2) := $$(RT_BUILD_DIR_$(1)_$(2))/arch/$$(HOST_$(1))/morestack.o
122+
MORESTACK_OBJS_$(1)_$(2) := $$(RT_BUILD_DIR_$(1)_$(2))/arch/$$(HOST_$(1))/morestack.o
126123
ALL_OBJ_FILES += $$(MORESTACK_OBJS_$(1)_$(2))
127124

128125
$$(RT_BUILD_DIR_$(1)_$(2))/%.o: rt/%.cpp $$(MKFILE_DEPS)
@@ -140,9 +137,9 @@ $$(RT_BUILD_DIR_$(1)_$(2))/%.o: rt/%.S $$(MKFILE_DEPS) \
140137
@$$(call E, compile: $$@)
141138
$$(Q)$$(call CFG_ASSEMBLE_$(1),$$@,$$<)
142139

143-
$$(RT_BUILD_DIR_$(1)_$(2))/arch/$$(HOST_$(1))/libmorestack.a: $$(MORESTACK_OBJ_$(1)_$(2))
140+
$$(RT_BUILD_DIR_$(1)_$(2))/arch/$$(HOST_$(1))/libmorestack.a: $$(MORESTACK_OBJS_$(1)_$(2))
144141
@$$(call E, link: $$@)
145-
$$(Q)$(AR_$(1)) rcs $$@ $$<
142+
$$(Q)$(AR_$(1)) rcs $$@ $$^
146143

147144
$$(RT_BUILD_DIR_$(1)_$(2))/$(CFG_RUNTIME_$(1)): $$(RUNTIME_OBJS_$(1)_$(2)) $$(MKFILE_DEPS) \
148145
$$(RUNTIME_DEF_$(1)_$(2)) $$(LIBUV_LIB_$(1))

src/librustc/middle/trans/base.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2226,6 +2226,7 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) {
22262226
[path_name(item.ident)]),
22272227
decl,
22282228
body,
2229+
item.attrs,
22292230
llfndecl,
22302231
item.id);
22312232
} else if !generics.is_type_parameterized() {

src/librustc/middle/trans/foreign.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,14 +386,15 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: @mut CrateContext,
386386
path: &ast_map::path,
387387
decl: &ast::fn_decl,
388388
body: &ast::Block,
389+
attrs: &[ast::Attribute],
389390
llwrapfn: ValueRef,
390391
id: ast::NodeId) {
391392
let _icx = push_ctxt("foreign::build_foreign_fn");
392393
let tys = foreign_types_for_id(ccx, id);
393394

394395
unsafe { // unsafe because we call LLVM operations
395396
// Build up the Rust function (`foo0` above).
396-
let llrustfn = build_rust_fn(ccx, path, decl, body, id);
397+
let llrustfn = build_rust_fn(ccx, path, decl, body, attrs, id);
397398

398399
// Build up the foreign wrapper (`foo` above).
399400
return build_wrap_fn(ccx, llrustfn, llwrapfn, &tys);
@@ -403,6 +404,7 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: @mut CrateContext,
403404
path: &ast_map::path,
404405
decl: &ast::fn_decl,
405406
body: &ast::Block,
407+
attrs: &[ast::Attribute],
406408
id: ast::NodeId)
407409
-> ValueRef {
408410
let _icx = push_ctxt("foreign::foreign::build_rust_fn");
@@ -434,6 +436,7 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: @mut CrateContext,
434436
t.repr(tcx));
435437

436438
let llfndecl = base::decl_internal_rust_fn(ccx, f.sig.inputs, f.sig.output, ps);
439+
base::set_llvm_fn_attrs(attrs, llfndecl);
437440
base::trans_fn(ccx,
438441
(*path).clone(),
439442
decl,

src/librustc/rustc.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,8 +326,12 @@ pub fn monitor(f: ~fn(@diagnostic::Emitter)) {
326326
use std::comm::*;
327327

328328
// XXX: This is a hack for newsched since it doesn't support split stacks.
329-
// rustc needs a lot of stack!
330-
static STACK_SIZE: uint = 6000000;
329+
// rustc needs a lot of stack! When optimizations are disabled, it needs
330+
// even *more* stack than usual as well.
331+
#[cfg(rtopt)]
332+
static STACK_SIZE: uint = 6000000; // 6MB
333+
#[cfg(not(rtopt))]
334+
static STACK_SIZE: uint = 20000000; // 20MB
331335

332336
let (p, ch) = stream();
333337
let ch = SharedChan::new(ch);

0 commit comments

Comments
 (0)