Auto merge of #50144 - sfackler:oom-lang-item, r=alexcrichton

Replace {Alloc,GlobalAlloc}::oom with a lang item.

The decision of what to do after an allocation fails is orthogonal to the decision of how to allocate the memory, so this PR splits them apart. `Alloc::oom` and `GlobalAlloc::oom` have been removed, and a lang item has been added:

```rust
#[lang = "oom"]
fn oom() -> !;
```

It is specifically a weak lang item, like panic_fmt, except that it is required when you depend on liballoc rather than libcore. libstd provides an implementation that aborts with the message `fatal runtime error: memory allocation failed`, matching the current behavior.

The new implementation is also significantly simpler - it's "just another weak lang item". [RFC 2070](https://github.com/rust-lang/rfcs/blob/master/text/2070-panic-implementation.md) specifies a path towards stabilizing panic_fmt, so any complexities around stable weak lang item definition are already being solved.

To bootstrap, oom silently aborts in stage0. alloc_system no longer has a bunch of code to print to stderr, and alloc_jemalloc no longer depends on alloc_system to pull in that code.

One fun note: System's GlobalAlloc implementation didn't override the default implementation of oom, so it currently aborts silently!

r? @alexcrichton
This commit is contained in:
bors 2018-04-22 19:38:32 +00:00
commit e02868793b
23 changed files with 61 additions and 177 deletions

View file

@ -16,6 +16,5 @@ static A: usize = 0;
//~| the trait bound `usize:
//~| the trait bound `usize:
//~| the trait bound `usize:
//~| the trait bound `usize:
fn main() {}

View file

@ -10,13 +10,11 @@
#![feature(allocator_api, nonnull)]
use std::alloc::{Alloc, Global};
use std::alloc::{Alloc, Global, oom};
fn main() {
unsafe {
let ptr = Global.alloc_one::<i32>().unwrap_or_else(|_| {
Global.oom()
});
let ptr = Global.alloc_one::<i32>().unwrap_or_else(|_| oom());
*ptr.as_ptr() = 4;
assert_eq!(*ptr.as_ptr(), 4);
Global.dealloc_one(ptr);

View file

@ -15,7 +15,7 @@
#![feature(heap_api, allocator_api)]
use std::alloc::{Global, Alloc, Layout};
use std::alloc::{Global, Alloc, Layout, oom};
use std::ptr::{self, NonNull};
fn main() {
@ -50,7 +50,7 @@ unsafe fn test_triangle() -> bool {
println!("allocate({:?})", layout);
}
let ret = Global.alloc(layout.clone()).unwrap_or_else(|_| Global.oom());
let ret = Global.alloc(layout.clone()).unwrap_or_else(|_| oom());
if PRINT {
println!("allocate({:?}) = {:?}", layout, ret);
@ -73,7 +73,7 @@ unsafe fn test_triangle() -> bool {
}
let ret = Global.realloc(NonNull::new_unchecked(ptr).as_opaque(), old.clone(), new.size())
.unwrap_or_else(|_| Global.oom());
.unwrap_or_else(|_| oom());
if PRINT {
println!("reallocate({:?}, old={:?}, new={:?}) = {:?}",

View file

@ -12,7 +12,7 @@
#![feature(allocator_api)]
use std::alloc::{Alloc, Global, Layout};
use std::alloc::{Alloc, Global, Layout, oom};
use std::ptr::NonNull;
struct arena(());
@ -33,7 +33,7 @@ struct Ccx {
fn alloc<'a>(_bcx : &'a arena) -> &'a Bcx<'a> {
unsafe {
let ptr = Global.alloc(Layout::new::<Bcx>())
.unwrap_or_else(|_| Global.oom());
.unwrap_or_else(|_| oom());
&*(ptr.as_ptr() as *const _)
}
}