Skip to content

Commit 68a9c78

Browse files
committed
---
yaml --- r: 63178 b: refs/heads/snap-stage3 c: 5c5095d h: refs/heads/master v: v3
1 parent a77154f commit 68a9c78

File tree

9 files changed

+94
-60
lines changed

9 files changed

+94
-60
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 2d28d645422c1617be58c8ca7ad9a457264ca850
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 779191cd4b8719e8efdf69fb6da93e2a8905ca1d
4+
refs/heads/snap-stage3: 5c5095d25e3652c434c8d4ec178e6844877e3c2d
55
refs/heads/try: 7b78b52e602bb3ea8174f9b2006bff3315f03ef9
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/librustc/back/link.rs

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ pub mod jit {
103103
use back::link::llvm_err;
104104
use driver::session::Session;
105105
use lib::llvm::llvm;
106-
use lib::llvm::{ModuleRef, PassManagerRef};
106+
use lib::llvm::{ModuleRef, PassManagerRef, ContextRef};
107107
use metadata::cstore;
108108

109109
use core::cast;
@@ -126,6 +126,7 @@ pub mod jit {
126126

127127
pub fn exec(sess: Session,
128128
pm: PassManagerRef,
129+
c: ContextRef,
129130
m: ModuleRef,
130131
opt: c_int,
131132
stacks: bool) {
@@ -154,26 +155,43 @@ pub mod jit {
154155
});
155156
}
156157

157-
// The execute function will return a void pointer
158-
// to the _rust_main function. We can do closure
159-
// magic here to turn it straight into a callable rust
160-
// closure. It will also cleanup the memory manager
161-
// for us.
162-
163-
let entry = llvm::LLVMRustExecuteJIT(manager,
164-
pm, m, opt, stacks);
165-
166-
if ptr::is_null(entry) {
167-
llvm_err(sess, ~"Could not JIT");
168-
} else {
169-
let closure = Closure {
170-
code: entry,
171-
env: ptr::null()
172-
};
173-
let func: &fn() = cast::transmute(closure);
158+
// We custom-build a JIT execution engine via some rust wrappers
159+
// first. This wrappers takes ownership of the module passed in.
160+
let ee = llvm::LLVMRustBuildJIT(manager, pm, m, opt, stacks);
161+
if ee.is_null() {
162+
llvm::LLVMContextDispose(c);
163+
llvm_err(sess, ~"Could not create the JIT");
164+
}
174165

175-
func();
166+
// Next, we need to get a handle on the _rust_main function by
167+
// looking up it's corresponding ValueRef and then requesting that
168+
// the execution engine compiles the function.
169+
let fun = do str::as_c_str("_rust_main") |entry| {
170+
llvm::LLVMGetNamedFunction(m, entry)
171+
};
172+
if fun.is_null() {
173+
llvm::LLVMDisposeExecutionEngine(ee);
174+
llvm::LLVMContextDispose(c);
175+
llvm_err(sess, ~"Could not find _rust_main in the JIT");
176176
}
177+
178+
// Finally, once we have the pointer to the code, we can do some
179+
// closure magic here to turn it straight into a callable rust
180+
// closure
181+
let code = llvm::LLVMGetPointerToGlobal(ee, fun);
182+
assert!(!code.is_null());
183+
let closure = Closure {
184+
code: code,
185+
env: ptr::null()
186+
};
187+
let func: &fn() = cast::transmute(closure);
188+
func();
189+
190+
// Sadly, there currently is no interface to re-use this execution
191+
// engine, so it's disposed of here along with the context to
192+
// prevent leaks.
193+
llvm::LLVMDisposeExecutionEngine(ee);
194+
llvm::LLVMContextDispose(c);
177195
}
178196
}
179197
}
@@ -190,6 +208,7 @@ pub mod write {
190208
use driver::session;
191209
use lib::llvm::llvm;
192210
use lib::llvm::{ModuleRef, mk_pass_manager, mk_target_data};
211+
use lib::llvm::{False, ContextRef};
193212
use lib;
194213

195214
use back::passes;
@@ -208,6 +227,7 @@ pub mod write {
208227
}
209228

210229
pub fn run_passes(sess: Session,
230+
llcx: ContextRef,
211231
llmod: ModuleRef,
212232
output_type: output_type,
213233
output: &Path) {
@@ -282,7 +302,7 @@ pub mod write {
282302
// JIT execution takes ownership of the module,
283303
// so don't dispose and return.
284304

285-
jit::exec(sess, pm.llpm, llmod, CodeGenOptLevel, true);
305+
jit::exec(sess, pm.llpm, llcx, llmod, CodeGenOptLevel, true);
286306

287307
if sess.time_llvm_passes() {
288308
llvm::LLVMRustPrintPassTimings();
@@ -350,6 +370,7 @@ pub mod write {
350370
// Clean up and return
351371

352372
llvm::LLVMDisposeModule(llmod);
373+
llvm::LLVMContextDispose(llcx);
353374
if sess.time_llvm_passes() {
354375
llvm::LLVMRustPrintPassTimings();
355376
}
@@ -368,6 +389,7 @@ pub mod write {
368389
}
369390

370391
llvm::LLVMDisposeModule(llmod);
392+
llvm::LLVMContextDispose(llcx);
371393
if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
372394
}
373395
}

branches/snap-stage3/src/librustc/driver/driver.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ pub fn compile_rest(sess: Session,
217217

218218
let mut crate = crate_opt.unwrap();
219219

220-
let (llmod, link_meta) = {
220+
let (llcx, llmod, link_meta) = {
221221
crate = time(time_passes, ~"intrinsic injection", ||
222222
front::intrinsic_inject::inject_intrinsic(sess, crate));
223223

@@ -340,14 +340,14 @@ pub fn compile_rest(sess: Session,
340340
let obj_filename = outputs.obj_filename.with_filetype("s");
341341

342342
time(time_passes, ~"LLVM passes", ||
343-
link::write::run_passes(sess, llmod, output_type,
344-
&obj_filename));
343+
link::write::run_passes(sess, llcx, llmod, output_type,
344+
&obj_filename));
345345

346346
link::write::run_ndk(sess, &obj_filename, &outputs.obj_filename);
347347
} else {
348348
time(time_passes, ~"LLVM passes", ||
349-
link::write::run_passes(sess, llmod, sess.opts.output_type,
350-
&outputs.obj_filename));
349+
link::write::run_passes(sess, llcx, llmod, sess.opts.output_type,
350+
&outputs.obj_filename));
351351
}
352352

353353
let stop_after_codegen =

branches/snap-stage3/src/librustc/lib/llvm.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ pub enum BasicBlock_opaque {}
205205
pub type BasicBlockRef = *BasicBlock_opaque;
206206
pub enum Builder_opaque {}
207207
pub type BuilderRef = *Builder_opaque;
208+
pub enum ExecutionEngine_opaque {}
209+
pub type ExecutionEngineRef = *ExecutionEngine_opaque;
208210
pub enum MemoryBuffer_opaque {}
209211
pub type MemoryBufferRef = *MemoryBuffer_opaque;
210212
pub enum PassManager_opaque {}
@@ -223,7 +225,7 @@ pub enum Pass_opaque {}
223225
pub type PassRef = *Pass_opaque;
224226

225227
pub mod llvm {
226-
use super::{AtomicBinOp, AtomicOrdering, BasicBlockRef};
228+
use super::{AtomicBinOp, AtomicOrdering, BasicBlockRef, ExecutionEngineRef};
227229
use super::{Bool, BuilderRef, ContextRef, MemoryBufferRef, ModuleRef};
228230
use super::{ObjectFileRef, Opcode, PassManagerRef, PassManagerBuilderRef};
229231
use super::{SectionIteratorRef, TargetDataRef, TypeKind, TypeRef, UseRef};
@@ -363,6 +365,10 @@ pub mod llvm {
363365
pub unsafe fn LLVMGetPointerAddressSpace(PointerTy: TypeRef)
364366
-> c_uint;
365367
#[fast_ffi]
368+
pub unsafe fn LLVMGetPointerToGlobal(EE: ExecutionEngineRef,
369+
V: ValueRef)
370+
-> *();
371+
#[fast_ffi]
366372
pub unsafe fn LLVMGetVectorSize(VectorTy: TypeRef) -> c_uint;
367373

368374
/* Operations on other types */
@@ -1003,6 +1009,8 @@ pub mod llvm {
10031009
Name: *c_char);
10041010
#[fast_ffi]
10051011
pub unsafe fn LLVMDisposeBuilder(Builder: BuilderRef);
1012+
#[fast_ffi]
1013+
pub unsafe fn LLVMDisposeExecutionEngine(EE: ExecutionEngineRef);
10061014

10071015
/* Metadata */
10081016
#[fast_ffi]
@@ -1819,11 +1827,11 @@ pub mod llvm {
18191827

18201828
/** Execute the JIT engine. */
18211829
#[fast_ffi]
1822-
pub unsafe fn LLVMRustExecuteJIT(MM: *(),
1830+
pub unsafe fn LLVMRustBuildJIT(MM: *(),
18231831
PM: PassManagerRef,
18241832
M: ModuleRef,
18251833
OptLevel: c_int,
1826-
EnableSegmentedStacks: bool) -> *();
1834+
EnableSegmentedStacks: bool) -> ExecutionEngineRef;
18271835

18281836
/** Parses the bitcode in the given memory buffer. */
18291837
#[fast_ffi]

branches/snap-stage3/src/librustc/middle/trans/base.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3023,7 +3023,7 @@ pub fn trans_crate(sess: session::Session,
30233023
tcx: ty::ctxt,
30243024
output: &Path,
30253025
emap2: resolve::ExportMap2,
3026-
maps: astencode::Maps) -> (ModuleRef, LinkMeta) {
3026+
maps: astencode::Maps) -> (ContextRef, ModuleRef, LinkMeta) {
30273027
30283028
let symbol_hasher = @mut hash::default_state();
30293029
let link_meta = link::build_link_meta(sess, crate, output, symbol_hasher);
@@ -3045,9 +3045,11 @@ pub fn trans_crate(sess: session::Session,
30453045
let llmod_id = link_meta.name.to_owned() + ".rc";
30463046
30473047
unsafe {
3048-
if !llvm::LLVMRustStartMultithreading() {
3049-
sess.bug("couldn't enable multi-threaded LLVM");
3050-
}
3048+
// FIXME(#6511): get LLVM building with --enable-threads so this
3049+
// function can be called
3050+
// if !llvm::LLVMRustStartMultithreading() {
3051+
// sess.bug("couldn't enable multi-threaded LLVM");
3052+
// }
30513053
let llcx = llvm::LLVMContextCreate();
30523054
set_task_llcx(llcx);
30533055
let llmod = str::as_c_str(llmod_id, |buf| {
@@ -3187,7 +3189,8 @@ pub fn trans_crate(sess: session::Session,
31873189
io::println(fmt!("%-7u %s", v, k));
31883190
}
31893191
}
3190-
return (llmod, link_meta);
3192+
unset_task_llcx();
3193+
return (llcx, llmod, link_meta);
31913194
}
31923195
}
31933196
@@ -3198,8 +3201,10 @@ pub fn task_llcx() -> ContextRef {
31983201
*opt.expect("task-local LLVMContextRef wasn't ever set!")
31993202
}
32003203

3201-
fn set_task_llcx(c: ContextRef) {
3202-
unsafe {
3203-
local_data::local_data_set(task_local_llcx_key, @c);
3204-
}
3204+
unsafe fn set_task_llcx(c: ContextRef) {
3205+
local_data::local_data_set(task_local_llcx_key, @c);
3206+
}
3207+
3208+
unsafe fn unset_task_llcx() {
3209+
local_data::local_data_pop(task_local_llcx_key);
32053210
}

branches/snap-stage3/src/librusti/rusti.rc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -476,8 +476,10 @@ mod tests {
476476
debug!("regression test for #5784");
477477
run_cmds(["let a = 1;"]);
478478

479-
debug!("regression test for #5803");
480-
run_cmds(["spawn( || println(\"Please don't segfault\") );",
481-
"do spawn { println(\"Please?\"); }"]);
479+
// XXX: can't spawn new tasks because the JIT code is cleaned up
480+
// after the main function is done.
481+
// debug!("regression test for #5803");
482+
// run_cmds(["spawn( || println(\"Please don't segfault\") );",
483+
// "do spawn { println(\"Please?\"); }"]);
482484
}
483485
}

branches/snap-stage3/src/rustllvm/RustWrapper.cpp

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -329,12 +329,12 @@ LLVMRustLoadCrate(void* mem, const char* crate) {
329329
return true;
330330
}
331331

332-
extern "C" void*
333-
LLVMRustExecuteJIT(void* mem,
334-
LLVMPassManagerRef PMR,
335-
LLVMModuleRef M,
336-
CodeGenOpt::Level OptLevel,
337-
bool EnableSegmentedStacks) {
332+
extern "C" LLVMExecutionEngineRef
333+
LLVMRustBuildJIT(void* mem,
334+
LLVMPassManagerRef PMR,
335+
LLVMModuleRef M,
336+
CodeGenOpt::Level OptLevel,
337+
bool EnableSegmentedStacks) {
338338

339339
InitializeNativeTarget();
340340
InitializeNativeTargetAsmPrinter();
@@ -371,21 +371,15 @@ LLVMRustExecuteJIT(void* mem,
371371

372372
if(!EE || Err != "") {
373373
LLVMRustError = Err.c_str();
374-
return 0;
374+
// The EngineBuilder only takes ownership of these two structures if the
375+
// create() call is successful, but here it wasn't successful.
376+
LLVMDisposeModule(M);
377+
delete MM;
378+
return NULL;
375379
}
376380

377381
MM->invalidateInstructionCache();
378-
Function* func = EE->FindFunctionNamed("_rust_main");
379-
380-
if(!func || Err != "") {
381-
LLVMRustError = Err.c_str();
382-
return 0;
383-
}
384-
385-
void* entry = EE->getPointerToFunction(func);
386-
assert(entry);
387-
388-
return entry;
382+
return wrap(EE);
389383
}
390384

391385
extern "C" bool

branches/snap-stage3/src/rustllvm/rustllvm.def.in

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ LLVMRustConstSmallInt
66
LLVMRustConstInt
77
LLVMRustLoadCrate
88
LLVMRustPrepareJIT
9-
LLVMRustExecuteJIT
9+
LLVMRustBuildJIT
1010
LLVMRustParseBitcode
1111
LLVMRustParseAssemblyFile
1212
LLVMRustPrintPassTimings
1313
LLVMRustStartMultithreading
1414
LLVMCreateObjectFile
1515
LLVMDisposeObjectFile
16+
LLVMDisposeExecutionEngine
1617
LLVMGetSections
1718
LLVMDisposeSectionIterator
1819
LLVMIsSectionIteratorAtEnd
@@ -356,6 +357,7 @@ LLVMGetParamParent
356357
LLVMGetParamTypes
357358
LLVMGetParams
358359
LLVMGetPointerAddressSpace
360+
LLVMGetPointerToGlobal
359361
LLVMGetPreviousBasicBlock
360362
LLVMGetPreviousFunction
361363
LLVMGetPreviousGlobal

branches/snap-stage3/src/rustllvm/rustllvm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include "llvm/Transforms/Vectorize.h"
4646
#include "llvm-c/Core.h"
4747
#include "llvm-c/BitReader.h"
48+
#include "llvm-c/ExecutionEngine.h"
4849
#include "llvm-c/Object.h"
4950

5051
// Used by RustMCJITMemoryManager::getPointerToNamedFunction()

0 commit comments

Comments
 (0)