fix hashstate
This commit is contained in:
parent
6e294ecaf9
commit
cd0e1344e4
8 changed files with 132 additions and 43 deletions
|
@ -32,7 +32,7 @@ uncooperative = ["cooperative", "mmtk/immix_non_moving", "mmtk/immix_zero_on_rel
|
||||||
# VMKit is built for use in cooperative runtime. Such runtime
|
# VMKit is built for use in cooperative runtime. Such runtime
|
||||||
# would be able to use write barriers and safepoints. Such environment
|
# would be able to use write barriers and safepoints. Such environment
|
||||||
# must also provide precise object layout (stack can be uncooperative).
|
# must also provide precise object layout (stack can be uncooperative).
|
||||||
cooperative = ["object_pinning", "mmtk/vo_bit", "mmtk/is_mmtk_object", "mmtk/vo_bit_access", "mmtk/immix_non_moving"]
|
cooperative = ["object_pinning", "mmtk/vo_bit", "mmtk/is_mmtk_object", "mmtk/vo_bit_access"]
|
||||||
# VMKit is built for use in full-precise runtime. Such runtime
|
# VMKit is built for use in full-precise runtime. Such runtime
|
||||||
# would be able to use precise write barriers and safepoints, object
|
# would be able to use precise write barriers and safepoints, object
|
||||||
# layout is fully precise.
|
# layout is fully precise.
|
||||||
|
|
|
@ -126,7 +126,7 @@ impl NodeRef {
|
||||||
&METADATA,
|
&METADATA,
|
||||||
AllocationSemantics::Default,
|
AllocationSemantics::Default,
|
||||||
);
|
);
|
||||||
|
//node.hashcode::<BenchVM>();
|
||||||
node.set_field_object::<BenchVM, false>(offset_of!(Node, left), left.0);
|
node.set_field_object::<BenchVM, false>(offset_of!(Node, left), left.0);
|
||||||
node.set_field_object::<BenchVM, false>(offset_of!(Node, right), right.0);
|
node.set_field_object::<BenchVM, false>(offset_of!(Node, right), right.0);
|
||||||
|
|
||||||
|
@ -188,15 +188,8 @@ fn main() {
|
||||||
.parse::<usize>()
|
.parse::<usize>()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mut builder = MMTKBuilder::new();
|
let mut builder = MMTKBuilder::new();
|
||||||
builder.options.plan.set(PlanSelector::Immix);
|
builder.options.plan.set(PlanSelector::StickyImmix);
|
||||||
builder.options.threads.set(nthreads);
|
builder.options.threads.set(nthreads);
|
||||||
builder
|
|
||||||
.options
|
|
||||||
.gc_trigger
|
|
||||||
.set(mmtk::util::options::GCTriggerSelector::DynamicHeapSize(
|
|
||||||
4 * 1024 * 1024 * 1024,
|
|
||||||
16 * 1024 * 1024 * 1024,
|
|
||||||
));
|
|
||||||
VM.set(BenchVM {
|
VM.set(BenchVM {
|
||||||
vmkit: VMKit::new(&mut builder),
|
vmkit: VMKit::new(&mut builder),
|
||||||
})
|
})
|
||||||
|
|
|
@ -20,6 +20,8 @@ pub mod threading;
|
||||||
#[cfg(feature = "uncooperative")]
|
#[cfg(feature = "uncooperative")]
|
||||||
pub mod bdwgc_shim;
|
pub mod bdwgc_shim;
|
||||||
|
|
||||||
|
pub use mmtk;
|
||||||
|
|
||||||
pub trait VirtualMachine: Sized + 'static + Send + Sync {
|
pub trait VirtualMachine: Sized + 'static + Send + Sync {
|
||||||
type ThreadContext: threading::ThreadContext<Self>;
|
type ThreadContext: threading::ThreadContext<Self>;
|
||||||
type BlockAdapterList: threading::BlockAdapterList<Self>;
|
type BlockAdapterList: threading::BlockAdapterList<Self>;
|
||||||
|
@ -27,6 +29,8 @@ pub trait VirtualMachine: Sized + 'static + Send + Sync {
|
||||||
type Slot: SlotExtra;
|
type Slot: SlotExtra;
|
||||||
type MemorySlice: MemorySlice<SlotType = Self::Slot>;
|
type MemorySlice: MemorySlice<SlotType = Self::Slot>;
|
||||||
|
|
||||||
|
/*#[cfg(feature = "address_based_hashing")]
|
||||||
|
const HASH_STATE_SPEC: VMLocalHashStateSpec = VMLocalHashStateSpec::in_header(61);*/
|
||||||
/// 1-word local metadata for spaces that may copy objects.
|
/// 1-word local metadata for spaces that may copy objects.
|
||||||
/// This metadata has to be stored in the header.
|
/// This metadata has to be stored in the header.
|
||||||
/// This metadata can be defined at a position within the object payload.
|
/// This metadata can be defined at a position within the object payload.
|
||||||
|
|
|
@ -57,6 +57,7 @@ pub mod scanning;
|
||||||
pub mod stack_bounds;
|
pub mod stack_bounds;
|
||||||
pub mod tlab;
|
pub mod tlab;
|
||||||
pub mod traits;
|
pub mod traits;
|
||||||
|
pub mod spec;
|
||||||
|
|
||||||
impl<VM: VirtualMachine> MemoryManager<VM> {
|
impl<VM: VirtualMachine> MemoryManager<VM> {
|
||||||
pub extern "C-unwind" fn request_gc() -> bool {
|
pub extern "C-unwind" fn request_gc() -> bool {
|
||||||
|
@ -100,10 +101,7 @@ impl<VM: VirtualMachine> MemoryManager<VM> {
|
||||||
let object_start =
|
let object_start =
|
||||||
mmtk::memory_manager::alloc(thread.mutator(), size, alignment, 0, semantics);
|
mmtk::memory_manager::alloc(thread.mutator(), size, alignment, 0, semantics);
|
||||||
|
|
||||||
object_start.store(HeapObjectHeader::<VM> {
|
object_start.store(HeapObjectHeader::<VM>::new(metadata));
|
||||||
metadata: AtomicBitfieldContainer::new(metadata.to_bitfield()),
|
|
||||||
marker: PhantomData,
|
|
||||||
});
|
|
||||||
let object = VMKitObject::from_address(object_start + OBJECT_REF_OFFSET);
|
let object = VMKitObject::from_address(object_start + OBJECT_REF_OFFSET);
|
||||||
Self::set_vo_bit(object);
|
Self::set_vo_bit(object);
|
||||||
Self::refill_tlab(thread);
|
Self::refill_tlab(thread);
|
||||||
|
@ -146,10 +144,7 @@ impl<VM: VirtualMachine> MemoryManager<VM> {
|
||||||
tlab.allocate::<VM>(size, alignment, OBJECT_REF_OFFSET as usize);
|
tlab.allocate::<VM>(size, alignment, OBJECT_REF_OFFSET as usize);
|
||||||
|
|
||||||
if !object_start.is_zero() {
|
if !object_start.is_zero() {
|
||||||
object_start.store(HeapObjectHeader::<VM> {
|
object_start.store(HeapObjectHeader::<VM>::new(metadata));
|
||||||
metadata: AtomicBitfieldContainer::new(metadata.to_bitfield()),
|
|
||||||
marker: PhantomData,
|
|
||||||
});
|
|
||||||
let object = VMKitObject::from_address(object_start + OBJECT_REF_OFFSET);
|
let object = VMKitObject::from_address(object_start + OBJECT_REF_OFFSET);
|
||||||
Self::set_vo_bit(object);
|
Self::set_vo_bit(object);
|
||||||
return object;
|
return object;
|
||||||
|
@ -185,10 +180,7 @@ impl<VM: VirtualMachine> MemoryManager<VM> {
|
||||||
);
|
);
|
||||||
|
|
||||||
let object = VMKitObject::from_address(object_start + OBJECT_REF_OFFSET);
|
let object = VMKitObject::from_address(object_start + OBJECT_REF_OFFSET);
|
||||||
object_start.store(HeapObjectHeader::<VM> {
|
object_start.store(HeapObjectHeader::<VM>::new(metadata));
|
||||||
metadata: AtomicBitfieldContainer::new(metadata.to_bitfield()),
|
|
||||||
marker: PhantomData,
|
|
||||||
});
|
|
||||||
|
|
||||||
//Self::set_vo_bit(object);
|
//Self::set_vo_bit(object);
|
||||||
Self::refill_tlab(thread);
|
Self::refill_tlab(thread);
|
||||||
|
@ -222,10 +214,7 @@ impl<VM: VirtualMachine> MemoryManager<VM> {
|
||||||
);
|
);
|
||||||
|
|
||||||
let object = VMKitObject::from_address(object_start + OBJECT_REF_OFFSET);
|
let object = VMKitObject::from_address(object_start + OBJECT_REF_OFFSET);
|
||||||
object_start.store(HeapObjectHeader::<VM> {
|
object_start.store(HeapObjectHeader::<VM>::new(metadata));
|
||||||
metadata: AtomicBitfieldContainer::new(metadata.to_bitfield()),
|
|
||||||
marker: PhantomData,
|
|
||||||
});
|
|
||||||
Self::set_vo_bit(object);
|
Self::set_vo_bit(object);
|
||||||
Self::refill_tlab(thread);
|
Self::refill_tlab(thread);
|
||||||
object
|
object
|
||||||
|
@ -252,10 +241,7 @@ impl<VM: VirtualMachine> MemoryManager<VM> {
|
||||||
);
|
);
|
||||||
|
|
||||||
let object = VMKitObject::from_address(object_start + OBJECT_REF_OFFSET);
|
let object = VMKitObject::from_address(object_start + OBJECT_REF_OFFSET);
|
||||||
object_start.store(HeapObjectHeader::<VM> {
|
object_start.store(HeapObjectHeader::<VM>::new(metadata));
|
||||||
metadata: AtomicBitfieldContainer::new(metadata.to_bitfield()),
|
|
||||||
marker: PhantomData,
|
|
||||||
});
|
|
||||||
Self::set_vo_bit(object);
|
Self::set_vo_bit(object);
|
||||||
Self::refill_tlab(thread);
|
Self::refill_tlab(thread);
|
||||||
object
|
object
|
||||||
|
@ -283,10 +269,7 @@ impl<VM: VirtualMachine> MemoryManager<VM> {
|
||||||
semantics,
|
semantics,
|
||||||
);
|
);
|
||||||
|
|
||||||
object_start.store(HeapObjectHeader::<VM> {
|
object_start.store(HeapObjectHeader::<VM>::new(metadata));
|
||||||
metadata: AtomicBitfieldContainer::new(metadata.to_bitfield()),
|
|
||||||
marker: PhantomData,
|
|
||||||
});
|
|
||||||
let object = VMKitObject::from_address(object_start + OBJECT_REF_OFFSET);
|
let object = VMKitObject::from_address(object_start + OBJECT_REF_OFFSET);
|
||||||
Self::set_vo_bit(object);
|
Self::set_vo_bit(object);
|
||||||
Self::refill_tlab(thread);
|
Self::refill_tlab(thread);
|
||||||
|
|
|
@ -14,7 +14,7 @@ use mmtk::{
|
||||||
MutatorContext,
|
MutatorContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{conservative_roots::ConservativeRoots, traits::ToSlot};
|
use super::traits::ToSlot;
|
||||||
|
|
||||||
pub struct VMKitScanning<VM: VirtualMachine>(PhantomData<VM>);
|
pub struct VMKitScanning<VM: VirtualMachine>(PhantomData<VM>);
|
||||||
|
|
||||||
|
@ -95,13 +95,15 @@ impl<VM: VirtualMachine> Scanning<MemoryManager<VM>> for VMKitScanning<VM> {
|
||||||
fn scan_roots_in_mutator_thread(
|
fn scan_roots_in_mutator_thread(
|
||||||
_tls: mmtk::util::VMWorkerThread,
|
_tls: mmtk::util::VMWorkerThread,
|
||||||
mutator: &'static mut mmtk::Mutator<MemoryManager<VM>>,
|
mutator: &'static mut mmtk::Mutator<MemoryManager<VM>>,
|
||||||
mut factory: impl mmtk::vm::RootsWorkFactory<VM::Slot>,
|
factory: impl mmtk::vm::RootsWorkFactory<VM::Slot>,
|
||||||
) {
|
) {
|
||||||
let tls = Thread::<VM>::from_vm_mutator_thread(mutator.get_tls());
|
let tls = Thread::<VM>::from_vm_mutator_thread(mutator.get_tls());
|
||||||
tls.context.scan_roots(factory.clone());
|
tls.context.scan_roots(factory.clone());
|
||||||
|
|
||||||
#[cfg(not(feature = "full-precise"))]
|
#[cfg(not(feature = "full-precise"))]
|
||||||
{
|
{
|
||||||
|
let mut factory = factory;
|
||||||
|
use super::conservative_roots::ConservativeRoots;
|
||||||
let mut croots = ConservativeRoots::new(128);
|
let mut croots = ConservativeRoots::new(128);
|
||||||
let bounds = *tls.stack_bounds();
|
let bounds = *tls.stack_bounds();
|
||||||
unsafe { croots.add_span(bounds.origin(), tls.stack_pointer()) };
|
unsafe { croots.add_span(bounds.origin(), tls.stack_pointer()) };
|
||||||
|
@ -124,6 +126,7 @@ impl<VM: VirtualMachine> Scanning<MemoryManager<VM>> for VMKitScanning<VM> {
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let object = VMKitObject::from(object);
|
let object = VMKitObject::from(object);
|
||||||
let metadata = object.header::<VM>().metadata();
|
let metadata = object.header::<VM>().metadata();
|
||||||
|
|
||||||
matches!(metadata.gc_metadata().trace, TraceCallback::ScanSlots(_))
|
matches!(metadata.gc_metadata().trace, TraceCallback::ScanSlots(_))
|
||||||
&& (!metadata.is_object() || metadata.to_slot().is_some())
|
&& (!metadata.is_object() || metadata.to_slot().is_some())
|
||||||
}
|
}
|
||||||
|
|
93
vmkit/src/mm/spec.rs
Normal file
93
vmkit/src/mm/spec.rs
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/// Define a VM metadata spec. This is essentially bitfields for storing object metadata.
|
||||||
|
/// Using this your VM can declare side metadata or local (header) metadata with ease.
|
||||||
|
///
|
||||||
|
/// This macro is copied from mmtk-core source code.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! define_vm_metadata_spec {
|
||||||
|
($(#[$outer:meta])*$spec_name: ident, $is_global: expr, $log_num_bits: expr, $side_min_obj_size: expr) => {
|
||||||
|
$(#[$outer])*
|
||||||
|
pub struct $spec_name($crate::mmtk::util::metadata::MetadataSpec);
|
||||||
|
impl $spec_name {
|
||||||
|
/// The number of bits (in log2) that are needed for the spec.
|
||||||
|
pub const LOG_NUM_BITS: usize = $log_num_bits;
|
||||||
|
|
||||||
|
/// Whether this spec is global or local. For side metadata, the binding needs to make sure
|
||||||
|
/// global specs are laid out after another global spec, and local specs are laid
|
||||||
|
/// out after another local spec. Otherwise, there will be an assertion failure.
|
||||||
|
pub const IS_GLOBAL: bool = $is_global;
|
||||||
|
|
||||||
|
/// Declare that the VM uses in-header metadata for this metadata type.
|
||||||
|
/// For the specification of the `bit_offset` argument, please refer to
|
||||||
|
/// the document of `[crate::util::metadata::header_metadata::HeaderMetadataSpec.bit_offset]`.
|
||||||
|
/// The binding needs to make sure that the bits used for a spec in the header do not conflict with
|
||||||
|
/// the bits of another spec (unless it is specified that some bits may be reused).
|
||||||
|
pub const fn in_header(bit_offset: isize) -> Self {
|
||||||
|
Self($crate::mmtk::util::metadata::MetadataSpec::InHeader($crate::mmtk::util::metadata::header_metadata::HeaderMetadataSpec {
|
||||||
|
bit_offset,
|
||||||
|
num_of_bits: 1 << Self::LOG_NUM_BITS,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Declare that the VM uses side metadata for this metadata type,
|
||||||
|
/// and the side metadata is the first of its kind (global or local).
|
||||||
|
/// The first global or local side metadata should be declared with `side_first()`,
|
||||||
|
/// and the rest side metadata should be declared with `side_after()` after a defined
|
||||||
|
/// side metadata of the same kind (global or local). Logically, all the declarations
|
||||||
|
/// create two list of side metadata, one for global, and one for local.
|
||||||
|
pub const fn side_first() -> Self {
|
||||||
|
if Self::IS_GLOBAL {
|
||||||
|
Self($crate::mmtk::util::metadata::MetadataSpec::OnSide($crate::mmtk::util::metadata::side_metadata::SideMetadataSpec {
|
||||||
|
name: stringify!($spec_name),
|
||||||
|
is_global: Self::IS_GLOBAL,
|
||||||
|
offset: $crate::mmtk::util::metadata::side_metadata::GLOBAL_SIDE_METADATA_VM_BASE_OFFSET,
|
||||||
|
log_num_of_bits: Self::LOG_NUM_BITS,
|
||||||
|
log_bytes_in_region: $side_min_obj_size as usize,
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
Self($crate::mmtk::util::metadata::MetadataSpec::OnSide($crate::mmtk::util::metadata::side_metadata::SideMetadataSpec {
|
||||||
|
name: stringify!($spec_name),
|
||||||
|
is_global: Self::IS_GLOBAL,
|
||||||
|
offset: $crate::mmtk::util::metadata::side_metadata::LOCAL_SIDE_METADATA_VM_BASE_OFFSET,
|
||||||
|
log_num_of_bits: Self::LOG_NUM_BITS,
|
||||||
|
log_bytes_in_region: $side_min_obj_size as usize,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Declare that the VM uses side metadata for this metadata type,
|
||||||
|
/// and the side metadata should be laid out after the given side metadata spec.
|
||||||
|
/// The first global or local side metadata should be declared with `side_first()`,
|
||||||
|
/// and the rest side metadata should be declared with `side_after()` after a defined
|
||||||
|
/// side metadata of the same kind (global or local). Logically, all the declarations
|
||||||
|
/// create two list of side metadata, one for global, and one for local.
|
||||||
|
pub const fn side_after(spec: &$crate::mmtk::util::metadata::MetadataSpec) -> Self {
|
||||||
|
assert!(spec.is_on_side());
|
||||||
|
let side_spec = spec.extract_side_spec();
|
||||||
|
assert!(side_spec.is_global == Self::IS_GLOBAL);
|
||||||
|
Self($crate::mmtk::util::metadata::MetadataSpec::OnSide($crate::mmtk::util::metadata::side_metadata::SideMetadataSpec {
|
||||||
|
name: stringify!($spec_name),
|
||||||
|
is_global: Self::IS_GLOBAL,
|
||||||
|
offset: $crate::mmtk::util::metadata::side_metadata::SideMetadataOffset::layout_after(side_spec),
|
||||||
|
log_num_of_bits: Self::LOG_NUM_BITS,
|
||||||
|
log_bytes_in_region: $side_min_obj_size as usize,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the inner `[crate::util::metadata::MetadataSpec]` for the metadata type.
|
||||||
|
pub const fn as_spec(&self) -> &$crate::mmtk::util::metadata::MetadataSpec {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the number of bits for the metadata type.
|
||||||
|
pub const fn num_bits(&self) -> usize {
|
||||||
|
1 << $log_num_bits
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl std::ops::Deref for $spec_name {
|
||||||
|
type Target = $crate::mmtk::util::metadata::MetadataSpec;
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
self.as_spec()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ use std::marker::PhantomData;
|
||||||
use crate::{mm::MemoryManager, VirtualMachine};
|
use crate::{mm::MemoryManager, VirtualMachine};
|
||||||
use header::{HashState, HASHCODE_OFFSET, OBJECT_HEADER_OFFSET, OBJECT_REF_OFFSET};
|
use header::{HashState, HASHCODE_OFFSET, OBJECT_HEADER_OFFSET, OBJECT_REF_OFFSET};
|
||||||
use mmtk::{
|
use mmtk::{
|
||||||
util::{alloc::fill_alignment_gap, constants::LOG_BYTES_IN_ADDRESS, ObjectReference},
|
util::{alloc::fill_alignment_gap, constants::LOG_BYTES_IN_ADDRESS, metadata::MetadataSpec, ObjectReference},
|
||||||
vm::*,
|
vm::*,
|
||||||
};
|
};
|
||||||
use object::{MoveTarget, VMKitObject};
|
use object::{MoveTarget, VMKitObject};
|
||||||
|
@ -159,7 +159,7 @@ impl<VM: VirtualMachine> ObjectModel<MemoryManager<VM>> for VMKitObjectModel<VM>
|
||||||
}
|
}
|
||||||
impl<VM: VirtualMachine> VMKitObjectModel<VM> {
|
impl<VM: VirtualMachine> VMKitObjectModel<VM> {
|
||||||
fn move_object(from_obj: VMKitObject, mut to: MoveTarget, num_bytes: usize) -> VMKitObject {
|
fn move_object(from_obj: VMKitObject, mut to: MoveTarget, num_bytes: usize) -> VMKitObject {
|
||||||
log::trace!(
|
log::debug!(
|
||||||
"move_object: from_obj: {}, to: {}, bytes={}",
|
"move_object: from_obj: {}, to: {}, bytes={}",
|
||||||
from_obj.as_address(),
|
from_obj.as_address(),
|
||||||
to,
|
to,
|
||||||
|
@ -209,7 +209,9 @@ impl<VM: VirtualMachine> VMKitObjectModel<VM> {
|
||||||
// Update hash state if necessary
|
// Update hash state if necessary
|
||||||
if hash_state == HashState::Hashed {
|
if hash_state == HashState::Hashed {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
||||||
let hash_code = from_obj.as_address().as_usize() >> LOG_BYTES_IN_ADDRESS;
|
let hash_code = from_obj.as_address().as_usize() >> LOG_BYTES_IN_ADDRESS;
|
||||||
|
|
||||||
to_obj
|
to_obj
|
||||||
.as_address()
|
.as_address()
|
||||||
.offset(HASHCODE_OFFSET)
|
.offset(HASHCODE_OFFSET)
|
||||||
|
@ -224,4 +226,16 @@ impl<VM: VirtualMachine> VMKitObjectModel<VM> {
|
||||||
|
|
||||||
to_obj
|
to_obj
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const fn last_side_metadata_spec() -> &'static MetadataSpec {
|
||||||
|
#[cfg(feature="object_pinning")]
|
||||||
|
{
|
||||||
|
Self::LOCAL_PINNING_BIT_SPEC.as_spec()
|
||||||
|
}
|
||||||
|
#[cfg(not(feature="object_pinning"))]
|
||||||
|
{
|
||||||
|
Self::LOCAL_LOS_MARK_NURSERY_SPEC.as_spec()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use crate::VirtualMachine;
|
use crate::{define_vm_metadata_spec, VirtualMachine};
|
||||||
use easy_bitfield::*;
|
use easy_bitfield::*;
|
||||||
|
|
||||||
use super::object::ADDRESS_BASED_HASHING;
|
use super::object::ADDRESS_BASED_HASHING;
|
||||||
|
@ -13,7 +13,7 @@ pub const HASHCODE_OFFSET: isize = -(OBJECT_REF_OFFSET + size_of::<usize>() as i
|
||||||
|
|
||||||
|
|
||||||
pub const METADATA_BIT_LIMIT: usize = if ADDRESS_BASED_HASHING {
|
pub const METADATA_BIT_LIMIT: usize = if ADDRESS_BASED_HASHING {
|
||||||
61
|
60
|
||||||
} else {
|
} else {
|
||||||
63
|
63
|
||||||
};
|
};
|
||||||
|
@ -21,6 +21,7 @@ pub const METADATA_BIT_LIMIT: usize = if ADDRESS_BASED_HASHING {
|
||||||
pub type MetadataField = BitField<u64, usize, 0, METADATA_BIT_LIMIT, false>;
|
pub type MetadataField = BitField<u64, usize, 0, METADATA_BIT_LIMIT, false>;
|
||||||
pub type HashStateField = BitField<u64, HashState, { MetadataField::NEXT_BIT }, 2, false>;
|
pub type HashStateField = BitField<u64, HashState, { MetadataField::NEXT_BIT }, 2, false>;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum HashState {
|
pub enum HashState {
|
||||||
Unhashed,
|
Unhashed,
|
||||||
|
@ -98,6 +99,4 @@ impl<VM: VirtualMachine> HeapObjectHeader<VM> {
|
||||||
self.metadata.update_synchronized::<MetadataField>(metadata.to_bitfield() as _);
|
self.metadata.update_synchronized::<MetadataField>(metadata.to_bitfield() as _);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue