diff --git a/mk/rt.mk b/mk/rt.mk index d858fec0976e..3ca15beb31a2 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -33,7 +33,7 @@ RUNTIME_CS := rt/sync/timer.cpp \ RUNTIME_LL := rt/new_exit.ll -RUNTIME_S := rt/activate_glue.s +RUNTIME_S := rt/activate_glue.s rt/yield_glue.s RUNTIME_HDR := rt/globals.h \ rt/rust.h \ diff --git a/src/comp/back/x86.rs b/src/comp/back/x86.rs index 7d32a21caa30..79235df1d99d 100644 --- a/src/comp/back/x86.rs +++ b/src/comp/back/x86.rs @@ -86,43 +86,6 @@ fn store_esp_to_runtime_sp_second_arg() -> vec[str] { ret ["movl %esp, " + wstr(abi::task_field_runtime_sp) + "(%edx)"]; } - -/* More glue code, this time the 'bottom half' of yielding. - * - * We arrived here because an native call decided to deschedule the - * running task. So the native call's return address got patched to the - * first instruction of this glue code. - * - * When the native call does 'ret' it will come here, and its esp will be - * pointing to the last argument pushed on the C stack before making - * the native call: the 0th argument to the native call, which is always - * the task ptr performing the native call. That's where we take over. - * - * Our goal is to complete the descheduling - * - * - Switch over to the task stack temporarily. - * - * - Save the task's callee-saves onto the task stack. - * (the task is now 'descheduled', safe to set aside) - * - * - Switch *back* to the C stack. - * - * - Restore the C-stack callee-saves. - * - * - Return to the caller on the C stack that activated the task. - * - */ - -fn rust_yield_glue() -> vec[str] { - ret ["movl 0(%esp), %ecx # ecx = rust_task"] - + load_esp_from_rust_sp_first_arg() - + save_callee_saves() - + store_esp_to_rust_sp_first_arg() - + load_esp_from_runtime_sp_first_arg() - + restore_callee_saves() - + ["ret"]; -} - fn native_glue(int n_args, abi::native_glue_type ngt) -> vec[str] { let bool pass_task; @@ -218,11 +181,8 @@ fn get_module_asm() -> str { auto prefix = get_symbol_prefix(); - auto glues = - [decl_glue(align, prefix, - abi::yield_glue_name(), - rust_yield_glue())] - + let vec[str] glues = + [] + vec::init_fn[str](bind decl_native_glue(align, prefix, abi::ngt_rust, _), (abi::n_native_glues + 1) as uint) + vec::init_fn[str](bind decl_native_glue(align, prefix, diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 7c71a00f03cc..9895cb47d129 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -7660,9 +7660,6 @@ fn create_crate_constant(ValueRef crate_ptr, @glue_fns glues) { let ValueRef crate_addr = p2i(crate_ptr); - let ValueRef yield_glue_off = - llvm::LLVMConstSub(p2i(glues.yield_glue), crate_addr); - let ValueRef crate_val = C_struct([C_null(T_int()), // ptrdiff_t image_base_off p2i(crate_ptr), // uintptr_t self_addr @@ -7671,10 +7668,10 @@ fn create_crate_constant(ValueRef crate_ptr, @glue_fns glues) { C_null(T_int()), // ptrdiff_t debug_info_off C_null(T_int()), // size_t debug_info_sz C_null(T_int()), // size_t pad - yield_glue_off, // size_t yield_glue_off C_null(T_int()), // size_t pad - C_null(T_int()), // size_t gc_glue_off C_null(T_int()), // size_t pad2 + C_null(T_int()), // size_t gc_glue_off + C_null(T_int()), // size_t pad3 C_null(T_int()), // int n_rust_syms C_null(T_int()), // int n_c_syms C_null(T_int()) // int n_libs diff --git a/src/rt/rust_crate.cpp b/src/rt/rust_crate.cpp index 6783d43c04ca..2e312c8c564b 100644 --- a/src/rt/rust_crate.cpp +++ b/src/rt/rust_crate.cpp @@ -16,11 +16,6 @@ rust_crate::get_gc_glue() const { return ((uintptr_t)this + gc_glue_off); } -uintptr_t -rust_crate::get_yield_glue() const { - return ((uintptr_t)this + yield_glue_off); -} - rust_crate::mem_area::mem_area(rust_dom *dom, uintptr_t pos, size_t sz) : dom(dom), base(pos), diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h index 6bd638ed4698..03022812a091 100644 --- a/src/rt/rust_internal.h +++ b/src/rt/rust_internal.h @@ -232,10 +232,10 @@ class rust_crate { size_t debug_info_sz; // Size of .debug_info. ptrdiff_t activate_glue_off; - ptrdiff_t yield_glue_off; ptrdiff_t pad; - ptrdiff_t gc_glue_off; ptrdiff_t pad2; + ptrdiff_t gc_glue_off; + ptrdiff_t pad3; public: @@ -247,7 +247,6 @@ public: uintptr_t get_image_base() const; ptrdiff_t get_relocation_diff() const; - uintptr_t get_yield_glue() const; uintptr_t get_gc_glue() const; struct mem_area diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index db72be6d12d6..bd57eb89cca3 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -317,12 +317,14 @@ rust_task::yield(size_t nargs) { yield(nargs, 0); } +extern "C" void new_rust_yield_glue(void) asm("new_rust_yield_glue"); + void rust_task::yield(size_t nargs, size_t time_in_us) { LOG(this, task, "task %s @0x%" PRIxPTR " yielding for %d us", name, this, time_in_us); yield_timer.reset(time_in_us); - run_after_return(nargs, dom->root_crate->get_yield_glue()); + run_after_return(nargs, (uintptr_t) new_rust_yield_glue); } static inline uintptr_t diff --git a/src/rt/yield_glue.s b/src/rt/yield_glue.s new file mode 100644 index 000000000000..767c9c5cae6d --- /dev/null +++ b/src/rt/yield_glue.s @@ -0,0 +1,42 @@ +/* More glue code, this time the 'bottom half' of yielding. + * + * We arrived here because an native call decided to deschedule the + * running task. So the native call's return address got patched to the + * first instruction of this glue code. + * + * When the native call does 'ret' it will come here, and its esp will be + * pointing to the last argument pushed on the C stack before making + * the native call: the 0th argument to the native call, which is always + * the task ptr performing the native call. That's where we take over. + * + * Our goal is to complete the descheduling + * + * - Switch over to the task stack temporarily. + * + * - Save the task's callee-saves onto the task stack. + * (the task is now 'descheduled', safe to set aside) + * + * - Switch *back* to the C stack. + * + * - Restore the C-stack callee-saves. + * + * - Return to the caller on the C stack that activated the task. + * + */ + + .globl new_rust_yield_glue + .balign 4 +new_rust_yield_glue: + movl 0(%esp), %ecx # ecx = rust_task + movl 16(%ecx), %esp + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + movl %esp, 16(%ecx) + movl 12(%ecx), %esp + popl %ebx + popl %esi + popl %edi + popl %ebp + ret