Skip to content

Commit 22fa492

Browse files
committed
Edge trait
Note that this commit does not add support for compressed OOPs.
1 parent 040da09 commit 22fa492

File tree

4 files changed

+111
-31
lines changed

4 files changed

+111
-31
lines changed

mmtk/src/abi.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,86 @@ use mmtk::util::constants::*;
33
use mmtk::util::conversions;
44
use mmtk::util::ObjectReference;
55
use mmtk::util::{Address, OpaquePointer};
6+
use mmtk::vm::edge_shape::Edge;
7+
use mmtk::vm::edge_shape::SimpleEdge;
68
use std::ffi::CStr;
79
use std::fmt;
10+
use std::sync::atomic::AtomicU32;
11+
use std::sync::atomic::Ordering;
812
use std::{mem, slice};
913

14+
#[derive(Clone, Copy)]
15+
pub struct CompressedOopEdge {
16+
slot_addr: *mut AtomicU32,
17+
}
18+
19+
unsafe impl Send for CompressedOopEdge {}
20+
21+
impl CompressedOopEdge {
22+
pub fn from_address(address: Address) -> Self {
23+
Self { slot_addr: address.to_mut_ptr() }
24+
}
25+
26+
pub fn as_address(&self) -> Address {
27+
Address::from_mut_ptr(self.slot_addr)
28+
}
29+
}
30+
31+
impl Edge for CompressedOopEdge {
32+
fn load(&self) -> ObjectReference {
33+
let compressed = unsafe { (*self.slot_addr).load(Ordering::Relaxed) };
34+
let expanded = (compressed as usize) << 3;
35+
unsafe { Address::from_usize(expanded).to_object_reference() }
36+
}
37+
38+
fn store(&self, object: ObjectReference) {
39+
let expanded = object.to_address().as_usize();
40+
let compressed = (expanded >> 3) as u32;
41+
unsafe { (*self.slot_addr).store(compressed, Ordering::Relaxed) }
42+
}
43+
}
44+
45+
#[derive(Clone, Copy)]
46+
pub enum OpenJDKEdge {
47+
Simple(SimpleEdge),
48+
Compressed(CompressedOopEdge),
49+
}
50+
51+
unsafe impl Send for OpenJDKEdge {}
52+
53+
impl OpenJDKEdge {
54+
#[inline(always)]
55+
pub fn simple_from_addr(edge: Address) -> Self {
56+
Self::Simple(SimpleEdge::from_address(edge))
57+
}
58+
59+
#[inline(always)]
60+
pub fn from_oop_ref(oop_ref: &Oop) -> Self {
61+
Self::Simple(SimpleEdge::from_address(Address::from_ref(oop_ref)))
62+
}
63+
64+
#[inline(always)]
65+
pub fn compressed_from_addr(edge: Address) -> Self {
66+
Self::Compressed(CompressedOopEdge::from_address(edge))
67+
}
68+
}
69+
70+
impl Edge for OpenJDKEdge {
71+
fn load(&self) -> ObjectReference {
72+
match self {
73+
Self::Simple(s) => s.load(),
74+
Self::Compressed(c) => c.load(),
75+
}
76+
}
77+
78+
fn store(&self, object: ObjectReference) {
79+
match self {
80+
Self::Simple(s) => s.store(object),
81+
Self::Compressed(c) => c.store(object),
82+
}
83+
}
84+
}
85+
1086
#[repr(i32)]
1187
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
1288
#[allow(dead_code)]

mmtk/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ extern crate once_cell;
66

77
use std::ptr::null_mut;
88

9+
use abi::OpenJDKEdge;
910
use libc::{c_char, c_void, uintptr_t};
1011
use mmtk::util::alloc::AllocationError;
1112
use mmtk::util::opaque_pointer::*;
@@ -103,6 +104,7 @@ impl VMBinding for OpenJDK {
103104
type VMCollection = collection::VMCollection;
104105
type VMActivePlan = active_plan::VMActivePlan;
105106
type VMReferenceGlue = reference_glue::VMReferenceGlue;
107+
type VMEdge = OpenJDKEdge;
106108
}
107109

