Auto merge of #50880 - glandium:oom, r=SimonSapin

OOM handling changes

As discussed in https://github.com/rust-lang/rust/issues/49668#issuecomment-384893456 and subsequent.

This does have codegen implications. Even without the hooks, and with a handler that ignores the arguments, the compiler doesn't eliminate calling `rust_oom` with the `Layout`. Even if it managed to eliminate that, with the hooks, I don't know if the compiler would be able to figure out it can skip it if the hook is never set.

A couple implementation notes:
- I went with explicit enums rather than bools because it makes it clearer in callers what is being requested.
- I didn't know what `feature` to put the hook setting functions behind. (and surprisingly, the compile went through without any annotation on the functions)
- There's probably some bikeshedding to do on the naming.

Cc: @Simonsapin, @sfackler
This commit is contained in:
bors 2018-05-30 11:35:00 +00:00
commit 4f99f37b7e
10 changed files with 206 additions and 113 deletions

View file

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

View file

@ -50,7 +50,7 @@ unsafe fn test_triangle() -> bool {
println!("allocate({:?})", layout);
}
let ret = Global.alloc(layout.clone()).unwrap_or_else(|_| oom());
let ret = Global.alloc(layout).unwrap_or_else(|_| oom(layout));
if PRINT {
println!("allocate({:?}) = {:?}", layout, ret);
@ -72,8 +72,8 @@ unsafe fn test_triangle() -> bool {
println!("reallocate({:?}, old={:?}, new={:?})", ptr, old, new);
}
let ret = Global.realloc(NonNull::new_unchecked(ptr).as_opaque(), old.clone(), new.size())
.unwrap_or_else(|_| oom());
let ret = Global.realloc(NonNull::new_unchecked(ptr).as_opaque(), old, new.size())
.unwrap_or_else(|_| oom(Layout::from_size_align_unchecked(new.size(), old.align())));
if PRINT {
println!("reallocate({:?}, old={:?}, new={:?}) = {:?}",

View file

@ -32,8 +32,8 @@ struct Ccx {
fn alloc<'a>(_bcx : &'a arena) -> &'a Bcx<'a> {
unsafe {
let ptr = Global.alloc(Layout::new::<Bcx>())
.unwrap_or_else(|_| oom());
let layout = Layout::new::<Bcx>();
let ptr = Global.alloc(layout).unwrap_or_else(|_| oom(layout));
&*(ptr.as_ptr() as *const _)
}
}