Merge pull request #662 from bjorn3/jit_dylib
Load dependent dylibs in JIT mode
This commit is contained in:
commit
7633bb6902
11
Cargo.lock
generated
11
Cargo.lock
generated
@ -396,6 +396,15 @@ name = "libc"
|
||||
version = "0.2.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.8"
|
||||
@ -606,6 +615,7 @@ dependencies = [
|
||||
"gimli 0.19.0 (git+https://github.com/gimli-rs/gimli.git)",
|
||||
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libloading 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"object 0.12.0 (git+https://github.com/gimli-rs/object.git)",
|
||||
"target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -884,6 +894,7 @@ dependencies = [
|
||||
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
|
||||
"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
|
||||
"checksum libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb"
|
||||
"checksum libloading 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a5692f82b51823e27c4118b3e5c0d98aee9be90633ebc71ad12afef380b50219"
|
||||
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||
"checksum mach 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "86dd2487cdfea56def77b88438a2c915fb45113c5319bfe7e14306ca4cd0b0e1"
|
||||
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
|
||||
|
@ -26,6 +26,7 @@ tempfile = "3.0.7"
|
||||
gimli = { git = "https://github.com/gimli-rs/gimli.git" }
|
||||
indexmap = "1.0.2"
|
||||
object = "0.12.0"
|
||||
libloading = "0.5.1"
|
||||
|
||||
[patch."https://github.com/CraneStation/cranelift.git"]
|
||||
cranelift = { git = "https://github.com/bjorn3/cretonne.git", branch = "do_not_remove_cg_clif_i128" }
|
||||
|
@ -28,7 +28,7 @@ fi
|
||||
|
||||
# Copy files to sysroot
|
||||
mkdir -p sysroot/lib/rustlib/$TARGET_TRIPLE/lib/
|
||||
cp target/$TARGET_TRIPLE/$sysroot_channel/deps/*.rlib sysroot/lib/rustlib/$TARGET_TRIPLE/lib/
|
||||
cp target/$TARGET_TRIPLE/$sysroot_channel/deps/* sysroot/lib/rustlib/$TARGET_TRIPLE/lib/
|
||||
|
||||
if [[ "$1" == "--release" ]]; then
|
||||
channel='release'
|
||||
@ -39,4 +39,4 @@ else
|
||||
fi
|
||||
|
||||
# Copy files to sysroot
|
||||
cp sysroot_src/src/libtest/target/$TARGET_TRIPLE/$sysroot_channel/deps/*.rlib sysroot/lib/rustlib/$TARGET_TRIPLE/lib/
|
||||
cp sysroot_src/src/libtest/target/$TARGET_TRIPLE/$sysroot_channel/deps/* sysroot/lib/rustlib/$TARGET_TRIPLE/lib/
|
||||
|
@ -15,3 +15,6 @@ TARGET_TRIPLE=$(rustc -vV | grep host | cut -d: -f2 | tr -d " ")
|
||||
export RUSTFLAGS='-Zalways-encode-mir -Cpanic=abort -Cdebuginfo=2 -Zcodegen-backend='$(pwd)'/target/'$CHANNEL'/librustc_codegen_cranelift.'$dylib_ext' --sysroot '$(pwd)'/build_sysroot/sysroot'
|
||||
RUSTC="rustc $RUSTFLAGS -L crate=target/out --out-dir target/out"
|
||||
export RUSTC_LOG=warn # display metadata load errors
|
||||
|
||||
export LD_LIBRARY_PATH="$(pwd)/target/out:$(pwd)/build_sysroot/sysroot/lib/rustlib/$TARGET_TRIPLE/lib"
|
||||
export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH
|
||||
|
@ -369,9 +369,6 @@ pub trait FnMut<Args>: FnOnce<Args> {
|
||||
}
|
||||
|
||||
#[lang = "panic"]
|
||||
// Make it available to jited mini_core_hello_world
|
||||
// FIXME remove next line when jit supports linking rlibs
|
||||
#[inline(always)]
|
||||
pub fn panic(&(_msg, _file, _line, _col): &(&'static str, &'static str, u32, u32)) -> ! {
|
||||
unsafe {
|
||||
libc::puts("Panicking\0" as *const str as *const u8);
|
||||
@ -419,15 +416,11 @@ fn deref(&self) -> &Self::Target {
|
||||
}
|
||||
|
||||
#[lang = "exchange_malloc"]
|
||||
// Make it available to jited mini_core_hello_world
|
||||
// FIXME remove next line when jit supports linking rlibs
|
||||
#[inline(always)]
|
||||
unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
|
||||
libc::malloc(size)
|
||||
}
|
||||
|
||||
#[lang = "box_free"]
|
||||
#[inline(always)]
|
||||
unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
|
||||
libc::free(ptr as *mut u8);
|
||||
}
|
||||
|
@ -18,13 +18,6 @@ pub fn codegen_crate(
|
||||
metadata: EncodedMetadata,
|
||||
need_metadata_module: bool,
|
||||
) -> Box<dyn Any> {
|
||||
if !tcx.sess.crate_types.get().contains(&CrateType::Executable)
|
||||
&& std::env::var("SHOULD_RUN").is_ok()
|
||||
{
|
||||
tcx.sess
|
||||
.err("Can't JIT run non executable (SHOULD_RUN env var is set)");
|
||||
}
|
||||
|
||||
tcx.sess.abort_if_errors();
|
||||
|
||||
let mut log = if cfg!(debug_assertions) {
|
||||
@ -33,7 +26,9 @@ pub fn codegen_crate(
|
||||
None
|
||||
};
|
||||
|
||||
if std::env::var("SHOULD_RUN").is_ok() {
|
||||
if std::env::var("SHOULD_RUN").is_ok()
|
||||
&& tcx.sess.crate_types.get().contains(&CrateType::Executable)
|
||||
{
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
let _: ! = run_jit(tcx, &mut log);
|
||||
|
||||
@ -48,9 +43,14 @@ pub fn codegen_crate(
|
||||
fn run_jit(tcx: TyCtxt<'_>, log: &mut Option<File>) -> ! {
|
||||
use cranelift_simplejit::{SimpleJITBackend, SimpleJITBuilder};
|
||||
|
||||
let mut jit_module: Module<SimpleJITBackend> = Module::new(SimpleJITBuilder::new(
|
||||
let imported_symbols = load_imported_symbols_for_jit(tcx);
|
||||
|
||||
let mut jit_builder = SimpleJITBuilder::with_isa(
|
||||
crate::build_isa(tcx.sess, false),
|
||||
cranelift_module::default_libcall_names(),
|
||||
));
|
||||
);
|
||||
jit_builder.symbols(imported_symbols);
|
||||
let mut jit_module: Module<SimpleJITBackend> = Module::new(jit_builder);
|
||||
assert_eq!(pointer_ty(tcx), jit_module.target_config().pointer_type());
|
||||
|
||||
let sig = Signature {
|
||||
@ -95,6 +95,53 @@ fn run_jit(tcx: TyCtxt<'_>, log: &mut Option<File>) -> ! {
|
||||
std::process::exit(ret);
|
||||
}
|
||||
|
||||
fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> {
|
||||
use rustc::middle::dependency_format::Linkage;
|
||||
|
||||
let mut dylib_paths = Vec::new();
|
||||
|
||||
let crate_info = CrateInfo::new(tcx);
|
||||
let formats = tcx.sess.dependency_formats.borrow();
|
||||
let data = formats.get(&CrateType::Executable).unwrap();
|
||||
for &(cnum, _) in &crate_info.used_crates_dynamic {
|
||||
let src = &crate_info.used_crate_source[&cnum];
|
||||
match data[cnum.as_usize() - 1] {
|
||||
Linkage::NotLinked | Linkage::IncludedFromDylib => {}
|
||||
Linkage::Static => {
|
||||
let name = tcx.crate_name(cnum);
|
||||
let mut err = tcx.sess.struct_err(&format!("Can't load static lib {}", name.as_str()));
|
||||
err.note("rustc_codegen_cranelift can only load dylibs in JIT mode.");
|
||||
err.emit();
|
||||
}
|
||||
Linkage::Dynamic => {
|
||||
dylib_paths.push(src.dylib.as_ref().unwrap().0.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut imported_symbols = Vec::new();
|
||||
for path in dylib_paths {
|
||||
use object::Object;
|
||||
let lib = libloading::Library::new(&path).unwrap();
|
||||
let obj = std::fs::read(path).unwrap();
|
||||
let obj = object::File::parse(&obj).unwrap();
|
||||
imported_symbols.extend(obj.dynamic_symbols().filter_map(|(_idx, symbol)| {
|
||||
let name = symbol.name().unwrap().to_string();
|
||||
if name.is_empty() || !symbol.is_global() || symbol.is_undefined() {
|
||||
return None;
|
||||
}
|
||||
let symbol: libloading::Symbol<*const u8> =
|
||||
unsafe { lib.get(name.as_bytes()) }.unwrap();
|
||||
Some((name, *symbol))
|
||||
}));
|
||||
std::mem::forget(lib)
|
||||
}
|
||||
|
||||
tcx.sess.abort_if_errors();
|
||||
|
||||
imported_symbols
|
||||
}
|
||||
|
||||
fn run_aot(
|
||||
tcx: TyCtxt<'_>,
|
||||
metadata: EncodedMetadata,
|
||||
@ -104,7 +151,7 @@ fn run_aot(
|
||||
let new_module = |name: String| {
|
||||
let module: Module<FaerieBackend> = Module::new(
|
||||
FaerieBuilder::new(
|
||||
crate::build_isa(tcx.sess),
|
||||
crate::build_isa(tcx.sess, true),
|
||||
name + ".o",
|
||||
FaerieTrapCollection::Disabled,
|
||||
cranelift_module::default_libcall_names(),
|
||||
@ -176,7 +223,7 @@ fn run_aot(
|
||||
.to_string();
|
||||
|
||||
let mut metadata_artifact =
|
||||
faerie::Artifact::new(crate::build_isa(tcx.sess).triple().clone(), metadata_cgu_name.clone());
|
||||
faerie::Artifact::new(crate::build_isa(tcx.sess, true).triple().clone(), metadata_cgu_name.clone());
|
||||
crate::metadata::write_metadata(tcx, &mut metadata_artifact);
|
||||
|
||||
let tmp_file = tcx
|
||||
|
10
src/lib.rs
10
src/lib.rs
@ -239,10 +239,14 @@ fn target_triple(sess: &Session) -> target_lexicon::Triple {
|
||||
target.parse().unwrap()
|
||||
}
|
||||
|
||||
fn build_isa(sess: &Session) -> Box<dyn isa::TargetIsa + 'static> {
|
||||
fn build_isa(sess: &Session, enable_pic: bool) -> Box<dyn isa::TargetIsa + 'static> {
|
||||
let mut flags_builder = settings::builder();
|
||||
flags_builder.enable("is_pic").unwrap();
|
||||
flags_builder.set("probestack_enabled", "false").unwrap(); // ___cranelift_probestack is not provided
|
||||
if enable_pic {
|
||||
flags_builder.enable("is_pic").unwrap();
|
||||
} else {
|
||||
flags_builder.set("is_pic", "false").unwrap();
|
||||
}
|
||||
flags_builder.set("probestack_enabled", "false").unwrap(); // __cranelift_probestack is not provided
|
||||
flags_builder.set("enable_verifier", if cfg!(debug_assertions) {
|
||||
"true"
|
||||
} else {
|
||||
|
@ -218,7 +218,7 @@ pub fn write_clif_file<'tcx>(
|
||||
&mut clif,
|
||||
&func,
|
||||
&DisplayFunctionAnnotations {
|
||||
isa: Some(&*crate::build_isa(tcx.sess)),
|
||||
isa: Some(&*crate::build_isa(tcx.sess, true /* PIC doesn't matter here */)),
|
||||
value_ranges,
|
||||
},
|
||||
)
|
||||
|
7
test.sh
7
test.sh
@ -35,11 +35,14 @@ $RUSTC example/arbitrary_self_types_pointers_and_wrappers.rs --crate-name arbitr
|
||||
echo "[BUILD] sysroot"
|
||||
time ./build_sysroot/build_sysroot.sh
|
||||
|
||||
echo "[BUILD+RUN] alloc_example"
|
||||
echo "[AOT] alloc_example"
|
||||
$RUSTC example/alloc_example.rs --crate-type bin
|
||||
./target/out/alloc_example
|
||||
|
||||
echo "[BUILD+RUN] std_example"
|
||||
echo "[JIT] std_example"
|
||||
SHOULD_RUN=1 $RUSTC example/std_example.rs --crate-type bin -Cprefer-dynamic
|
||||
|
||||
echo "[AOT] std_example"
|
||||
$RUSTC example/std_example.rs --crate-type bin
|
||||
./target/out/std_example
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user