Skip to content

Commit

Permalink
32 bit count in reference counting (#1050)
Browse files Browse the repository at this point in the history
* Add sync bit

* Change count type

* Revert "Add sync bit"

This reverts commit 8342715.

* Fix record type

* Fix counter pointer

* Rename count type

* Refactor

* Fix build

* Fix header

* Update snapshots

* Fix FFI

* Bump version

* Update lock file

* Update Cargo.lock

* Fix versions

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
raviqqe and mergify[bot] authored Jun 2, 2022
1 parent 9533d76 commit ea892d5
Show file tree
Hide file tree
Showing 25 changed files with 117 additions and 89 deletions.
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions cmd/test/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cmd/test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ publish = false
edition = "2021"

[dependencies]
ffi = { package = "pen-ffi", version = "0.3" }
ffi = { package = "pen-ffi", version = "0.4" }
2 changes: 1 addition & 1 deletion lib/ffi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "pen-ffi"
description = "FFI library for Pen programming language"
version = "0.3.70"
version = "0.4.0"
publish = true
edition = "2021"
license = "MIT"
Expand Down
27 changes: 19 additions & 8 deletions lib/ffi/src/arc/arc_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,28 @@ use alloc::alloc::{alloc, dealloc};
use core::{
alloc::Layout,
ptr::{drop_in_place, null},
sync::atomic::{fence, AtomicUsize, Ordering},
sync::atomic::{fence, AtomicU32, Ordering},
};

const INITIAL_COUNT: usize = 0;
const INITIAL_COUNT: u32 = 0;
const EMPTY_TAG: u32 = 0;

#[derive(Debug)]
#[repr(C)]
pub struct ArcBlock {
pointer: *const u8,
}

#[derive(Debug)]
#[repr(C)]
struct ArcHeader {
count: AtomicU32,
tag: u32,
}

#[repr(C)]
struct ArcInner {
count: AtomicUsize,
header: ArcHeader,
payload: (),
}

Expand All @@ -26,7 +34,10 @@ impl ArcBlock {
} else {
let pointer = unsafe { &mut *(alloc(Self::inner_layout(layout)) as *mut ArcInner) };

pointer.count = AtomicUsize::new(INITIAL_COUNT);
pointer.header = ArcHeader {
count: AtomicU32::new(INITIAL_COUNT),
tag: EMPTY_TAG,
};

Self {
pointer: &pointer.payload as *const () as *const u8,
Expand All @@ -43,7 +54,7 @@ impl ArcBlock {
}

pub fn get_mut(&mut self) -> Option<*mut u8> {
if !self.is_static() && self.inner().count.load(Ordering::Acquire) == INITIAL_COUNT {
if !self.is_static() && self.inner().header.count.load(Ordering::Acquire) == INITIAL_COUNT {
Some(self.ptr_mut())
} else {
None
Expand All @@ -69,7 +80,7 @@ impl ArcBlock {
}

fn inner_layout(layout: Layout) -> Layout {
Layout::new::<AtomicUsize>()
Layout::new::<ArcHeader>()
.extend(layout)
.unwrap()
.0
Expand All @@ -78,7 +89,7 @@ impl ArcBlock {

pub fn clone(&self) -> Self {
if !self.is_static() {
self.inner().count.fetch_add(1, Ordering::Relaxed);
self.inner().header.count.fetch_add(1, Ordering::Relaxed);
}

Self {
Expand All @@ -91,7 +102,7 @@ impl ArcBlock {
return;
}

if self.inner().count.fetch_sub(1, Ordering::Release) == INITIAL_COUNT {
if self.inner().header.count.fetch_sub(1, Ordering::Release) == INITIAL_COUNT {
fence(Ordering::Acquire);

unsafe {
Expand Down
1 change: 1 addition & 0 deletions lib/mir-fmm/src/reference_count.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod count;
mod expression;
pub mod function;
pub mod heap;
Expand Down
13 changes: 13 additions & 0 deletions lib/mir-fmm/src/reference_count/count.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const INITIAL_COUNT: isize = 0;

pub const fn compile(count: isize) -> fmm::ir::Primitive {
fmm::ir::Primitive::Integer32(count as u32)
}

pub const fn compile_initial() -> fmm::ir::Primitive {
compile(INITIAL_COUNT)
}

pub const fn compile_type() -> fmm::types::Primitive {
fmm::types::Primitive::Integer32
}
37 changes: 27 additions & 10 deletions lib/mir-fmm/src/reference_count/heap.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use super::super::error::CompileError;
use super::{super::error::CompileError, count};
use once_cell::sync::Lazy;

pub(super) const COUNT_TYPE: fmm::types::Primitive = fmm::types::Primitive::PointerInteger;
pub(super) const INITIAL_COUNT: usize = 0;
const TAG_TYPE: fmm::types::Primitive = fmm::types::Primitive::Integer32;
const EMPTY_TAG: fmm::ir::Primitive = fmm::ir::Primitive::Integer32(0);

static HEADER_TYPE: Lazy<fmm::types::Record> =
Lazy::new(|| fmm::types::Record::new(vec![count::compile_type().into(), TAG_TYPE.into()]));

pub fn allocate(
builder: &fmm::build::InstructionBuilder,
Expand All @@ -10,17 +14,17 @@ pub fn allocate(
let type_ = type_.into();
let pointer = fmm::build::bit_cast(
fmm::types::Pointer::new(fmm::types::Record::new(vec![
COUNT_TYPE.into(),
HEADER_TYPE.clone().into(),
type_.clone(),
])),
builder.allocate_heap(fmm::build::size_of(fmm::types::Record::new(vec![
COUNT_TYPE.into(),
HEADER_TYPE.clone().into(),
type_,
]))),
);

builder.store(
fmm::ir::Primitive::PointerInteger(INITIAL_COUNT as i64),
fmm::build::record(vec![count::compile_initial().into(), EMPTY_TAG.into()]),
fmm::build::record_address(pointer.clone(), 0)?,
);

Expand All @@ -34,13 +38,26 @@ pub fn free(
builder.free_heap(fmm::build::bit_cast(
fmm::types::GENERIC_POINTER_TYPE.clone(),
fmm::build::pointer_address(
fmm::build::bit_cast(
fmm::types::Pointer::new(fmm::types::Primitive::PointerInteger),
pointer,
),
fmm::build::bit_cast(fmm::types::Pointer::new(HEADER_TYPE.clone()), pointer),
fmm::ir::Primitive::PointerInteger(-1),
)?,
));

Ok(())
}

pub fn get_counter_pointer(
heap_pointer: &fmm::build::TypedExpression,
) -> Result<fmm::build::TypedExpression, fmm::build::BuildError> {
Ok(fmm::build::record_address(
fmm::build::pointer_address(
fmm::build::bit_cast(
fmm::types::Pointer::new(HEADER_TYPE.clone()),
heap_pointer.clone(),
),
fmm::ir::Primitive::PointerInteger(-1),
)?,
0,
)?
.into())
}
30 changes: 8 additions & 22 deletions lib/mir-fmm/src/reference_count/pointer.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{super::error::CompileError, heap};
use super::{super::error::CompileError, count, heap};

pub fn clone(
builder: &fmm::build::InstructionBuilder,
Expand Down Expand Up @@ -88,12 +88,11 @@ pub fn is_owned(
|builder| {
Ok(builder.branch(fmm::build::comparison_operation(
fmm::ir::ComparisonOperator::Equal,
// TODO Does this actually need to be atomic?
builder.atomic_load(
get_counter_pointer(pointer)?,
heap::get_counter_pointer(pointer)?,
fmm::ir::AtomicOrdering::Relaxed,
)?,
fmm::ir::Primitive::PointerInteger(heap::INITIAL_COUNT as i64),
count::compile_initial(),
)?))
},
|builder| Ok(builder.branch(fmm::ir::Primitive::Boolean(false))),
Expand All @@ -107,8 +106,8 @@ fn increment_count(
) -> Result<(), CompileError> {
builder.atomic_operation(
fmm::ir::AtomicOperator::Add,
get_counter_pointer(pointer)?,
fmm::ir::Primitive::PointerInteger(1),
heap::get_counter_pointer(pointer)?,
count::compile(1),
ordering,
)?;

Expand All @@ -123,11 +122,11 @@ fn decrement_and_compare_count(
fmm::ir::ComparisonOperator::Equal,
builder.atomic_operation(
fmm::ir::AtomicOperator::Subtract,
get_counter_pointer(pointer)?,
fmm::ir::Primitive::PointerInteger(1),
heap::get_counter_pointer(pointer)?,
count::compile(1),
fmm::ir::AtomicOrdering::Release,
)?,
fmm::ir::Primitive::PointerInteger(heap::INITIAL_COUNT as i64),
count::compile_initial(),
)?
.into())
}
Expand Down Expand Up @@ -194,16 +193,3 @@ fn is_heap_pointer(
)?
.into())
}

fn get_counter_pointer(
heap_pointer: &fmm::build::TypedExpression,
) -> Result<fmm::build::TypedExpression, fmm::build::BuildError> {
Ok(fmm::build::pointer_address(
fmm::build::bit_cast(
fmm::types::Pointer::new(heap::COUNT_TYPE),
heap_pointer.clone(),
),
fmm::ir::Primitive::PointerInteger(-1),
)?
.into())
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ expression: "fmm::analysis::format_module(&context.module_builder().as_module())
(function _fmm_0 _closure
(block
(allocate-heap (size-of record) _fmm_1)
(store 0 (record-address (bit-cast _fmm_1) 0))
(store (record 0 0) (record-address (bit-cast _fmm_1) 0))
(store (record _fmm_2 _fmm_5 (record)) (record-address (bit-cast _fmm_1) 1))
(atomic-load (record-address (bit-cast (bit& (bit-cast (bit-cast (record-address (bit-cast _fmm_1) 1))) (bit! 1))) 0) _fmm_7)
(call _fmm_7 (bit-cast (bit-cast (record-address (bit-cast _fmm_1) 1))) _fmm_8)
Expand Down
4 changes: 2 additions & 2 deletions packages/core/ffi/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/core/ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ edition = "2021"
crate-type = ["staticlib"]

[dependencies]
ffi = { package = "pen-ffi", version = "0.3" }
ffi = { package = "pen-ffi", version = "0.4" }
siphasher = "0.3"
16 changes: 8 additions & 8 deletions packages/http/ffi/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/http/ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ edition = "2021"
crate-type = ["staticlib"]

[dependencies]
ffi = { package = "pen-ffi", version = "0.3", features = ["runtime"] }
ffi = { package = "pen-ffi", version = "0.4", features = ["runtime"] }
futures = "0.3"
hyper = { version = "0.14", features = [
"client",
Expand Down
4 changes: 2 additions & 2 deletions packages/json/ffi/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/json/ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ edition = "2021"
crate-type = ["staticlib"]

[dependencies]
ffi = { package = "pen-ffi", version = "0.3" }
ffi = { package = "pen-ffi", version = "0.4" }
Loading

0 comments on commit ea892d5

Please sign in to comment.