Skip to content

Commit 51e19e7

Browse files
committed
auto merge of #16308 : alexcrichton/rust/rollup, r=alexcrichton
2 parents dd20f09 + ffa2588 commit 51e19e7

File tree

24 files changed

+372
-123
lines changed

24 files changed

+372
-123
lines changed

mk/platform.mk

+2-2
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ RUSTC_CROSS_FLAGS_arm-unknown-linux-gnueabi :=
377377
# mipsel-linux configuration
378378
CC_mipsel-linux=mipsel-linux-gcc
379379
CXX_mipsel-linux=mipsel-linux-g++
380-
CPP_mipsel-linux=mipsel-linux-gcc
380+
CPP_mipsel-linux=mipsel-linux-gcc
381381
AR_mipsel-linux=mipsel-linux-ar
382382
CFG_LIB_NAME_mipsel-linux=lib$(1).so
383383
CFG_STATIC_LIB_NAME_mipsel-linux=lib$(1).a
@@ -641,7 +641,7 @@ define CFG_MAKE_TOOLCHAIN
641641
CXX_$(1)=$(CROSS_PREFIX_$(1))$(CXX_$(1))
642642
CPP_$(1)=$(CROSS_PREFIX_$(1))$(CPP_$(1))
643643
AR_$(1)=$(CROSS_PREFIX_$(1))$(AR_$(1))
644-
RUSTC_CROSS_FLAGS_$(1)=-C linker=$$(call FIND_COMPILER,$$(CXX_$(1))) \
644+
RUSTC_CROSS_FLAGS_$(1)=-C linker=$$(call FIND_COMPILER,$$(CC_$(1))) \
645645
-C ar=$$(call FIND_COMPILER,$$(AR_$(1))) $(RUSTC_CROSS_FLAGS_$(1))
646646

647647
RUSTC_FLAGS_$(1)=$$(RUSTC_CROSS_FLAGS_$(1)) $(RUSTC_FLAGS_$(1))

