Skip to content

Commit 1fec66f

Browse files
committed
---
yaml --- r: 6444 b: refs/heads/master c: 6bdf347 h: refs/heads/master v: v3
1 parent faa23fe commit 1fec66f

File tree

11 files changed

+113
-32
lines changed

11 files changed

+113
-32
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: a69c5617f02ff80dd7d39949004b386f9808b7d6
2+
refs/heads/master: 6bdf347418d04e48ef0fbbe0f4b2e940e9a24782

trunk/mk/rt.mk

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ RUNTIME_CS_$(1) := \
6767

6868
RUNTIME_S_$(1) := rt/arch/$$(HOST_$(1))/_context.S \
6969
rt/arch/$$(HOST_$(1))/ccall.S \
70-
rt/arch/$$(HOST_$(1))/morestack.S
70+
rt/arch/$$(HOST_$(1))/morestack.S \
71+
rt/arch/$$(HOST_$(1))/record_sp.S
7172

7273
RUNTIME_HDR_$(1) := rt/globals.h \
7374
rt/rust.h \

trunk/src/rt/arch/i386/morestack.S

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@
2929
#define ALIGNMENT 8
3030
#endif
3131

32+
#if defined (__APPLE__) || defined(_WIN32)
33+
#define NEW_STACK_ADDR rust_new_stack_sym-.L$pic_ref_pt_0(%eax)
34+
#define DEL_STACK_ADDR rust_del_stack_sym-.L$pic_ref_pt_1(%edx)
35+
#else
36+
#define NEW_STACK_ADDR $rust_new_stack
37+
#define DEL_STACK_ADDR $rust_del_stack
38+
#endif
39+
3240
#define RETURN_OFFSET 7
3341

3442
.globl RUST_NEW_STACK
@@ -39,6 +47,10 @@
3947
.globl UPCALL_CALL_C_STACK
4048
.globl MORESTACK
4149

50+
#ifdef __ELF__
51+
.type MORESTACK,@function
52+
#endif
53+
4254
MORESTACK:
4355

4456
// Sanity check to make sure that there is a currently-running task.
@@ -47,34 +59,33 @@ MORESTACK:
4759
testl %eax,%eax
4860
jz L$bail
4961

50-
subl $12,%esp
51-
pushl $12
62+
movl $12, (%esp)
5263
calll UPCALL_ALLOC_C_STACK
5364
movl %eax,%edx
5465

66+
movl %esp, 12(%edx)
5567
// C stack | esp+12
5668
// ---------------------+-------------------------
5769
movl 20(%esp),%eax // | ra stksz argsz x ra args
5870
movl %eax,8(%edx) // argsz > | ra stksz argsz x ra args
59-
leal 32(%esp),%eax // argsz | ra stksz argsz x ra args
71+
leal 28+ALIGNMENT(%esp),%eax // argsz | ra stksz argsz x ra args
6072
movl %eax,4(%edx) // argp > argsz | ra stksz argsz x ra args
6173
movl 16(%esp),%eax // argp argsz | ra stksz argsz x ra args
6274
movl %eax,(%edx) // stksz > argp argsz | ra stksz argsz x ra args
6375

64-
calll L$pic_ref_pt_0
65-
L$pic_ref_pt_0:
76+
calll .L$pic_ref_pt_0
77+
.L$pic_ref_pt_0:
6678
popl %eax
6779

68-
movl rust_new_stack_sym-L$pic_ref_pt_0(%eax),%eax
80+
movl NEW_STACK_ADDR,%eax
6981
movl %eax,(%esp)
7082
movl %edx,4(%esp)
7183
calll UPCALL_CALL_C_STACK
7284

73-
movl 16(%esp),%edx // Grab the return pointer.
85+
movl 12(%esp),%edx // Grab the return pointer.
7486
addl $RETURN_OFFSET,%edx // Skip past the `add esp,4` and the `ret`.
7587

7688
movl %eax,%esp // Switch stacks.
77-
subl $12,%esp // Align the stack.
7889
calll *%edx // Re-enter the function that called us.
7990

8091
// Now the function that called us has returned, so we need to delete the
@@ -86,22 +97,22 @@ L$pic_ref_pt_0:
8697
movl $0,(%esp)
8798
calll UPCALL_ALLOC_C_STACK
8899

89-
calll L$pic_ref_pt_1
90-
L$pic_ref_pt_1:
100+
calll .L$pic_ref_pt_1
101+
.L$pic_ref_pt_1:
91102
popl %edx
92103

93-
movl rust_del_stack_sym-L$pic_ref_pt_1(%edx),%edx
104+
movl DEL_STACK_ADDR,%edx
94105
movl %edx,(%esp)
95106
movl %eax,4(%esp)
96107
calll UPCALL_CALL_C_STACK
97108

98-
addl $16,%esp
99-
retl $16 + ALIGNMENT // ra stksz argsz x ra args
109+
addl $12,%esp
110+
retl $8 // ra stksz argsz x ra args
100111

101112
L$bail:
102113
movl 12(%esp),%edx
103114
addl $RETURN_OFFSET,%edx
104-
addl $12+16,%esp
115+
addl $12+4+8+ALIGNMENT,%esp
105116
jmpl *%edx
106117

107118
#ifdef __APPLE__
@@ -114,10 +125,5 @@ rust_del_stack_sym:
114125
.indirect_symbol RUST_DEL_STACK
115126
.long 0
116127

117-
#else
118-
119-
rust_new_stack_sym:
120-
rust_del_stack_sym:
121-
122128
#endif
123129

trunk/src/rt/arch/i386/record_sp.S

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
.text
2+
3+
#if defined(__APPLE__) || defined(_WIN32)
4+
#define RECORD_SP _record_sp
5+
#else
6+
#define RECORD_SP record_sp
7+
#endif
8+
9+
.globl RECORD_SP
10+
11+
#if defined(__linux__)
12+
RECORD_SP:
13+
movl 4(%esp), %eax
14+
movl %eax, %gs:48
15+
ret
16+
#else
17+
RECORD_SP:
18+
ret
19+
#endif

trunk/src/rt/rust_internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ static size_t const BUF_BYTES = 2048;
9494
// The error status to use when the process fails
9595
#define PROC_FAIL_CODE 101;
9696

97+
// FIXME: We want this to be 128 but need to slim the red zone calls down
98+
#define RED_ZONE_SIZE 256
99+
97100
// Every reference counted object should use this macro and initialize
98101
// ref_count.
99102

trunk/src/rt/rust_scheduler.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,10 +367,14 @@ rust_scheduler::init_tls() {
367367
tls_initialized = true;
368368
}
369369

370+
extern "C" CDECL void
371+
record_sp(void *limit);
372+
370373
void
371374
rust_scheduler::place_task_in_tls(rust_task *task) {
372375
int result = pthread_setspecific(task_key, task);
373376
assert(!result && "Couldn't place the task in TLS!");
377+
record_sp(task->stk->data + RED_ZONE_SIZE);
374378
}
375379

376380
rust_task *

trunk/src/rt/rust_task.cpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
#include "globals.h"
1616

17-
#define RED_ZONE_SIZE 128
1817

1918
// Stack size
2019
size_t g_custom_min_stack_size = 0;
@@ -63,30 +62,41 @@ del_stk(rust_task *task, stk_seg *stk)
6362
task->free(stk);
6463
}
6564

65+
extern "C" CDECL void
66+
record_sp(void *limit);
67+
6668
// Entry points for `__morestack` (see arch/*/morestack.S).
6769
extern "C" void *
68-
rust_new_stack(size_t stk_sz, void *args_addr, size_t args_sz) {
69-
std::cerr << "*** New stack!\n";
70-
70+
rust_new_stack(size_t stk_sz, void *args_addr, size_t args_sz,
71+
uintptr_t current_sp) {
7172
rust_task *task = rust_scheduler::get_task();
72-
if (!task)
73-
return NULL;
7473

75-
stk_seg *stk_seg = new_stk(task->sched, task, stk_sz);
76-
memcpy(stk_seg->data, args_addr, args_sz);
77-
return stk_seg->data;
74+
stk_seg *stk_seg = new_stk(task->sched, task, stk_sz + args_sz);
75+
76+
// Save the previous stack pointer so it can be restored later
77+
stk_seg->return_sp = current_sp;
78+
uint8_t *new_sp = (uint8_t*)stk_seg->limit;
79+
size_t sizeof_retaddr = sizeof(void*);
80+
// Make enough room on the new stack to hold the old stack pointer
81+
// in addition to the function arguments
82+
new_sp = align_down(new_sp - (args_sz + sizeof_retaddr));
83+
new_sp += sizeof_retaddr;
84+
memcpy(new_sp, args_addr, args_sz);
85+
record_sp(stk_seg->data + RED_ZONE_SIZE);
86+
return new_sp;
7887
}
7988

8089
extern "C" void
8190
rust_del_stack() {
8291
rust_task *task = rust_scheduler::get_task();
8392
del_stk(task, task->stk);
93+
record_sp(task->stk->data + RED_ZONE_SIZE);
8494
}
8595

86-
extern "C" void *
96+
extern "C" uintptr_t
8797
rust_get_prev_stack() {
8898
rust_task *task = rust_scheduler::get_task();
89-
return task->stk->next;
99+
return task->stk->return_sp;
90100
}
91101

92102
extern "C" rust_task *

trunk/src/rt/rust_task.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ struct rust_box;
2626
struct stk_seg {
2727
stk_seg *next;
2828
uintptr_t limit;
29+
uintptr_t return_sp;
2930
unsigned int valgrind_id;
3031
#ifndef _LP64
3132
uint32_t pad;

trunk/src/test/run-fail/morestack1.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// xfail-test
2+
fn getbig(i: int) {
3+
if i != 0 {
4+
getbig(i - 1);
5+
} else {
6+
fail;
7+
}
8+
}
9+
10+
fn main() {
11+
getbig(10000000);
12+
}

trunk/src/test/run-pass/morestack1.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// xfail-test
2+
fn getbig(i: int) {
3+
if i != 0 {
4+
getbig(i - 1);
5+
}
6+
}
7+
8+
fn main() {
9+
getbig(10000000);
10+
}

trunk/src/test/run-pass/morestack2.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// xfail-test
2+
fn getbig(i: int) -> int {
3+
let m = if i >= 0 {
4+
let j = getbig(i - 1);
5+
let k = getbig(j - 1);
6+
k
7+
} else {
8+
0
9+
};
10+
m
11+
}
12+
13+
fn main() {
14+
getbig(10000000);
15+
}

0 commit comments

Comments
 (0)