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.
use hir::def_id::CrateNum;
-use session;
use session::config;
use ty::TyCtxt;
use middle::cstore::{self, DepKind};
// 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
// 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)
}
}
}
-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]) {
/// 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>>,
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())),
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
}
});
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);
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(),
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(),
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(),
]);
TargetOptions {
- exe_allocation_crate: None,
executables: true,
has_elf_tls: true,
linker_is_gnu: true,
TargetOptions {
executables: true,
has_elf_tls: false,
- exe_allocation_crate: None,
panic_strategy: PanicStrategy::Abort,
linker: Some("ld".to_string()),
pre_link_args: args,
features: "+mips64r2".to_string(),
max_atomic_width: Some(64),
- // see #36994
- exe_allocation_crate: None,
-
..super::linux_base::opts()
},
})
features: "+mips64r2".to_string(),
max_atomic_width: Some(64),
- // see #36994
- exe_allocation_crate: None,
-
..super::linux_base::opts()
},
})
features: "+mips32r2,+fpxx,+nooddspreg".to_string(),
max_atomic_width: Some(32),
- // see #36994
- exe_allocation_crate: None,
-
..super::linux_base::opts()
},
})
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(),
features: "+mips32r2,+soft-float".to_string(),
max_atomic_width: Some(32),
- // see #36994
- exe_allocation_crate: None,
-
..super::linux_base::opts()
},
})
features: "+mips32r2,+fpxx,+nooddspreg".to_string(),
max_atomic_width: Some(32),
- // see #36994
- exe_allocation_crate: None,
-
..super::linux_base::opts()
},
})
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(),
features: "+mips32r2,+soft-float".to_string(),
max_atomic_width: Some(32),
- // see #36994
- exe_allocation_crate: None,
-
..super::linux_base::opts()
},
})
/// `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,
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,
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);
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);
// 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(),
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(),
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(),
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(),
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(),
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(),
// 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 {
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(),
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(),
// 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(),
base.has_rpath = false;
base.position_independent_executables = false;
base.disable_redzone = true;
- base.exe_allocation_crate = None;
base.stack_probes = true;
Ok(Target {