Partially implement reallocation (e.g. for growing Vecs).
This commit is contained in:
parent
8d3d8af67a
commit
f472018fbb
3 changed files with 48 additions and 4 deletions
|
@ -530,6 +530,17 @@ impl<'a, 'tcx: 'a, 'arena> Interpreter<'a, 'tcx, 'arena> {
|
||||||
try!(self.memory.write_ptr(dest, ptr));
|
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),
|
_ => panic!("can't call C ABI function: {}", link_name),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ pub struct AllocId(u64);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Allocation {
|
pub struct Allocation {
|
||||||
pub bytes: Box<[u8]>,
|
pub bytes: Vec<u8>,
|
||||||
pub relocations: BTreeMap<usize, AllocId>,
|
pub relocations: BTreeMap<usize, AllocId>,
|
||||||
pub undef_mask: UndefMask,
|
pub undef_mask: UndefMask,
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ impl Memory {
|
||||||
pub fn allocate(&mut self, size: usize) -> Pointer {
|
pub fn allocate(&mut self, size: usize) -> Pointer {
|
||||||
let id = AllocId(self.next_id);
|
let id = AllocId(self.next_id);
|
||||||
let alloc = Allocation {
|
let alloc = Allocation {
|
||||||
bytes: vec![0; size].into_boxed_slice(),
|
bytes: vec![0; size],
|
||||||
relocations: BTreeMap::new(),
|
relocations: BTreeMap::new(),
|
||||||
undef_mask: UndefMask::new(size),
|
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
|
// Allocation accessors
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
13
test/vecs.rs
13
test/vecs.rs
|
@ -2,7 +2,7 @@
|
||||||
#![allow(dead_code, unused_attributes)]
|
#![allow(dead_code, unused_attributes)]
|
||||||
|
|
||||||
#[miri_run]
|
#[miri_run]
|
||||||
fn make_vec() -> Vec<i32> {
|
fn make_vec() -> Vec<u8> {
|
||||||
let mut v = Vec::with_capacity(4);
|
let mut v = Vec::with_capacity(4);
|
||||||
v.push(1);
|
v.push(1);
|
||||||
v.push(2);
|
v.push(2);
|
||||||
|
@ -10,7 +10,7 @@ fn make_vec() -> Vec<i32> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[miri_run]
|
#[miri_run]
|
||||||
fn make_vec_macro() -> Vec<i32> {
|
fn make_vec_macro() -> Vec<u8> {
|
||||||
vec![1, 2]
|
vec![1, 2]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,3 +23,12 @@ fn make_vec_macro_repeat() -> Vec<u8> {
|
||||||
fn vec_into_iter() -> i32 {
|
fn vec_into_iter() -> i32 {
|
||||||
vec![1, 2, 3, 4].into_iter().fold(0, |x, y| x + y)
|
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
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue