mirror of
https://github.com/urbit/ares.git
synced 2024-11-23 00:25:49 +03:00
Merge remote-tracking branch 'origin/status' into revert-177-revert-175-eamsden/gc-top-frame
This commit is contained in:
commit
be4a6552e1
@ -317,6 +317,7 @@ impl<T: Copy + Preserve> Hamt<T> {
|
||||
let chunk = mug & 0x1F; // 5 bits
|
||||
mug >>= 5;
|
||||
match stem.entry(chunk) {
|
||||
// No entry found at mug chunk index; add Leaf to current Stem
|
||||
None => {
|
||||
let new_leaf_buffer = stack.struct_alloc(1);
|
||||
*new_leaf_buffer = (*n, t);
|
||||
@ -341,6 +342,7 @@ impl<T: Copy + Preserve> Hamt<T> {
|
||||
};
|
||||
break Hamt(stem_ret);
|
||||
}
|
||||
// Stem found at mug chunk index; insert into found Stem
|
||||
Some((Left(next_stem), idx)) => {
|
||||
let new_buffer = stack.struct_alloc(stem.size());
|
||||
copy_nonoverlapping(stem.buffer, new_buffer, stem.size());
|
||||
@ -354,7 +356,9 @@ impl<T: Copy + Preserve> Hamt<T> {
|
||||
depth += 1;
|
||||
continue;
|
||||
}
|
||||
// Leaf found at mug chunk index
|
||||
Some((Right(leaf), idx)) => {
|
||||
// Override existing value for key, if one exists
|
||||
for (ldx, pair) in leaf.to_mut_slice().iter_mut().enumerate() {
|
||||
if unifying_equality(stack, n, &mut pair.0) {
|
||||
let new_leaf_buffer = stack.struct_alloc(leaf.len);
|
||||
@ -376,6 +380,8 @@ impl<T: Copy + Preserve> Hamt<T> {
|
||||
break 'insert Hamt(stem_ret);
|
||||
}
|
||||
}
|
||||
// No existing pair in this Leaf matches the key, and we've maxxed out the
|
||||
// Hamt depth; add the the key-value pair to the list of pairs for this Leaf
|
||||
if depth >= 5 {
|
||||
let new_leaf_buffer = stack.struct_alloc(leaf.len + 1);
|
||||
copy_nonoverlapping(leaf.buffer, new_leaf_buffer, leaf.len);
|
||||
@ -394,15 +400,19 @@ impl<T: Copy + Preserve> Hamt<T> {
|
||||
buffer: new_buffer,
|
||||
};
|
||||
break 'insert Hamt(stem_ret);
|
||||
// No existing pair in this Leaf matches the key, but we haven't maxxed out
|
||||
// the Hamt depth yet. If we haven't hit the depth limit yet, we shouldn't
|
||||
// be making a linked list of pairs. Turn the Leaf into a Stem and insert
|
||||
// the new pair into the new Stem (also insert the pair in the existing
|
||||
// Leaf, too).
|
||||
} else {
|
||||
// if we haven't hit depth limit yet we shouldn't be chaining
|
||||
// we'll make a fake node pointing to the old leaf and "insert into" that
|
||||
// Make a fake node pointing to the old leaf and "insert into it" the
|
||||
// next time around
|
||||
assert!(leaf.len == 1);
|
||||
let fake_buffer = stack.struct_alloc(1);
|
||||
*fake_buffer = Entry { leaf };
|
||||
// get the mug chunk for the noun at *the next level* so
|
||||
// we can build a fake stem for it
|
||||
// Get the mug chunk for the Noun at the *next* level so that we can
|
||||
// build a fake stem for it
|
||||
let fake_mug = mug_u32(stack, (*leaf.buffer).0);
|
||||
let fake_chunk = (fake_mug >> ((depth + 1) * 5)) & 0x1F;
|
||||
let next_stem = Stem {
|
||||
|
@ -31,6 +31,24 @@ const CELL_TAG: u64 = u64::MAX & INDIRECT_MASK;
|
||||
/** Tag mask for a cell. */
|
||||
const CELL_MASK: u64 = !(u64::MAX >> 3);
|
||||
|
||||
/* A note on forwarding pointers:
|
||||
*
|
||||
* Forwarding pointers are only used temporarily during copies between NockStack frames and between
|
||||
* the NockStack and the PMA. Since unifying equality checks can create structural sharing between
|
||||
* Noun objects, forwarding pointers act as a signal that a Noun has already been copied to the
|
||||
* "to" space. The old Noun object in the "from" space is given a forwarding pointer so that any
|
||||
* future refernces to the same structure know that it has already been copied and that they should
|
||||
* retain the structural sharing relationship by referencing the new copy in the "to" copy space.
|
||||
*
|
||||
* The Nouns in the "from" space marked with forwarding pointers are dangling pointers after a copy
|
||||
* operation. No code outside of the copying code checks for forwarding pointers. This invariant
|
||||
* must be enforced in two ways:
|
||||
* 1. The current frame must be immediately popped after preserving data, when
|
||||
* copying from a junior NockStack frame to a senior NockStack frame.
|
||||
* 2. All persistent derived state (e.g. Hot state, Warm state) must be preserved
|
||||
* and the root NockStack frame flipped after saving data to the PMA.
|
||||
*/
|
||||
|
||||
/** Tag for a forwarding pointer */
|
||||
const FORWARDING_TAG: u64 = u64::MAX & CELL_MASK;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user