Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce ArcFlexMut for Space references #965

Draft
wants to merge 28 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
efe572d
Move global state from BasePlan to GlobalState
qinsoon Sep 7, 2023
8768970
Move more stuff out of BasePlan. Allocator no longer keeps a ref to
qinsoon Sep 8, 2023
2e2e9aa
Fix build and style
qinsoon Sep 8, 2023
c4b3160
Remove ActivePlan::global
qinsoon Sep 8, 2023
f14ad1a
Introduce notify_collection_required and refactor collection_required.
qinsoon Sep 12, 2023
a6fd28a
Fix docs
qinsoon Sep 12, 2023
d2c929d
Some cleanup
qinsoon Sep 12, 2023
5c13a6c
Merge branch 'master' into refactor-global-state
qinsoon Sep 12, 2023
280758a
Revert changes about collection_required
qinsoon Sep 19, 2023
6bf649e
Add SpaceRef
qinsoon Sep 26, 2023
9fd91b3
Use peace_lock
qinsoon Sep 27, 2023
63e8057
Implement SharedRef
qinsoon Sep 28, 2023
f968c07
Use SharedRef for spaces
qinsoon Sep 28, 2023
f209311
Refactor for all the plans. Rename SharedRef to ArcFlexMut
qinsoon Sep 29, 2023
48615af
Update docs
qinsoon Sep 29, 2023
92cb35c
Remove get_plan_mut and UnsafeCell for plan. prepare/release/end_of_gc
qinsoon Sep 29, 2023
0fc150c
Add comments for ArcFlexMut
qinsoon Sep 29, 2023
b95ff4b
Clean up deps
qinsoon Sep 29, 2023
9e5ef1c
Merge branch 'master' into space-ref
qinsoon Sep 29, 2023
dcdb87a
Fix style check in tests
qinsoon Sep 29, 2023
5e4c0a0
Disabling PrepareMutator from PlanConstraints (#964)
qinsoon Oct 3, 2023
edb8c50
Merge branch 'master' into space-ref
qinsoon Oct 3, 2023
edc393e
Fix doc code
qinsoon Oct 3, 2023
c15b1cb
Merge branch 'master' into space-ref
qinsoon Oct 25, 2023
1c254f4
Minor cleanup
qinsoon Oct 26, 2023
2c27b79
Add criterion bench for post_alloc
qinsoon Oct 26, 2023
f20e3c3
Remove tag in comments
qinsoon Oct 26, 2023
2e69a01
Get StatsForDefrag before use write on the space
qinsoon Oct 26, 2023
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add comments for ArcFlexMut
  • Loading branch information
qinsoon committed Sep 29, 2023
commit 0fc150ca1a331142eabdcc8ed0885b2bec660d8c
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ strum_macros = "0.24"
sysinfo = "0.29"

parking_lot = { version = "0.12", features = [] }
peace-lock = { git = "https://github.com/qinsoon/peace-lock.git", rev = "b91104c295ff60f815a931c670a69858dfdafbe5" }
peace-lock = "0.1.3"
# peace-lock = { path = "../peace-lock" }

[dev-dependencies]
Expand All @@ -76,8 +76,8 @@ perf_counter = ["pfm"]
# Do not modify the following line - ci-common.sh matches it
# -- Non mutually exclusive features --

# Turn on checks in peace-lock to check race conditions
peace_lock_race_check = ["peace-lock/check"]
# Turn on checks for the type ArcFlexMut (we use peace-lock for the type so just turn on check for peace-lock).
check_flex_mut = ["peace-lock/check"]

# spaces with different semantics

Expand Down Expand Up @@ -136,7 +136,7 @@ nogc_no_zeroing = ["nogc_lock_free"]
single_worker = []

# To run expensive comprehensive runtime checks, such as checking duplicate edges
extreme_assertions = []
extreme_assertions = ["check_flex_mut"]

# Enable multiple spaces for NoGC, each allocator maps to an individual ImmortalSpace.
nogc_multi_space = []
Expand Down
62 changes: 45 additions & 17 deletions src/util/rust_util/flex_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ macro_rules! to_trait_object {
}};
}

/// `ArcFlexMut` is a replacement for `UnsafeCell` for a shared reference in situations where 1.
/// their mutability is managed by the programmer, 2. mutability is hard to reason about statically,
/// 3. using locks or `RefCell`/`AtomicRefCell` is not plausible for the sake of performance, and
/// 4. the shared reference could be both statically typed and a dyn ref to a trait object, depending
/// on where it is used.
/// `ArcFlexMut` does not guarantee thread safety, and it does not provide any actual locking.
/// It provides methods for acquiring a read or write guard, and can optionally check if there is
/// any possible data race. Without the checks, in a release build, `ArcFlexMut` should perform
/// as efficient as `UnsafeCell`.
/// We currently use this type for [`crate::policy::space::Space`]s.
#[repr(transparent)]
pub struct ArcFlexMut<T>
where
T: ?Sized,
Expand All @@ -21,42 +32,54 @@ where
}

impl<T> ArcFlexMut<T> {
/// Create a shared reference to the object.
pub fn new(v: T) -> Self {
Self {
inner: Arc::new(peace_lock::RwLock::new(v)),
}
}
}

impl<T> ArcFlexMut<T> {
pub fn into_dyn_space<VM: VMBinding>(self) -> ArcFlexMut<dyn Space<VM>>
where
T: 'static + Space<VM>,
{
to_trait_object!(self, dyn Space<VM>)
}
}

impl<T: ?Sized> ArcFlexMut<T> {
/// Acquire a read guard to get immutable access to the data. It is allowed to have a reader when there is no writer.
/// If the feature `check_flex_mut` is enabled, the method will panic if the rule is violated.
pub fn read(&self) -> ArcFlexMutReadGuard<'_, T> {
ArcFlexMutReadGuard {
inner: self.inner.read(),
}
}

/// Acquire a write guard to get mutable access to the data. It is allowed to have a writer when there is no other writer or reader.
/// If the feature `check_flex_mut` is enabled, the method will panic if the rule is violated.
pub fn write(&self) -> ArcFlexMutWriteGuard<'_, T> {
ArcFlexMutWriteGuard {
inner: self.inner.write(),
}
}
}

impl<T> Clone for ArcFlexMut<T>
where
T: ?Sized,
{
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}

// For types that implements `Downcast`, we can turn the shared reference into a reference of a concrete type.

impl<T: 'static + Downcast + ?Sized> ArcFlexMut<T> {
/// Is it allowed to downcast to the given type?
fn can_downcast<S: 'static>(&self) -> bool {
let lock = self.inner.read();
(*lock).as_any().downcast_ref::<S>().is_some()
}

/// Downcast the shared reference into a shared reference of a concrete type. The new reference share
/// the count and the lock with the old consumed reference.
pub fn downcast<S: 'static>(self) -> ArcFlexMut<S> {
if self.can_downcast::<S>() {
let raw = Arc::into_raw(self.inner);
Expand All @@ -68,17 +91,21 @@ impl<T: 'static + Downcast + ?Sized> ArcFlexMut<T> {
}
}

impl<T> Clone for ArcFlexMut<T>
where
T: ?Sized,
{
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
// Methods to turn the shared reference into a shared reference of a trait object.
// The references points to the same object with the same count.
// This impl block is a workaround to implement the functionality specifically for
// `dyn Space`, as I can't find a way to implement this using generics.

impl<T> ArcFlexMut<T> {
pub fn into_dyn_space<VM: VMBinding>(self) -> ArcFlexMut<dyn Space<VM>>
where
T: 'static + Space<VM>,
{
to_trait_object!(self, dyn Space<VM>)
}
}

/// Read guard for ArcFlexMut
pub struct ArcFlexMutReadGuard<'a, T>
where
T: ?Sized,
Expand All @@ -98,6 +125,7 @@ where
}
}

/// Write guard for ArcFlexMut
pub struct ArcFlexMutWriteGuard<'a, T>
where
T: ?Sized,
Expand Down