mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 11:48:30 +00:00
Stub a __morestack implementation and stack segment allocation. Untested.
This commit is contained in:
parent
799ba7b122
commit
c9003d301f
3
mk/rt.mk
3
mk/rt.mk
@ -38,7 +38,8 @@ RUNTIME_CS := rt/sync/timer.cpp \
|
|||||||
RUNTIME_LL :=
|
RUNTIME_LL :=
|
||||||
|
|
||||||
RUNTIME_S := rt/arch/i386/_context.S \
|
RUNTIME_S := rt/arch/i386/_context.S \
|
||||||
rt/arch/i386/ccall.S
|
rt/arch/i386/ccall.S \
|
||||||
|
rt/arch/i386/morestack.S
|
||||||
|
|
||||||
RUNTIME_HDR := rt/globals.h \
|
RUNTIME_HDR := rt/globals.h \
|
||||||
rt/rust.h \
|
rt/rust.h \
|
||||||
|
@ -5,6 +5,11 @@
|
|||||||
RUSTLLVM_OBJS_CS := $(addprefix rustllvm/, RustGCMetadataPrinter.cpp \
|
RUSTLLVM_OBJS_CS := $(addprefix rustllvm/, RustGCMetadataPrinter.cpp \
|
||||||
RustGCStrategy.cpp RustWrapper.cpp)
|
RustGCStrategy.cpp RustWrapper.cpp)
|
||||||
|
|
||||||
|
# Behind an ifdef for now since this requires a patched LLVM.
|
||||||
|
ifdef CFG_STACK_GROWTH
|
||||||
|
RUSTLLVM_OBJS_CS += rustllvm/RustPrologHook.cpp
|
||||||
|
endif
|
||||||
|
|
||||||
RUSTLLVM_DEF := rustllvm/rustllvm$(CFG_DEF_SUFFIX)
|
RUSTLLVM_DEF := rustllvm/rustllvm$(CFG_DEF_SUFFIX)
|
||||||
|
|
||||||
RUSTLLVM_INCS := -iquote $(CFG_LLVM_INCDIR) \
|
RUSTLLVM_INCS := -iquote $(CFG_LLVM_INCDIR) \
|
||||||
|
38
src/rt/arch/i386/morestack.S
Normal file
38
src/rt/arch/i386/morestack.S
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
.text
|
||||||
|
|
||||||
|
// __morestack
|
||||||
|
//
|
||||||
|
// LLVM generates a call to this to allocate more stack space in a functiono
|
||||||
|
// prolog when we run out.
|
||||||
|
|
||||||
|
#if defined(__APPLE__) || defined(_WIN32)
|
||||||
|
#define RUST_NEW_STACK _rust_new_stack
|
||||||
|
#define RUST_DEL_STACK _rust_del_stack
|
||||||
|
#else
|
||||||
|
#define RUST_NEW_STACK rust_new_stack
|
||||||
|
#define RUST_DEL_STACK rust_del_stack
|
||||||
|
#endif
|
||||||
|
|
||||||
|
.globl RUST_NEW_STACK
|
||||||
|
.globl RUST_DEL_STACK
|
||||||
|
|
||||||
|
.globl __morestack
|
||||||
|
|
||||||
|
__morestack:
|
||||||
|
pushl %edx // param 2: size of arguments
|
||||||
|
leal 8(%esp),%eax
|
||||||
|
pushl %eax // param 1: starting addr of arguments
|
||||||
|
pushl %ecx // param 0: amount of space needed
|
||||||
|
calll RUST_NEW_STACK
|
||||||
|
|
||||||
|
movl (%esp),%edx // Grab the return pointer.
|
||||||
|
incl %edx // Skip past the `ret`.
|
||||||
|
movl %eax,%esp // Switch to the new stack.
|
||||||
|
calll *%edx // Enter the new function.
|
||||||
|
|
||||||
|
// Now the function that called us has returned, so we need to delete the
|
||||||
|
// old stack space.
|
||||||
|
calll RUST_DEL_STACK
|
||||||
|
movl %eax,%esp // Switch back to the old stack.
|
||||||
|
retl
|
||||||
|
|
@ -8,6 +8,8 @@
|
|||||||
#ifndef __WIN32__
|
#ifndef __WIN32__
|
||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
|
||||||
@ -36,22 +38,46 @@ new_stk(rust_scheduler *sched, rust_task *task, size_t minsz)
|
|||||||
stk_seg *stk = (stk_seg *)task->malloc(sz, "stack");
|
stk_seg *stk = (stk_seg *)task->malloc(sz, "stack");
|
||||||
LOGPTR(task->sched, "new stk", (uintptr_t)stk);
|
LOGPTR(task->sched, "new stk", (uintptr_t)stk);
|
||||||
memset(stk, 0, sizeof(stk_seg));
|
memset(stk, 0, sizeof(stk_seg));
|
||||||
|
stk->next = task->stk;
|
||||||
stk->limit = (uintptr_t) &stk->data[minsz];
|
stk->limit = (uintptr_t) &stk->data[minsz];
|
||||||
LOGPTR(task->sched, "stk limit", stk->limit);
|
LOGPTR(task->sched, "stk limit", stk->limit);
|
||||||
stk->valgrind_id =
|
stk->valgrind_id =
|
||||||
VALGRIND_STACK_REGISTER(&stk->data[0],
|
VALGRIND_STACK_REGISTER(&stk->data[0],
|
||||||
&stk->data[minsz]);
|
&stk->data[minsz]);
|
||||||
|
task->stk = stk;
|
||||||
return stk;
|
return stk;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
del_stk(rust_task *task, stk_seg *stk)
|
del_stk(rust_task *task, stk_seg *stk)
|
||||||
{
|
{
|
||||||
|
assert(stk == task->stk && "Freeing stack segments out of order!");
|
||||||
|
|
||||||
|
task->stk = stk->next;
|
||||||
|
|
||||||
VALGRIND_STACK_DEREGISTER(stk->valgrind_id);
|
VALGRIND_STACK_DEREGISTER(stk->valgrind_id);
|
||||||
LOGPTR(task->sched, "freeing stk segment", (uintptr_t)stk);
|
LOGPTR(task->sched, "freeing stk segment", (uintptr_t)stk);
|
||||||
task->free(stk);
|
task->free(stk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Entry points for `__morestack` (see arch/*/morestack.S).
|
||||||
|
extern "C" void *
|
||||||
|
rust_new_stack(size_t stk_sz, void *args_addr, size_t args_sz) {
|
||||||
|
rust_task *task = rust_scheduler::get_task();
|
||||||
|
stk_seg *stk_seg = new_stk(task->sched, task, stk_sz);
|
||||||
|
memcpy(stk_seg->data, args_addr, args_sz);
|
||||||
|
return stk_seg->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void *
|
||||||
|
rust_del_stack() {
|
||||||
|
rust_task *task = rust_scheduler::get_task();
|
||||||
|
stk_seg *next_seg = task->stk->next;
|
||||||
|
del_stk(task, task->stk);
|
||||||
|
return next_seg->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Tasks
|
// Tasks
|
||||||
rust_task::rust_task(rust_scheduler *sched, rust_task_list *state,
|
rust_task::rust_task(rust_scheduler *sched, rust_task_list *state,
|
||||||
rust_task *spawner, const char *name) :
|
rust_task *spawner, const char *name) :
|
||||||
|
@ -24,8 +24,13 @@ struct chan_handle {
|
|||||||
struct rust_box;
|
struct rust_box;
|
||||||
|
|
||||||
struct stk_seg {
|
struct stk_seg {
|
||||||
unsigned int valgrind_id;
|
stk_seg *next;
|
||||||
uintptr_t limit;
|
uintptr_t limit;
|
||||||
|
unsigned int valgrind_id;
|
||||||
|
#ifndef _LP64
|
||||||
|
uint32_t pad;
|
||||||
|
#endif
|
||||||
|
|
||||||
uint8_t data[];
|
uint8_t data[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user