Overhaul of the AllocRef trait to match allocator-wg's latest consens

This commit is contained in:
Tim Diekmann 2020-03-24 11:45:38 +01:00
parent 2fbb07525e
commit 56cbf2f22a
19 changed files with 1409 additions and 1546 deletions

View file

@ -7,7 +7,7 @@
extern crate helper;
use std::alloc::{self, Global, AllocRef, System, Layout};
use std::alloc::{self, AllocInit, AllocRef, Global, Layout, System};
use std::sync::atomic::{AtomicUsize, Ordering};
static HITS: AtomicUsize = AtomicUsize::new(0);
@ -37,7 +37,7 @@ fn main() {
unsafe {
let layout = Layout::from_size_align(4, 2).unwrap();
let (ptr, _) = Global.alloc(layout.clone()).unwrap();
let (ptr, _) = Global.alloc(layout.clone(), AllocInit::Uninitialized).unwrap();
helper::work_with(&ptr);
assert_eq!(HITS.load(Ordering::SeqCst), n + 1);
Global.dealloc(ptr, layout.clone());
@ -49,7 +49,7 @@ fn main() {
drop(s);
assert_eq!(HITS.load(Ordering::SeqCst), n + 4);
let (ptr, _) = System.alloc(layout.clone()).unwrap();
let (ptr, _) = System.alloc(layout.clone(), AllocInit::Uninitialized).unwrap();
assert_eq!(HITS.load(Ordering::SeqCst), n + 4);
helper::work_with(&ptr);
System.dealloc(ptr, layout);

View file

@ -9,8 +9,8 @@
extern crate custom;
extern crate helper;
use std::alloc::{Global, AllocRef, System, Layout};
use std::sync::atomic::{Ordering, AtomicUsize};
use std::alloc::{AllocInit, AllocRef, Global, Layout, System};
use std::sync::atomic::{AtomicUsize, Ordering};
#[global_allocator]
static GLOBAL: custom::A = custom::A(AtomicUsize::new(0));
@ -20,13 +20,13 @@ fn main() {
let n = GLOBAL.0.load(Ordering::SeqCst);
let layout = Layout::from_size_align(4, 2).unwrap();
let (ptr, _) = Global.alloc(layout.clone()).unwrap();
let (ptr, _) = Global.alloc(layout.clone(), AllocInit::Uninitialized).unwrap();
helper::work_with(&ptr);
assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 1);
Global.dealloc(ptr, layout.clone());
assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2);
let (ptr, _) = System.alloc(layout.clone()).unwrap();
let (ptr, _) = System.alloc(layout.clone(), AllocInit::Uninitialized).unwrap();
assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2);
helper::work_with(&ptr);
System.dealloc(ptr, layout);

View file

@ -6,7 +6,7 @@
#![feature(allocator_api)]
use std::alloc::{Global, AllocRef, Layout, handle_alloc_error};
use std::alloc::{handle_alloc_error, AllocInit, AllocRef, Global, Layout, ReallocPlacement};
use std::ptr::{self, NonNull};
fn main() {
@ -16,17 +16,17 @@ fn main() {
}
unsafe fn test_triangle() -> bool {
static COUNT : usize = 16;
static COUNT: usize = 16;
let mut ascend = vec![ptr::null_mut(); COUNT];
let ascend = &mut *ascend;
static ALIGN : usize = 1;
static ALIGN: usize = 1;
// Checks that `ascend` forms triangle of ascending size formed
// from pairs of rows (where each pair of rows is equally sized),
// and the elements of the triangle match their row-pair index.
unsafe fn sanity_check(ascend: &[*mut u8]) {
for i in 0..COUNT / 2 {
let (p0, p1, size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
let (p0, p1, size) = (ascend[2 * i], ascend[2 * i + 1], idx_to_size(i));
for j in 0..size {
assert_eq!(*p0.add(j), i as u8);
assert_eq!(*p1.add(j), i as u8);
@ -34,14 +34,16 @@ unsafe fn test_triangle() -> bool {
}
}
static PRINT : bool = false;
static PRINT: bool = false;
unsafe fn allocate(layout: Layout) -> *mut u8 {
if PRINT {
println!("allocate({:?})", layout);
}
let (ptr, _) = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout));
let (ptr, _) = Global
.alloc(layout, AllocInit::Uninitialized)
.unwrap_or_else(|_| handle_alloc_error(layout));
if PRINT {
println!("allocate({:?}) = {:?}", layout, ptr);
@ -63,19 +65,33 @@ unsafe fn test_triangle() -> bool {
println!("reallocate({:?}, old={:?}, new={:?})", ptr, old, new);
}
let (ptr, _) = Global.realloc(NonNull::new_unchecked(ptr), old, new.size())
.unwrap_or_else(|_| handle_alloc_error(
Layout::from_size_align_unchecked(new.size(), old.align())
));
let allocation = if new.size() > old.size() {
Global.grow(
NonNull::new_unchecked(ptr),
old,
new.size(),
ReallocPlacement::MayMove,
AllocInit::Uninitialized,
)
} else if new.size() < old.size() {
Global.shrink(NonNull::new_unchecked(ptr), old, new.size(), ReallocPlacement::MayMove)
} else {
return ptr;
};
let (ptr, _) = allocation.unwrap_or_else(|_| {
handle_alloc_error(Layout::from_size_align_unchecked(new.size(), old.align()))
});
if PRINT {
println!("reallocate({:?}, old={:?}, new={:?}) = {:?}",
ptr, old, new, ptr);
println!("reallocate({:?}, old={:?}, new={:?}) = {:?}", ptr, old, new, ptr);
}
ptr.cast().as_ptr()
}
fn idx_to_size(i: usize) -> usize { (i+1) * 10 }
fn idx_to_size(i: usize) -> usize {
(i + 1) * 10
}
// Allocate pairs of rows that form a triangle shape. (Hope is
// that at least two rows will be allocated near each other, so
@ -83,13 +99,13 @@ unsafe fn test_triangle() -> bool {
// way.)
for i in 0..COUNT / 2 {
let size = idx_to_size(i);
ascend[2*i] = allocate(Layout::from_size_align(size, ALIGN).unwrap());
ascend[2*i+1] = allocate(Layout::from_size_align(size, ALIGN).unwrap());
ascend[2 * i] = allocate(Layout::from_size_align(size, ALIGN).unwrap());
ascend[2 * i + 1] = allocate(Layout::from_size_align(size, ALIGN).unwrap());
}
// Initialize each pair of rows to distinct value.
for i in 0..COUNT / 2 {
let (p0, p1, size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
let (p0, p1, size) = (ascend[2 * i], ascend[2 * i + 1], idx_to_size(i));
for j in 0..size {
*p0.add(j) = i as u8;
*p1.add(j) = i as u8;
@ -104,8 +120,8 @@ unsafe fn test_triangle() -> bool {
for i in 0..COUNT / 2 {
let size = idx_to_size(i);
deallocate(ascend[2*i], Layout::from_size_align(size, ALIGN).unwrap());
deallocate(ascend[2*i+1], Layout::from_size_align(size, ALIGN).unwrap());
deallocate(ascend[2 * i], Layout::from_size_align(size, ALIGN).unwrap());
deallocate(ascend[2 * i + 1], Layout::from_size_align(size, ALIGN).unwrap());
}
return true;
@ -115,68 +131,68 @@ unsafe fn test_triangle() -> bool {
// realloc'ing each row from top to bottom, and checking all the
// rows as we go.
unsafe fn test_1(ascend: &mut [*mut u8]) {
let new_size = idx_to_size(COUNT-1);
let new_size = idx_to_size(COUNT - 1);
let new = Layout::from_size_align(new_size, ALIGN).unwrap();
for i in 0..COUNT / 2 {
let (p0, p1, old_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
let (p0, p1, old_size) = (ascend[2 * i], ascend[2 * i + 1], idx_to_size(i));
assert!(old_size < new_size);
let old = Layout::from_size_align(old_size, ALIGN).unwrap();
ascend[2*i] = reallocate(p0, old.clone(), new.clone());
ascend[2 * i] = reallocate(p0, old.clone(), new.clone());
sanity_check(&*ascend);
ascend[2*i+1] = reallocate(p1, old.clone(), new.clone());
ascend[2 * i + 1] = reallocate(p1, old.clone(), new.clone());
sanity_check(&*ascend);
}
}
// Test 2: turn the square back into a triangle, top to bottom.
unsafe fn test_2(ascend: &mut [*mut u8]) {
let old_size = idx_to_size(COUNT-1);
let old_size = idx_to_size(COUNT - 1);
let old = Layout::from_size_align(old_size, ALIGN).unwrap();
for i in 0..COUNT / 2 {
let (p0, p1, new_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
let (p0, p1, new_size) = (ascend[2 * i], ascend[2 * i + 1], idx_to_size(i));
assert!(new_size < old_size);
let new = Layout::from_size_align(new_size, ALIGN).unwrap();
ascend[2*i] = reallocate(p0, old.clone(), new.clone());
ascend[2 * i] = reallocate(p0, old.clone(), new.clone());
sanity_check(&*ascend);
ascend[2*i+1] = reallocate(p1, old.clone(), new.clone());
ascend[2 * i + 1] = reallocate(p1, old.clone(), new.clone());
sanity_check(&*ascend);
}
}
// Test 3: turn triangle into a square, bottom to top.
unsafe fn test_3(ascend: &mut [*mut u8]) {
let new_size = idx_to_size(COUNT-1);
let new_size = idx_to_size(COUNT - 1);
let new = Layout::from_size_align(new_size, ALIGN).unwrap();
for i in (0..COUNT / 2).rev() {
let (p0, p1, old_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
let (p0, p1, old_size) = (ascend[2 * i], ascend[2 * i + 1], idx_to_size(i));
assert!(old_size < new_size);
let old = Layout::from_size_align(old_size, ALIGN).unwrap();
ascend[2*i+1] = reallocate(p1, old.clone(), new.clone());
ascend[2 * i + 1] = reallocate(p1, old.clone(), new.clone());
sanity_check(&*ascend);
ascend[2*i] = reallocate(p0, old.clone(), new.clone());
ascend[2 * i] = reallocate(p0, old.clone(), new.clone());
sanity_check(&*ascend);
}
}
// Test 4: turn the square back into a triangle, bottom to top.
unsafe fn test_4(ascend: &mut [*mut u8]) {
let old_size = idx_to_size(COUNT-1);
let old_size = idx_to_size(COUNT - 1);
let old = Layout::from_size_align(old_size, ALIGN).unwrap();
for i in (0..COUNT / 2).rev() {
let (p0, p1, new_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
let (p0, p1, new_size) = (ascend[2 * i], ascend[2 * i + 1], idx_to_size(i));
assert!(new_size < old_size);
let new = Layout::from_size_align(new_size, ALIGN).unwrap();
ascend[2*i+1] = reallocate(p1, old.clone(), new.clone());
ascend[2 * i + 1] = reallocate(p1, old.clone(), new.clone());
sanity_check(&*ascend);
ascend[2*i] = reallocate(p0, old.clone(), new.clone());
ascend[2 * i] = reallocate(p0, old.clone(), new.clone());
sanity_check(&*ascend);
}
}

View file

@ -1,33 +1,33 @@
// run-pass
#![allow(dead_code)]
#![allow(non_camel_case_types)]
// pretty-expanded FIXME #23616
#![feature(allocator_api)]
use std::alloc::{AllocRef, Global, Layout, handle_alloc_error};
use std::alloc::{handle_alloc_error, AllocInit, AllocRef, Global, Layout};
use std::ptr::NonNull;
struct arena(());
struct Bcx<'a> {
fcx: &'a Fcx<'a>
fcx: &'a Fcx<'a>,
}
struct Fcx<'a> {
arena: &'a arena,
ccx: &'a Ccx
ccx: &'a Ccx,
}
struct Ccx {
x: isize
x: isize,
}
fn alloc(_bcx: &arena) -> &Bcx<'_> {
unsafe {
let layout = Layout::new::<Bcx>();
let (ptr, _) = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout));
let (ptr, _) = Global
.alloc(layout, AllocInit::Uninitialized)
.unwrap_or_else(|_| handle_alloc_error(layout));
&*(ptr.as_ptr() as *const _)
}
}