mirror of
https://github.com/urbit/ares.git
synced 2024-11-26 09:57:56 +03:00
Merge branch 'revert-177-revert-175-eamsden/gc-top-frame' into eamsden/integrate-pma-tmp-fix-gc
This commit is contained in:
commit
59180a704b
16
.github/scripts/arch/get-runner-arch
vendored
Executable file
16
.github/scripts/arch/get-runner-arch
vendored
Executable file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This could be improved by separately looking up OS and architecture
|
||||
# but it will do for now.
|
||||
for kv in "X64-Linux,x86_64-linux" "X64-macOS,x86_64-darwin" "ARM64-macOS,aarch64-darwin"; do
|
||||
KEY=${kv%,*};
|
||||
VAL=${kv#*,};
|
||||
|
||||
if [ "$KEY" = "${1}-${2}" ]
|
||||
then
|
||||
echo "nix-arch=${VAL}"
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
echo "Unknown Github runner arch-os pair: ${1}-${2}"
|
||||
exit 1
|
45
.github/workflows/ares-shared.yml
vendored
45
.github/workflows/ares-shared.yml
vendored
@ -15,12 +15,48 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
# Determine proper nix platform attribute for runner
|
||||
- name: Determine Nix platform
|
||||
id: set-nix-platform
|
||||
working-directory: .
|
||||
run:
|
||||
.github/scripts/arch/get-runner-arch ${{ runner.arch }} ${{ runner.os }} > $GITHUB_OUTPUT
|
||||
|
||||
# Install nix, required by nix-shell-action
|
||||
- uses: cachix/install-nix-action@v23
|
||||
name: Install Nix
|
||||
with:
|
||||
extra_nix_config: "extra-experimental-features = nix-command flakes"
|
||||
|
||||
- name: Set cache key for dev env
|
||||
id: set-cache-key
|
||||
run: |
|
||||
echo "Determining devshell path for platform ${{ steps.set-nix-platform.outputs.nix-arch }}"
|
||||
echo "nix-devshell-path=$(nix eval --raw ".#devShells.${{ steps.set-nix-platform.outputs.nix-arch }}.default.outPath")" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache nix build artifacts
|
||||
id: nix-cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
nix-devshell.nixstore
|
||||
key: nix-${{ steps.set-cache-key.outputs.nix-devshell-path }}
|
||||
|
||||
- name: Restore cached nix artifacts
|
||||
if: steps.nix-cache.outputs.cache-hit == 'true'
|
||||
working-directory: .
|
||||
run: |
|
||||
pwd
|
||||
ls
|
||||
nix-store --import < nix-devshell.nixstore
|
||||
|
||||
- name: Cache rust build artifacts
|
||||
id: cache_rust
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
key: rust-${{ steps.set-cache-key.outputs.nix-devshell-path }}
|
||||
workspaces: "rust/ares -> target"
|
||||
|
||||
# Check formatting
|
||||
- name: Format
|
||||
run: |
|
||||
@ -46,3 +82,12 @@ jobs:
|
||||
run: |
|
||||
nix develop --command bash -c "cargo test --verbose -- --test-threads=1"
|
||||
|
||||
- name: Build nix cache export
|
||||
if: steps.nix-cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
pwd
|
||||
nix eval --json ".#devShells.${{ steps.set-nix-platform.outputs.nix-arch }}.default.buildInputs" 2>/dev/null
|
||||
nix eval --json ".#devShells.${{ steps.set-nix-platform.outputs.nix-arch }}.default.buildInputs" 2>/dev/null | jq -r '.[]' | xargs nix-store --query --requisites
|
||||
nix-store --export $(nix eval --json ".#devShells.${{ steps.set-nix-platform.outputs.nix-arch }}.default.buildInputs" 2>/dev/null | jq -r '.[]' | xargs nix-store --query --requisites) > ../../nix-devshell.nixstore
|
||||
ls -lh
|
||||
|
||||
|
@ -338,6 +338,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);
|
||||
@ -362,6 +363,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());
|
||||
@ -375,7 +377,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);
|
||||
@ -397,6 +401,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);
|
||||
@ -415,15 +421,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 {
|
||||
|
@ -830,7 +830,7 @@ struct HotMem {
|
||||
impl Preserve for Hot {
|
||||
unsafe fn preserve(&mut self, stack: &mut NockStack) {
|
||||
let mut it = self;
|
||||
while !it.0.is_null() && !stack.is_in_frame(it.0) {
|
||||
while !it.0.is_null() && stack.is_in_frame(it.0) {
|
||||
let dest_mem = stack.struct_alloc_in_previous_frame(1);
|
||||
copy_nonoverlapping(it.0, dest_mem, 1);
|
||||
it.0 = dest_mem;
|
||||
|
@ -159,7 +159,17 @@ impl NockStack {
|
||||
let ptr_u64 = ptr as *const u64;
|
||||
let prev = *self.prev_stack_pointer_pointer();
|
||||
if self.is_west() {
|
||||
ptr_u64 >= self.alloc_pointer && ptr_u64 < prev
|
||||
// If we are in a top/west frame, the stack pointer will be null, so our allocation
|
||||
// arena was the alloc pointer to the top of the NockStack arena
|
||||
if prev.is_null() {
|
||||
ptr_u64 >= self.alloc_pointer && ptr_u64 < self.start.add(self.size)
|
||||
} else {
|
||||
ptr_u64 >= self.alloc_pointer && ptr_u64 < prev
|
||||
}
|
||||
// If we are in a top/east frame, the stack pointer will be null, so our allocation arena
|
||||
// was the alloc pointer to the bottom of the NockStack arena
|
||||
} else if prev.is_null() {
|
||||
ptr_u64 >= self.start && ptr_u64 < self.alloc_pointer
|
||||
} else {
|
||||
ptr_u64 >= prev && ptr_u64 < self.alloc_pointer
|
||||
}
|
||||
|
@ -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