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

WIP: Rename functions related to object pinning. #920

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 0 additions & 41 deletions src/memory_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -780,47 +780,6 @@ pub fn add_finalizer<VM: VMBinding>(
mmtk.finalizable_processor.lock().unwrap().add(object);
}

/// Pin an object. MMTk will make sure that the object does not move
/// during GC. Note that action cannot happen in some plans, eg, semispace.
/// It returns true if the pinning operation has been performed, i.e.,
/// the object status changed from non-pinned to pinned
///
/// Arguments:
/// * `object`: The object to be pinned
#[cfg(feature = "object_pinning")]
pub fn pin_object<VM: VMBinding>(object: ObjectReference) -> bool {
use crate::mmtk::SFT_MAP;
SFT_MAP
.get_checked(object.to_address::<VM>())
.pin_object(object)
}

/// Unpin an object.
/// Returns true if the unpinning operation has been performed, i.e.,
/// the object status changed from pinned to non-pinned
///
/// Arguments:
/// * `object`: The object to be pinned
#[cfg(feature = "object_pinning")]
pub fn unpin_object<VM: VMBinding>(object: ObjectReference) -> bool {
use crate::mmtk::SFT_MAP;
SFT_MAP
.get_checked(object.to_address::<VM>())
.unpin_object(object)
}

/// Check whether an object is currently pinned
///
/// Arguments:
/// * `object`: The object to be checked
#[cfg(feature = "object_pinning")]
pub fn is_pinned<VM: VMBinding>(object: ObjectReference) -> bool {
use crate::mmtk::SFT_MAP;
SFT_MAP
.get_checked(object.to_address::<VM>())
.is_object_pinned(object)
}

/// Get an object that is ready for finalization. After each GC, if any registered object is not
/// alive, this call will return one of the objects. MMTk will retain the liveness of those objects
/// until they are popped through this call. Once an object is popped, it is the responsibility of
Expand Down
6 changes: 3 additions & 3 deletions src/policy/copyspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,17 @@ impl<VM: VMBinding> SFT for CopySpace<VM> {
}