108110
lazy_static! {

mmtk/src/object_scanning.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,28 @@ use super::abi::*;
22
use super::UPCALLS;
33
use mmtk::util::constants::*;
44
use mmtk::util::opaque_pointer::*;
5-
use mmtk::util::{Address, ObjectReference};
5+
use mmtk::util::ObjectReference;
66
use mmtk::vm::EdgeVisitor;
77
use std::{mem, slice};
88

99
trait OopIterate: Sized {
10-
fn oop_iterate(&self, oop: Oop, closure: &mut impl EdgeVisitor);
10+
fn oop_iterate(&self, oop: Oop, closure: &mut impl EdgeVisitor<OpenJDKEdge>);
1111
}
1212

1313
impl OopIterate for OopMapBlock {
1414
#[inline]
15-
fn oop_iterate(&self, oop: Oop, closure: &mut impl EdgeVisitor) {
15+
fn oop_iterate(&self, oop: Oop, closure: &mut impl EdgeVisitor<OpenJDKEdge>) {
1616
let start = oop.get_field_address(self.offset);
1717
for i in 0..self.count as usize {
1818
let edge = start + (i << LOG_BYTES_IN_ADDRESS);
19-
closure.visit_edge(edge);
19+
closure.visit_edge(OpenJDKEdge::simple_from_addr(edge));
2020
}
2121
}
2222
}
2323

2424
impl OopIterate for InstanceKlass {
2525
#[inline]
26-
fn oop_iterate(&self, oop: Oop, closure: &mut impl EdgeVisitor) {
26+
fn oop_iterate(&self, oop: Oop, closure: &mut impl EdgeVisitor<OpenJDKEdge>) {
2727
let oop_maps = self.nonstatic_oop_maps();
2828
for map in oop_maps {
2929
map.oop_iterate(oop, closure)
@@ -33,7 +33,7 @@ impl OopIterate for InstanceKlass {
3333

3434
impl OopIterate for InstanceMirrorKlass {
3535
#[inline]
36-
fn oop_iterate(&self, oop: Oop, closure: &mut impl EdgeVisitor) {
36+
fn oop_iterate(&self, oop: Oop, closure: &mut impl EdgeVisitor<OpenJDKEdge>) {
3737
self.instance_klass.oop_iterate(oop, closure);
3838
// if (Devirtualizer::do_metadata(closure)) {
3939
// Klass* klass = java_lang_Class::as_Klass(obj);
@@ -67,14 +67,14 @@ impl OopIterate for InstanceMirrorKlass {
6767
let len = Self::static_oop_field_count(oop);
6868
let slice = unsafe { slice::from_raw_parts(start, len as _) };
6969
for oop in slice {
70-
closure.visit_edge(Address::from_ref(oop as &Oop));
70+
closure.visit_edge(OpenJDKEdge::from_oop_ref(oop));
7171
}
7272
}
7373
}
7474

7575
impl OopIterate for InstanceClassLoaderKlass {
7676
#[inline]
77-
fn oop_iterate(&self, oop: Oop, closure: &mut impl EdgeVisitor) {
77+
fn oop_iterate(&self, oop: Oop, closure: &mut impl EdgeVisitor<OpenJDKEdge>) {
7878
self.instance_klass.oop_iterate(oop, closure);
7979
// if (Devirtualizer::do_metadata(closure)) {
8080
// ClassLoaderData* cld = java_lang_ClassLoader::loader_data(obj);
@@ -88,25 +88,25 @@ impl OopIterate for InstanceClassLoaderKlass {
8888

8989
impl OopIterate for ObjArrayKlass {
9090
#[inline]
91-
fn oop_iterate(&self, oop: Oop, closure: &mut impl EdgeVisitor) {
91+
fn oop_iterate(&self, oop: Oop, closure: &mut impl EdgeVisitor<OpenJDKEdge>) {
9292
let array = unsafe { oop.as_array_oop() };
9393
for oop in unsafe { array.data::<Oop>(BasicType::T_OBJECT) } {
94-
closure.visit_edge(Address::from_ref(oop as &Oop));
94+
closure.visit_edge(OpenJDKEdge::from_oop_ref(oop));
9595
}
9696
}
9797
}
9898

9999
impl OopIterate for TypeArrayKlass {
100100
#[inline]
101-
fn oop_iterate(&self, _oop: Oop, _closure: &mut impl EdgeVisitor) {
101+
fn oop_iterate(&self, _oop: Oop, _closure: &mut impl EdgeVisitor<OpenJDKEdge>) {
102102
// Performance tweak: We skip processing the klass pointer since all
103103
// TypeArrayKlasses are guaranteed processed via the null class loader.
104104
}
105105
}
106106

107107
impl OopIterate for InstanceRefKlass {
108108
#[inline]
109-
fn oop_iterate(&self, oop: Oop, closure: &mut impl EdgeVisitor) {
109+
fn oop_iterate(&self, oop: Oop, closure: &mut impl EdgeVisitor<OpenJDKEdge>) {
110110
use crate::abi::*;
111111
use crate::api::{add_phantom_candidate, add_soft_candidate, add_weak_candidate};
112112
self.instance_klass.oop_iterate(oop, closure);
@@ -139,23 +139,23 @@ impl InstanceRefKlass {
139139
!*SINGLETON.get_options().no_reference_types
140140
}
141141
#[inline]
142-
fn process_ref_as_strong(oop: Oop, closure: &mut impl EdgeVisitor) {
142+
fn process_ref_as_strong(oop: Oop, closure: &mut impl EdgeVisitor<OpenJDKEdge>) {
143143
let referent_addr = Self::referent_address(oop);
144-
closure.visit_edge(referent_addr);
144+
closure.visit_edge(OpenJDKEdge::simple_from_addr(referent_addr));
145145
let discovered_addr = Self::discovered_address(oop);
146-
closure.visit_edge(discovered_addr);
146+
closure.visit_edge(OpenJDKEdge::simple_from_addr(discovered_addr));
147147
}
148148
}
149149

150150
#[allow(unused)]
151-
fn oop_iterate_slow(oop: Oop, closure: &mut impl EdgeVisitor, tls: OpaquePointer) {
151+
fn oop_iterate_slow(oop: Oop, closure: &mut impl EdgeVisitor<OpenJDKEdge>, tls: OpaquePointer) {
152152
unsafe {
153153
((*UPCALLS).scan_object)(closure as *mut _ as _, mem::transmute(oop), tls);
154154
}
155155
}
156156

157157
#[inline]
158-
fn oop_iterate(oop: Oop, closure: &mut impl EdgeVisitor) {
158+
fn oop_iterate(oop: Oop, closure: &mut impl EdgeVisitor<OpenJDKEdge>) {
159159
let klass_id = oop.klass.id;
160160
debug_assert!(
161161
klass_id as i32 >= 0 && (klass_id as i32) < 6,
@@ -192,7 +192,7 @@ fn oop_iterate(oop: Oop, closure: &mut impl EdgeVisitor) {
192192
}
193193

194194
#[inline]
195-
pub fn scan_object(object: ObjectReference, closure: &mut impl EdgeVisitor, _tls: VMWorkerThread) {
195+
pub fn scan_object(object: ObjectReference, closure: &mut impl EdgeVisitor<OpenJDKEdge>, _tls: VMWorkerThread) {
196196
// println!("*****scan_object(0x{:x}) -> \n 0x{:x}, 0x{:x} \n",
197197
// object,
198198
// unsafe { *(object.value() as *const usize) },

mmtk/src/scanning.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::gc_work::*;
22
use super::{NewBuffer, SINGLETON, UPCALLS};
33
use crate::OpenJDK;
4+
use crate::abi::OpenJDKEdge;
45
use mmtk::memory_manager;
56
use mmtk::scheduler::ProcessEdgesWork;
67
use mmtk::scheduler::WorkBucketStage;
@@ -19,10 +20,11 @@ pub(crate) extern "C" fn create_process_edges_work<W: ProcessEdgesWork<VM = Open
1920
) -> NewBuffer {
2021
if !ptr.is_null() {
2122
let buf = unsafe { Vec::<Address>::from_raw_parts(ptr, length, capacity) };
23+
let edges = buf.iter().copied().map(OpenJDKEdge::simple_from_addr).collect::<Vec<_>>();
2224
memory_manager::add_work_packet(
2325
&SINGLETON,
2426
WorkBucketStage::Closure,
25-
W::new(buf, true, &SINGLETON),
27+
W::new(edges, true, &SINGLETON),
2628
);
2729
}
2830
let (ptr, _, capacity) = {
@@ -39,7 +41,7 @@ impl Scanning<OpenJDK> for VMScanning {
3941
const SCAN_MUTATORS_IN_SAFEPOINT: bool = false;
4042
const SINGLE_THREAD_MUTATOR_SCANNING: bool = false;
4143

42-
fn scan_object<EV: EdgeVisitor>(
44+
fn scan_object<EV: EdgeVisitor<OpenJDKEdge>>(
4345
tls: VMWorkerThread,
4446
object: ObjectReference,
4547
edge_visitor: &mut EV,
@@ -75,17 +77,17 @@ impl Scanning<OpenJDK> for VMScanning {
7577
&SINGLETON,
7678
WorkBucketStage::Prepare,
7779
vec![
78-
Box::new(ScanUniverseRoots::<W>::new()),
79-
Box::new(ScanJNIHandlesRoots::<W>::new()),
80-
Box::new(ScanObjectSynchronizerRoots::<W>::new()),
81-
Box::new(ScanManagementRoots::<W>::new()),
82-
Box::new(ScanJvmtiExportRoots::<W>::new()),
83-
Box::new(ScanAOTLoaderRoots::<W>::new()),
84-
Box::new(ScanSystemDictionaryRoots::<W>::new()),
85-
Box::new(ScanCodeCacheRoots::<W>::new()),
86-
Box::new(ScanStringTableRoots::<W>::new()),
87-
Box::new(ScanClassLoaderDataGraphRoots::<W>::new()),
88-
Box::new(ScanWeakProcessorRoots::<W>::new()),
80+
Box::new(ScanUniverseRoots::<W>::new()) as _,
81+
Box::new(ScanJNIHandlesRoots::<W>::new()) as _,
82+
Box::new(ScanObjectSynchronizerRoots::<W>::new()) as _,
83+
Box::new(ScanManagementRoots::<W>::new()) as _,
84+
Box::new(ScanJvmtiExportRoots::<W>::new()) as _,
85+
Box::new(ScanAOTLoaderRoots::<W>::new()) as _,
86+
Box::new(ScanSystemDictionaryRoots::<W>::new()) as _,
87+
Box::new(ScanCodeCacheRoots::<W>::new()) as _,
88+
Box::new(ScanStringTableRoots::<W>::new()) as _,
89+
Box::new(ScanClassLoaderDataGraphRoots::<W>::new()) as _,
90+
Box::new(ScanWeakProcessorRoots::<W>::new()) as _,
8991
],
9092
);
9193
if !(Self::SCAN_MUTATORS_IN_SAFEPOINT && Self::SINGLE_THREAD_MUTATOR_SCANNING) {

0 commit comments

Comments
 (0)