diff --git a/src/Cargo.lock b/src/Cargo.lock index 2ac51263cb5ca..32304c81182f1 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -15,16 +15,6 @@ dependencies = [ "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "alloc_system" -version = "0.0.0" -dependencies = [ - "compiler_builtins 0.0.0", - "core 0.0.0", - "dlmalloc 0.0.0", - "libc 0.0.0", -] - [[package]] name = "ammonia" version = "1.1.0" @@ -2104,7 +2094,6 @@ name = "rustc_asan" version = "0.0.0" dependencies = [ "alloc 0.0.0", - "alloc_system 0.0.0", "build_helper 0.1.0", "cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", "compiler_builtins 0.0.0", @@ -2276,7 +2265,6 @@ name = "rustc_lsan" version = "0.0.0" dependencies = [ "alloc 0.0.0", - "alloc_system 0.0.0", "build_helper 0.1.0", "cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", "compiler_builtins 0.0.0", @@ -2328,7 +2316,6 @@ name = "rustc_msan" version = "0.0.0" dependencies = [ "alloc 0.0.0", - "alloc_system 0.0.0", "build_helper 0.1.0", "cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", "compiler_builtins 0.0.0", @@ -2440,7 +2427,6 @@ name = "rustc_tsan" version = "0.0.0" dependencies = [ "alloc 0.0.0", - "alloc_system 0.0.0", "build_helper 0.1.0", "cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", "compiler_builtins 0.0.0", @@ -2679,11 +2665,11 @@ name = "std" version = "0.0.0" dependencies = [ "alloc 0.0.0", - "alloc_system 0.0.0", "build_helper 0.1.0", "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "compiler_builtins 0.0.0", "core 0.0.0", + "dlmalloc 0.0.0", "libc 0.0.0", "panic_abort 0.0.0", "panic_unwind 0.0.0", diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 567b47a70a12c..0aab64465fd1c 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -859,7 +859,6 @@ impl Step for Src { "src/build_helper", "src/dlmalloc", "src/liballoc", - "src/liballoc_system", "src/libbacktrace", "src/libcompiler_builtins", "src/libcore", diff --git a/src/ci/docker/wasm32-unknown/Dockerfile b/src/ci/docker/wasm32-unknown/Dockerfile index f2a29b0315100..161f0c0062fa0 100644 --- a/src/ci/docker/wasm32-unknown/Dockerfile +++ b/src/ci/docker/wasm32-unknown/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:16.04 +FROM ubuntu:18.04 RUN apt-get update && apt-get install -y --no-install-recommends \ g++ \ diff --git a/src/liballoc/tests/heap.rs b/src/liballoc/tests/heap.rs index b6be38107da7f..bf256b23f9ac0 100644 --- a/src/liballoc/tests/heap.rs +++ b/src/liballoc/tests/heap.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use alloc_system::System; -use std::alloc::{Global, Alloc, Layout}; +use std::alloc::{Global, Alloc, Layout, System}; /// https://github.com/rust-lang/rust/issues/45955 #[test] diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 3294837cb91c4..e514a8a69c020 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -9,7 +9,6 @@ // except according to those terms. #![feature(allocator_api)] -#![feature(alloc_system)] #![feature(box_syntax)] #![feature(drain_filter)] #![feature(exact_size_is_empty)] @@ -20,7 +19,6 @@ #![feature(unboxed_closures)] #![feature(repeat_generic_slice)] -extern crate alloc_system; extern crate core; extern crate rand; diff --git a/src/liballoc_system/Cargo.toml b/src/liballoc_system/Cargo.toml deleted file mode 100644 index c34e2f203a837..0000000000000 --- a/src/liballoc_system/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "alloc_system" -version = "0.0.0" - -[lib] -name = "alloc_system" -path = "lib.rs" -test = false -doc = false - -[dependencies] -core = { path = "../libcore" } -libc = { path = "../rustc/libc_shim" } -compiler_builtins = { path = "../rustc/compiler_builtins_shim" } - -# See comments in the source for what this dependency is -[target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies] -dlmalloc = { path = "../rustc/dlmalloc_shim" } diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs deleted file mode 100644 index 0e6887a508223..0000000000000 --- a/src/liballoc_system/lib.rs +++ /dev/null @@ -1,411 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![no_std] -#![allow(unused_attributes)] -#![unstable(feature = "alloc_system", - reason = "this library is unlikely to be stabilized in its current \ - form or name", - issue = "32838")] - -#![feature(allocator_api)] -#![feature(core_intrinsics)] -#![feature(nll)] -#![feature(staged_api)] -#![feature(rustc_attrs)] -#![cfg_attr( - all(target_arch = "wasm32", not(target_os = "emscripten")), - 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. -#[cfg(all(any(target_arch = "x86", - target_arch = "arm", - target_arch = "mips", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "asmjs", - target_arch = "wasm32")))] -#[allow(dead_code)] -const MIN_ALIGN: usize = 8; -#[cfg(all(any(target_arch = "x86_64", - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "s390x", - target_arch = "sparc64")))] -#[allow(dead_code)] -const MIN_ALIGN: usize = 16; - -use core::alloc::{Alloc, GlobalAlloc, AllocErr, Layout}; -use core::ptr::NonNull; - -/// The default memory allocator provided by the operating system. -/// -/// This is based on `malloc` on Unix platforms and `HeapAlloc` on Windows, -/// plus related functions. -/// -/// This type can be used in a `static` item -/// with the `#[global_allocator]` attribute -/// to force the global allocator to be the system’s one. -/// (The default is jemalloc for executables, on some platforms.) -/// -/// ```rust -/// use std::alloc::System; -/// -/// #[global_allocator] -/// static A: System = System; -/// -/// fn main() { -/// let a = Box::new(4); // Allocates from the system allocator. -/// println!("{}", a); -/// } -/// ``` -/// -/// It can also be used directly to allocate memory -/// independently of the standard library’s global allocator. -#[stable(feature = "alloc_system_type", since = "1.28.0")] -pub struct System; - -#[unstable(feature = "allocator_api", issue = "32838")] -unsafe impl Alloc for System { - #[inline] - unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { - NonNull::new(GlobalAlloc::alloc(self, layout)).ok_or(AllocErr) - } - - #[inline] - unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result, AllocErr> { - NonNull::new(GlobalAlloc::alloc_zeroed(self, layout)).ok_or(AllocErr) - } - - #[inline] - unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { - GlobalAlloc::dealloc(self, ptr.as_ptr(), layout) - } - - #[inline] - unsafe fn realloc(&mut self, - ptr: NonNull, - layout: Layout, - new_size: usize) -> Result, AllocErr> { - NonNull::new(GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size)).ok_or(AllocErr) - } -} - -#[cfg(any(windows, unix, target_os = "cloudabi", target_os = "redox"))] -mod realloc_fallback { - use core::alloc::{GlobalAlloc, Layout}; - use core::cmp; - use core::ptr; - - impl super::System { - pub(crate) unsafe fn realloc_fallback(&self, ptr: *mut u8, old_layout: Layout, - new_size: usize) -> *mut u8 { - // Docs for GlobalAlloc::realloc require this to be valid: - let new_layout = Layout::from_size_align_unchecked(new_size, old_layout.align()); - - let new_ptr = GlobalAlloc::alloc(self, new_layout); - if !new_ptr.is_null() { - let size = cmp::min(old_layout.size(), new_size); - ptr::copy_nonoverlapping(ptr, new_ptr, size); - GlobalAlloc::dealloc(self, ptr, old_layout); - } - new_ptr - } - } -} - -#[cfg(any(unix, target_os = "cloudabi", target_os = "redox"))] -mod platform { - extern crate libc; - - use core::ptr; - - use MIN_ALIGN; - use System; - use core::alloc::{GlobalAlloc, Layout}; - - #[stable(feature = "alloc_system_type", since = "1.28.0")] - unsafe impl GlobalAlloc for System { - #[inline] - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { - libc::malloc(layout.size()) as *mut u8 - } else { - #[cfg(target_os = "macos")] - { - if layout.align() > (1 << 31) { - return ptr::null_mut() - } - } - aligned_malloc(&layout) - } - } - - #[inline] - unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { - if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { - libc::calloc(layout.size(), 1) as *mut u8 - } else { - let ptr = self.alloc(layout.clone()); - if !ptr.is_null() { - ptr::write_bytes(ptr, 0, layout.size()); - } - ptr - } - } - - #[inline] - unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { - libc::free(ptr as *mut libc::c_void) - } - - #[inline] - unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { - if layout.align() <= MIN_ALIGN && layout.align() <= new_size { - libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 - } else { - self.realloc_fallback(ptr, layout, new_size) - } - } - } - - #[cfg(any(target_os = "android", - target_os = "hermit", - target_os = "redox", - target_os = "solaris"))] - #[inline] - unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { - // On android we currently target API level 9 which unfortunately - // doesn't have the `posix_memalign` API used below. Instead we use - // `memalign`, but this unfortunately has the property on some systems - // where the memory returned cannot be deallocated by `free`! - // - // Upon closer inspection, however, this appears to work just fine with - // Android, so for this platform we should be fine to call `memalign` - // (which is present in API level 9). Some helpful references could - // possibly be chromium using memalign [1], attempts at documenting that - // memalign + free is ok [2] [3], or the current source of chromium - // which still uses memalign on android [4]. - // - // [1]: https://codereview.chromium.org/10796020/ - // [2]: https://code.google.com/p/android/issues/detail?id=35391 - // [3]: https://bugs.chromium.org/p/chromium/issues/detail?id=138579 - // [4]: https://chromium.googlesource.com/chromium/src/base/+/master/ - // /memory/aligned_memory.cc - libc::memalign(layout.align(), layout.size()) as *mut u8 - } - - #[cfg(not(any(target_os = "android", - target_os = "hermit", - target_os = "redox", - target_os = "solaris")))] - #[inline] - unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { - let mut out = ptr::null_mut(); - let ret = libc::posix_memalign(&mut out, layout.align(), layout.size()); - if ret != 0 { - ptr::null_mut() - } else { - out as *mut u8 - } - } -} - -#[cfg(windows)] -#[allow(nonstandard_style)] -mod platform { - use MIN_ALIGN; - use System; - use core::alloc::{GlobalAlloc, Layout}; - - type LPVOID = *mut u8; - type HANDLE = LPVOID; - type SIZE_T = usize; - type DWORD = u32; - type BOOL = i32; - - extern "system" { - fn GetProcessHeap() -> HANDLE; - fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID; - fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID; - fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL; - fn GetLastError() -> DWORD; - } - - #[repr(C)] - struct Header(*mut u8); - - const HEAP_ZERO_MEMORY: DWORD = 0x00000008; - - unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header { - &mut *(ptr as *mut Header).offset(-1) - } - - unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 { - let aligned = ptr.add(align - (ptr as usize & (align - 1))); - *get_header(aligned) = Header(ptr); - aligned - } - - #[inline] - unsafe fn allocate_with_flags(layout: Layout, flags: DWORD) -> *mut u8 { - let ptr = if layout.align() <= MIN_ALIGN { - HeapAlloc(GetProcessHeap(), flags, layout.size()) - } else { - let size = layout.size() + layout.align(); - let ptr = HeapAlloc(GetProcessHeap(), flags, size); - if ptr.is_null() { - ptr - } else { - align_ptr(ptr, layout.align()) - } - }; - ptr as *mut u8 - } - - #[stable(feature = "alloc_system_type", since = "1.28.0")] - unsafe impl GlobalAlloc for System { - #[inline] - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - allocate_with_flags(layout, 0) - } - - #[inline] - unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { - allocate_with_flags(layout, HEAP_ZERO_MEMORY) - } - - #[inline] - unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - if layout.align() <= MIN_ALIGN { - let err = HeapFree(GetProcessHeap(), 0, ptr as LPVOID); - debug_assert!(err != 0, "Failed to free heap memory: {}", - GetLastError()); - } else { - let header = get_header(ptr); - let err = HeapFree(GetProcessHeap(), 0, header.0 as LPVOID); - debug_assert!(err != 0, "Failed to free heap memory: {}", - GetLastError()); - } - } - - #[inline] - unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { - if layout.align() <= MIN_ALIGN { - HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, new_size) as *mut u8 - } else { - self.realloc_fallback(ptr, layout, new_size) - } - } - } -} - -// This is an implementation of a global allocator on the wasm32 platform when -// emscripten is not in use. In that situation there's no actual runtime for us -// to lean on for allocation, so instead we provide our own! -// -// The wasm32 instruction set has two instructions for getting the current -// amount of memory and growing the amount of memory. These instructions are the -// foundation on which we're able to build an allocator, so we do so! Note that -// the instructions are also pretty "global" and this is the "global" allocator -// after all! -// -// The current allocator here is the `dlmalloc` crate which we've got included -// in the rust-lang/rust repository as a submodule. The crate is a port of -// dlmalloc.c from C to Rust and is basically just so we can have "pure Rust" -// for now which is currently technically required (can't link with C yet). -// -// The crate itself provides a global allocator which on wasm has no -// synchronization as there are no threads! -#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] -mod platform { - extern crate dlmalloc; - - use core::alloc::{GlobalAlloc, Layout}; - use System; - - static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::DLMALLOC_INIT; - - #[stable(feature = "alloc_system_type", since = "1.28.0")] - unsafe impl GlobalAlloc for System { - #[inline] - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - let _lock = lock::lock(); - DLMALLOC.malloc(layout.size(), layout.align()) - } - - #[inline] - unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { - let _lock = lock::lock(); - DLMALLOC.calloc(layout.size(), layout.align()) - } - - #[inline] - unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - let _lock = lock::lock(); - DLMALLOC.free(ptr, layout.size(), layout.align()) - } - - #[inline] - unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { - let _lock = lock::lock(); - DLMALLOC.realloc(ptr, layout.size(), layout.align(), new_size) - } - } - - #[cfg(target_feature = "atomics")] - mod lock { - use core::arch::wasm32; - use core::sync::atomic::{AtomicI32, Ordering::SeqCst}; - - static LOCKED: AtomicI32 = AtomicI32::new(0); - - pub struct DropLock; - - pub fn lock() -> DropLock { - loop { - if LOCKED.swap(1, SeqCst) == 0 { - return DropLock - } - unsafe { - let r = wasm32::atomic::wait_i32( - &LOCKED as *const AtomicI32 as *mut i32, - 1, // expected value - -1, // timeout - ); - debug_assert!(r == 0 || r == 1); - } - } - } - - impl Drop for DropLock { - fn drop(&mut self) { - let r = LOCKED.swap(0, SeqCst); - debug_assert_eq!(r, 1); - unsafe { - wasm32::atomic::wake( - &LOCKED as *const AtomicI32 as *mut i32, - 1, // only one thread - ); - } - } - } - } - - #[cfg(not(target_feature = "atomics"))] - mod lock { - #[inline] - pub fn lock() {} // no atomics, no threads, that's easy! - } -} diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs index e3f9c51a1235e..671f513d5b933 100644 --- a/src/librustc/middle/dependency_format.rs +++ b/src/librustc/middle/dependency_format.rs @@ -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, } } -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]) { diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index efd7e8b610efc..8cfbd27fc6163 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -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>, pub allocator_kind: Once>, pub injected_panic_runtime: Once>, @@ -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())), diff --git a/src/librustc_asan/Cargo.toml b/src/librustc_asan/Cargo.toml index 34d8b75a5bfb3..734564c2d8567 100644 --- a/src/librustc_asan/Cargo.toml +++ b/src/librustc_asan/Cargo.toml @@ -15,6 +15,5 @@ cmake = "0.1.18" [dependencies] alloc = { path = "../liballoc" } -alloc_system = { path = "../liballoc_system" } core = { path = "../libcore" } compiler_builtins = { path = "../rustc/compiler_builtins_shim" } diff --git a/src/librustc_asan/lib.rs b/src/librustc_asan/lib.rs index 7b845e631ffa3..47f917e40c1ff 100644 --- a/src/librustc_asan/lib.rs +++ b/src/librustc_asan/lib.rs @@ -9,7 +9,6 @@ // except according to those terms. #![sanitizer_runtime] -#![feature(alloc_system)] #![feature(nll)] #![feature(sanitizer_runtime)] #![feature(staged_api)] @@ -17,10 +16,3 @@ #![unstable(feature = "sanitizer_runtime_lib", reason = "internal implementation detail of sanitizers", issue = "0")] - -extern crate alloc_system; - -use alloc_system::System; - -#[global_allocator] -static ALLOC: System = System; diff --git a/src/librustc_lsan/Cargo.toml b/src/librustc_lsan/Cargo.toml index 9c19b53742654..2573825a5ff45 100644 --- a/src/librustc_lsan/Cargo.toml +++ b/src/librustc_lsan/Cargo.toml @@ -15,6 +15,5 @@ cmake = "0.1.18" [dependencies] alloc = { path = "../liballoc" } -alloc_system = { path = "../liballoc_system" } core = { path = "../libcore" } compiler_builtins = { path = "../rustc/compiler_builtins_shim" } diff --git a/src/librustc_lsan/lib.rs b/src/librustc_lsan/lib.rs index 7b845e631ffa3..47f917e40c1ff 100644 --- a/src/librustc_lsan/lib.rs +++ b/src/librustc_lsan/lib.rs @@ -9,7 +9,6 @@ // except according to those terms. #![sanitizer_runtime] -#![feature(alloc_system)] #![feature(nll)] #![feature(sanitizer_runtime)] #![feature(staged_api)] @@ -17,10 +16,3 @@ #![unstable(feature = "sanitizer_runtime_lib", reason = "internal implementation detail of sanitizers", issue = "0")] - -extern crate alloc_system; - -use alloc_system::System; - -#[global_allocator] -static ALLOC: System = System; diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 7733ab2e246d1..a14dd99eeb3b3 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -16,7 +16,7 @@ use decoder::proc_macro_def_path_table; use schema::CrateRoot; use rustc_data_structures::sync::{Lrc, RwLock, Lock}; -use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX}; +use rustc::hir::def_id::CrateNum; use rustc_data_structures::svh::Svh; use rustc::middle::allocator::AllocatorKind; use rustc::middle::cstore::DepKind; @@ -864,7 +864,6 @@ 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 } @@ -872,20 +871,15 @@ impl<'a> CrateLoader<'a> { // 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; - for ct in self.sess.crate_types.borrow().iter() { - match *ct { - config::CrateType::Executable => need_exe_alloc = true, - config::CrateType::Dylib | - config::CrateType::ProcMacro | - config::CrateType::Cdylib | - config::CrateType::Staticlib => need_lib_alloc = true, - config::CrateType::Rlib => {} - } - } - if !need_lib_alloc && !need_exe_alloc { - self.sess.injected_allocator.set(None); + let all_rlib = self.sess.crate_types.borrow() + .iter() + .all(|ct| { + match *ct { + config::CrateType::Rlib => true, + _ => false, + } + }); + if all_rlib { self.sess.allocator_kind.set(None); return } @@ -924,103 +918,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); @@ -1083,8 +1001,6 @@ impl<'a> CrateLoader<'a> { impl<'a> CrateLoader<'a> { pub fn postprocess(&mut self, krate: &ast::Crate) { - // inject the sanitizer runtime before the allocator runtime because all - // sanitizers force the use of the `alloc_system` allocator self.inject_sanitizer_runtime(); self.inject_profiler_runtime(); self.inject_allocator_crate(krate); diff --git a/src/librustc_msan/Cargo.toml b/src/librustc_msan/Cargo.toml index 17ec2b96438ad..29165675a2ad7 100644 --- a/src/librustc_msan/Cargo.toml +++ b/src/librustc_msan/Cargo.toml @@ -15,6 +15,5 @@ cmake = "0.1.18" [dependencies] alloc = { path = "../liballoc" } -alloc_system = { path = "../liballoc_system" } core = { path = "../libcore" } compiler_builtins = { path = "../rustc/compiler_builtins_shim" } diff --git a/src/librustc_msan/lib.rs b/src/librustc_msan/lib.rs index 7b845e631ffa3..47f917e40c1ff 100644 --- a/src/librustc_msan/lib.rs +++ b/src/librustc_msan/lib.rs @@ -9,7 +9,6 @@ // except according to those terms. #![sanitizer_runtime] -#![feature(alloc_system)] #![feature(nll)] #![feature(sanitizer_runtime)] #![feature(staged_api)] @@ -17,10 +16,3 @@ #![unstable(feature = "sanitizer_runtime_lib", reason = "internal implementation detail of sanitizers", issue = "0")] - -extern crate alloc_system; - -use alloc_system::System; - -#[global_allocator] -static ALLOC: System = System; diff --git a/src/librustc_target/spec/aarch64_unknown_freebsd.rs b/src/librustc_target/spec/aarch64_unknown_freebsd.rs index 541f0564a01e2..b120f57192bfb 100644 --- a/src/librustc_target/spec/aarch64_unknown_freebsd.rs +++ b/src/librustc_target/spec/aarch64_unknown_freebsd.rs @@ -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(), diff --git a/src/librustc_target/spec/aarch64_unknown_linux_gnu.rs b/src/librustc_target/spec/aarch64_unknown_linux_gnu.rs index 2351d01469215..af7ec6a1787f0 100644 --- a/src/librustc_target/spec/aarch64_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/aarch64_unknown_linux_gnu.rs @@ -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(), diff --git a/src/librustc_target/spec/aarch64_unknown_linux_musl.rs b/src/librustc_target/spec/aarch64_unknown_linux_musl.rs index 5ab55a076f45b..e5ca91aabe56a 100644 --- a/src/librustc_target/spec/aarch64_unknown_linux_musl.rs +++ b/src/librustc_target/spec/aarch64_unknown_linux_musl.rs @@ -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(), diff --git a/src/librustc_target/spec/hermit_base.rs b/src/librustc_target/spec/hermit_base.rs index 2a24f771e9289..168eac685e4f3 100644 --- a/src/librustc_target/spec/hermit_base.rs +++ b/src/librustc_target/spec/hermit_base.rs @@ -21,7 +21,6 @@ pub fn opts() -> TargetOptions { ]); TargetOptions { - exe_allocation_crate: None, executables: true, has_elf_tls: true, linker_is_gnu: true, diff --git a/src/librustc_target/spec/l4re_base.rs b/src/librustc_target/spec/l4re_base.rs index 4ebc930d48b6f..7932adf3b1054 100644 --- a/src/librustc_target/spec/l4re_base.rs +++ b/src/librustc_target/spec/l4re_base.rs @@ -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, diff --git a/src/librustc_target/spec/mips64_unknown_linux_gnuabi64.rs b/src/librustc_target/spec/mips64_unknown_linux_gnuabi64.rs index 1f60d918908d0..b80b6b561cd42 100644 --- a/src/librustc_target/spec/mips64_unknown_linux_gnuabi64.rs +++ b/src/librustc_target/spec/mips64_unknown_linux_gnuabi64.rs @@ -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() }, }) diff --git a/src/librustc_target/spec/mips64el_unknown_linux_gnuabi64.rs b/src/librustc_target/spec/mips64el_unknown_linux_gnuabi64.rs index e42fde8d403fb..1c835af6e412b 100644 --- a/src/librustc_target/spec/mips64el_unknown_linux_gnuabi64.rs +++ b/src/librustc_target/spec/mips64el_unknown_linux_gnuabi64.rs @@ -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() }, }) diff --git a/src/librustc_target/spec/mips_unknown_linux_gnu.rs b/src/librustc_target/spec/mips_unknown_linux_gnu.rs index 59e15137cf40d..6331031c9a284 100644 --- a/src/librustc_target/spec/mips_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/mips_unknown_linux_gnu.rs @@ -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() }, }) diff --git a/src/librustc_target/spec/mips_unknown_linux_musl.rs b/src/librustc_target/spec/mips_unknown_linux_musl.rs index 8ee399ba56c32..0b20765172a02 100644 --- a/src/librustc_target/spec/mips_unknown_linux_musl.rs +++ b/src/librustc_target/spec/mips_unknown_linux_musl.rs @@ -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(), diff --git a/src/librustc_target/spec/mips_unknown_linux_uclibc.rs b/src/librustc_target/spec/mips_unknown_linux_uclibc.rs index 384ab1e413123..d3f614c982ae4 100644 --- a/src/librustc_target/spec/mips_unknown_linux_uclibc.rs +++ b/src/librustc_target/spec/mips_unknown_linux_uclibc.rs @@ -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() }, }) diff --git a/src/librustc_target/spec/mipsel_unknown_linux_gnu.rs b/src/librustc_target/spec/mipsel_unknown_linux_gnu.rs index edd29164caca8..79ebefa79a320 100644 --- a/src/librustc_target/spec/mipsel_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/mipsel_unknown_linux_gnu.rs @@ -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() }, }) diff --git a/src/librustc_target/spec/mipsel_unknown_linux_musl.rs b/src/librustc_target/spec/mipsel_unknown_linux_musl.rs index 1d9378ca1b814..042e2b71c3256 100644 --- a/src/librustc_target/spec/mipsel_unknown_linux_musl.rs +++ b/src/librustc_target/spec/mipsel_unknown_linux_musl.rs @@ -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(), diff --git a/src/librustc_target/spec/mipsel_unknown_linux_uclibc.rs b/src/librustc_target/spec/mipsel_unknown_linux_uclibc.rs index a1db1791bb7ce..8cb5cd3f03a67 100644 --- a/src/librustc_target/spec/mipsel_unknown_linux_uclibc.rs +++ b/src/librustc_target/spec/mipsel_unknown_linux_uclibc.rs @@ -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() }, }) diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index c8af81c02ea4a..16dc2a91030f1 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -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, - /// Flag indicating whether ELF TLS (e.g. #[thread_local]) is available for /// this target. pub has_elf_tls: bool, @@ -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, @@ -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); @@ -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); diff --git a/src/librustc_target/spec/powerpc64_unknown_linux_gnu.rs b/src/librustc_target/spec/powerpc64_unknown_linux_gnu.rs index 1959871161343..1d0afcd5e0c60 100644 --- a/src/librustc_target/spec/powerpc64_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/powerpc64_unknown_linux_gnu.rs @@ -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(), diff --git a/src/librustc_target/spec/powerpc64le_unknown_linux_gnu.rs b/src/librustc_target/spec/powerpc64le_unknown_linux_gnu.rs index 39840692dff18..01811c5a0c322 100644 --- a/src/librustc_target/spec/powerpc64le_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/powerpc64le_unknown_linux_gnu.rs @@ -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(), diff --git a/src/librustc_target/spec/powerpc64le_unknown_linux_musl.rs b/src/librustc_target/spec/powerpc64le_unknown_linux_musl.rs index 34ec82412289d..590c5ba8d54b4 100644 --- a/src/librustc_target/spec/powerpc64le_unknown_linux_musl.rs +++ b/src/librustc_target/spec/powerpc64le_unknown_linux_musl.rs @@ -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(), diff --git a/src/librustc_target/spec/powerpc_unknown_linux_gnu.rs b/src/librustc_target/spec/powerpc_unknown_linux_gnu.rs index c05b110a75d39..99d8d99fbb2b6 100644 --- a/src/librustc_target/spec/powerpc_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/powerpc_unknown_linux_gnu.rs @@ -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(), diff --git a/src/librustc_target/spec/powerpc_unknown_linux_gnuspe.rs b/src/librustc_target/spec/powerpc_unknown_linux_gnuspe.rs index c76c3119c87c5..9b15b0a5dc4b7 100644 --- a/src/librustc_target/spec/powerpc_unknown_linux_gnuspe.rs +++ b/src/librustc_target/spec/powerpc_unknown_linux_gnuspe.rs @@ -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(), diff --git a/src/librustc_target/spec/powerpc_unknown_netbsd.rs b/src/librustc_target/spec/powerpc_unknown_netbsd.rs index 740222c960805..98625a63f5298 100644 --- a/src/librustc_target/spec/powerpc_unknown_netbsd.rs +++ b/src/librustc_target/spec/powerpc_unknown_netbsd.rs @@ -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(), diff --git a/src/librustc_target/spec/s390x_unknown_linux_gnu.rs b/src/librustc_target/spec/s390x_unknown_linux_gnu.rs index c9a9625ebab95..bd8b7e435d340 100644 --- a/src/librustc_target/spec/s390x_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/s390x_unknown_linux_gnu.rs @@ -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 { diff --git a/src/librustc_target/spec/sparc64_unknown_linux_gnu.rs b/src/librustc_target/spec/sparc64_unknown_linux_gnu.rs index f68b5fd24bf75..f2b99aa46d2d0 100644 --- a/src/librustc_target/spec/sparc64_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/sparc64_unknown_linux_gnu.rs @@ -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(), diff --git a/src/librustc_target/spec/sparc_unknown_linux_gnu.rs b/src/librustc_target/spec/sparc_unknown_linux_gnu.rs index 4e352374f90b0..81db39cd23f87 100644 --- a/src/librustc_target/spec/sparc_unknown_linux_gnu.rs +++ b/src/librustc_target/spec/sparc_unknown_linux_gnu.rs @@ -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(), diff --git a/src/librustc_target/spec/sparcv9_sun_solaris.rs b/src/librustc_target/spec/sparcv9_sun_solaris.rs index 8bc233107b8bb..5029e857eb543 100644 --- a/src/librustc_target/spec/sparcv9_sun_solaris.rs +++ b/src/librustc_target/spec/sparcv9_sun_solaris.rs @@ -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(), diff --git a/src/librustc_target/spec/x86_64_rumprun_netbsd.rs b/src/librustc_target/spec/x86_64_rumprun_netbsd.rs index 684bf5a6c1026..e7570cd2da6ec 100644 --- a/src/librustc_target/spec/x86_64_rumprun_netbsd.rs +++ b/src/librustc_target/spec/x86_64_rumprun_netbsd.rs @@ -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 { diff --git a/src/librustc_tsan/Cargo.toml b/src/librustc_tsan/Cargo.toml index 8bb67c0bbac5f..baadb64511ae1 100644 --- a/src/librustc_tsan/Cargo.toml +++ b/src/librustc_tsan/Cargo.toml @@ -15,6 +15,5 @@ cmake = "0.1.18" [dependencies] alloc = { path = "../liballoc" } -alloc_system = { path = "../liballoc_system" } core = { path = "../libcore" } compiler_builtins = { path = "../rustc/compiler_builtins_shim" } diff --git a/src/librustc_tsan/lib.rs b/src/librustc_tsan/lib.rs index 7b845e631ffa3..47f917e40c1ff 100644 --- a/src/librustc_tsan/lib.rs +++ b/src/librustc_tsan/lib.rs @@ -9,7 +9,6 @@ // except according to those terms. #![sanitizer_runtime] -#![feature(alloc_system)] #![feature(nll)] #![feature(sanitizer_runtime)] #![feature(staged_api)] @@ -17,10 +16,3 @@ #![unstable(feature = "sanitizer_runtime_lib", reason = "internal implementation detail of sanitizers", issue = "0")] - -extern crate alloc_system; - -use alloc_system::System; - -#[global_allocator] -static ALLOC: System = System; diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 0f22459b34349..2b1d515c83b75 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -14,7 +14,6 @@ crate-type = ["dylib", "rlib"] [dependencies] alloc = { path = "../liballoc" } -alloc_system = { path = "../liballoc_system" } panic_unwind = { path = "../libpanic_unwind", optional = true } panic_abort = { path = "../libpanic_abort" } core = { path = "../libcore" } @@ -36,6 +35,9 @@ rustc_lsan = { path = "../librustc_lsan" } rustc_msan = { path = "../librustc_msan" } rustc_tsan = { path = "../librustc_tsan" } +[target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies] +dlmalloc = { path = '../rustc/dlmalloc_shim' } + [build-dependencies] cc = "1.0" build_helper = { path = "../build_helper" } diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs index 1ff342fa7a7be..485b2ffe1975e 100644 --- a/src/libstd/alloc.rs +++ b/src/libstd/alloc.rs @@ -73,15 +73,100 @@ use core::sync::atomic::{AtomicPtr, Ordering}; use core::{mem, ptr}; +use core::ptr::NonNull; use sys_common::util::dumb_print; #[stable(feature = "alloc_module", since = "1.28.0")] #[doc(inline)] pub use alloc_crate::alloc::*; +/// The default memory allocator provided by the operating system. +/// +/// This is based on `malloc` on Unix platforms and `HeapAlloc` on Windows, +/// plus related functions. +/// +/// This type implements the `GlobalAlloc` trait and Rust programs by deafult +/// work as if they had this definition: +/// +/// ```rust +/// use std::alloc::System; +/// +/// #[global_allocator] +/// static A: System = System; +/// +/// fn main() { +/// let a = Box::new(4); // Allocates from the system allocator. +/// println!("{}", a); +/// } +/// ``` +/// +/// You can also define your own wrapper around `System` if you'd like, such as +/// keeping track of the number of all bytes allocated: +/// +/// ```rust +/// use std::alloc::{System, GlobalAlloc, Layout}; +/// use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering::SeqCst}; +/// +/// struct Counter; +/// +/// static ALLOCATED: AtomicUsize = ATOMIC_USIZE_INIT; +/// +/// unsafe impl GlobalAlloc for Counter { +/// unsafe fn alloc(&self, layout: Layout) -> *mut u8 { +/// let ret = System.alloc(layout); +/// if !ret.is_null() { +/// ALLOCATED.fetch_add(layout.size(), SeqCst); +/// } +/// return ret +/// } +/// +/// unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { +/// System.dealloc(ptr, layout); +/// ALLOCATED.fetch_sub(layout.size(), SeqCst); +/// } +/// } +/// +/// #[global_allocator] +/// static A: Counter = Counter; +/// +/// fn main() { +/// println!("allocated bytes before main: {}", ALLOCATED.load(SeqCst)); +/// } +/// ``` +/// +/// It can also be used directly to allocate memory independently of whatever +/// global allocator has been selected for a Rust program. For example if a Rust +/// program opts in to using jemalloc as the global allocator, `System` will +/// still allocate memory using `malloc` and `HeapAlloc`. #[stable(feature = "alloc_system_type", since = "1.28.0")] -#[doc(inline)] -pub use alloc_system::System; +#[derive(Debug, Copy, Clone)] +pub struct System; + +#[unstable(feature = "allocator_api", issue = "32838")] +unsafe impl Alloc for System { + #[inline] + unsafe fn alloc(&mut self, layout: Layout) -> Result, AllocErr> { + NonNull::new(GlobalAlloc::alloc(self, layout)).ok_or(AllocErr) + } + + #[inline] + unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result, AllocErr> { + NonNull::new(GlobalAlloc::alloc_zeroed(self, layout)).ok_or(AllocErr) + } + + #[inline] + unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout) { + GlobalAlloc::dealloc(self, ptr.as_ptr(), layout) + } + + #[inline] + unsafe fn realloc(&mut self, + ptr: NonNull, + layout: Layout, + new_size: usize) -> Result, AllocErr> { + NonNull::new(GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size)).ok_or(AllocErr) + } +} static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut()); diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 0829593505d69..f460d109c894a 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -235,7 +235,6 @@ #![cfg_attr(test, feature(test, update_panic_count))] #![feature(alloc)] #![feature(alloc_error_handler)] -#![feature(alloc_system)] #![feature(allocator_api)] #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] @@ -316,7 +315,7 @@ #[cfg(stage0)] #[global_allocator] -static ALLOC: alloc_system::System = alloc_system::System; +static ALLOC: alloc::System = alloc::System; // Explicitly import the prelude. The compiler uses this same unstable attribute // to import the prelude implicitly when building crates that depend on std. @@ -337,7 +336,6 @@ pub use core::{unreachable, unimplemented, write, writeln, try}; #[allow(unused_imports)] // macros from `alloc` are not used on all platforms #[macro_use] extern crate alloc as alloc_crate; -extern crate alloc_system; #[doc(masked)] extern crate libc; diff --git a/src/libstd/sys/cloudabi/mod.rs b/src/libstd/sys/cloudabi/mod.rs index 9e943c17fc85f..dfb56472c6c83 100644 --- a/src/libstd/sys/cloudabi/mod.rs +++ b/src/libstd/sys/cloudabi/mod.rs @@ -12,6 +12,8 @@ use io; use libc; use mem; +#[path = "../unix/alloc.rs"] +pub mod alloc; pub mod args; #[cfg(feature = "backtrace")] pub mod backtrace; diff --git a/src/libstd/sys/redox/mod.rs b/src/libstd/sys/redox/mod.rs index f943257c68733..edb407ecd23ce 100644 --- a/src/libstd/sys/redox/mod.rs +++ b/src/libstd/sys/redox/mod.rs @@ -15,6 +15,8 @@ use io::{self, ErrorKind}; pub use libc::strlen; pub use self::rand::hashmap_random_keys; +#[path = "../unix/alloc.rs"] +pub mod alloc; pub mod args; #[cfg(feature = "backtrace")] pub mod backtrace; diff --git a/src/libstd/sys/unix/alloc.rs b/src/libstd/sys/unix/alloc.rs new file mode 100644 index 0000000000000..2a7f1934518e1 --- /dev/null +++ b/src/libstd/sys/unix/alloc.rs @@ -0,0 +1,100 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use ptr; +use libc; +use sys_common::alloc::{MIN_ALIGN, realloc_fallback}; +use alloc::{GlobalAlloc, Layout, System}; + +#[stable(feature = "alloc_system_type", since = "1.28.0")] +unsafe impl GlobalAlloc for System { + #[inline] + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { + libc::malloc(layout.size()) as *mut u8 + } else { + #[cfg(target_os = "macos")] + { + if layout.align() > (1 << 31) { + return ptr::null_mut() + } + } + aligned_malloc(&layout) + } + } + + #[inline] + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { + if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { + libc::calloc(layout.size(), 1) as *mut u8 + } else { + let ptr = self.alloc(layout.clone()); + if !ptr.is_null() { + ptr::write_bytes(ptr, 0, layout.size()); + } + ptr + } + } + + #[inline] + unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { + libc::free(ptr as *mut libc::c_void) + } + + #[inline] + unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { + if layout.align() <= MIN_ALIGN && layout.align() <= new_size { + libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 + } else { + realloc_fallback(self, ptr, layout, new_size) + } + } +} + +#[cfg(any(target_os = "android", + target_os = "hermit", + target_os = "redox", + target_os = "solaris"))] +#[inline] +unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { + // On android we currently target API level 9 which unfortunately + // doesn't have the `posix_memalign` API used below. Instead we use + // `memalign`, but this unfortunately has the property on some systems + // where the memory returned cannot be deallocated by `free`! + // + // Upon closer inspection, however, this appears to work just fine with + // Android, so for this platform we should be fine to call `memalign` + // (which is present in API level 9). Some helpful references could + // possibly be chromium using memalign [1], attempts at documenting that + // memalign + free is ok [2] [3], or the current source of chromium + // which still uses memalign on android [4]. + // + // [1]: https://codereview.chromium.org/10796020/ + // [2]: https://code.google.com/p/android/issues/detail?id=35391 + // [3]: https://bugs.chromium.org/p/chromium/issues/detail?id=138579 + // [4]: https://chromium.googlesource.com/chromium/src/base/+/master/ + // /memory/aligned_memory.cc + libc::memalign(layout.align(), layout.size()) as *mut u8 +} + +#[cfg(not(any(target_os = "android", + target_os = "hermit", + target_os = "redox", + target_os = "solaris")))] +#[inline] +unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { + let mut out = ptr::null_mut(); + let ret = libc::posix_memalign(&mut out, layout.align(), layout.size()); + if ret != 0 { + ptr::null_mut() + } else { + out as *mut u8 + } +} diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index 17214be5b0549..e8101bd0bc964 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -36,6 +36,7 @@ pub use libc::strlen; #[macro_use] pub mod weak; +pub mod alloc; pub mod args; pub mod android; #[cfg(feature = "backtrace")] diff --git a/src/libstd/sys/wasm/alloc.rs b/src/libstd/sys/wasm/alloc.rs new file mode 100644 index 0000000000000..0faa3c9a740f1 --- /dev/null +++ b/src/libstd/sys/wasm/alloc.rs @@ -0,0 +1,105 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! This is an implementation of a global allocator on the wasm32 platform when +//! emscripten is not in use. In that situation there's no actual runtime for us +//! to lean on for allocation, so instead we provide our own! +//! +//! The wasm32 instruction set has two instructions for getting the current +//! amount of memory and growing the amount of memory. These instructions are the +//! foundation on which we're able to build an allocator, so we do so! Note that +//! the instructions are also pretty "global" and this is the "global" allocator +//! after all! +//! +//! The current allocator here is the `dlmalloc` crate which we've got included +//! in the rust-lang/rust repository as a submodule. The crate is a port of +//! dlmalloc.c from C to Rust and is basically just so we can have "pure Rust" +//! for now which is currently technically required (can't link with C yet). +//! +//! The crate itself provides a global allocator which on wasm has no +//! synchronization as there are no threads! + +extern crate dlmalloc; + +use alloc::{GlobalAlloc, Layout, System}; + +static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::DLMALLOC_INIT; + +#[stable(feature = "alloc_system_type", since = "1.28.0")] +unsafe impl GlobalAlloc for System { + #[inline] + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + let _lock = lock::lock(); + DLMALLOC.malloc(layout.size(), layout.align()) + } + + #[inline] + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { + let _lock = lock::lock(); + DLMALLOC.calloc(layout.size(), layout.align()) + } + + #[inline] + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + let _lock = lock::lock(); + DLMALLOC.free(ptr, layout.size(), layout.align()) + } + + #[inline] + unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { + let _lock = lock::lock(); + DLMALLOC.realloc(ptr, layout.size(), layout.align(), new_size) + } +} + +#[cfg(target_feature = "atomics")] +mod lock { + use arch::wasm32; + use sync::atomic::{AtomicI32, Ordering::SeqCst}; + + static LOCKED: AtomicI32 = AtomicI32::new(0); + + pub struct DropLock; + + pub fn lock() -> DropLock { + loop { + if LOCKED.swap(1, SeqCst) == 0 { + return DropLock + } + unsafe { + let r = wasm32::atomic::wait_i32( + &LOCKED as *const AtomicI32 as *mut i32, + 1, // expected value + -1, // timeout + ); + debug_assert!(r == 0 || r == 1); + } + } + } + + impl Drop for DropLock { + fn drop(&mut self) { + let r = LOCKED.swap(0, SeqCst); + debug_assert_eq!(r, 1); + unsafe { + wasm32::atomic::wake( + &LOCKED as *const AtomicI32 as *mut i32, + 1, // only one thread + ); + } + } + } +} + +#[cfg(not(target_feature = "atomics"))] +mod lock { + #[inline] + pub fn lock() {} // no atomics, no threads, that's easy! +} diff --git a/src/libstd/sys/wasm/mod.rs b/src/libstd/sys/wasm/mod.rs index e11b4d71aaeea..e8f7e32ac9177 100644 --- a/src/libstd/sys/wasm/mod.rs +++ b/src/libstd/sys/wasm/mod.rs @@ -32,6 +32,7 @@ use sys_common::{AsInner, FromInner}; use ffi::{OsString, OsStr}; use time::Duration; +pub mod alloc; pub mod args; #[cfg(feature = "backtrace")] pub mod backtrace; diff --git a/src/libstd/sys/windows/alloc.rs b/src/libstd/sys/windows/alloc.rs new file mode 100644 index 0000000000000..e5de3e016c99b --- /dev/null +++ b/src/libstd/sys/windows/alloc.rs @@ -0,0 +1,77 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use alloc::{GlobalAlloc, Layout, System}; +use sys::c; +use sys_common::alloc::{MIN_ALIGN, realloc_fallback}; + +#[repr(C)] +struct Header(*mut u8); + +unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header { + &mut *(ptr as *mut Header).offset(-1) +} + +unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 { + let aligned = ptr.add(align - (ptr as usize & (align - 1))); + *get_header(aligned) = Header(ptr); + aligned +} + +#[inline] +unsafe fn allocate_with_flags(layout: Layout, flags: c::DWORD) -> *mut u8 { + if layout.align() <= MIN_ALIGN { + return c::HeapAlloc(c::GetProcessHeap(), flags, layout.size()) as *mut u8 + } + + let size = layout.size() + layout.align(); + let ptr = c::HeapAlloc(c::GetProcessHeap(), flags, size); + if ptr.is_null() { + ptr as *mut u8 + } else { + align_ptr(ptr as *mut u8, layout.align()) + } +} + +#[stable(feature = "alloc_system_type", since = "1.28.0")] +unsafe impl GlobalAlloc for System { + #[inline] + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + allocate_with_flags(layout, 0) + } + + #[inline] + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { + allocate_with_flags(layout, c::HEAP_ZERO_MEMORY) + } + + #[inline] + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + if layout.align() <= MIN_ALIGN { + let err = c::HeapFree(c::GetProcessHeap(), 0, ptr as c::LPVOID); + debug_assert!(err != 0, "Failed to free heap memory: {}", + c::GetLastError()); + } else { + let header = get_header(ptr); + let err = c::HeapFree(c::GetProcessHeap(), 0, header.0 as c::LPVOID); + debug_assert!(err != 0, "Failed to free heap memory: {}", + c::GetLastError()); + } + } + + #[inline] + unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { + if layout.align() <= MIN_ALIGN { + c::HeapReAlloc(c::GetProcessHeap(), 0, ptr as c::LPVOID, new_size) as *mut u8 + } else { + realloc_fallback(self, ptr, layout, new_size) + } + } +} diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs index f4bd9c22bb93f..c84874a3e880f 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -309,6 +309,8 @@ pub const FD_SETSIZE: usize = 64; pub const STACK_SIZE_PARAM_IS_A_RESERVATION: DWORD = 0x00010000; +pub const HEAP_ZERO_MEMORY: DWORD = 0x00000008; + #[repr(C)] #[cfg(not(target_pointer_width = "64"))] pub struct WSADATA { @@ -1277,6 +1279,11 @@ extern "system" { #[link_name = "SystemFunction036"] pub fn RtlGenRandom(RandomBuffer: *mut u8, RandomBufferLength: ULONG) -> BOOLEAN; + + pub fn GetProcessHeap() -> HANDLE; + pub fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID; + pub fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID; + pub fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL; } // Functions that aren't available on every version of Windows that we support, diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 31ef9fa2bedfd..f880bc8c050be 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -22,6 +22,7 @@ pub use self::rand::hashmap_random_keys; #[macro_use] pub mod compat; +pub mod alloc; pub mod args; #[cfg(feature = "backtrace")] pub mod backtrace; diff --git a/src/libstd/sys_common/alloc.rs b/src/libstd/sys_common/alloc.rs new file mode 100644 index 0000000000000..439a9dfb3fdb5 --- /dev/null +++ b/src/libstd/sys_common/alloc.rs @@ -0,0 +1,50 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +use alloc::{GlobalAlloc, Layout, System}; +use cmp; +use ptr; + +// The minimum alignment guaranteed by the architecture. This value is used to +// add fast paths for low alignment values. +#[cfg(all(any(target_arch = "x86", + target_arch = "arm", + target_arch = "mips", + target_arch = "powerpc", + target_arch = "powerpc64", + target_arch = "asmjs", + target_arch = "wasm32")))] +pub const MIN_ALIGN: usize = 8; +#[cfg(all(any(target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64")))] +pub const MIN_ALIGN: usize = 16; + +pub unsafe fn realloc_fallback( + alloc: &System, + ptr: *mut u8, + old_layout: Layout, + new_size: usize, +) -> *mut u8 { + // Docs for GlobalAlloc::realloc require this to be valid: + let new_layout = Layout::from_size_align_unchecked(new_size, old_layout.align()); + + let new_ptr = GlobalAlloc::alloc(alloc, new_layout); + if !new_ptr.is_null() { + let size = cmp::min(old_layout.size(), new_size); + ptr::copy_nonoverlapping(ptr, new_ptr, size); + GlobalAlloc::dealloc(alloc, ptr, old_layout); + } + new_ptr +} diff --git a/src/libstd/sys_common/mod.rs b/src/libstd/sys_common/mod.rs index d0c4d6a773746..4b8cde3d1f486 100644 --- a/src/libstd/sys_common/mod.rs +++ b/src/libstd/sys_common/mod.rs @@ -38,6 +38,7 @@ macro_rules! rtassert { }) } +pub mod alloc; pub mod at_exit_imp; #[cfg(feature = "backtrace")] pub mod backtrace; diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index e8f197ba78afe..12e9a54da5281 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -27,7 +27,6 @@ //! //! - core may not have platform-specific code //! - libcompiler_builtins may have platform-specific code -//! - liballoc_system may have platform-specific code //! - libpanic_abort may have platform-specific code //! - libpanic_unwind may have platform-specific code //! - libunwind may have platform-specific code @@ -51,7 +50,6 @@ use std::iter::Iterator; // Paths that may contain platform-specific code const EXCEPTION_PATHS: &[&str] = &[ // std crates - "src/liballoc_system", "src/libcompiler_builtins", "src/liblibc", "src/libpanic_abort",