From 19adece68b00bd1873499cca6f1537750608d769 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 13 Jun 2013 12:40:22 -0700 Subject: [PATCH] Revert "Have JIT execution take ownership of the LLVMContextRef" This reverts commit 5c5095d25e3652c434c8d4ec178e6844877e3c2d. Conflicts: src/librusti/rusti.rc --- src/librustc/back/link.rs | 64 ++++++++++--------------------- src/librustc/driver/driver.rs | 10 ++--- src/librustc/lib/llvm.rs | 14 ++----- src/librustc/middle/trans/base.rs | 23 +++++------ src/librusti/rusti.rc | 4 ++ src/rustllvm/RustWrapper.cpp | 30 +++++++++------ src/rustllvm/rustllvm.def.in | 4 +- src/rustllvm/rustllvm.h | 1 - 8 files changed, 61 insertions(+), 89 deletions(-) diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index f37ef83e770..3c8705b4ee9 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -102,7 +102,7 @@ pub mod jit { use back::link::llvm_err; use driver::session::Session; use lib::llvm::llvm; - use lib::llvm::{ModuleRef, PassManagerRef, ContextRef}; + use lib::llvm::{ModuleRef, PassManagerRef}; use metadata::cstore; use core::cast; @@ -125,7 +125,6 @@ pub mod jit { pub fn exec(sess: Session, pm: PassManagerRef, - c: ContextRef, m: ModuleRef, opt: c_int, stacks: bool) { @@ -154,43 +153,26 @@ pub mod jit { }); } - // We custom-build a JIT execution engine via some rust wrappers - // first. This wrappers takes ownership of the module passed in. - let ee = llvm::LLVMRustBuildJIT(manager, pm, m, opt, stacks); - if ee.is_null() { - llvm::LLVMContextDispose(c); - llvm_err(sess, ~"Could not create the JIT"); + // The execute function will return a void pointer + // to the _rust_main function. We can do closure + // magic here to turn it straight into a callable rust + // closure. It will also cleanup the memory manager + // for us. + + let entry = llvm::LLVMRustExecuteJIT(manager, + pm, m, opt, stacks); + + if ptr::is_null(entry) { + llvm_err(sess, ~"Could not JIT"); + } else { + let closure = Closure { + code: entry, + env: ptr::null() + }; + let func: &fn() = cast::transmute(closure); + + func(); } - - // Next, we need to get a handle on the _rust_main function by - // looking up it's corresponding ValueRef and then requesting that - // the execution engine compiles the function. - let fun = do str::as_c_str("_rust_main") |entry| { - llvm::LLVMGetNamedFunction(m, entry) - }; - if fun.is_null() { - llvm::LLVMDisposeExecutionEngine(ee); - llvm::LLVMContextDispose(c); - llvm_err(sess, ~"Could not find _rust_main in the JIT"); - } - - // Finally, once we have the pointer to the code, we can do some - // closure magic here to turn it straight into a callable rust - // closure - let code = llvm::LLVMGetPointerToGlobal(ee, fun); - assert!(!code.is_null()); - let closure = Closure { - code: code, - env: ptr::null() - }; - let func: &fn() = cast::transmute(closure); - func(); - - // Sadly, there currently is no interface to re-use this execution - // engine, so it's disposed of here along with the context to - // prevent leaks. - llvm::LLVMDisposeExecutionEngine(ee); - llvm::LLVMContextDispose(c); } } } @@ -207,7 +189,6 @@ pub mod write { use driver::session; use lib::llvm::llvm; use lib::llvm::{ModuleRef, mk_pass_manager, mk_target_data}; - use lib::llvm::{ContextRef}; use lib; use back::passes; @@ -226,7 +207,6 @@ pub mod write { } pub fn run_passes(sess: Session, - llcx: ContextRef, llmod: ModuleRef, output_type: output_type, output: &Path) { @@ -301,7 +281,7 @@ pub mod write { // JIT execution takes ownership of the module, // so don't dispose and return. - jit::exec(sess, pm.llpm, llcx, llmod, CodeGenOptLevel, true); + jit::exec(sess, pm.llpm, llmod, CodeGenOptLevel, true); if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); @@ -369,7 +349,6 @@ pub mod write { // Clean up and return llvm::LLVMDisposeModule(llmod); - llvm::LLVMContextDispose(llcx); if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); } @@ -388,7 +367,6 @@ pub mod write { } llvm::LLVMDisposeModule(llmod); - llvm::LLVMContextDispose(llcx); if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); } } } diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 0447481596a..b72cdd40ecd 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -216,7 +216,7 @@ pub fn compile_rest(sess: Session, let mut crate = crate_opt.unwrap(); - let (llcx, llmod, link_meta) = { + let (llmod, link_meta) = { crate = time(time_passes, ~"intrinsic injection", || front::intrinsic_inject::inject_intrinsic(sess, crate)); @@ -339,14 +339,14 @@ pub fn compile_rest(sess: Session, let obj_filename = outputs.obj_filename.with_filetype("s"); time(time_passes, ~"LLVM passes", || - link::write::run_passes(sess, llcx, llmod, output_type, - &obj_filename)); + link::write::run_passes(sess, llmod, output_type, + &obj_filename)); link::write::run_ndk(sess, &obj_filename, &outputs.obj_filename); } else { time(time_passes, ~"LLVM passes", || - link::write::run_passes(sess, llcx, llmod, sess.opts.output_type, - &outputs.obj_filename)); + link::write::run_passes(sess, llmod, sess.opts.output_type, + &outputs.obj_filename)); } let stop_after_codegen = diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index b18c9e9b4c2..0e9ea982d9f 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -205,8 +205,6 @@ pub enum BasicBlock_opaque {} pub type BasicBlockRef = *BasicBlock_opaque; pub enum Builder_opaque {} pub type BuilderRef = *Builder_opaque; -pub enum ExecutionEngine_opaque {} -pub type ExecutionEngineRef = *ExecutionEngine_opaque; pub enum MemoryBuffer_opaque {} pub type MemoryBufferRef = *MemoryBuffer_opaque; pub enum PassManager_opaque {} @@ -225,7 +223,7 @@ pub enum Pass_opaque {} pub type PassRef = *Pass_opaque; pub mod llvm { - use super::{AtomicBinOp, AtomicOrdering, BasicBlockRef, ExecutionEngineRef}; + use super::{AtomicBinOp, AtomicOrdering, BasicBlockRef}; use super::{Bool, BuilderRef, ContextRef, MemoryBufferRef, ModuleRef}; use super::{ObjectFileRef, Opcode, PassManagerRef, PassManagerBuilderRef}; use super::{SectionIteratorRef, TargetDataRef, TypeKind, TypeRef, UseRef}; @@ -365,10 +363,6 @@ pub mod llvm { pub unsafe fn LLVMGetPointerAddressSpace(PointerTy: TypeRef) -> c_uint; #[fast_ffi] - pub unsafe fn LLVMGetPointerToGlobal(EE: ExecutionEngineRef, - V: ValueRef) - -> *(); - #[fast_ffi] pub unsafe fn LLVMGetVectorSize(VectorTy: TypeRef) -> c_uint; /* Operations on other types */ @@ -1009,8 +1003,6 @@ pub mod llvm { Name: *c_char); #[fast_ffi] pub unsafe fn LLVMDisposeBuilder(Builder: BuilderRef); - #[fast_ffi] - pub unsafe fn LLVMDisposeExecutionEngine(EE: ExecutionEngineRef); /* Metadata */ #[fast_ffi] @@ -1827,11 +1819,11 @@ pub mod llvm { /** Execute the JIT engine. */ #[fast_ffi] - pub unsafe fn LLVMRustBuildJIT(MM: *(), + pub unsafe fn LLVMRustExecuteJIT(MM: *(), PM: PassManagerRef, M: ModuleRef, OptLevel: c_int, - EnableSegmentedStacks: bool) -> ExecutionEngineRef; + EnableSegmentedStacks: bool) -> *(); /** Parses the bitcode in the given memory buffer. */ #[fast_ffi] diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 7337b07c402..eefc162d0e3 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -3018,7 +3018,7 @@ pub fn trans_crate(sess: session::Session, tcx: ty::ctxt, output: &Path, emap2: resolve::ExportMap2, - maps: astencode::Maps) -> (ContextRef, ModuleRef, LinkMeta) { + maps: astencode::Maps) -> (ModuleRef, LinkMeta) { let symbol_hasher = @mut hash::default_state(); let link_meta = link::build_link_meta(sess, crate, output, symbol_hasher); @@ -3040,11 +3040,9 @@ pub fn trans_crate(sess: session::Session, let llmod_id = link_meta.name.to_owned() + ".rc"; unsafe { - // FIXME(#6511): get LLVM building with --enable-threads so this - // function can be called - // if !llvm::LLVMRustStartMultithreading() { - // sess.bug("couldn't enable multi-threaded LLVM"); - // } + if !llvm::LLVMRustStartMultithreading() { + sess.bug("couldn't enable multi-threaded LLVM"); + } let llcx = llvm::LLVMContextCreate(); set_task_llcx(llcx); let llmod = str::as_c_str(llmod_id, |buf| { @@ -3180,8 +3178,7 @@ pub fn trans_crate(sess: session::Session, io::println(fmt!("%-7u %s", v, k)); } } - unset_task_llcx(); - return (llcx, llmod, link_meta); + return (llmod, link_meta); } } @@ -3192,10 +3189,8 @@ pub fn task_llcx() -> ContextRef { *opt.expect("task-local LLVMContextRef wasn't ever set!") } -unsafe fn set_task_llcx(c: ContextRef) { - local_data::local_data_set(task_local_llcx_key, @c); -} - -unsafe fn unset_task_llcx() { - local_data::local_data_pop(task_local_llcx_key); +fn set_task_llcx(c: ContextRef) { + unsafe { + local_data::local_data_set(task_local_llcx_key, @c); + } } diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc index 90a5a350b7f..1a97c806027 100644 --- a/src/librusti/rusti.rc +++ b/src/librusti/rusti.rc @@ -648,5 +648,9 @@ mod tests { fn f() {} f() "); + + debug!("regression test for #5803"); + run_cmds(["spawn( || println(\"Please don't segfault\") );", + "do spawn { println(\"Please?\"); }"]); } } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 30e01b53ab7..17eb0f50b9b 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -329,12 +329,12 @@ LLVMRustLoadCrate(void* mem, const char* crate) { return true; } -extern "C" LLVMExecutionEngineRef -LLVMRustBuildJIT(void* mem, - LLVMPassManagerRef PMR, - LLVMModuleRef M, - CodeGenOpt::Level OptLevel, - bool EnableSegmentedStacks) { +extern "C" void* +LLVMRustExecuteJIT(void* mem, + LLVMPassManagerRef PMR, + LLVMModuleRef M, + CodeGenOpt::Level OptLevel, + bool EnableSegmentedStacks) { InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); @@ -371,15 +371,21 @@ LLVMRustBuildJIT(void* mem, if(!EE || Err != "") { LLVMRustError = Err.c_str(); - // The EngineBuilder only takes ownership of these two structures if the - // create() call is successful, but here it wasn't successful. - LLVMDisposeModule(M); - delete MM; - return NULL; + return 0; } MM->invalidateInstructionCache(); - return wrap(EE); + Function* func = EE->FindFunctionNamed("_rust_main"); + + if(!func || Err != "") { + LLVMRustError = Err.c_str(); + return 0; + } + + void* entry = EE->getPointerToFunction(func); + assert(entry); + + return entry; } extern "C" bool diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in index f5397165781..f8c68d798b9 100644 --- a/src/rustllvm/rustllvm.def.in +++ b/src/rustllvm/rustllvm.def.in @@ -6,14 +6,13 @@ LLVMRustConstSmallInt LLVMRustConstInt LLVMRustLoadCrate LLVMRustPrepareJIT -LLVMRustBuildJIT +LLVMRustExecuteJIT LLVMRustParseBitcode LLVMRustParseAssemblyFile LLVMRustPrintPassTimings LLVMRustStartMultithreading LLVMCreateObjectFile LLVMDisposeObjectFile -LLVMDisposeExecutionEngine LLVMGetSections LLVMDisposeSectionIterator LLVMIsSectionIteratorAtEnd @@ -357,7 +356,6 @@ LLVMGetParamParent LLVMGetParamTypes LLVMGetParams LLVMGetPointerAddressSpace -LLVMGetPointerToGlobal LLVMGetPreviousBasicBlock LLVMGetPreviousFunction LLVMGetPreviousGlobal diff --git a/src/rustllvm/rustllvm.h b/src/rustllvm/rustllvm.h index 394146eea20..1c8842f7b4a 100644 --- a/src/rustllvm/rustllvm.h +++ b/src/rustllvm/rustllvm.h @@ -45,7 +45,6 @@ #include "llvm/Transforms/Vectorize.h" #include "llvm-c/Core.h" #include "llvm-c/BitReader.h" -#include "llvm-c/ExecutionEngine.h" #include "llvm-c/Object.h" // Used by RustMCJITMemoryManager::getPointerToNamedFunction()