diff --git a/Makefile.in b/Makefile.in index 9bb39a6777be0..f9700ed79df71 100644 --- a/Makefile.in +++ b/Makefile.in @@ -163,6 +163,7 @@ export CFG_LLVM_ROOT LLVM_AS := $(CFG_LLVM_BINDIR)/llvm-as +LLC := $(CFG_LLVM_BINDIR)/llc ###################################################################### # Single-target rules diff --git a/mk/rt.mk b/mk/rt.mk index 173d811e8c50f..f65fa99ee9d1c 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -31,6 +31,8 @@ RUNTIME_CS := rt/sync/timer.cpp \ rt/test/rust_test_runtime.cpp \ rt/test/rust_test_util.cpp +RUNTIME_LL := rt/new_exit.ll + RUNTIME_HDR := rt/globals.h \ rt/rust.h \ rt/rust_dwarf.h \ @@ -63,7 +65,7 @@ RUNTIME_HDR := rt/globals.h \ RUNTIME_DEF := rt/rustrt$(CFG_DEF_SUFFIX) RUNTIME_INCS := -I $(S)src/rt/isaac -I $(S)src/rt/uthash -RUNTIME_OBJS := $(RUNTIME_CS:.cpp=.o) +RUNTIME_OBJS := $(RUNTIME_CS:.cpp=.o) $(RUNTIME_LL:.ll=.o) RUNTIME_LIBS := $(CFG_GCCISH_POST_LIB_FLAGS) @@ -71,6 +73,9 @@ rt/%.o: rt/%.cpp $(MKFILES) @$(call E, compile: $@) $(Q)$(call CFG_COMPILE_C, $@, $(RUNTIME_INCS)) $< +rt/%.o: rt/%.ll $(MKFILES) + @$(call E, llc: $@) + $(Q)$(LLC) -filetype=obj -relocation-model=pic -march=x86 -o $@ $< rt/$(CFG_RUNTIME): $(RUNTIME_OBJS) $(MKFILES) $(RUNTIME_HDR) $(RUNTIME_DEF) @$(call E, link: $@) diff --git a/src/rt/new_exit.ll b/src/rt/new_exit.ll new file mode 100644 index 0000000000000..07798153ff4cc --- /dev/null +++ b/src/rt/new_exit.ll @@ -0,0 +1,11 @@ +declare fastcc i32 @rust_native_rust_1(i32, i32) + +declare i32 @upcall_exit(i32) + +define void @rust_new_exit_task_glue(i32, i32, i32, i32, i32) { +entry: + %5 = inttoptr i32 %0 to void (i32, i32, i32, i32)* + tail call fastcc void %5(i32 %1, i32 %2, i32 %3, i32 %4) + %6 = tail call fastcc i32 @rust_native_rust_1(i32 ptrtoint (i32 (i32)* @upcall_exit to i32), i32 %2) + ret void +} diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index 0c7ec8d3abef1..1e708be0a49ff 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -99,7 +99,7 @@ rust_start(uintptr_t main_fn, rust_crate const *crate, int argc, } uintptr_t main_args[4] = {0, 0, 0, (uintptr_t)args->args}; - dom->root_task->start(crate->get_exit_task_glue(), + dom->root_task->start((uintptr_t)rust_new_exit_task_glue, main_fn, (uintptr_t)&main_args, sizeof(main_args)); diff --git a/src/rt/rust_crate.cpp b/src/rt/rust_crate.cpp index 5e64a0125b345..6f1889ffc024c 100644 --- a/src/rt/rust_crate.cpp +++ b/src/rt/rust_crate.cpp @@ -16,11 +16,6 @@ rust_crate::get_activate_glue() const { return (activate_glue_ty) ((uintptr_t)this + activate_glue_off); } -uintptr_t -rust_crate::get_exit_task_glue() const { - return ((uintptr_t)this + exit_task_glue_off); -} - uintptr_t rust_crate::get_unwind_glue() const { return ((uintptr_t)this + unwind_glue_off); diff --git a/src/rt/rust_dom.cpp b/src/rt/rust_dom.cpp index 9c4faf56490c5..7a3ed513d666b 100644 --- a/src/rt/rust_dom.cpp +++ b/src/rt/rust_dom.cpp @@ -263,7 +263,7 @@ rust_dom::start_main_loop() { DLOG(this, dom, "started domain loop"); DLOG(this, dom, "activate glue: " PTR ", exit glue: " PTR, - root_crate->get_activate_glue(), root_crate->get_exit_task_glue()); + root_crate->get_activate_glue(), rust_new_exit_task_glue); while (number_of_live_tasks() > 0) { A(this, kernel->is_deadlocked() == false, "deadlock"); diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h index dcc2501d61a89..e743455b4dcf3 100644 --- a/src/rt/rust_internal.h +++ b/src/rt/rust_internal.h @@ -251,7 +251,6 @@ class rust_crate { uintptr_t get_yield_glue() const; uintptr_t get_unwind_glue() const; uintptr_t get_gc_glue() const; - uintptr_t get_exit_task_glue() const; struct mem_area { @@ -358,6 +357,8 @@ rust_crate_cache : public dom_owned, void flush(); }; +extern "C" void rust_new_exit_task_glue(); + #include "rust_dwarf.h" class diff --git a/src/rt/test/rust_test_runtime.cpp b/src/rt/test/rust_test_runtime.cpp index 1cde532e94a51..717d8b0c5f4dd 100644 --- a/src/rt/test/rust_test_runtime.cpp +++ b/src/rt/test/rust_test_runtime.cpp @@ -53,7 +53,7 @@ rust_task_test::worker::run() { rust_handle *handle = kernel->create_domain(crate, "test"); rust_dom *domain = handle->referent(); - domain->root_task->start(crate->get_exit_task_glue(), + domain->root_task->start((uintptr_t)rust_new_exit_task_glue, (uintptr_t)&task_entry, (uintptr_t)NULL, 0); domain->start_main_loop(); kernel->destroy_domain(domain);