Skip to content

Commit be58acf

Browse files
committed
---
yaml --- r: 156540 b: refs/heads/master c: a34b8de h: refs/heads/master v: v3
1 parent 8055bc0 commit be58acf

File tree

21 files changed

+815
-44
lines changed

21 files changed

+815
-44
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 1484f9cd46013a227d1d057508ff57ebc5930a8d
2+
refs/heads/master: a34b8dec697014f15e725215e17ea8d956c0ab1a
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: d44ea720fa9dfe062ef06d0eb49a58d4e7e92344
55
refs/heads/try: 6601b0501e31d08d3892a2d5a7d8a57ab120bf75

trunk/src/libcore/intrinsics.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,17 @@ extern "rust-intrinsic" {
260260
/// NB: This is very different from the `unreachable!()` macro!
261261
pub fn unreachable() -> !;
262262

263+
/// Inform the optimizer that a condition is always true.
264+
/// If the condition is false, the behavior is undefined.
265+
///
266+
/// No code is generated for this intrinsic, but the optimizer will try
267+
/// to preserve it (and its condition) between passes, which may interfere
268+
/// with optimization of surrounding code and reduce performance. It should
269+
/// not be used if the invariant can be discovered by the optimizer on its
270+
/// own, or if it does not enable any significant optimizations.
271+
#[cfg(not(stage0))]
272+
pub fn assume(b: bool);
273+
263274
/// Execute a breakpoint trap, for inspection by a debugger.
264275
pub fn breakpoint();
265276

trunk/src/libgreen/simple.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ impl Runtime for SimpleTask {
8181
}
8282
fn local_io<'a>(&'a mut self) -> Option<rtio::LocalIo<'a>> { None }
8383
fn stack_bounds(&self) -> (uint, uint) { fail!() }
84+
fn stack_guard(&self) -> Option<uint> { fail!() }
8485
fn can_block(&self) -> bool { true }
8586
fn wrap(self: Box<SimpleTask>) -> Box<Any+'static> { fail!() }
8687
}

trunk/src/libgreen/stack.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ impl Stack {
8282
}
8383
}
8484

85+
/// Point to the last writable byte of the stack
86+
pub fn guard(&self) -> *const uint {
87+
(self.start() as uint + page_size()) as *const uint
88+
}
89+
8590
/// Point to the low end of the allocated stack
8691
pub fn start(&self) -> *const uint {
8792
self.buf.as_ref().map(|m| m.data() as *const uint)

trunk/src/libgreen/task.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,13 @@ impl Runtime for GreenTask {
486486
c.current_stack_segment.end() as uint)
487487
}
488488

489+
fn stack_guard(&self) -> Option<uint> {
490+
let c = self.coroutine.as_ref()
491+
.expect("GreenTask.stack_guard called without a coroutine");
492+
493+
Some(c.current_stack_segment.guard() as uint)
494+
}
495+
489496
fn can_block(&self) -> bool { false }
490497

491498
fn wrap(self: Box<GreenTask>) -> Box<Any+'static> {

trunk/src/libnative/io/c_unix.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -252,16 +252,6 @@ mod signal {
252252
pub status: libc::c_int,
253253
}
254254

