mirror of
https://github.com/urbit/ares.git
synced 2024-12-24 13:55:23 +03:00
hamt: preserve traversal_stack uses rust stack
this was using the lightweight stack, but this presented the following issue: NockStack::copy() can be called during the Hamt::preserve() call, and the lightweight stack may not be empty. NockStack::copy() presumes that the lightweight stack is empty when it is called, and thus tried to pop elements that preserve() had pushed onto it. NockStack::copy() should probably assert that the lightweight stack is empty when its called
This commit is contained in:
parent
21a13ee444
commit
2bfe5a06c6
@ -437,17 +437,26 @@ impl<T: Copy + Preserve> Preserve for Hamt<T> {
|
||||
let dest_buffer = stack.struct_alloc_in_previous_frame(self.0.size());
|
||||
copy_nonoverlapping(self.0.buffer, dest_buffer, self.0.size());
|
||||
self.0.buffer = dest_buffer;
|
||||
*(stack.push::<(Stem<T>, u32)>()) = (self.0, 0);
|
||||
// Here we're using the Rust stack since the array is a fixed
|
||||
// size. Thus it will be cleaned up if the Rust thread running
|
||||
// this is killed, and is therefore not an issue vs. if it were allocated
|
||||
// on the heap.
|
||||
//
|
||||
// In the past, this traversal stack was allocated in NockStack, but
|
||||
// exactly the right way to do this is less clear with the split stack.
|
||||
let mut traversal_stack: [Option<(Stem<T>, u32)>; 6] = [None; 6];
|
||||
traversal_stack[0] = Some((self.0, 0));
|
||||
let mut traversal_depth = 1;
|
||||
'preserve: loop {
|
||||
if traversal_depth == 0 {
|
||||
break;
|
||||
}
|
||||
let (stem, mut position) = *(stack.top::<(Stem<T>, u32)>());
|
||||
let Some((stem, mut position)) = traversal_stack[traversal_depth - 1] else {
|
||||
panic!("Attempted to access uninitialized array element");
|
||||
};
|
||||
// can we loop over the size and count leading 0s remaining in the bitmap?
|
||||
'preserve_stem: loop {
|
||||
if position >= 32 {
|
||||
stack.pop::<(Stem<T>, u32)>();
|
||||
traversal_depth -= 1;
|
||||
continue 'preserve;
|
||||
}
|
||||
@ -472,8 +481,8 @@ impl<T: Copy + Preserve> Preserve for Hamt<T> {
|
||||
};
|
||||
*(stem.buffer.add(idx) as *mut Entry<T>) = Entry { stem: new_stem };
|
||||
assert!(traversal_depth <= 5); // will increment
|
||||
(*(stack.top::<(Stem<T>, u32)>())).1 = position + 1;
|
||||
*(stack.push::<(Stem<T>, u32)>()) = (new_stem, 0);
|
||||
traversal_stack[traversal_depth - 1].unwrap().1 = position + 1;
|
||||
traversal_stack[traversal_depth] = Some((new_stem, 0));
|
||||
traversal_depth += 1;
|
||||
continue 'preserve;
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user