src/doc/guide.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -3295,7 +3295,7 @@ fn times_four(x: int) -> int { x * 4 }
32953295
#[cfg(test)]
32963296
mod test {
32973297
use super::add_three;
3298-
use super::add_four;
3298+
use super::times_four;
32993299
33003300
#[test]
33013301
fn test_add_three() {
@@ -3344,7 +3344,7 @@ about yet, and that's these lines:
33443344

33453345
```{rust,ignore}
33463346
use super::add_three;
3347-
use super::add_four;
3347+
use super::times_four;
33483348
```
33493349

33503350
Because we've made a nested module, we can import functions from the parent

src/etc/gedit/share/gtksourceview-3.0/language-specs/rust.lang

+1-1
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@
266266

267267
<define-regex id="common_escape" extended="true">
268268
'|"|
269-
\\|n|r|t|
269+
\\|n|r|t|0|
270270
x\%{hex_digit}{2}|
271271
u\%{hex_digit}{4}|
272272
U\%{hex_digit}{8}

src/etc/get-snapshot.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def unpack_snapshot(triple, dl_path):
5353
dl_path = sys.argv[2]
5454
else:
5555
# There are no 64-bit Windows snapshots yet, so we'll use 32-bit ones instead, for now
56-
snap_triple = triple if triple != "x86_64-w64-mingw32" else "i686-pc-mingw32"
56+
snap_triple = triple if triple != "x86_64-w64-mingw32" else "i686-w64-mingw32"
5757
snap = determine_curr_snapshot(snap_triple)
5858
dl = os.path.join(download_dir_base, snap)
5959
url = download_url_base + "/" + snap

src/libgreen/context.rs

+31-13
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ use std::uint;
1313
use std::mem::transmute;
1414
use std::rt::stack;
1515
use std::raw;
16+
#[cfg(target_arch = "x86_64")]
17+
use std::simd;
1618

1719
// FIXME #7761: Registers is boxed so that it is 16-byte aligned, for storing
1820
// SSE regs. It would be marginally better not to do this. In C++ we
@@ -103,11 +105,11 @@ impl Context {
103105
// invalid for the current task. Lucky for us `rust_swap_registers`
104106
// is a C function so we don't have to worry about that!
105107
match in_context.stack_bounds {
106-
Some((lo, hi)) => stack::record_stack_bounds(lo, hi),
108+
Some((lo, hi)) => stack::record_rust_managed_stack_bounds(lo, hi),
107109
// If we're going back to one of the original contexts or
108110
// something that's possibly not a "normal task", then reset
109111
// the stack limit to 0 to make morestack never fail
110-
None => stack::record_stack_bounds(0, uint::MAX),
112+
None => stack::record_rust_managed_stack_bounds(0, uint::MAX),
111113
}
112114
rust_swap_registers(out_regs, in_regs)
113115
}
@@ -186,14 +188,30 @@ fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
186188
// windows requires saving more registers (both general and XMM), so the windows
187189
// register context must be larger.
188190
#[cfg(windows, target_arch = "x86_64")]
189-
type Registers = [uint, ..34];
191+
struct Registers {
192+
gpr:[uint, ..14],
193+
_xmm:[simd::u32x4, ..10]
194+
}
190195
#[cfg(not(windows), target_arch = "x86_64")]
191-
type Registers = [uint, ..22];
196+
struct Registers {
197+
gpr:[uint, ..10],
198+
_xmm:[simd::u32x4, ..6]
199+
}
192200

193201
#[cfg(windows, target_arch = "x86_64")]
194-
fn new_regs() -> Box<Registers> { box() ([0, .. 34]) }
202+
fn new_regs() -> Box<Registers> {
203+
box() Registers {
204+
gpr:[0,..14],
205+
_xmm:[simd::u32x4(0,0,0,0),..10]
206+
}
207+
}
195208
#[cfg(not(windows), target_arch = "x86_64")]
196-
fn new_regs() -> Box<Registers> { box() ([0, .. 22]) }
209+
fn new_regs() -> Box<Registers> {
210+
box() Registers {
211+
gpr:[0,..10],
212+
_xmm:[simd::u32x4(0,0,0,0),..6]
213+
}
214+
}
197215

198216
#[cfg(target_arch = "x86_64")]
199217
fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
@@ -222,20 +240,20 @@ fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
222240

223241
// These registers are frobbed by rust_bootstrap_green_task into the right
224242
// location so we can invoke the "real init function", `fptr`.
225-
regs[RUSTRT_R12] = arg as uint;
226-
regs[RUSTRT_R13] = procedure.code as uint;
227-
regs[RUSTRT_R14] = procedure.env as uint;
228-
regs[RUSTRT_R15] = fptr as uint;
243+
regs.gpr[RUSTRT_R12] = arg as uint;
244+
regs.gpr[RUSTRT_R13] = procedure.code as uint;
245+
regs.gpr[RUSTRT_R14] = procedure.env as uint;
246+
regs.gpr[RUSTRT_R15] = fptr as uint;
229247

230248
// These registers are picked up by the regular context switch paths. These
231249
// will put us in "mostly the right context" except for frobbing all the
232250
// arguments to the right place. We have the small trampoline code inside of
233251
// rust_bootstrap_green_task to do that.
234-
regs[RUSTRT_RSP] = sp as uint;
235-
regs[RUSTRT_IP] = rust_bootstrap_green_task as uint;
252+
regs.gpr[RUSTRT_RSP] = sp as uint;
253+
regs.gpr[RUSTRT_IP] = rust_bootstrap_green_task as uint;
236254

237255
// Last base pointer on the stack should be 0
238-
regs[RUSTRT_RBP] = 0;
256+
regs.gpr[RUSTRT_RBP] = 0;
239257
}
240258

241259
#[cfg(target_arch = "arm")]

src/libnative/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ pub fn start(argc: int, argv: *const *const u8, main: proc()) -> int {
137137
task.name = Some(str::Slice("<main>"));
138138
drop(task.run(|| {
139139
unsafe {
140-
rt::stack::record_stack_bounds(my_stack_bottom, my_stack_top);
140+
rt::stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top);
141141
}
142142
exit_code = Some(run(main.take_unwrap()));
143143
}).destroy());

src/libnative/task.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ pub fn spawn_opts(opts: TaskOpts, f: proc():Send) {
8484
let addr = &something_around_the_top_of_the_stack as *const int;
8585
let my_stack = addr as uint;
8686
unsafe {
87-
stack::record_stack_bounds(my_stack - stack + 1024, my_stack);
87+
stack::record_os_managed_stack_bounds(my_stack - stack + 1024, my_stack);
8888
}
8989
let mut ops = ops;
9090
ops.stack_bounds = (my_stack - stack + 1024, my_stack);

src/librustdoc/html/static/main.css

+5
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ code, pre {
120120
font-family: "Source Code Pro", Menlo, Monaco, Consolas, "DejaVu Sans Mono", Inconsolata, monospace;
121121
white-space: pre-wrap;
122122
}
123+
.docblock code {
124+
background-color: #F5F5F5;
125+
border-radius: 3px;
126+
padding: 0 0.2em;
127+
}
123128
pre {
124129
background-color: #F5F5F5;
125130
padding: 14px;

src/librustdoc/lib.rs

+34-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,40 @@ local_data_key!(pub analysiskey: core::CrateAnalysis)
8989
type Output = (clean::Crate, Vec<plugins::PluginJson> );
9090

9191
pub fn main() {
92-
std::os::set_exit_status(main_args(std::os::args().as_slice()));
92+
// Why run rustdoc in a separate task? That's a good question!
93+
//
94+
// We first begin our adventure at the ancient commit of e7c4fb69. In this
95+
// commit it was discovered that the stack limit frobbing on windows ended
96+
// up causing some syscalls to fail. This was worked around manually in the
97+
// relevant location.
98+
//
99+
// Our journey now continues with #13259 where it was discovered that this
100+
// stack limit frobbing has the ability to affect nearly any syscall. Note
101+
// that the key idea here is that there is currently no knowledge as to why
102+
// this is happening or how to preserve it, fun times!
103+
//
104+
// Now we continue along to #16275 where it was discovered that --test on
105+
// windows didn't work at all! Yet curiously rustdoc worked without --test.
106+
// The exact reason that #16275 cropped up is that during the expansion
107+
// phase the compiler attempted to open libstd to read out its macros. This
108+
// invoked the LLVMRustOpenArchive shim which in turned went to LLVM to go
109+
// open a file and read it. Lo and behold this function returned an error!
110+
// It was then discovered that when the same fix mentioned in #13259 was
111+
// applied, the error went away. The plot thickens!
112+
//
113+
// Remember that rustdoc works without --test, which raises the question of
114+
// how because the --test and non --test paths are almost identical. The
115+
// first thing both paths do is parse and expand a crate! It turns out that
116+
// the difference is that --test runs on the *main task* while the normal
117+
// path runs in subtask. It turns out that running --test in a sub task also
118+
// fixes the problem!
119+
//
120+
// So, in summary, it is unknown why this is necessary, what it is
121+
// preventing, or what the actual bug is. In the meantime, this allows
122+
// --test to work on windows, which seems good, right? Fun times.
123+
spawn(proc() {
124+
std::os::set_exit_status(main_args(std::os::args().as_slice()));
125+
});
93126
}
94127

95128
pub fn opts() -> Vec<getopts::OptGroup> {

src/librustrt/libunwind.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub type _Unwind_Word = libc::uintptr_t;
6060
pub static unwinder_private_data_size: uint = 5;
6161

6262
#[cfg(target_arch = "x86_64")]
63-
pub static unwinder_private_data_size: uint = 2;
63+
pub static unwinder_private_data_size: uint = 6;
6464

6565
#[cfg(target_arch = "arm", not(target_os = "ios"))]
6666
pub static unwinder_private_data_size: uint = 20;

src/librustrt/stack.rs

+24-8
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,23 @@ extern fn stack_exhausted() {
124124
}
125125
}
126126

127+
// Windows maintains a record of upper and lower stack bounds in the Thread Information
128+
// Block (TIB), and some syscalls do check that addresses which are supposed to be in
129+
// the stack, indeed lie between these two values.
130+
// (See https://github.com/rust-lang/rust/issues/3445#issuecomment-26114839)
131+
//
132+
// When using Rust-managed stacks (libgreen), we must maintain these values accordingly.
133+
// For OS-managed stacks (libnative), we let the OS manage them for us.
134+
//
135+
// On all other platforms both variants behave identically.
136+
127137
#[inline(always)]
128-
pub unsafe fn record_stack_bounds(stack_lo: uint, stack_hi: uint) {
138+
pub unsafe fn record_os_managed_stack_bounds(stack_lo: uint, _stack_hi: uint) {
139+
record_sp_limit(stack_lo + RED_ZONE);
140+
}
141+
142+
#[inline(always)]
143+
pub unsafe fn record_rust_managed_stack_bounds(stack_lo: uint, stack_hi: uint) {
129144
// When the old runtime had segmented stacks, it used a calculation that was
130145
// "limit + RED_ZONE + FUDGE". The red zone was for things like dynamic
131146
// symbol resolution, llvm function calls, etc. In theory this red zone
@@ -138,16 +153,17 @@ pub unsafe fn record_stack_bounds(stack_lo: uint, stack_hi: uint) {
138153

139154
return target_record_stack_bounds(stack_lo, stack_hi);
140155

141-
#[cfg(not(windows))] #[cfg(not(target_arch = "x86_64"))] #[inline(always)]
156+
#[cfg(not(windows))] #[inline(always)]
142157
unsafe fn target_record_stack_bounds(_stack_lo: uint, _stack_hi: uint) {}
158+
159+
#[cfg(windows, target_arch = "x86")] #[inline(always)]
160+
unsafe fn target_record_stack_bounds(stack_lo: uint, stack_hi: uint) {
161+
// stack range is at TIB: %fs:0x04 (top) and %fs:0x08 (bottom)
162+
asm!("mov $0, %fs:0x04" :: "r"(stack_hi) :: "volatile");
163+
asm!("mov $0, %fs:0x08" :: "r"(stack_lo) :: "volatile");
164+
}
143165
#[cfg(windows, target_arch = "x86_64")] #[inline(always)]
144166
unsafe fn target_record_stack_bounds(stack_lo: uint, stack_hi: uint) {
145-
// Windows compiles C functions which may check the stack bounds. This
146-
// means that if we want to perform valid FFI on windows, then we need
147-
// to ensure that the stack bounds are what they truly are for this
148-
// task. More info can be found at:
149-
// https://github.com/rust-lang/rust/issues/3445#issuecomment-26114839
150-
//
151167
// stack range is at TIB: %gs:0x08 (top) and %gs:0x10 (bottom)
152168
asm!("mov $0, %gs:0x08" :: "r"(stack_hi) :: "volatile");
153169
asm!("mov $0, %gs:0x10" :: "r"(stack_lo) :: "volatile");

src/librustrt/thread.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ static DEFAULT_STACK_SIZE: uint = 1024 * 1024;
4444
#[no_split_stack]
4545
extern fn thread_start(main: *mut libc::c_void) -> imp::rust_thread_return {
4646
unsafe {
47-
stack::record_stack_bounds(0, uint::MAX);
47+
stack::record_os_managed_stack_bounds(0, uint::MAX);
4848
let f: Box<proc()> = mem::transmute(main);
4949
(*f)();
5050
mem::transmute(0 as imp::rust_thread_return)

0 commit comments

Comments
 (0)