Skip to content

Commit a288b40

Browse files
author
Javad Amiri
authored
Refactor Metadata (#342)
* remove gc_byte and header_byte, and move per-object metadata to VM object model * restructure side_metadata to a submodule of metadata * add header_metadata as a submodule of metadata * suggest more metadata access inlining * improve object forwading code style
1 parent 65109a6 commit a288b40

40 files changed

+1917
-965
lines changed

Cargo.toml

-3
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,6 @@ nogc_no_zeroing = ["nogc_lock_free"]
6464
# Q: Why do we need this as a compile time flat? We can always set the number of GC threads through options.
6565
single_worker = []
6666

67-
# To support VMs that do not provide in-header GC byte
68-
side_gc_header = []
69-
7067
# To run expensive comprehensive runtime checks, such as checking duplicate edges
7168
extreme_assertions = []
7269

docs/tutorial/code/mygc_semispace/gc_work.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::plan::CopyContext;
44
use crate::policy::space::Space;
55
use crate::scheduler::gc_work::*;
66
use crate::util::alloc::{Allocator, BumpAllocator};
7-
use crate::util::forwarding_word;
7+
use crate::util::object_forwarding;
88
use crate::util::{Address, ObjectReference};
99
use crate::util::opaque_pointer::*;
1010
use crate::vm::VMBinding;
@@ -61,7 +61,7 @@ impl<VM: VMBinding> CopyContext for MyGCCopyContext<VM> {
6161
_bytes: usize,
6262
_semantics: crate::AllocationSemantics,
6363
) {
64-
forwarding_word::clear_forwarding_bits::<VM>(obj);
64+
object_forwarding::clear_forwarding_bits::<VM>(obj);
6565
}
6666
// ANCHOR_END: copycontext_post_copy
6767
}

docs/tutorial/code/mygc_semispace/global.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::util::heap::layout::heap_layout::VMMap;
1818
use crate::util::heap::layout::vm_layout_constants::{HEAP_END, HEAP_START};
1919
use crate::util::heap::HeapMeta;
2020
use crate::util::heap::VMRequest;
21-
use crate::util::side_metadata::{SideMetadataSanity, SideMetadataContext};
21+
use crate::util::metadata::side_metadata::{SideMetadataSanity, SideMetadataContext};
2222
use crate::util::options::UnsafeOptionsWrapper;
2323
use crate::util::opaque_pointer::*;
2424
use crate::vm::VMBinding;

src/memory_manager.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::scheduler::GCWorker;
1818
use crate::scheduler::Work;
1919
use crate::scheduler::WorkBucketStage;
2020
use crate::util::alloc::allocators::AllocatorSelector;
21-
use crate::util::constants::LOG_BYTES_IN_PAGE;
21+
use crate::util::constants::{LOG_BYTES_IN_PAGE, MIN_OBJECT_SIZE};
2222
use crate::util::heap::layout::vm_layout_constants::HEAP_END;
2323
use crate::util::heap::layout::vm_layout_constants::HEAP_START;
2424
use crate::util::opaque_pointer::*;
@@ -108,8 +108,7 @@ pub fn alloc<VM: VMBinding>(
108108
// their object sizes are all larger than MMTk's min object size, so we simply put an assertion here.
109109
// If you plan to use MMTk with a VM with its object size smaller than MMTk's min object size, you should
110110
// meet the min object size in the fastpath.
111-
#[cfg(debug_assertions)]
112-
crate::util::forwarding_word::check_alloc_size::<VM>(size);
111+
debug_assert!(size >= MIN_OBJECT_SIZE);
113112
mutator.alloc(size, align, offset, semantics)
114113
}
115114

src/plan/barriers.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
//! Read/Write barrier implementations.
22
3+
use atomic::Ordering;
4+
35
use crate::scheduler::gc_work::*;
46
use crate::scheduler::WorkBucketStage;
5-
use crate::util::side_metadata::*;
7+
use crate::util::metadata::{compare_exchange_metadata, MetadataSpec};
68
use crate::util::*;
9+
use crate::vm::VMBinding;
710
use crate::MMTK;
811

