Skip to content

Commit 32158cd

Browse files
author
Yi Lin
committed
* Introduced CommonPlan
* Introduced HeapMeta * Introduced SpaceDescriptor * Sanity code is conditionally compiled.
1 parent 3149c86 commit 32158cd

25 files changed

+510
-384
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ lazy_static = "1.1"
1616
log = {version = "0.4", features = ["max_level_trace", "release_max_level_off"] }
1717
crossbeam-deque = "0.6"
1818
num_cpus = "1.8"
19+
derivative = "1.0.3"
1920

2021
[features]
2122
default = ["nogc", "openjdk"]

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ extern crate lazy_static;
1717
extern crate log;
1818
extern crate crossbeam_deque;
1919
extern crate num_cpus;
20+
#[macro_use]
21+
extern crate derivative;
2022

2123
#[macro_use]
2224
pub mod util;

src/mm/memory_manager.rs

Lines changed: 58 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use libc::c_void;
33
use libc::c_char;
44

55
use std::ffi::CStr;
6-
use std::str;
6+
use std::{str, thread};
77

88
use std::sync::atomic::Ordering;
99

@@ -12,7 +12,6 @@ use ::plan::MutatorContext;
1212
use ::plan::TraceLocal;
1313
use ::plan::CollectorContext;
1414
use ::plan::ParallelCollectorGroup;
15-
use ::plan::plan::CONTROL_COLLECTOR_CONTEXT;
1615

1716
use ::vm::{Collection, VMCollection};
1817

@@ -31,7 +30,6 @@ use ::plan::Allocator;
3130
use util::constants::LOG_BYTES_IN_PAGE;
3231
use util::heap::layout::vm_layout_constants::HEAP_START;
3332
use util::heap::layout::vm_layout_constants::HEAP_END;
34-
use ::util::sanity::sanity_checker::{INSIDE_SANITY, SanityChecker};
3533
use util::OpaquePointer;
3634
use crate::mmtk::SINGLETON;
3735

@@ -77,7 +75,7 @@ pub unsafe extern fn openjdk_gc_init(calls: *const OpenJDK_Upcalls, heap_size: u
7775
#[no_mangle]
7876
#[cfg(any(feature = "jikesrvm", feature = "openjdk"))]
7977
pub extern fn start_control_collector(tls: OpaquePointer) {
80-
CONTROL_COLLECTOR_CONTEXT.run(tls);
78+
SINGLETON.plan.common().control_collector_context.run(tls);
8179
}
8280

8381
#[no_mangle]
@@ -96,7 +94,10 @@ pub unsafe extern fn gc_init(heap_size: usize) {
9694
}
9795
::util::logger::init().unwrap();
9896
SINGLETON.plan.gc_init(heap_size, &SINGLETON.vm_map);
99-
::plan::plan::INITIALIZED.store(true, Ordering::SeqCst);
97+
SINGLETON.plan.common().initialized.store(true, Ordering::SeqCst);
98+
thread::spawn(|| {
99+
SINGLETON.plan.common().control_collector_context.run(OpaquePointer::UNINITIALIZED)
100+
});
100101
}
101102

102103
#[no_mangle]
@@ -145,48 +146,72 @@ pub unsafe extern fn is_valid_ref(val: ObjectReference) -> bool {
145146
}
146147

