rustc: Clean up allocator injection logic
This commit cleans up allocator injection logic found in the compiler around selecting the global allocator. It turns out that now that jemalloc is gone the compiler never actually injects anything! This means that basically everything around loading crates here and there can be easily pruned. This also removes the `exe_allocation_crate` option from custom target specs as it's no longer used by the compiler anywhere.
This commit is contained in:
parent
a88613c869
commit
d3939322e3
@ -25,7 +25,6 @@
|
||||
feature(integer_atomics, stdsimd)
|
||||
)]
|
||||
#![cfg_attr(any(unix, target_os = "cloudabi", target_os = "redox"), feature(libc))]
|
||||
#![rustc_alloc_kind = "lib"]
|
||||
|
||||
// The minimum alignment guaranteed by the architecture. This value is used to
|
||||
// add fast paths for low alignment values.
|
||||
|
@ -63,7 +63,6 @@
|
||||
|
||||
use hir::def_id::CrateNum;
|
||||
|
||||
use session;
|
||||
use session::config;
|
||||
use ty::TyCtxt;
|
||||
use middle::cstore::{self, DepKind};
|
||||
@ -224,7 +223,6 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
// quite yet, so do so here.
|
||||
activate_injected_dep(*sess.injected_panic_runtime.get(), &mut ret,
|
||||
&|cnum| tcx.is_panic_runtime(cnum));
|
||||
activate_injected_allocator(sess, &mut ret);
|
||||
|
||||
// When dylib B links to dylib A, then when using B we must also link to A.
|
||||
// It could be the case, however, that the rlib for A is present (hence we
|
||||
@ -303,7 +301,6 @@ fn attempt_static<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<DependencyLis
|
||||
// that here and activate them.
|
||||
activate_injected_dep(*sess.injected_panic_runtime.get(), &mut ret,
|
||||
&|cnum| tcx.is_panic_runtime(cnum));
|
||||
activate_injected_allocator(sess, &mut ret);
|
||||
|
||||
Some(ret)
|
||||
}
|
||||
@ -336,18 +333,6 @@ fn activate_injected_dep(injected: Option<CrateNum>,
|
||||
}
|
||||
}
|
||||
|
||||
fn activate_injected_allocator(sess: &session::Session,
|
||||
list: &mut DependencyList) {
|
||||
let cnum = match sess.injected_allocator.get() {
|
||||
Some(cnum) => cnum,
|
||||
None => return,
|
||||
};
|
||||
let idx = cnum.as_usize() - 1;
|
||||
if list[idx] == Linkage::NotLinked {
|
||||
list[idx] = Linkage::Static;
|
||||
}
|
||||
}
|
||||
|
||||
// After the linkage for a crate has been determined we need to verify that
|
||||
// there's only going to be one allocator in the output.
|
||||
fn verify_ok<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, list: &[Linkage]) {
|
||||
|
@ -112,7 +112,6 @@ pub struct Session {
|
||||
/// The metadata::creader module may inject an allocator/panic_runtime
|
||||
/// dependency if it didn't already find one, and this tracks what was
|
||||
/// injected.
|
||||
pub injected_allocator: Once<Option<CrateNum>>,
|
||||
pub allocator_kind: Once<Option<AllocatorKind>>,
|
||||
pub injected_panic_runtime: Once<Option<CrateNum>>,
|
||||
|
||||
@ -1162,7 +1161,6 @@ pub fn build_session_(
|
||||
type_length_limit: Once::new(),
|
||||
const_eval_stack_frame_limit: 100,
|
||||
next_node_id: OneThread::new(Cell::new(NodeId::new(1))),
|
||||
injected_allocator: Once::new(),
|
||||
allocator_kind: Once::new(),
|
||||
injected_panic_runtime: Once::new(),
|
||||
imported_macro_spans: OneThread::new(RefCell::new(FxHashMap::default())),
|
||||
|
@ -864,7 +864,6 @@ fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
|
||||
needs_allocator = needs_allocator || data.root.needs_allocator;
|
||||
});
|
||||
if !needs_allocator {
|
||||
self.sess.injected_allocator.set(None);
|
||||
self.sess.allocator_kind.set(None);
|
||||
return
|
||||
}
|
||||
@ -872,20 +871,18 @@ fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
|
||||
// At this point we've determined that we need an allocator. Let's see
|
||||
// if our compilation session actually needs an allocator based on what
|
||||
// we're emitting.
|
||||
let mut need_lib_alloc = false;
|
||||
let mut need_exe_alloc = false;
|
||||
let mut all_rlib = true;
|
||||
for ct in self.sess.crate_types.borrow().iter() {
|
||||
match *ct {
|
||||
config::CrateType::Executable => need_exe_alloc = true,
|
||||
config::CrateType::Executable |
|
||||
config::CrateType::Dylib |
|
||||
config::CrateType::ProcMacro |
|
||||
config::CrateType::Cdylib |
|
||||
config::CrateType::Staticlib => need_lib_alloc = true,
|
||||
config::CrateType::Staticlib => all_rlib = false,
|
||||
config::CrateType::Rlib => {}
|
||||
}
|
||||
}
|
||||
if !need_lib_alloc && !need_exe_alloc {
|
||||
self.sess.injected_allocator.set(None);
|
||||
if all_rlib {
|
||||
self.sess.allocator_kind.set(None);
|
||||
return
|
||||
}
|
||||
@ -924,103 +921,27 @@ fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
|
||||
});
|
||||
if global_allocator.is_some() {
|
||||
self.sess.allocator_kind.set(Some(AllocatorKind::Global));
|
||||
self.sess.injected_allocator.set(None);
|
||||
return
|
||||
}
|
||||
|
||||
// Ok we haven't found a global allocator but we still need an
|
||||
// allocator. At this point we'll either fall back to the "library
|
||||
// allocator" or the "exe allocator" depending on a few variables. Let's
|
||||
// figure out which one.
|
||||
//
|
||||
// Note that here we favor linking to the "library allocator" as much as
|
||||
// possible. If we're not creating rustc's version of libstd
|
||||
// (need_lib_alloc and prefer_dynamic) then we select `None`, and if the
|
||||
// exe allocation crate doesn't exist for this target then we also
|
||||
// select `None`.
|
||||
let exe_allocation_crate_data =
|
||||
if need_lib_alloc && !self.sess.opts.cg.prefer_dynamic {
|
||||
None
|
||||
} else {
|
||||
self.sess
|
||||
.target
|
||||
.target
|
||||
.options
|
||||
.exe_allocation_crate
|
||||
.as_ref()
|
||||
.map(|name| {
|
||||
// We've determined that we're injecting an "exe allocator" which means
|
||||
// that we're going to load up a whole new crate. An example of this is
|
||||
// that we're producing a normal binary on Linux which means we need to
|
||||
// load the `alloc_jemalloc` crate to link as an allocator.
|
||||
let name = Symbol::intern(name);
|
||||
let (cnum, data) = self.resolve_crate(&None,
|
||||
name,
|
||||
name,
|
||||
None,
|
||||
None,
|
||||
DUMMY_SP,
|
||||
PathKind::Crate,
|
||||
DepKind::Implicit)
|
||||
.unwrap_or_else(|err| err.report());
|
||||
self.sess.injected_allocator.set(Some(cnum));
|
||||
data
|
||||
})
|
||||
};
|
||||
|
||||
let allocation_crate_data = exe_allocation_crate_data.or_else(|| {
|
||||
// No allocator was injected
|
||||
self.sess.injected_allocator.set(None);
|
||||
|
||||
if attr::contains_name(&krate.attrs, "default_lib_allocator") {
|
||||
// Prefer self as the allocator if there's a collision
|
||||
return None;
|
||||
// allocator. At this point our allocator request is typically fulfilled
|
||||
// by the standard library, denoted by the `#![default_lib_allocator]`
|
||||
// attribute.
|
||||
let mut has_default = attr::contains_name(&krate.attrs, "default_lib_allocator");
|
||||
self.cstore.iter_crate_data(|_, data| {
|
||||
if data.root.has_default_lib_allocator {
|
||||
has_default = true;
|
||||
}
|
||||
// We're not actually going to inject an allocator, we're going to
|
||||
// require that something in our crate graph is the default lib
|
||||
// allocator. This is typically libstd, so this'll rarely be an
|
||||
// error.
|
||||
let mut allocator = None;
|
||||
self.cstore.iter_crate_data(|_, data| {
|
||||
if allocator.is_none() && data.root.has_default_lib_allocator {
|
||||
allocator = Some(data.clone());
|
||||
}
|
||||
});
|
||||
allocator
|
||||
});
|
||||
|
||||
match allocation_crate_data {
|
||||
Some(data) => {
|
||||
// We have an allocator. We detect separately what kind it is, to allow for some
|
||||
// flexibility in misconfiguration.
|
||||
let attrs = data.get_item_attrs(CRATE_DEF_INDEX, self.sess);
|
||||
let kind_interned = attr::first_attr_value_str_by_name(&attrs, "rustc_alloc_kind")
|
||||
.map(Symbol::as_str);
|
||||
let kind_str = kind_interned
|
||||
.as_ref()
|
||||
.map(|s| s as &str);
|
||||
let alloc_kind = match kind_str {
|
||||
None |
|
||||
Some("lib") => AllocatorKind::DefaultLib,
|
||||
Some("exe") => AllocatorKind::DefaultExe,
|
||||
Some(other) => {
|
||||
self.sess.err(&format!("Allocator kind {} not known", other));
|
||||
return;
|
||||
}
|
||||
};
|
||||
self.sess.allocator_kind.set(Some(alloc_kind));
|
||||
},
|
||||
None => {
|
||||
if !attr::contains_name(&krate.attrs, "default_lib_allocator") {
|
||||
self.sess.err("no global memory allocator found but one is \
|
||||
required; link to std or \
|
||||
add #[global_allocator] to a static item \
|
||||
that implements the GlobalAlloc trait.");
|
||||
return;
|
||||
}
|
||||
self.sess.allocator_kind.set(Some(AllocatorKind::DefaultLib));
|
||||
}
|
||||
if !has_default {
|
||||
self.sess.err("no global memory allocator found but one is \
|
||||
required; link to std or \
|
||||
add #[global_allocator] to a static item \
|
||||
that implements the GlobalAlloc trait.");
|
||||
}
|
||||
self.sess.allocator_kind.set(Some(AllocatorKind::DefaultLib));
|
||||
|
||||
fn has_global_allocator(krate: &ast::Crate) -> bool {
|
||||
struct Finder(bool);
|
||||
|
@ -14,9 +14,6 @@ pub fn target() -> TargetResult {
|
||||
let mut base = super::freebsd_base::opts();
|
||||
base.max_atomic_width = Some(128);
|
||||
|
||||
// see #36994
|
||||
base.exe_allocation_crate = None;
|
||||
|
||||
Ok(Target {
|
||||
llvm_target: "aarch64-unknown-freebsd".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
|
@ -14,9 +14,6 @@ pub fn target() -> TargetResult {
|
||||
let mut base = super::linux_base::opts();
|
||||
base.max_atomic_width = Some(128);
|
||||
|
||||
// see #36994
|
||||
base.exe_allocation_crate = None;
|
||||
|
||||
Ok(Target {
|
||||
llvm_target: "aarch64-unknown-linux-gnu".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
|
@ -14,9 +14,6 @@ pub fn target() -> TargetResult {
|
||||
let mut base = super::linux_musl_base::opts();
|
||||
base.max_atomic_width = Some(128);
|
||||
|
||||
// see #36994
|
||||
base.exe_allocation_crate = None;
|
||||
|
||||
Ok(Target {
|
||||
llvm_target: "aarch64-unknown-linux-musl".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
|
@ -21,7 +21,6 @@ pub fn opts() -> TargetOptions {
|
||||
]);
|
||||
|
||||
TargetOptions {
|
||||
exe_allocation_crate: None,
|
||||
executables: true,
|
||||
has_elf_tls: true,
|
||||
linker_is_gnu: true,
|
||||
|
@ -30,7 +30,6 @@ pub fn opts() -> TargetOptions {
|
||||
TargetOptions {
|
||||
executables: true,
|
||||
has_elf_tls: false,
|
||||
exe_allocation_crate: None,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
linker: Some("ld".to_string()),
|
||||
pre_link_args: args,
|
||||
|
@ -28,9 +28,6 @@ pub fn target() -> TargetResult {
|
||||
features: "+mips64r2".to_string(),
|
||||
max_atomic_width: Some(64),
|
||||
|
||||
// see #36994
|
||||
exe_allocation_crate: None,
|
||||
|
||||
..super::linux_base::opts()
|
||||
},
|
||||
})
|
||||
|
@ -28,9 +28,6 @@ pub fn target() -> TargetResult {
|
||||
features: "+mips64r2".to_string(),
|
||||
max_atomic_width: Some(64),
|
||||
|
||||
// see #36994
|
||||
exe_allocation_crate: None,
|
||||
|
||||
..super::linux_base::opts()
|
||||
},
|
||||
})
|
||||
|
@ -27,9 +27,6 @@ pub fn target() -> TargetResult {
|
||||
features: "+mips32r2,+fpxx,+nooddspreg".to_string(),
|
||||
max_atomic_width: Some(32),
|
||||
|
||||
// see #36994
|
||||
exe_allocation_crate: None,
|
||||
|
||||
..super::linux_base::opts()
|
||||
},
|
||||
})
|
||||
|
@ -15,8 +15,6 @@ pub fn target() -> TargetResult {
|
||||
base.cpu = "mips32r2".to_string();
|
||||
base.features = "+mips32r2,+soft-float".to_string();
|
||||
base.max_atomic_width = Some(32);
|
||||
// see #36994
|
||||
base.exe_allocation_crate = None;
|
||||
base.crt_static_default = false;
|
||||
Ok(Target {
|
||||
llvm_target: "mips-unknown-linux-musl".to_string(),
|
||||
|
@ -27,9 +27,6 @@ pub fn target() -> TargetResult {
|
||||
features: "+mips32r2,+soft-float".to_string(),
|
||||
max_atomic_width: Some(32),
|
||||
|
||||
// see #36994
|
||||
exe_allocation_crate: None,
|
||||
|
||||
..super::linux_base::opts()
|
||||
},
|
||||
})
|
||||
|
@ -28,9 +28,6 @@ pub fn target() -> TargetResult {
|
||||
features: "+mips32r2,+fpxx,+nooddspreg".to_string(),
|
||||
max_atomic_width: Some(32),
|
||||
|
||||
// see #36994
|
||||
exe_allocation_crate: None,
|
||||
|
||||
..super::linux_base::opts()
|
||||
},
|
||||
})
|
||||
|
@ -15,8 +15,6 @@ pub fn target() -> TargetResult {
|
||||
base.cpu = "mips32r2".to_string();
|
||||
base.features = "+mips32r2,+soft-float".to_string();
|
||||
base.max_atomic_width = Some(32);
|
||||
// see #36994
|
||||
base.exe_allocation_crate = None;
|
||||
base.crt_static_default = false;
|
||||
Ok(Target {
|
||||
llvm_target: "mipsel-unknown-linux-musl".to_string(),
|
||||
|
@ -28,9 +28,6 @@ pub fn target() -> TargetResult {
|
||||
features: "+mips32r2,+soft-float".to_string(),
|
||||
max_atomic_width: Some(32),
|
||||
|
||||
// see #36994
|
||||
exe_allocation_crate: None,
|
||||
|
||||
..super::linux_base::opts()
|
||||
},
|
||||
})
|
||||
|
@ -596,9 +596,6 @@ pub struct TargetOptions {
|
||||
/// `eh_unwind_resume` lang item.
|
||||
pub custom_unwind_resume: bool,
|
||||
|
||||
/// If necessary, a different crate to link exe allocators by default
|
||||
pub exe_allocation_crate: Option<String>,
|
||||
|
||||
/// Flag indicating whether ELF TLS (e.g. #[thread_local]) is available for
|
||||
/// this target.
|
||||
pub has_elf_tls: bool,
|
||||
@ -740,7 +737,6 @@ fn default() -> TargetOptions {
|
||||
link_env: Vec::new(),
|
||||
archive_format: "gnu".to_string(),
|
||||
custom_unwind_resume: false,
|
||||
exe_allocation_crate: None,
|
||||
allow_asm: true,
|
||||
has_elf_tls: false,
|
||||
obj_is_bitcode: false,
|
||||
@ -1025,7 +1021,6 @@ macro_rules! key {
|
||||
key!(archive_format);
|
||||
key!(allow_asm, bool);
|
||||
key!(custom_unwind_resume, bool);
|
||||
key!(exe_allocation_crate, optional);
|
||||
key!(has_elf_tls, bool);
|
||||
key!(obj_is_bitcode, bool);
|
||||
key!(no_integrated_as, bool);
|
||||
@ -1235,7 +1230,6 @@ macro_rules! target_option_val {
|
||||
target_option_val!(archive_format);
|
||||
target_option_val!(allow_asm);
|
||||
target_option_val!(custom_unwind_resume);
|
||||
target_option_val!(exe_allocation_crate);
|
||||
target_option_val!(has_elf_tls);
|
||||
target_option_val!(obj_is_bitcode);
|
||||
target_option_val!(no_integrated_as);
|
||||
|
@ -20,9 +20,6 @@ pub fn target() -> TargetResult {
|
||||
// for now. https://github.com/rust-lang/rust/pull/43170#issuecomment-315411474
|
||||
base.relro_level = RelroLevel::Partial;
|
||||
|
||||
// see #36994
|
||||
base.exe_allocation_crate = None;
|
||||
|
||||
Ok(Target {
|
||||
llvm_target: "powerpc64-unknown-linux-gnu".to_string(),
|
||||
target_endian: "big".to_string(),
|
||||
|
@ -16,9 +16,6 @@ pub fn target() -> TargetResult {
|
||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
||||
base.max_atomic_width = Some(64);
|
||||
|
||||
// see #36994
|
||||
base.exe_allocation_crate = None;
|
||||
|
||||
Ok(Target {
|
||||
llvm_target: "powerpc64le-unknown-linux-gnu".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
|
@ -16,9 +16,6 @@ pub fn target() -> TargetResult {
|
||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
||||
base.max_atomic_width = Some(64);
|
||||
|
||||
// see #36994
|
||||
base.exe_allocation_crate = None;
|
||||
|
||||
Ok(Target {
|
||||
llvm_target: "powerpc64le-unknown-linux-musl".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
|
@ -15,9 +15,6 @@ pub fn target() -> TargetResult {
|
||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
|
||||
base.max_atomic_width = Some(32);
|
||||
|
||||
// see #36994
|
||||
base.exe_allocation_crate = None;
|
||||
|
||||
Ok(Target {
|
||||
llvm_target: "powerpc-unknown-linux-gnu".to_string(),
|
||||
target_endian: "big".to_string(),
|
||||
|
@ -15,9 +15,6 @@ pub fn target() -> TargetResult {
|
||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mspe".to_string());
|
||||
base.max_atomic_width = Some(32);
|
||||
|
||||
// see #36994
|
||||
base.exe_allocation_crate = None;
|
||||
|
||||
Ok(Target {
|
||||
llvm_target: "powerpc-unknown-linux-gnuspe".to_string(),
|
||||
target_endian: "big".to_string(),
|
||||
|
@ -15,9 +15,6 @@ pub fn target() -> TargetResult {
|
||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
|
||||
base.max_atomic_width = Some(32);
|
||||
|
||||
// see #36994
|
||||
base.exe_allocation_crate = None;
|
||||
|
||||
Ok(Target {
|
||||
llvm_target: "powerpc-unknown-netbsd".to_string(),
|
||||
target_endian: "big".to_string(),
|
||||
|
@ -19,8 +19,6 @@ pub fn target() -> TargetResult {
|
||||
// Pass the -vector feature string to LLVM to respect this assumption.
|
||||
base.features = "-vector".to_string();
|
||||
base.max_atomic_width = Some(64);
|
||||
// see #36994
|
||||
base.exe_allocation_crate = None;
|
||||
base.min_global_align = Some(16);
|
||||
|
||||
Ok(Target {
|
||||
|
@ -14,7 +14,6 @@ pub fn target() -> TargetResult {
|
||||
let mut base = super::linux_base::opts();
|
||||
base.cpu = "v9".to_string();
|
||||
base.max_atomic_width = Some(64);
|
||||
base.exe_allocation_crate = None;
|
||||
|
||||
Ok(Target {
|
||||
llvm_target: "sparc64-unknown-linux-gnu".to_string(),
|
||||
|
@ -15,7 +15,6 @@ pub fn target() -> TargetResult {
|
||||
base.cpu = "v9".to_string();
|
||||
base.max_atomic_width = Some(64);
|
||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mv8plus".to_string());
|
||||
base.exe_allocation_crate = None;
|
||||
|
||||
Ok(Target {
|
||||
llvm_target: "sparc-unknown-linux-gnu".to_string(),
|
||||
|
@ -16,7 +16,6 @@ pub fn target() -> TargetResult {
|
||||
// llvm calls this "v9"
|
||||
base.cpu = "v9".to_string();
|
||||
base.max_atomic_width = Some(64);
|
||||
base.exe_allocation_crate = None;
|
||||
|
||||
Ok(Target {
|
||||
llvm_target: "sparcv9-sun-solaris".to_string(),
|
||||
|
@ -21,7 +21,6 @@ pub fn target() -> TargetResult {
|
||||
base.has_rpath = false;
|
||||
base.position_independent_executables = false;
|
||||
base.disable_redzone = true;
|
||||
base.exe_allocation_crate = None;
|
||||
base.stack_probes = true;
|
||||
|
||||
Ok(Target {
|
||||
|
Loading…
Reference in New Issue
Block a user