Skip to content

Commit f8a77a3

Browse files
committed
---
yaml --- r: 6059 b: refs/heads/master c: c9003d3 h: refs/heads/master i: 6057: d49b09d 6055: 9db1b0c v: v3
1 parent bf05076 commit f8a77a3

File tree

6 files changed

+78
-3
lines changed

6 files changed

+78
-3
lines changed

[refs]

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 799ba7b1226cda3cf167cbe1c7e8aaf2f78c82f9
2+
refs/heads/master: c9003d301f602cb44d8cc3fd464c95b09e08548e

trunk/mk/rt.mk

+2-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ RUNTIME_CS := rt/sync/timer.cpp \
3838
RUNTIME_LL :=
3939

4040
RUNTIME_S := rt/arch/i386/_context.S \
41-
rt/arch/i386/ccall.S
41+
rt/arch/i386/ccall.S \
42+
rt/arch/i386/morestack.S
4243

4344
RUNTIME_HDR := rt/globals.h \
4445
rt/rust.h \

trunk/mk/rustllvm.mk

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
RUSTLLVM_OBJS_CS := $(addprefix rustllvm/, RustGCMetadataPrinter.cpp \
66
RustGCStrategy.cpp RustWrapper.cpp)
77

8+
# Behind an ifdef for now since this requires a patched LLVM.
9+
ifdef CFG_STACK_GROWTH
10+
RUSTLLVM_OBJS_CS += rustllvm/RustPrologHook.cpp
11+
endif
12+
813
RUSTLLVM_DEF := rustllvm/rustllvm$(CFG_DEF_SUFFIX)
914

1015
RUSTLLVM_INCS := -iquote $(CFG_LLVM_INCDIR) \

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

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
.text
2+
3+
// __morestack
4+
//
5+
// LLVM generates a call to this to allocate more stack space in a functiono
6+
// prolog when we run out.
7+
8+
#if defined(__APPLE__) || defined(_WIN32)
9+
#define RUST_NEW_STACK _rust_new_stack
10+
#define RUST_DEL_STACK _rust_del_stack
11+
#else
12+
#define RUST_NEW_STACK rust_new_stack
13+
#define RUST_DEL_STACK rust_del_stack
14+
#endif
15+
16+
.globl RUST_NEW_STACK
17+
.globl RUST_DEL_STACK
18+
19+
.globl __morestack
20+
21+
__morestack:
22+
pushl %edx // param 2: size of arguments
23+
leal 8(%esp),%eax
24+
pushl %eax // param 1: starting addr of arguments
25+
pushl %ecx // param 0: amount of space needed
26+
calll RUST_NEW_STACK
27+
28+
movl (%esp),%edx // Grab the return pointer.
29+
incl %edx // Skip past the `ret`.
30+
movl %eax,%esp // Switch to the new stack.
31+
calll *%edx // Enter the new function.
32+
33+
// Now the function that called us has returned, so we need to delete the
34+
// old stack space.
35+
calll RUST_DEL_STACK
36+
movl %eax,%esp // Switch back to the old stack.
37+
retl
38+

trunk/src/rt/rust_task.cpp

+26
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#ifndef __WIN32__
99
#include <execinfo.h>
1010
#endif
11+
#include <cassert>
12+
#include <cstring>
1113

1214
#include "globals.h"
1315

@@ -36,22 +38,46 @@ new_stk(rust_scheduler *sched, rust_task *task, size_t minsz)
3638
stk_seg *stk = (stk_seg *)task->malloc(sz, "stack");
3739
LOGPTR(task->sched, "new stk", (uintptr_t)stk);
3840
memset(stk, 0, sizeof(stk_seg));
41+
stk->next = task->stk;
3942
stk->limit = (uintptr_t) &stk->data[minsz];
4043
LOGPTR(task->sched, "stk limit", stk->limit);
4144
stk->valgrind_id =
4245
VALGRIND_STACK_REGISTER(&stk->data[0],
4346
&stk->data[minsz]);
47+
task->stk = stk;
4448
return stk;
4549
}
4650

4751
static void
4852
del_stk(rust_task *task, stk_seg *stk)
4953
{
54+
assert(stk == task->stk && "Freeing stack segments out of order!");
55+
56+
task->stk = stk->next;
57+
5058
VALGRIND_STACK_DEREGISTER(stk->valgrind_id);
5159
LOGPTR(task->sched, "freeing stk segment", (uintptr_t)stk);
5260
task->free(stk);
5361
}
5462

63+
// Entry points for `__morestack` (see arch/*/morestack.S).
64+
extern "C" void *
65+
rust_new_stack(size_t stk_sz, void *args_addr, size_t args_sz) {
66+
rust_task *task = rust_scheduler::get_task();
67+
stk_seg *stk_seg = new_stk(task->sched, task, stk_sz);
68+
memcpy(stk_seg->data, args_addr, args_sz);
69+
return stk_seg->data;
70+
}
71+
72+
extern "C" void *
73+
rust_del_stack() {
74+
rust_task *task = rust_scheduler::get_task();
75+
stk_seg *next_seg = task->stk->next;
76+
del_stk(task, task->stk);
77+
return next_seg->data;
78+
}
79+
80+
5581
// Tasks
5682
rust_task::rust_task(rust_scheduler *sched, rust_task_list *state,
5783
rust_task *spawner, const char *name) :

trunk/src/rt/rust_task.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,13 @@ struct chan_handle {
2424
struct rust_box;
2525

2626
struct stk_seg {
27-
unsigned int valgrind_id;
27+
stk_seg *next;
2828
uintptr_t limit;
29+
unsigned int valgrind_id;
30+
#ifndef _LP64
31+
uint32_t pad;
32+
#endif
33+
2934
uint8_t data[];
3035
};
3136

0 commit comments

Comments
 (0)