255-
#[cfg(any(target_os = "macos", target_os = "ios"))]
256-
#[repr(C)]
257-
pub struct sigaction {
258-
pub sa_handler: extern fn(libc::c_int),
259-
sa_tramp: *mut libc::c_void,
260-
pub sa_mask: sigset_t,
261-
pub sa_flags: libc::c_int,
262-
}
263-
264-
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
265255
#[repr(C)]
266256
pub struct sigaction {
267257
pub sa_handler: extern fn(libc::c_int),

trunk/src/libnative/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ pub fn start(argc: int, argv: *const *const u8, main: proc()) -> int {
132132
rt::init(argc, argv);
133133
let mut exit_code = None;
134134
let mut main = Some(main);
135-
let mut task = task::new((my_stack_bottom, my_stack_top));
135+
let mut task = task::new((my_stack_bottom, my_stack_top),
136+
rt::thread::main_guard_page());
136137
task.name = Some(str::Slice("<main>"));
137138
drop(task.run(|| {
138139
unsafe {

trunk/src/libnative/task.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ use io;
2929
use std::task::{TaskBuilder, Spawner};
3030

3131
/// Creates a new Task which is ready to execute as a 1:1 task.
32-
pub fn new(stack_bounds: (uint, uint)) -> Box<Task> {
32+
pub fn new(stack_bounds: (uint, uint), stack_guard: uint) -> Box<Task> {
3333
let mut task = box Task::new();
3434
let mut ops = ops();
3535
ops.stack_bounds = stack_bounds;
36+
ops.stack_guard = stack_guard;
3637
task.put_runtime(ops);
3738
return task;
3839
}
@@ -44,6 +45,7 @@ fn ops() -> Box<Ops> {
4445
io: io::IoFactory::new(),
4546
// these *should* get overwritten
4647
stack_bounds: (0, 0),
48+
stack_guard: 0
4749
}
4850
}
4951

@@ -82,6 +84,7 @@ impl Spawner for NativeSpawner {
8284
my_stack);
8385
}
8486
let mut ops = ops;
87+
ops.stack_guard = rt::thread::current_guard_page();
8588
ops.stack_bounds = (my_stack - stack + 1024, my_stack);
8689

8790
let mut f = Some(f);
@@ -115,6 +118,8 @@ struct Ops {
115118
// native tasks necessarily know their precise bounds, hence this is
116119
// optional.
117120
stack_bounds: (uint, uint),
121+
122+
stack_guard: uint
118123
}
119124

120125
impl rt::Runtime for Ops {
@@ -138,6 +143,14 @@ impl rt::Runtime for Ops {
138143

139144
fn stack_bounds(&self) -> (uint, uint) { self.stack_bounds }
140145

146+
fn stack_guard(&self) -> Option<uint> {
147+
if self.stack_guard != 0 {
148+
Some(self.stack_guard)
149+
} else {
150+
None
151+
}
152+
}
153+
141154
fn can_block(&self) -> bool { true }
142155

143156
// This function gets a little interesting. There are a few safety and

trunk/src/librustc/middle/trans/context.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,7 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef
860860
ifn!("llvm.lifetime.end" fn(t_i64, i8p) -> void);
861861

862862
ifn!("llvm.expect.i1" fn(i1, i1) -> i1);
863+
ifn!("llvm.assume" fn(i1) -> void);
863864

864865
// Some intrinsics were introduced in later versions of LLVM, but they have
865866
// fallbacks in libc or libm and such. Currently, all of these intrinsics

trunk/src/librustc/middle/trans/intrinsic.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ pub fn get_simple_intrinsic(ccx: &CrateContext, item: &ast::ForeignItem) -> Opti
8181
"bswap16" => "llvm.bswap.i16",
8282
"bswap32" => "llvm.bswap.i32",
8383
"bswap64" => "llvm.bswap.i64",
84+
"assume" => "llvm.assume",
8485
_ => return None
8586
};
8687
Some(ccx.get_intrinsic(&name))

trunk/src/librustc/middle/typeck/check/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5707,6 +5707,8 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
57075707

57085708
"return_address" => (0, vec![], ty::mk_imm_ptr(tcx, ty::mk_u8())),
57095709

5710+
"assume" => (0, vec![ty::mk_bool()], ty::mk_nil()),
5711+
57105712
ref other => {
57115713
span_err!(tcx.sess, it.span, E0093,
57125714
"unrecognized intrinsic function: `{}`", *other);

trunk/src/librustrt/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ mod local_ptr;
5151
mod thread_local_storage;
5252
mod util;
5353
mod libunwind;
54+
mod stack_overflow;
5455

5556
pub mod args;
5657
pub mod bookkeeping;
@@ -92,6 +93,8 @@ pub trait Runtime {
9293
fn local_io<'a>(&'a mut self) -> Option<rtio::LocalIo<'a>>;
9394
/// The (low, high) edges of the current stack.
9495
fn stack_bounds(&self) -> (uint, uint); // (lo, hi)
96+
/// The last writable byte of the stack next to the guard page
97+
fn stack_guard(&self) -> Option<uint>;
9598
fn can_block(&self) -> bool;
9699

97100
// FIXME: This is a serious code smell and this should not exist at all.
@@ -113,6 +116,7 @@ pub fn init(argc: int, argv: *const *const u8) {
113116
args::init(argc, argv);
114117
local_ptr::init();
115118
at_exit_imp::init();
119+
thread::init();
116120
}
117121

118122
// FIXME(#14344) this shouldn't be necessary
@@ -151,6 +155,7 @@ pub unsafe fn cleanup() {
151155
bookkeeping::wait_for_other_tasks();
152156
at_exit_imp::run();
153157
args::cleanup();
158+
thread::cleanup();
154159
local_ptr::cleanup();
155160
}
156161

trunk/src/librustrt/stack.rs

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,6 @@ pub const RED_ZONE: uint = 20 * 1024;
5555
#[cfg(not(test))] // in testing, use the original libstd's version
5656
#[lang = "stack_exhausted"]
5757
extern fn stack_exhausted() {
58-
use core::prelude::*;
59-
use alloc::boxed::Box;
60-
use local::Local;
61-
use task::Task;
6258
use core::intrinsics;
6359

6460
unsafe {
@@ -104,21 +100,7 @@ extern fn stack_exhausted() {
104100
// #9854 - unwinding on windows through __morestack has never worked
105101
// #2361 - possible implementation of not using landing pads
106102

107-
let task: Option<Box<Task>> = Local::try_take();
108-
let name = match task {
109-
Some(ref task) => {
110-
task.name.as_ref().map(|n| n.as_slice())
111-
}
112-
None => None
113-
};
114-
let name = name.unwrap_or("<unknown>");
115-
116-
// See the message below for why this is not emitted to the
117-
// task's logger. This has the additional conundrum of the
118-
// logger may not be initialized just yet, meaning that an FFI
119-
// call would happen to initialized it (calling out to libuv),
120-
// and the FFI call needs 2MB of stack when we just ran out.
121-
rterrln!("task '{}' has overflowed its stack", name);
103+
::stack_overflow::report();
122104

123105
intrinsics::abort();
124106
}

0 commit comments

Comments
 (0)