Skip to content

Commit e8da68f

Browse files
authored
Weak reference support (#145)
This adds weak reference support, and updates MMTk core to mmtk/mmtk-core#564. * if weak reference is enabled in MMTk, we will add weak references during our tracing. Otherwise, still treat them as strong references. * implement new changes in mmtk/mmtk-core#564 * add test with weak reference enabled (by default, it is disabled).
1 parent 67b6508 commit e8da68f

File tree

12 files changed

+283
-19
lines changed

12 files changed

+283
-19
lines changed

.github/scripts/ci-test-weak-ref.sh

Lines changed: 174 additions & 0 deletions
Large diffs are not rendered by default.

.github/scripts/ci-test.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ cd $cur
77
./ci-test-assertions.sh
88
cd $cur
99
./ci-test-global-alloc-bit.sh
10+
cd $cur
11+
./ci-test-weak-ref.sh

.github/workflows/ci.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,19 @@ jobs:
2525
- name: Style checks
2626
run: ./.github/scripts/ci-style.sh
2727

28+
test-weak-ref:
29+
runs-on: ubuntu-18.04
30+
steps:
31+
- uses: actions/checkout@v2
32+
- name: Setup environments
33+
run: |
34+
./.github/scripts/ci-checkout.sh
35+
./.github/scripts/ci-setup.sh
36+
37+
# Run the tests
38+
- name: Dacapo Tests with Weak ref
39+
run: ./.github/scripts/ci-test-weak-ref.sh
40+
2841
msrv:
2942
runs-on: ubuntu-18.04
3043
steps:

mmtk/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ once_cell = "1.10.0"
2828
# - change branch
2929
# - change repo name
3030
# But other changes including adding/removing whitespaces in commented lines may break the CI.
31-
mmtk = { git = "https://github.com/mmtk/mmtk-core.git", rev = "0babba20290d3c4e4cdb2a83284aa7204c9a23cc" }
31+
mmtk = { git = "https://github.com/mmtk/mmtk-core.git", rev = "21176127d1f0493444fd901ea7277099a24bcecc" }
3232
# Uncomment the following to build locally
3333
# mmtk = { path = "../repos/mmtk-core" }
3434

mmtk/src/abi.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ pub struct InstanceKlass {
138138
// #endif
139139
pub idnum_allocated_count: u16,
140140
pub init_state: u8,
141-
pub reference_type: u8,
141+
pub reference_type: ReferenceType,
142142
pub this_class_index: u16,
143143
// #if INCLUDE_JVMTI
144144
pub jvmti_cached_class_field_map: OpaquePointer, // JvmtiCachedClassFieldMap*
@@ -154,6 +154,18 @@ pub struct InstanceKlass {
154154
pub fields: OpaquePointer, // Array<u2>*
155155
}
156156

157+
#[repr(u8)]
158+
#[derive(Copy, Clone, Debug)]
159+
#[allow(dead_code)]
160+
pub enum ReferenceType {
161+
None, // Regular class
162+
Other, // Subclass of java/lang/ref/Reference, but not subclass of one of the classes below
163+
Soft, // Subclass of java/lang/ref/SoftReference
164+
Weak, // Subclass of java/lang/ref/WeakReference
165+
Final, // Subclass of java/lang/ref/FinalReference
166+
Phantom, // Subclass of java/lang/ref/PhantomReference
167+
}
168+
157169
impl InstanceKlass {
158170
const HEADER_SIZE: usize = mem::size_of::<Self>() / BYTES_IN_WORD;
159171
const VTABLE_START_OFFSET: usize = Self::HEADER_SIZE * BYTES_IN_WORD;

mmtk/src/api.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -179,18 +179,18 @@ pub extern "C" fn modify_check(object: ObjectReference) {
179179
}
180180

181181
#[no_mangle]
182-
pub extern "C" fn add_weak_candidate(reff: ObjectReference, referent: ObjectReference) {
183-
memory_manager::add_weak_candidate(&SINGLETON, reff, referent)
182+
pub extern "C" fn add_weak_candidate(reff: ObjectReference) {
183+
memory_manager::add_weak_candidate(&SINGLETON, reff)
184184
}
185185

186186
#[no_mangle]
187-
pub extern "C" fn add_soft_candidate(reff: ObjectReference, referent: ObjectReference) {
188-
memory_manager::add_soft_candidate(&SINGLETON, reff, referent)
187+
pub extern "C" fn add_soft_candidate(reff: ObjectReference) {
188+
memory_manager::add_soft_candidate(&SINGLETON, reff)
189189
}
190190

191191
#[no_mangle]
192-
pub extern "C" fn add_phantom_candidate(reff: ObjectReference, referent: ObjectReference) {
193-
memory_manager::add_phantom_candidate(&SINGLETON, reff, referent)
192+
pub extern "C" fn add_phantom_candidate(reff: ObjectReference) {
193+
memory_manager::add_phantom_candidate(&SINGLETON, reff)
194194
}
195195

196196
// The harness_begin()/end() functions are different than other API functions in terms of the thread state.

mmtk/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ pub struct OpenJDK_Upcalls {
7777
pub number_of_mutators: extern "C" fn() -> usize,
7878
pub schedule_finalizer: extern "C" fn(),
7979
pub prepare_for_roots_re_scanning: extern "C" fn(),
80+
pub enqueue_references: extern "C" fn(objects: *const ObjectReference, len: usize),
8081
}
8182

8283
pub static mut UPCALLS: *const OpenJDK_Upcalls = null_mut();

mmtk/src/object_scanning.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,39 @@ impl OopIterate for TypeArrayKlass {
107107
impl OopIterate for InstanceRefKlass {
108108
#[inline]
109109
fn oop_iterate(&self, oop: Oop, closure: &mut impl EdgeVisitor) {
110+
use crate::abi::*;
111+
use crate::api::{add_phantom_candidate, add_soft_candidate, add_weak_candidate};
110112
self.instance_klass.oop_iterate(oop, closure);
113+
114+
if Self::should_scan_weak_refs() {
115+
let reference = ObjectReference::from(oop);
116+
match self.instance_klass.reference_type {
117+
ReferenceType::None => {
118+
panic!("oop_iterate on InstanceRefKlass with reference_type as None")
119+
}
120+
ReferenceType::Weak => add_weak_candidate(reference),
121+
ReferenceType::Soft => add_soft_candidate(reference),
122+
ReferenceType::Phantom => add_phantom_candidate(reference),
123+
// Process these two types normally (as if they are strong refs)
124+
// We will handle final reference later
125+
ReferenceType::Final | ReferenceType::Other => {
126+
Self::process_ref_as_strong(oop, closure)
127+
}
128+
}
129+
} else {
130+
Self::process_ref_as_strong(oop, closure);
131+
}
132+
}
133+
}
134+
135+
impl InstanceRefKlass {
136+
#[inline]
137+
fn should_scan_weak_refs() -> bool {
138+
use SINGLETON;
139+
!*SINGLETON.get_options().no_reference_types
140+
}
141+
#[inline]
142+
fn process_ref_as_strong(oop: Oop, closure: &mut impl EdgeVisitor) {
111143
let referent_addr = Self::referent_address(oop);
112144
closure.visit_edge(referent_addr);
113145
let discovered_addr = Self::discovered_address(oop);

mmtk/src/reference_glue.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
1+
use crate::abi::{InstanceRefKlass, Oop};
12
use crate::OpenJDK;
3+
use crate::UPCALLS;
24
use mmtk::util::opaque_pointer::VMWorkerThread;
35
use mmtk::util::ObjectReference;
46
use mmtk::vm::ReferenceGlue;
5-
use mmtk::TraceLocal;
67

78
pub struct VMReferenceGlue {}
89

910
impl ReferenceGlue<OpenJDK> for VMReferenceGlue {
10-
fn set_referent(_reff: ObjectReference, _referent: ObjectReference) {
11-
unimplemented!()
11+
fn set_referent(reff: ObjectReference, referent: ObjectReference) {
12+
let oop = Oop::from(reff);
13+
unsafe { InstanceRefKlass::referent_address(oop).store(referent) };
1214
}
13-
fn get_referent(_object: ObjectReference) -> ObjectReference {
14-
unimplemented!()
15+
fn get_referent(object: ObjectReference) -> ObjectReference {
16+
let oop = Oop::from(object);
17+
unsafe { InstanceRefKlass::referent_address(oop).load::<ObjectReference>() }
1518
}
16-
fn process_reference<T: TraceLocal>(
17-
_trace: &mut T,
18-
_reference: ObjectReference,
19-
_tls: VMWorkerThread,
20-
) -> ObjectReference {
21-
unimplemented!()
19+
fn enqueue_references(references: &[ObjectReference], _tls: VMWorkerThread) {
20+
unsafe {
21+
((*UPCALLS).enqueue_references)(references.as_ptr(), references.len());
22+
}
2223
}
2324
}

openjdk/mmtk.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ typedef struct {
144144
size_t (*number_of_mutators)();
145145
void (*schedule_finalizer)();
146146
void (*prepare_for_roots_re_scanning)();
147+
void (*enqueue_references)(void** objects, size_t len);
147148
} OpenJDK_Upcalls;
148149

149150
extern void openjdk_gc_init(OpenJDK_Upcalls *calls, size_t heap_size);

openjdk/mmtkUpcalls.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,27 @@ static void mmtk_prepare_for_roots_re_scanning() {
319319
#endif
320320
}
321321

322+
static void mmtk_enqueue_references(void** objects, size_t len) {
323+
if (len == 0) {
324+
return;
325+
}
326+
327+
MutexLocker x(Heap_lock);
328+
329+
oop prev = NULL;
330+
for (size_t i = 0; i < len; i++) {
331+
oop reff = (oop) objects[i];
332+
if (prev != NULL) {
333+
HeapAccess<AS_NO_KEEPALIVE>::oop_store_at(prev, java_lang_ref_Reference::discovered_offset, reff);
334+
}
335+
prev = reff;
336+
}
337+
338+
oop old = Universe::swap_reference_pending_list(prev);
339+
HeapAccess<AS_NO_KEEPALIVE>::oop_store_at(prev, java_lang_ref_Reference::discovered_offset, old);
340+
assert(Universe::has_reference_pending_list(), "Reference pending list is empty after swap");
341+
}
342+
322343
OpenJDK_Upcalls mmtk_upcalls = {
323344
mmtk_stop_all_mutators,
324345
mmtk_resume_mutators,
@@ -360,4 +381,5 @@ OpenJDK_Upcalls mmtk_upcalls = {
360381
mmtk_number_of_mutators,
361382
mmtk_schedule_finalizer,
362383
mmtk_prepare_for_roots_re_scanning,
384+
mmtk_enqueue_references
363385
};

openjdk/mmtkVMCompanionThread.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ void MMTkVMCompanionThread::run() {
7676
_reached_state = _threads_resumed;
7777
_lock->notify_all();
7878
}
79+
{
80+
MutexLocker x(Heap_lock);
81+
if (Universe::has_reference_pending_list()) {
82+
Heap_lock->notify_all();
83+
}
84+
}
7985
}
8086
}
8187

0 commit comments

Comments
 (0)