Skip to content

Commit 83d44f8

Browse files
committed
auto merge of #7125 : alexcrichton/rust/rusti-issues, r=brson
This un-reverts the reverts of the rusti commits made awhile back. These were reverted for an LLVM failure in rustpkg. I believe that this is not a problem with these commits, but rather that rustc is being used in parallel for rustpkg tests (in-process). This is not working yet (almost! see #7011), so I serialized all the tests to run one after another. @brson, I'm mainly just guessing as to the cause of the LLVM failures in rustpkg tests. I'm confident that running tests in parallel is more likely to be the problem than those commits I made. Additionally, this fixes two recently reported issues with rusti.
2 parents 7d1065e + 9c3b1cb commit 83d44f8

File tree

15 files changed

+241
-214
lines changed

15 files changed

+241
-214
lines changed

src/librustc/back/link.rs

+55-51
Original file line numberDiff line numberDiff line change
@@ -101,34 +101,21 @@ pub mod jit {
101101
use back::link::llvm_err;
102102
use driver::session::Session;
103103
use lib::llvm::llvm;
104-
use lib::llvm::{ModuleRef, PassManagerRef};
104+
use lib::llvm::{ModuleRef, ContextRef};
105105
use metadata::cstore;
106106

107107
use core::cast;
108-
use core::libc::c_int;
109108
use core::ptr;
110109
use core::str;
111-
112-
pub mod rusti {
113-
#[nolink]
114-
#[abi = "rust-intrinsic"]
115-
pub extern "rust-intrinsic" {
116-
pub fn morestack_addr() -> *();
117-
}
118-
}
119-
120-
pub struct Closure {
121-
code: *(),
122-
env: *(),
123-
}
110+
use core::sys;
111+
use core::unstable::intrinsics;
124112

125113
pub fn exec(sess: Session,
126-
pm: PassManagerRef,
114+
c: ContextRef,
127115
m: ModuleRef,
128-
opt: c_int,
129116
stacks: bool) {
130117
unsafe {
131-
let manager = llvm::LLVMRustPrepareJIT(rusti::morestack_addr());
118+
let manager = llvm::LLVMRustPrepareJIT(intrinsics::morestack_addr());
132119

133120
// We need to tell JIT where to resolve all linked
134121
// symbols from. The equivalent of -lstd, -lcore, etc.
@@ -152,26 +139,43 @@ pub mod jit {
152139
});
153140
}
154141

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

173-
func();
150+
// Next, we need to get a handle on the _rust_main function by
151+
// looking up it's corresponding ValueRef and then requesting that
152+
// the execution engine compiles the function.
153+
let fun = do str::as_c_str("_rust_main") |entry| {
154+
llvm::LLVMGetNamedFunction(m, entry)
155+
};
156+
if fun.is_null() {
157+
llvm::LLVMDisposeExecutionEngine(ee);
158+
llvm::LLVMContextDispose(c);
159+
llvm_err(sess, ~"Could not find _rust_main in the JIT");
174160
}
161+
162+
// Finally, once we have the pointer to the code, we can do some
163+
// closure magic here to turn it straight into a callable rust
164+
// closure
165+
let code = llvm::LLVMGetPointerToGlobal(ee, fun);
166+
assert!(!code.is_null());
167+
let closure = sys::Closure {
168+
code: code,
169+
env: ptr::null()
170+
};
171+
let func: &fn() = cast::transmute(closure);
172+
func();
173+
174+
// Sadly, there currently is no interface to re-use this execution
175+
// engine, so it's disposed of here along with the context to
176+
// prevent leaks.
177+
llvm::LLVMDisposeExecutionEngine(ee);
178+
llvm::LLVMContextDispose(c);
175179
}
176180
}
177181
}
@@ -188,6 +192,7 @@ pub mod write {
188192
use driver::session;
189193
use lib::llvm::llvm;
190194
use lib::llvm::{ModuleRef, mk_pass_manager, mk_target_data};
195+
use lib::llvm::{ContextRef};
191196
use lib;
192197

193198
use back::passes;
@@ -206,6 +211,7 @@ pub mod write {
206211
}
207212

208213
pub fn run_passes(sess: Session,
214+
llcx: ContextRef,
209215
llmod: ModuleRef,
210216
output_type: output_type,
211217
output: &Path) {
@@ -261,7 +267,17 @@ pub mod write {
261267
debug!("Running Module Optimization Pass");
262268
mpm.run(llmod);
263269

264-
if is_object_or_assembly_or_exe(output_type) || opts.jit {
270+
if opts.jit {
271+
// If we are using JIT, go ahead and create and execute the
272+
// engine now. JIT execution takes ownership of the module and
273+
// context, so don't dispose and return.
274+
jit::exec(sess, llcx, llmod, true);
275+
276+
if sess.time_llvm_passes() {
277+
llvm::LLVMRustPrintPassTimings();
278+
}
279+
return;
280+
} else if is_object_or_assembly_or_exe(output_type) {
265281
let LLVMOptNone = 0 as c_int; // -O0
266282
let LLVMOptLess = 1 as c_int; // -O1
267283
let LLVMOptDefault = 2 as c_int; // -O2, -Os
@@ -274,20 +290,6 @@ pub mod write {
274290
session::Aggressive => LLVMOptAggressive
275291
};
276292

277-
if opts.jit {
278-
// If we are using JIT, go ahead and create and
279-
// execute the engine now.
280-
// JIT execution takes ownership of the module,
281-
// so don't dispose and return.
282-
283-
jit::exec(sess, pm.llpm, llmod, CodeGenOptLevel, true);
284-
285-
if sess.time_llvm_passes() {
286-
llvm::LLVMRustPrintPassTimings();
287-
}
288-
return;
289-
}
290-
291293
let FileType;
292294
if output_type == output_type_object ||
293295
output_type == output_type_exe {
@@ -348,6 +350,7 @@ pub mod write {
348350
// Clean up and return
349351

350352
llvm::LLVMDisposeModule(llmod);
353+
llvm::LLVMContextDispose(llcx);
351354
if sess.time_llvm_passes() {
352355
llvm::LLVMRustPrintPassTimings();
353356
}
@@ -366,6 +369,7 @@ pub mod write {
366369
}
367370

368371
llvm::LLVMDisposeModule(llmod);
372+
llvm::LLVMContextDispose(llcx);
369373
if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
370374
}
371375
}

src/librustc/driver/driver.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ pub fn compile_rest(sess: Session,
215215

216216
let mut crate = crate_opt.unwrap();
217217

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

@@ -338,14 +338,14 @@ pub fn compile_rest(sess: Session,
338338
let obj_filename = outputs.obj_filename.with_filetype("s");
339339

340340
time(time_passes, ~"LLVM passes", ||
341-
link::write::run_passes(sess, llmod, output_type,
342-
&obj_filename));
341+
link::write::run_passes(sess, llcx, llmod, output_type,
342+
&obj_filename));
343343

344344
link::write::run_ndk(sess, &obj_filename, &outputs.obj_filename);
345345
} else {
346346
time(time_passes, ~"LLVM passes", ||
347-
link::write::run_passes(sess, llmod, sess.opts.output_type,
348-
&outputs.obj_filename));
347+
link::write::run_passes(sess, llcx, llmod, sess.opts.output_type,
348+
&outputs.obj_filename));
349349
}
350350

351351
let stop_after_codegen =

0 commit comments

Comments
 (0)