提交 d3939322 编写于 作者: A Alex Crichton

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.
上级 a88613c8
......@@ -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 @@ pub fn from_json(obj: Json) -> TargetResult {
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 @@ fn to_json(&self) -> Json {
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 {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册