Skip to content

Commit

Permalink
rustc: Clean up allocator injection logic
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
alexcrichton committed Nov 11, 2018
1 parent a88613c commit d393932
Show file tree
Hide file tree
Showing 29 changed files with 17 additions and 177 deletions.
1 change: 0 additions & 1 deletion src/liballoc_system/lib.rs
Expand Up @@ -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.
Expand Down
15 changes: 0 additions & 15 deletions src/librustc/middle/dependency_format.rs
Expand Up @@ -63,7 +63,6 @@

use hir::def_id::CrateNum;

use session;
use session::config;
use ty::TyCtxt;
use middle::cstore::{self, DepKind};
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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]) {
Expand Down
2 changes: 0 additions & 2 deletions src/librustc/session/mod.rs
Expand Up @@ -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>>,

Expand Down Expand Up @@ -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())),
Expand Down
113 changes: 17 additions & 96 deletions src/librustc_metadata/creader.rs
Expand Up @@ -864,28 +864,25 @@ impl<'a> CrateLoader<'a> {
needs_allocator = needs_allocator || data.root.needs_allocator;
});
if !needs_allocator {
self.sess.injected_allocator.set(None);
self.sess.allocator_kind.set(None);
return
}

// 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
}
Expand Down Expand Up @@ -924,103 +921,27 @@ impl<'a> CrateLoader<'a> {
});
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);
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_target/spec/aarch64_unknown_freebsd.rs
Expand Up @@ -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(),
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_target/spec/aarch64_unknown_linux_gnu.rs
Expand Up @@ -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(),
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_target/spec/aarch64_unknown_linux_musl.rs
Expand Up @@ -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(),
Expand Down
1 change: 0 additions & 1 deletion src/librustc_target/spec/hermit_base.rs
Expand Up @@ -21,7 +21,6 @@ pub fn opts() -> TargetOptions {
]);

TargetOptions {
exe_allocation_crate: None,
executables: true,
has_elf_tls: true,
linker_is_gnu: true,
Expand Down
1 change: 0 additions & 1 deletion src/librustc_target/spec/l4re_base.rs
Expand Up @@ -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,
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_target/spec/mips64_unknown_linux_gnuabi64.rs
Expand Up @@ -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()
},
})
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_target/spec/mips64el_unknown_linux_gnuabi64.rs
Expand Up @@ -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()
},
})
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_target/spec/mips_unknown_linux_gnu.rs
Expand Up @@ -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()
},
})
Expand Down
2 changes: 0 additions & 2 deletions src/librustc_target/spec/mips_unknown_linux_musl.rs
Expand Up @@ -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(),
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_target/spec/mips_unknown_linux_uclibc.rs
Expand Up @@ -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()
},
})
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_target/spec/mipsel_unknown_linux_gnu.rs
Expand Up @@ -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()
},
})
Expand Down
2 changes: 0 additions & 2 deletions src/librustc_target/spec/mipsel_unknown_linux_musl.rs
Expand Up @@ -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(),
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_target/spec/mipsel_unknown_linux_uclibc.rs
Expand Up @@ -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()
},
})
Expand Down
6 changes: 0 additions & 6 deletions src/librustc_target/spec/mod.rs
Expand Up @@ -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,
Expand Down Expand Up @@ -740,7 +737,6 @@ impl Default for 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,
Expand Down Expand Up @@ -1025,7 +1021,6 @@ impl Target {
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);
Expand Down Expand Up @@ -1235,7 +1230,6 @@ impl ToJson for Target {
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);
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_target/spec/powerpc64_unknown_linux_gnu.rs
Expand Up @@ -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(),
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_target/spec/powerpc64le_unknown_linux_gnu.rs
Expand Up @@ -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(),
Expand Down

0 comments on commit d393932

Please sign in to comment.