147148
#[no_mangle]
149+
#[cfg(feature = "sanity")]
148150
pub unsafe extern fn report_delayed_root_edge(trace_local: *mut c_void, addr: *mut c_void) {
149-
trace!("JikesRVM called report_delayed_root_edge with trace_local={:?}", trace_local);
150-
if cfg!(feature = "sanity") && INSIDE_SANITY.load(Ordering::Relaxed) {
151-
let local = &mut *(trace_local as *mut SanityChecker);
152-
local.report_delayed_root_edge(Address::from_usize(addr as usize));
151+
use ::util::sanity::sanity_checker::SanityChecker;
152+
if SINGLETON.plan.common().is_in_sanity() {
153+
report_delayed_root_edge_inner::<SanityChecker>(trace_local, addr)
153154
} else {
154-
let local = &mut *(trace_local as *mut <SelectedPlan as Plan>::TraceLocalT);
155-
local.report_delayed_root_edge(Address::from_usize(addr as usize));
155+
report_delayed_root_edge_inner::<<SelectedPlan as Plan>::TraceLocalT>(trace_local, addr)
156156
}
157+
}
158+
#[no_mangle]
159+
#[cfg(not(feature = "sanity"))]
160+
pub unsafe extern fn report_delayed_root_edge(trace_local: *mut c_void, addr: *mut c_void) {
161+
report_delayed_root_edge_inner::<<SelectedPlan as Plan>::TraceLocalT>(trace_local, addr)
162+
}
163+
unsafe fn report_delayed_root_edge_inner<T: TraceLocal>(trace_local: *mut c_void, addr: *mut c_void) {
164+
trace!("report_delayed_root_edge with trace_local={:?}", trace_local);
165+
let local = &mut *(trace_local as *mut T);
166+
local.report_delayed_root_edge(Address::from_usize(addr as usize));
157167
trace!("report_delayed_root_edge returned with trace_local={:?}", trace_local);
158168
}
159169

160170
#[no_mangle]
171+
#[cfg(feature = "sanity")]
161172
pub unsafe extern fn will_not_move_in_current_collection(trace_local: *mut c_void, obj: *mut c_void) -> bool {
162-
trace!("will_not_move_in_current_collection({:?}, {:?})", trace_local, obj);
163-
if cfg!(feature = "sanity") && INSIDE_SANITY.load(Ordering::Relaxed) {
164-
let local = &mut *(trace_local as *mut SanityChecker);
165-
let ret = local.will_not_move_in_current_collection(Address::from_usize(obj as usize).to_object_reference());
166-
trace!("will_not_move_in_current_collection returned with trace_local={:?}", trace_local);
167-
ret
173+
use ::util::sanity::sanity_checker::SanityChecker;
174+
if SINGLETON.plan.common().is_in_sanity() {
175+
will_not_move_in_current_collection_inner::<SanityChecker>(trace_local, obj)
168176
} else {
169-
let local = &mut *(trace_local as *mut <SelectedPlan as Plan>::TraceLocalT);
170-
let ret = local.will_not_move_in_current_collection(Address::from_usize(obj as usize).to_object_reference());
171-
trace!("will_not_move_in_current_collection returned with trace_local={:?}", trace_local);
172-
ret
177+
will_not_move_in_current_collection_inner::<<SelectedPlan as Plan>::TraceLocalT>(trace_local, obj)
173178
}
174179
}
180+
#[no_mangle]
181+
#[cfg(not(feature = "sanity"))]
182+
pub unsafe extern fn will_not_move_in_current_collection(trace_local: *mut c_void, obj: *mut c_void) -> bool {
183+
will_not_move_in_current_collection_inner::<<SelectedPlan as Plan>::TraceLocalT>(trace_local, obj)
184+
}
185+
unsafe fn will_not_move_in_current_collection_inner<T: TraceLocal>(trace_local: *mut c_void, obj: *mut c_void) -> bool {
186+
trace!("will_not_move_in_current_collection({:?}, {:?})", trace_local, obj);
187+
let local = &mut *(trace_local as *mut T);
188+
let ret = local.will_not_move_in_current_collection(Address::from_usize(obj as usize).to_object_reference());
189+
trace!("will_not_move_in_current_collection returned with trace_local={:?}", trace_local);
190+
ret
191+
}
175192

176193
#[no_mangle]
194+
#[cfg(feature = "sanity")]
177195
pub unsafe extern fn process_interior_edge(trace_local: *mut c_void, target: *mut c_void, slot: *mut c_void, root: bool) {
178-
trace!("JikesRVM called process_interior_edge with trace_local={:?}", trace_local);
179-
if cfg!(feature = "sanity") && INSIDE_SANITY.load(Ordering::Relaxed) {
180-
let local = &mut *(trace_local as *mut SanityChecker);
181-
local.process_interior_edge(Address::from_usize(target as usize).to_object_reference(),
182-
Address::from_usize(slot as usize), root);
196+
use ::util::sanity::sanity_checker::SanityChecker;
197+
if SINGLETON.plan.common().is_in_sanity() {
198+
process_interior_edge_inner::<SanityChecker>(trace_local, target, slot, root)
183199
} else {
184-
let local = &mut *(trace_local as *mut <SelectedPlan as Plan>::TraceLocalT);
185-
local.process_interior_edge(Address::from_usize(target as usize).to_object_reference(),
186-
Address::from_usize(slot as usize), root);
200+
process_interior_edge_inner::<<SelectedPlan as Plan>::TraceLocalT>(trace_local, target, slot, root)
187201
}
188202
trace!("process_interior_root_edge returned with trace_local={:?}", trace_local);
189-
203+
}
204+
#[no_mangle]
205+
#[cfg(not(feature = "sanity"))]
206+
pub unsafe extern fn process_interior_edge(trace_local: *mut c_void, target: *mut c_void, slot: *mut c_void, root: bool) {
207+
process_interior_edge_inner::<<SelectedPlan as Plan>::TraceLocalT>(trace_local, target, slot, root)
208+
}
209+
unsafe fn process_interior_edge_inner<T: TraceLocal>(trace_local: *mut c_void, target: *mut c_void, slot: *mut c_void, root: bool) {
210+
trace!("process_interior_edge with trace_local={:?}", trace_local);
211+
let local = &mut *(trace_local as *mut T);
212+
local.process_interior_edge(Address::from_usize(target as usize).to_object_reference(),
213+
Address::from_usize(slot as usize), root);
214+
trace!("process_interior_root_edge returned with trace_local={:?}", trace_local);
190215
}
191216

192217
#[no_mangle]
@@ -199,9 +224,9 @@ pub unsafe extern fn start_worker(tls: OpaquePointer, worker: *mut c_void) {
199224
#[no_mangle]
200225
#[cfg(feature = "jikesrvm")]
201226
pub unsafe extern fn enable_collection(tls: OpaquePointer) {
202-
(&mut *CONTROL_COLLECTOR_CONTEXT.workers.get()).init_group(&SINGLETON, tls);
227+
(&mut *SINGLETON.plan.common().control_collector_context.workers.get()).init_group(&SINGLETON, tls);
203228
VMCollection::spawn_worker_thread::<<SelectedPlan as Plan>::CollectorT>(tls, null_mut()); // spawn controller thread
204-
::plan::plan::INITIALIZED.store(true, Ordering::SeqCst);
229+
SINGLETON.plan.common().initialized.store(true, Ordering::SeqCst);
205230
}
206231

207232
#[no_mangle]
@@ -279,6 +304,7 @@ pub extern fn executable() -> bool {
279304
}
280305

281306
#[no_mangle]
307+
#[cfg(feature = "sanity")]
282308
pub unsafe extern fn scan_region(){
283309
::util::sanity::memory_scan::scan_region(&SINGLETON.plan);
284310
}

src/plan/controller_collector_context.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ impl ControllerCollectorContext {
6060
VMCollection::stop_all_mutators(tls);
6161

6262
// For heap growth logic
63-
let user_triggered_collection: bool = SelectedPlan::is_user_triggered_collection();
63+
// FIXME: This is not used. However, we probably want to set a 'user_triggered' flag
64+
// when GC is requested.
65+
// let user_triggered_collection: bool = SelectedPlan::is_user_triggered_collection();
6466

6567
self.clear_request();
6668

src/plan/nogc/nogc.rs

Lines changed: 32 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,20 @@ use super::NoGCTraceLocal;
1919
use super::NoGCMutator;
2020
use super::NoGCCollector;
2121
use util::conversions::bytes_to_pages;
22-
use plan::plan::create_vm_space;
22+
use plan::plan::{create_vm_space, CommonPlan};
2323
use util::heap::layout::heap_layout::VMMap;
2424
use util::heap::layout::heap_layout::Mmapper;
2525
use util::options::{Options, UnsafeOptionsWrapper};
2626
use std::sync::Arc;
27+
use util::heap::HeapMeta;
28+
use util::heap::layout::vm_layout_constants::{HEAP_START, HEAP_END};
29+
use std::sync::atomic::Ordering;
2730

2831
pub type SelectedPlan = NoGC;
2932

3033
pub struct NoGC {
31-
pub control_collector_context: ControllerCollectorContext,
3234
pub unsync: UnsafeCell<NoGCUnsync>,
35+
pub common: CommonPlan,
3336
}
3437

3538
unsafe impl Sync for NoGC {}
@@ -38,9 +41,6 @@ pub struct NoGCUnsync {
3841
vm_space: ImmortalSpace,
3942
pub space: ImmortalSpace,
4043
pub los: LargeObjectSpace,
41-
pub mmapper: &'static Mmapper,
42-
pub options: Arc<UnsafeOptionsWrapper>,
43-
pub total_pages: usize,
4444
}
4545

4646
impl Plan for NoGC {
@@ -49,53 +49,36 @@ impl Plan for NoGC {
4949
type CollectorT = NoGCCollector;
5050

5151
fn new(vm_map: &'static VMMap, mmapper: &'static Mmapper, options: Arc<UnsafeOptionsWrapper>) -> Self {
52+
let mut heap = HeapMeta::new(HEAP_START, HEAP_END);
53+
5254
NoGC {
53-
control_collector_context: ControllerCollectorContext::new(),
5455
unsync: UnsafeCell::new(NoGCUnsync {
55-
vm_space: create_vm_space(vm_map, mmapper),
56+
vm_space: create_vm_space(vm_map, mmapper, &mut heap),
5657
space: ImmortalSpace::new("nogc_space", true,
57-
VMRequest::discontiguous(), vm_map, mmapper),
58-
los: LargeObjectSpace::new("los", true, VMRequest::discontiguous(), vm_map, mmapper),
59-
mmapper,
60-
options,
61-
total_pages: 0,
62-
}
63-
),
58+
VMRequest::discontiguous(), vm_map, mmapper, &mut heap),
59+
los: LargeObjectSpace::new("los", true, VMRequest::discontiguous(), vm_map, mmapper, &mut heap),
60+
}),
61+
common: CommonPlan::new(vm_map, mmapper, options, heap),
6462
}
6563
}
6664

6765
unsafe fn gc_init(&self, heap_size: usize, vm_map: &'static VMMap) {
68-
vm_map.finalize_static_space_map();
66+
vm_map.finalize_static_space_map(self.common.heap.get_discontig_start(), self.common.heap.get_discontig_end());
67+
6968
let unsync = &mut *self.unsync.get();
70-
unsync.total_pages = bytes_to_pages(heap_size);
69+
self.common.heap.total_pages.store(bytes_to_pages(heap_size), Ordering::Relaxed);
7170
// FIXME correctly initialize spaces based on options
7271
unsync.vm_space.init(vm_map);
7372
unsync.space.init(vm_map);
7473
unsync.los.init(vm_map);
75-
76-
// These VMs require that the controller thread is started by the VM itself.
77-
// (Usually because it calls into VM code that accesses the TLS.)
78-
if !(cfg!(feature = "jikesrvm") || cfg!(feature = "openjdk")) {
79-
thread::spawn(|| {
80-
::plan::plan::CONTROL_COLLECTOR_CONTEXT.run(OpaquePointer::UNINITIALIZED )
81-
});
82-
}
83-
}
84-
85-
fn mmapper(&self) -> &'static Mmapper {
86-
let unsync = unsafe { &*self.unsync.get() };
87-
unsync.mmapper
8874
}
8975

90-
fn options(&self) -> &Options {
91-
let unsync = unsafe { &*self.unsync.get() };
92-
&unsync.options
76+
fn common(&self) -> &CommonPlan {
77+
&self.common
9378
}
9479

95-
fn bind_mutator(&self, tls: OpaquePointer) -> *mut c_void {
96-
let unsync = unsafe { &*self.unsync.get() };
97-
Box::into_raw(Box::new(NoGCMutator::new(
98-
tls, &unsync.space, &unsync.los))) as *mut c_void
80+
fn bind_mutator(&'static self, tls: OpaquePointer) -> *mut c_void {
81+
Box::into_raw(Box::new(NoGCMutator::new(tls, self))) as *mut c_void
9982
}
10083

10184
fn will_never_move(&self, object: ObjectReference) -> bool {
@@ -104,11 +87,6 @@ impl Plan for NoGC {
10487

10588
unsafe fn collection_phase(&self, tls: OpaquePointer, phase: &Phase) {}
10689

107-
fn get_total_pages(&self) -> usize {
108-
let unsync = unsafe { &*self.unsync.get() };
109-
unsync.total_pages
110-
}
111-
11290
fn get_pages_used(&self) -> usize {
11391
let unsync = unsafe { &*self.unsync.get() };
11492
unsync.space.reserved_pages() + unsync.los.reserved_pages()
@@ -139,7 +117,7 @@ impl Plan for NoGC {
139117
unsync.vm_space.in_space(address.to_object_reference()) ||
140118
unsync.los.in_space(address.to_object_reference())
141119
} {
142-
return unsync.mmapper.address_is_mapped(address);
120+
return self.common.mmapper.address_is_mapped(address);
143121
} else {
144122
return false;
145123
}
@@ -158,4 +136,16 @@ impl Plan for NoGC {
158136
}
159137
return true;
160138
}
139+
}
140+
141+
impl NoGC {
142+
pub fn get_immortal_space(&self) -> &'static ImmortalSpace {
143+
let unsync = unsafe { &*self.unsync.get() };
144+
&unsync.space
145+
}
146+
147+
pub fn get_los(&self) -> &'static LargeObjectSpace {
148+
let unsync = unsafe { &*self.unsync.get() };
149+
&unsync.los
150+
}
161151
}

src/plan/nogc/nogcmutator.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ use ::util::heap::MonotonePageResource;
1010
use ::mmtk::SINGLETON;
1111
use ::util::OpaquePointer;
1212
use libc::c_void;
13+
use plan::nogc::NoGC;
1314

1415
#[repr(C)]
1516
pub struct NoGCMutator {
1617
// ImmortalLocal
1718
nogc: BumpAllocator<MonotonePageResource<ImmortalSpace>>,
18-
los: LargeObjectAllocator
19+
los: LargeObjectAllocator,
1920
}
2021

2122
impl MutatorContext for NoGCMutator {
@@ -56,10 +57,10 @@ impl MutatorContext for NoGCMutator {
5657
}
5758

5859
impl NoGCMutator {
59-
pub fn new(tls: OpaquePointer, space: &'static ImmortalSpace, los: &'static LargeObjectSpace) -> Self {
60+
pub fn new(tls: OpaquePointer, plan: &'static NoGC) -> Self {
6061
NoGCMutator {
61-
nogc: BumpAllocator::new(tls, Some(space)),
62-
los: LargeObjectAllocator::new(tls, Some(los))
62+
nogc: BumpAllocator::new(tls, Some(plan.get_immortal_space()), plan),
63+
los: LargeObjectAllocator::new(tls, Some(plan.get_los()), plan),
6364
}
6465
}
6566
}

src/plan/phase.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ impl PhaseManager {
144144
let order = collector.rendezvous();
145145
let primary = order == 0;
146146
if primary && resume {
147-
plan::plan::set_gc_status(plan::plan::GcStatus::GcProper);
147+
plan.common().set_gc_status(plan::plan::GcStatus::GcProper);
148148
}
149149
let mut is_even_phase = true;
150150
if primary {

0 commit comments

Comments
 (0)