Partially implement reallocation (e.g. for growing Vecs).

This commit is contained in:
Scott Olson 2016-04-06 17:29:56 -06:00
parent 8d3d8af67a
commit f472018fbb
3 changed files with 48 additions and 4 deletions

View File

@ -530,6 +530,17 @@ impl<'a, 'tcx: 'a, 'arena> Interpreter<'a, 'tcx, 'arena> {
try!(self.memory.write_ptr(dest, ptr));
}
"__rust_reallocate" => {
let ptr_arg = try!(self.eval_operand(&args[0]));
let _old_size_arg = try!(self.eval_operand(&args[1]));
let size_arg = try!(self.eval_operand(&args[2]));
let _align_arg = try!(self.eval_operand(&args[3]));
let ptr = try!(self.memory.read_ptr(ptr_arg));
let size = try!(self.memory.read_usize(size_arg));
try!(self.memory.reallocate(ptr, size as usize));
try!(self.memory.write_ptr(dest, ptr));
}
_ => panic!("can't call C ABI function: {}", link_name),
}

View File

@ -63,7 +63,7 @@ pub struct AllocId(u64);
#[derive(Debug)]
pub struct Allocation {
pub bytes: Box<[u8]>,
pub bytes: Vec<u8>,
pub relocations: BTreeMap<usize, AllocId>,
pub undef_mask: UndefMask,
}
@ -104,7 +104,7 @@ impl Memory {
pub fn allocate(&mut self, size: usize) -> Pointer {
let id = AllocId(self.next_id);
let alloc = Allocation {
bytes: vec![0; size].into_boxed_slice(),
bytes: vec![0; size],
relocations: BTreeMap::new(),
undef_mask: UndefMask::new(size),
};
@ -116,6 +116,30 @@ impl Memory {
}
}
// TODO(tsion): Track which allocations were returned from __rust_allocate and report an error
// when reallocating/deallocating any others.
pub fn reallocate(&mut self, ptr: Pointer, new_size: usize) -> EvalResult<()> {
if ptr.offset != 0 {
// TODO(tsion): Report error about non-__rust_allocate'd pointer.
panic!()
}
let alloc = try!(self.get_mut(ptr.alloc_id));
let size = alloc.bytes.len();
if new_size > size {
let amount = new_size - size;
alloc.bytes.extend(iter::repeat(0).take(amount));
alloc.undef_mask.grow(amount, false);
} else if size > new_size {
unimplemented!()
// alloc.bytes.truncate(new_size);
// alloc.undef_mask.len = new_size;
// TODO: potentially remove relocations
}
Ok(())
}
////////////////////////////////////////////////////////////////////////////////
// Allocation accessors
////////////////////////////////////////////////////////////////////////////////

View File

@ -2,7 +2,7 @@
#![allow(dead_code, unused_attributes)]
#[miri_run]
fn make_vec() -> Vec<i32> {
fn make_vec() -> Vec<u8> {
let mut v = Vec::with_capacity(4);
v.push(1);
v.push(2);
@ -10,7 +10,7 @@ fn make_vec() -> Vec<i32> {
}
#[miri_run]
fn make_vec_macro() -> Vec<i32> {
fn make_vec_macro() -> Vec<u8> {
vec![1, 2]
}
@ -23,3 +23,12 @@ fn make_vec_macro_repeat() -> Vec<u8> {
fn vec_into_iter() -> i32 {
vec![1, 2, 3, 4].into_iter().fold(0, |x, y| x + y)
}
#[miri_run]
fn vec_reallocate() -> Vec<u8> {
let mut v = vec![1, 2];
v.push(3);
v.push(4);
v.push(5);
v
}