912
/// BarrierSelector describes which barrier to use.
@@ -34,12 +37,12 @@ impl Barrier for NoBarrier {
3437
pub struct ObjectRememberingBarrier<E: ProcessEdgesWork> {
3538
mmtk: &'static MMTK<E::VM>,
3639
modbuf: Vec<ObjectReference>,
37-
meta: SideMetadataSpec,
40+
meta: MetadataSpec,
3841
}
3942

4043
impl<E: ProcessEdgesWork> ObjectRememberingBarrier<E> {
4144
#[allow(unused)]
42-
pub fn new(mmtk: &'static MMTK<E::VM>, meta: SideMetadataSpec) -> Self {
45+
pub fn new(mmtk: &'static MMTK<E::VM>, meta: MetadataSpec) -> Self {
4346
Self {
4447
mmtk,
4548
modbuf: vec![],
@@ -48,8 +51,16 @@ impl<E: ProcessEdgesWork> ObjectRememberingBarrier<E> {
4851
}
4952

5053
#[inline(always)]
51-
fn enqueue_node(&mut self, obj: ObjectReference) {
52-
if compare_exchange_atomic(self.meta, obj.to_address(), 0b1, 0b0) {
54+
fn enqueue_node<VM: VMBinding>(&mut self, obj: ObjectReference) {
55+
if compare_exchange_metadata::<VM>(
56+
self.meta,
57+
obj,
58+
0b1,
59+
0b0,
60+
None,
61+
Ordering::SeqCst,
62+
Ordering::SeqCst,
63+
) {
5364
self.modbuf.push(obj);
5465
if self.modbuf.len() >= E::CAPACITY {
5566
self.flush();
@@ -78,7 +89,7 @@ impl<E: ProcessEdgesWork> Barrier for ObjectRememberingBarrier<E> {
7889
fn post_write_barrier(&mut self, target: WriteTarget) {
7990
match target {
8091
WriteTarget::Object(obj) => {
81-
self.enqueue_node(obj);
92+
self.enqueue_node::<E::VM>(obj);
8293
}
8394
_ => unreachable!(),
8495
}

src/plan/gencopy/gc_work.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1+
use atomic::Ordering;
2+
13
use super::global::GenCopy;
24
use crate::plan::PlanConstraints;
35
use crate::plan::{barriers::BarrierSelector, CopyContext};
46
use crate::policy::space::Space;
57
use crate::scheduler::gc_work::*;
68
use crate::scheduler::WorkerLocal;
79
use crate::util::alloc::{Allocator, BumpAllocator};
8-
use crate::util::forwarding_word;
10+
use crate::util::metadata::store_metadata;
11+
use crate::util::object_forwarding;
912
use crate::util::opaque_pointer::*;
10-
use crate::util::side_metadata::*;
1113
use crate::util::{Address, ObjectReference};
1214
use crate::vm::*;
1315
use crate::MMTK;
@@ -53,9 +55,15 @@ impl<VM: VMBinding> CopyContext for GenCopyCopyContext<VM> {
5355
_bytes: usize,
5456
_semantics: crate::AllocationSemantics,
5557
) {
56-
forwarding_word::clear_forwarding_bits::<VM>(obj);
58+
object_forwarding::clear_forwarding_bits::<VM>(obj);
5759
if !super::NO_SLOW && super::ACTIVE_BARRIER == BarrierSelector::ObjectBarrier {
58-
store_atomic(super::LOGGING_META, obj.to_address(), 0b1);
60+
store_metadata::<VM>(
61+
VM::VMObjectModel::GLOBAL_LOG_BIT_SPEC,
62+
obj,
63+
0b1,
64+
None,
65+
Some(Ordering::SeqCst),
66+
);
5967
}
6068
}
6169
}

src/plan/gencopy/global.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1+
use super::gc_work::{GenCopyCopyContext, GenCopyMatureProcessEdges, GenCopyNurseryProcessEdges};
12
use super::mutator::ALLOCATOR_MAPPING;
2-
use super::{
3-
gc_work::{GenCopyCopyContext, GenCopyMatureProcessEdges, GenCopyNurseryProcessEdges},
4-
LOGGING_META,
5-
};
63
use crate::plan::global::BasePlan;
74
use crate::plan::global::CommonPlan;
85
use crate::plan::global::GcStatus;
@@ -14,17 +11,17 @@ use crate::policy::space::Space;
1411
use crate::scheduler::gc_work::*;
1512
use crate::scheduler::*;
1613
use crate::util::alloc::allocators::AllocatorSelector;
17-
use crate::util::conversions;
1814
use crate::util::heap::layout::heap_layout::Mmapper;
1915
use crate::util::heap::layout::heap_layout::VMMap;
2016
use crate::util::heap::layout::vm_layout_constants::{HEAP_END, HEAP_START};
2117
use crate::util::heap::HeapMeta;
2218
use crate::util::heap::VMRequest;
19+
use crate::util::metadata::side_metadata::{SideMetadataContext, SideMetadataSanity};
2320
use crate::util::options::UnsafeOptionsWrapper;
2421
#[cfg(feature = "sanity")]
2522
use crate::util::sanity::sanity_checker::*;
26-
use crate::util::side_metadata::{SideMetadataContext, SideMetadataSanity};
2723
use crate::util::VMWorkerThread;
24+
use crate::util::{conversions, metadata};
2825
use crate::vm::*;
2926
use crate::{mmtk::MMTK, plan::barriers::BarrierSelector};
3027
use enum_map::EnumMap;
@@ -203,7 +200,7 @@ impl<VM: VMBinding> GenCopy<VM> {
203200
) -> Self {
204201
let mut heap = HeapMeta::new(HEAP_START, HEAP_END);
205202
let gencopy_specs = if super::ACTIVE_BARRIER == BarrierSelector::ObjectBarrier {
206-
vec![LOGGING_META]
203+
metadata::extract_side_metadata(&[VM::VMObjectModel::GLOBAL_LOG_BIT_SPEC])
207204
} else {
208205
vec![]
209206
};

src/plan/gencopy/mod.rs

-15
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,3 @@ pub const FULL_NURSERY_GC: bool = false;
2323
pub const NO_SLOW: bool = false;
2424

2525
pub use self::global::GENCOPY_CONSTRAINTS;
26-
27-
#[cfg(feature = "side_gc_header")]
28-
use crate::util::gc_byte;
29-
use crate::util::side_metadata::*;
30-
31-
const LOGGING_META: SideMetadataSpec = SideMetadataSpec {
32-
scope: SideMetadataScope::Global,
33-
#[cfg(not(feature = "side_gc_header"))]
34-
offset: GLOBAL_SIDE_METADATA_BASE_ADDRESS.as_usize(),
35-
#[cfg(feature = "side_gc_header")]
36-
offset: GLOBAL_SIDE_METADATA_BASE_ADDRESS.as_usize()
37-
+ metadata_address_range_size(gc_byte::SIDE_GC_BYTE_SPEC),
38-
log_num_of_bits: 0,
39-
log_min_obj_size: 3,
40-
};

src/plan/gencopy/mutator.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::plan::AllocationSemantics as AllocationType;
77
use crate::util::alloc::allocators::{AllocatorSelector, Allocators};
88
use crate::util::alloc::BumpAllocator;
99
use crate::util::{VMMutatorThread, VMWorkerThread};
10-
use crate::vm::VMBinding;
10+
use crate::vm::{ObjectModel, VMBinding};
1111
use crate::MMTK;
1212
use enum_map::enum_map;
1313
use enum_map::EnumMap;
@@ -59,7 +59,7 @@ pub fn create_gencopy_mutator<VM: VMBinding>(
5959
allocators: Allocators::<VM>::new(mutator_tls, &*mmtk.plan, &config.space_mapping),
6060
barrier: box ObjectRememberingBarrier::<GenCopyNurseryProcessEdges<VM>>::new(
6161
mmtk,
62-
super::LOGGING_META,
62+
VM::VMObjectModel::GLOBAL_LOG_BIT_SPEC,
6363
),
6464
mutator_tls,
6565
config,

src/plan/global.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ use crate::util::heap::layout::heap_layout::VMMap;
1919
use crate::util::heap::layout::map::Map;
2020
use crate::util::heap::HeapMeta;
2121
use crate::util::heap::VMRequest;
22+
use crate::util::metadata::side_metadata::SideMetadataSanity;
23+
use crate::util::metadata::side_metadata::SideMetadataSpec;
2224
use crate::util::options::PlanSelector;
2325
use crate::util::options::{Options, UnsafeOptionsWrapper};
24-
use crate::util::side_metadata::SideMetadataSanity;
25-
use crate::util::side_metadata::SideMetadataSpec;
2626
use crate::util::statistics::stats::Stats;
2727
use crate::util::{Address, ObjectReference};
2828
use crate::util::{VMMutatorThread, VMWorkerThread};

src/plan/marksweep/global.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ use crate::util::heap::layout::heap_layout::Mmapper;
1717
use crate::util::heap::layout::heap_layout::VMMap;
1818
use crate::util::heap::layout::vm_layout_constants::{HEAP_END, HEAP_START};
1919
use crate::util::heap::HeapMeta;
20+
use crate::util::metadata::side_metadata::{SideMetadataContext, SideMetadataSanity};
2021
use crate::util::options::UnsafeOptionsWrapper;
2122
#[cfg(feature = "sanity")]
2223
use crate::util::sanity::sanity_checker::*;
23-
use crate::util::side_metadata::{SideMetadataContext, SideMetadataSanity};
2424
use crate::util::VMWorkerThread;
2525
use crate::vm::VMBinding;
2626
use std::sync::Arc;

src/plan/nogc/global.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ use crate::util::heap::layout::vm_layout_constants::{HEAP_END, HEAP_START};
1515
use crate::util::heap::HeapMeta;
1616
#[allow(unused_imports)]
1717
use crate::util::heap::VMRequest;
18+
use crate::util::metadata::side_metadata::{SideMetadataContext, SideMetadataSanity};
1819
use crate::util::opaque_pointer::*;
1920
use crate::util::options::UnsafeOptionsWrapper;
20-
use crate::util::side_metadata::{SideMetadataContext, SideMetadataSanity};
2121
use crate::vm::VMBinding;
2222
use enum_map::EnumMap;
2323
use std::sync::Arc;

src/plan/plan_constraints.rs

-4
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ pub struct PlanConstraints {
1313
pub gc_header_words: usize,
1414
pub num_specialized_scans: usize,
1515
pub max_non_los_copy_bytes: usize,
16-
pub needs_log_bit_in_header: bool,
17-
pub needs_log_bit_in_header_num: usize,
1816
pub barrier: BarrierSelector,
1917
// the following seems unused for now
2018
pub needs_linear_scan: bool,
@@ -31,8 +29,6 @@ impl PlanConstraints {
3129
gc_header_words: 0,
3230
num_specialized_scans: 0,
3331
max_non_los_copy_bytes: MAX_INT,
34-
needs_log_bit_in_header: false,
35-
needs_log_bit_in_header_num: 0,
3632
needs_linear_scan: SUPPORT_CARD_SCANNING || LAZY_SWEEP,
3733
needs_concurrent_workers: false,
3834
generate_gc_trace: false,

src/plan/semispace/gc_work.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::policy::space::Space;
55
use crate::scheduler::gc_work::*;
66
use crate::scheduler::WorkerLocal;
77
use crate::util::alloc::{Allocator, BumpAllocator};
8-
use crate::util::forwarding_word;
8+
use crate::util::object_forwarding;
99
use crate::util::opaque_pointer::*;
1010
use crate::util::{Address, ObjectReference};
1111
use crate::vm::VMBinding;
@@ -51,7 +51,7 @@ impl<VM: VMBinding> CopyContext for SSCopyContext<VM> {
5151
_bytes: usize,
5252
_semantics: crate::AllocationSemantics,
5353
) {
54-
forwarding_word::clear_forwarding_bits::<VM>(obj);
54+
object_forwarding::clear_forwarding_bits::<VM>(obj);
5555
}
5656
}
5757

src/plan/semispace/global.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ use crate::util::heap::layout::heap_layout::VMMap;
1818
use crate::util::heap::layout::vm_layout_constants::{HEAP_END, HEAP_START};
1919
use crate::util::heap::HeapMeta;
2020
use crate::util::heap::VMRequest;
21+
use crate::util::metadata::side_metadata::{SideMetadataContext, SideMetadataSanity};
2122
use crate::util::opaque_pointer::VMWorkerThread;
2223
use crate::util::options::UnsafeOptionsWrapper;
2324
#[cfg(feature = "sanity")]
2425
use crate::util::sanity::sanity_checker::*;
25-
use crate::util::side_metadata::{SideMetadataContext, SideMetadataSanity};
2626
use crate::{plan::global::BasePlan, vm::VMBinding};
2727
use std::sync::atomic::{AtomicBool, Ordering};
2828
use std::sync::Arc;

src/policy/copyspace.rs

+14-9
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ use crate::plan::{AllocationSemantics, CopyContext};
33
use crate::policy::space::SpaceOptions;
44
use crate::policy::space::{CommonSpace, Space, SFT};
55
use crate::util::constants::CARD_META_PAGES_PER_REGION;
6-
use crate::util::forwarding_word as ForwardingWord;
76
use crate::util::heap::layout::heap_layout::{Mmapper, VMMap};
87
use crate::util::heap::HeapMeta;
98
use crate::util::heap::VMRequest;
109
use crate::util::heap::{MonotonePageResource, PageResource};
11-
use crate::util::side_metadata::{SideMetadataContext, SideMetadataSpec};
10+
use crate::util::metadata::extract_side_metadata;
11+
use crate::util::metadata::side_metadata::{SideMetadataContext, SideMetadataSpec};
12+
use crate::util::object_forwarding;
1213
use crate::util::{Address, ObjectReference};
1314
use crate::vm::*;
1415
use libc::{mprotect, PROT_EXEC, PROT_NONE, PROT_READ, PROT_WRITE};
@@ -28,7 +29,7 @@ impl<VM: VMBinding> SFT for CopySpace<VM> {
2829
self.get_name()
2930
}
3031
fn is_live(&self, object: ObjectReference) -> bool {
31-
!self.from_space() || ForwardingWord::is_forwarded::<VM>(object)
32+
!self.from_space() || object_forwarding::is_forwarded::<VM>(object)
3233
}
3334
fn is_movable(&self) -> bool {
3435
true
@@ -75,6 +76,10 @@ impl<VM: VMBinding> CopySpace<VM> {
7576
mmapper: &'static Mmapper,
7677
heap: &mut HeapMeta,
7778
) -> Self {
79+
let local_specs = extract_side_metadata(&[
80+
VM::VMObjectModel::LOCAL_FORWARDING_BITS_SPEC,
81+
VM::VMObjectModel::LOCAL_FORWARDING_POINTER_SPEC,
82+
]);
7883
let common = CommonSpace::new(
7984
SpaceOptions {
8085
name,
@@ -84,7 +89,7 @@ impl<VM: VMBinding> CopySpace<VM> {
8489
vmrequest,
8590
side_metadata_specs: SideMetadataContext {
8691
global: global_side_metadata_specs,
87-
local: vec![],
92+
local: local_specs,
8893
},
8994
},
9095
vm_map,
@@ -136,21 +141,21 @@ impl<VM: VMBinding> CopySpace<VM> {
136141
return object;
137142
}
138143
trace!("attempting to forward");
139-
let forwarding_status = ForwardingWord::attempt_to_forward::<VM>(object);
144+
let forwarding_status = object_forwarding::attempt_to_forward::<VM>(object);
140145
trace!("checking if object is being forwarded");
141-
if ForwardingWord::state_is_forwarded_or_being_forwarded(forwarding_status) {
146+
if object_forwarding::state_is_forwarded_or_being_forwarded(forwarding_status) {
142147
trace!("... yes it is");
143148
let new_object =
144-
ForwardingWord::spin_and_get_forwarded_object::<VM>(object, forwarding_status);
149+
object_forwarding::spin_and_get_forwarded_object::<VM>(object, forwarding_status);
145150
trace!("Returning");
146151
new_object
147152
} else {
148153
trace!("... no it isn't. Copying");
149154
let new_object =
150-
ForwardingWord::forward_object::<VM, _>(object, semantics, copy_context);
155+
object_forwarding::forward_object::<VM, _>(object, semantics, copy_context);
151156
trace!("Forwarding pointer");
152157
trace.process_node(new_object);
153-
trace!("Copying [{:?} -> {:?}]", object, new_object);
158+
trace!("Copied [{:?} -> {:?}]", object, new_object);
154159
new_object
155160
}
156161
}

0 commit comments

Comments
 (0)