#[cfg(feature = "object_pinning")]
fn pin_object(&self, _object: ObjectReference) -> bool {
fn set_pinned(&self, _object: ObjectReference) -> bool {
panic!("Cannot pin/unpin objects of CopySpace.")
}

#[cfg(feature = "object_pinning")]
fn unpin_object(&self, _object: ObjectReference) -> bool {
fn unset_pinned(&self, _object: ObjectReference) -> bool {
panic!("Cannot pin/unpin objects of CopySpace.")
}

#[cfg(feature = "object_pinning")]
fn is_object_pinned(&self, _object: ObjectReference) -> bool {
fn debug_get_pinned(&self, _object: ObjectReference) -> bool {
false
}

Expand Down
8 changes: 4 additions & 4 deletions src/policy/immix/immixspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,15 @@ impl<VM: VMBinding> SFT for ImmixSpace<VM> {
ForwardingWord::is_forwarded::<VM>(object)
}
#[cfg(feature = "object_pinning")]
fn pin_object(&self, object: ObjectReference) -> bool {
fn set_pinned(&self, object: ObjectReference) -> bool {
VM::VMObjectModel::LOCAL_PINNING_BIT_SPEC.pin_object::<VM>(object)
}
#[cfg(feature = "object_pinning")]
fn unpin_object(&self, object: ObjectReference) -> bool {
fn unset_pinned(&self, object: ObjectReference) -> bool {
VM::VMObjectModel::LOCAL_PINNING_BIT_SPEC.unpin_object::<VM>(object)
}
#[cfg(feature = "object_pinning")]
fn is_object_pinned(&self, object: ObjectReference) -> bool {
fn debug_get_pinned(&self, object: ObjectReference) -> bool {
VM::VMObjectModel::LOCAL_PINNING_BIT_SPEC.is_object_pinned::<VM>(object)
}
fn is_movable(&self) -> bool {
Expand Down Expand Up @@ -741,7 +741,7 @@ impl<VM: VMBinding> ImmixSpace<VM> {
/// Check if an object is pinned.
fn is_pinned(&self, _object: ObjectReference) -> bool {
#[cfg(feature = "object_pinning")]
return self.is_object_pinned(_object);
return self.debug_get_pinned(_object);

#[cfg(not(feature = "object_pinning"))]
false
Expand Down
6 changes: 3 additions & 3 deletions src/policy/immortalspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ impl<VM: VMBinding> SFT for ImmortalSpace<VM> {
self.mark_state.is_marked::<VM>(object)
}
#[cfg(feature = "object_pinning")]
fn pin_object(&self, _object: ObjectReference) -> bool {
fn set_pinned(&self, _object: ObjectReference) -> bool {
false
}
#[cfg(feature = "object_pinning")]
fn unpin_object(&self, _object: ObjectReference) -> bool {
fn unset_pinned(&self, _object: ObjectReference) -> bool {
false
}
#[cfg(feature = "object_pinning")]
fn is_object_pinned(&self, _object: ObjectReference) -> bool {
fn debug_get_pinned(&self, _object: ObjectReference) -> bool {
true
}
fn is_movable(&self) -> bool {
Expand Down
6 changes: 3 additions & 3 deletions src/policy/largeobjectspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ impl<VM: VMBinding> SFT for LargeObjectSpace<VM> {
self.test_mark_bit(object, self.mark_state)
}
#[cfg(feature = "object_pinning")]
fn pin_object(&self, _object: ObjectReference) -> bool {
fn set_pinned(&self, _object: ObjectReference) -> bool {
false
}
#[cfg(feature = "object_pinning")]
fn unpin_object(&self, _object: ObjectReference) -> bool {
fn unset_pinned(&self, _object: ObjectReference) -> bool {
false
}
#[cfg(feature = "object_pinning")]
fn is_object_pinned(&self, _object: ObjectReference) -> bool {
fn debug_get_pinned(&self, _object: ObjectReference) -> bool {
true
}
fn is_movable(&self) -> bool {
Expand Down
6 changes: 3 additions & 3 deletions src/policy/lockfreeimmortalspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ impl<VM: VMBinding> SFT for LockFreeImmortalSpace<VM> {
unimplemented!()
}
#[cfg(feature = "object_pinning")]
fn pin_object(&self, _object: ObjectReference) -> bool {
fn set_pinned(&self, _object: ObjectReference) -> bool {
false
}
#[cfg(feature = "object_pinning")]
fn unpin_object(&self, _object: ObjectReference) -> bool {
fn unset_pinned(&self, _object: ObjectReference) -> bool {
false
}
#[cfg(feature = "object_pinning")]
fn is_object_pinned(&self, _object: ObjectReference) -> bool {
fn debug_get_pinned(&self, _object: ObjectReference) -> bool {
true
}
fn is_movable(&self) -> bool {
Expand Down
6 changes: 3 additions & 3 deletions src/policy/markcompactspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,17 @@ impl<VM: VMBinding> SFT for MarkCompactSpace<VM> {
}

#[cfg(feature = "object_pinning")]
fn pin_object(&self, _object: ObjectReference) -> bool {
fn set_pinned(&self, _object: ObjectReference) -> bool {
panic!("Cannot pin/unpin objects of MarkCompactSpace.")
}

#[cfg(feature = "object_pinning")]
fn unpin_object(&self, _object: ObjectReference) -> bool {
fn unset_pinned(&self, _object: ObjectReference) -> bool {
panic!("Cannot pin/unpin objects of MarkCompactSpace.")
}

#[cfg(feature = "object_pinning")]
fn is_object_pinned(&self, _object: ObjectReference) -> bool {
fn debug_get_pinned(&self, _object: ObjectReference) -> bool {
false
}

Expand Down
6 changes: 3 additions & 3 deletions src/policy/marksweepspace/malloc_ms/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,17 @@ impl<VM: VMBinding> SFT for MallocSpace<VM> {
}

#[cfg(feature = "object_pinning")]
fn pin_object(&self, _object: ObjectReference) -> bool {
fn set_pinned(&self, _object: ObjectReference) -> bool {
false
}

#[cfg(feature = "object_pinning")]
fn unpin_object(&self, _object: ObjectReference) -> bool {
fn unset_pinned(&self, _object: ObjectReference) -> bool {
false
}

#[cfg(feature = "object_pinning")]
fn is_object_pinned(&self, _object: ObjectReference) -> bool {
fn debug_get_pinned(&self, _object: ObjectReference) -> bool {
false
}

Expand Down
6 changes: 3 additions & 3 deletions src/policy/marksweepspace/native_ms/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,17 @@ impl<VM: VMBinding> SFT for MarkSweepSpace<VM> {
}

#[cfg(feature = "object_pinning")]
fn pin_object(&self, _object: ObjectReference) -> bool {
fn set_pinned(&self, _object: ObjectReference) -> bool {
false
}

#[cfg(feature = "object_pinning")]
fn unpin_object(&self, _object: ObjectReference) -> bool {
fn unset_pinned(&self, _object: ObjectReference) -> bool {
false
}

#[cfg(feature = "object_pinning")]
fn is_object_pinned(&self, _object: ObjectReference) -> bool {
fn debug_get_pinned(&self, _object: ObjectReference) -> bool {
false
}

Expand Down
12 changes: 6 additions & 6 deletions src/policy/sft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ pub trait SFT {
// pinning/unpinning action has been performed by the function, and is_object_pinned will return whether the object
// is currently pinned.
#[cfg(feature = "object_pinning")]
fn pin_object(&self, object: ObjectReference) -> bool;
fn set_pinned(&self, object: ObjectReference) -> bool;
#[cfg(feature = "object_pinning")]
fn unpin_object(&self, object: ObjectReference) -> bool;
fn unset_pinned(&self, object: ObjectReference) -> bool;
#[cfg(feature = "object_pinning")]
fn is_object_pinned(&self, object: ObjectReference) -> bool;
fn debug_get_pinned(&self, object: ObjectReference) -> bool;

/// Is the object movable, determined by the policy? E.g. the policy is non-moving,
/// or the object is pinned.
Expand Down Expand Up @@ -128,15 +128,15 @@ impl SFT for EmptySpaceSFT {
false
}
#[cfg(feature = "object_pinning")]
fn pin_object(&self, _object: ObjectReference) -> bool {
fn set_pinned(&self, _object: ObjectReference) -> bool {
panic!("Cannot pin/unpin objects of EmptySpace.")
}
#[cfg(feature = "object_pinning")]
fn unpin_object(&self, _object: ObjectReference) -> bool {
fn unset_pinned(&self, _object: ObjectReference) -> bool {
panic!("Cannot pin/unpin objects of EmptySpace.")
}
#[cfg(feature = "object_pinning")]
fn is_object_pinned(&self, _object: ObjectReference) -> bool {
fn debug_get_pinned(&self, _object: ObjectReference) -> bool {
false
}
fn is_movable(&self) -> bool {
Expand Down
3 changes: 3 additions & 0 deletions src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ pub mod memory;
pub mod opaque_pointer;
/// MMTk command line options.
pub mod options;
/// Per-object pinning state.
#[cfg(feature = "object_pinning")]
pub mod pin_state;
/// Reference processing implementation.
pub mod reference_processor;

Expand Down
71 changes: 71 additions & 0 deletions src/util/pin_state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//! This module provides a per-object pinning state which VM bindings can use to prevent the object
//! from being moved by the GC, but does not prevent it from being reclaimed (i.e. does not keep
//! the object alive).
//!
//! # Pinning state
//!
//! This module is enabled by the Cargo feature "object_pinning". When enabled, each object will
//! have an associated pinning state which can be true or false. If the state is true, the garbage
//! collector will not move the object. But if the garbage collector decides that the object is
//! dead, it may still reclaim the object regardless of the pinning state.
//!
//! For spaces that never move objects, including `MarkSweepSpace` and `ImmortalSpace`, the pinning
//! state is always true; for spaces that does not support object pinning, such as `CopySpace`, the
//! pinning state is always false. For spaces that supports object pinning, such as `ImmixSpace`,
//! the pinning state can be set and unset using the `set_pinned` and `unset_pinned` functions
//! provided by this module.
//!
//! Under the hood, the pin state may be (but not necessarily) implemented by the local PIN_BIT
//! side metadata defined in [`util::metadata::pin_bit`].
//!
//! # Alternative object pinning mechanisms
//!
//! TODO: Update comment after https://github.com/mmtk/mmtk-core/pull/897 is merged
//!

use crate::{mmtk::SFT_MAP, util::address::ObjectReference, vm::VMBinding};

/// Pin an object. MMTk will make sure that the object does not move during GC. Note that action
/// cannot happen in some plans, eg, semispace.
///
/// Arguments:
/// * `object`: The object to be pinned
///
/// It returns true if the pinning operation has been performed, i.e., the object status changed
/// from non-pinned to pinned.
pub fn set_pinned<VM: VMBinding>(object: ObjectReference) -> bool {
SFT_MAP
.get_checked(object.to_address::<VM>())
.set_pinned(object)
}

/// Unpin an object.
///
/// Arguments:
/// * `object`: The object to be pinned
///
/// Returns true if the unpinning operation has been performed, i.e., the object status changed
/// from pinned to non-pinned.
pub fn unset_pinned<VM: VMBinding>(object: ObjectReference) -> bool {
SFT_MAP
.get_checked(object.to_address::<VM>())
.unset_pinned(object)
}

/// Get the pinning state of an object. Used only for debug purpose.
///
/// **WARNING: Users should not use this function to decide whether it needs to pin or unpin an
/// object.** In a multi-threaded environment, one thread may change the pinning state during the
/// gap between when another thread reads the pinning state and when that thread takes action
/// accordingly. This is known as the "time-of-check to time-of-use" (TOC-TOU) problem. The VM
/// binding should introduce its own synchronisation mechanism when using this module.
///
/// Arguments:
/// * `object`: The object to be checked
///
/// Return true if the objet is pinned.
pub fn debug_get_pinned<VM: VMBinding>(object: ObjectReference) -> bool {
SFT_MAP
.get_checked(object.to_address::<VM>())
.debug_get_pinned(object)
}
Loading