Skip to content

Weak reference support #145

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Apr 28, 2022
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 174 additions & 0 deletions .github/scripts/ci-test-weak-ref.sh

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions .github/scripts/ci-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ cd $cur
./ci-test-assertions.sh
cd $cur
./ci-test-global-alloc-bit.sh
cd $cur
./ci-test-weak-ref.sh
13 changes: 13 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ jobs:
- name: Style checks
run: ./.github/scripts/ci-style.sh

test-weak-ref:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Setup environments
run: |
./.github/scripts/ci-checkout.sh
./.github/scripts/ci-setup.sh

# Run the tests
- name: Dacapo Tests with Weak ref
run: ./.github/scripts/ci-test-weak-ref.sh

msrv:
runs-on: ubuntu-18.04
steps:
Expand Down
2 changes: 1 addition & 1 deletion mmtk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ once_cell = "1.10.0"
# - change branch
# - change repo name
# But other changes including adding/removing whitespaces in commented lines may break the CI.
mmtk = { git = "https://github.com/mmtk/mmtk-core.git", rev = "be96a270815c0f20a169a7214eebccfe50484be4" }
mmtk = { git = "https://github.com/mmtk/mmtk-core.git", rev = "1767b5272355ceb8171148672cffa0d4aa27b2c3" }
# Uncomment the following to build locally
# mmtk = { path = "../repos/mmtk-core" }

Expand Down
14 changes: 13 additions & 1 deletion mmtk/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ pub struct InstanceKlass {
// #endif
pub idnum_allocated_count: u16,
pub init_state: u8,
pub reference_type: u8,
pub reference_type: ReferenceType,
pub this_class_index: u16,
// #if INCLUDE_JVMTI
pub jvmti_cached_class_field_map: OpaquePointer, // JvmtiCachedClassFieldMap*
Expand All @@ -154,6 +154,18 @@ pub struct InstanceKlass {
pub fields: OpaquePointer, // Array<u2>*
}

#[repr(u8)]
#[derive(Copy, Clone, Debug)]
#[allow(dead_code)]
pub enum ReferenceType {
None, // Regular class
Other, // Subclass of java/lang/ref/Reference, but not subclass of one of the classes below
Soft, // Subclass of java/lang/ref/SoftReference
Weak, // Subclass of java/lang/ref/WeakReference
Final, // Subclass of java/lang/ref/FinalReference
Phantom, // Subclass of java/lang/ref/PhantomReference
}

impl InstanceKlass {
const HEADER_SIZE: usize = mem::size_of::<Self>() / BYTES_IN_WORD;
const VTABLE_START_OFFSET: usize = Self::HEADER_SIZE * BYTES_IN_WORD;
Expand Down
12 changes: 6 additions & 6 deletions mmtk/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,18 +179,18 @@ pub extern "C" fn modify_check(object: ObjectReference) {
}

#[no_mangle]
pub extern "C" fn add_weak_candidate(reff: ObjectReference, referent: ObjectReference) {
memory_manager::add_weak_candidate(&SINGLETON, reff, referent)
pub extern "C" fn add_weak_candidate(reff: ObjectReference) {
memory_manager::add_weak_candidate(&SINGLETON, reff)
}

#[no_mangle]
pub extern "C" fn add_soft_candidate(reff: ObjectReference, referent: ObjectReference) {
memory_manager::add_soft_candidate(&SINGLETON, reff, referent)
pub extern "C" fn add_soft_candidate(reff: ObjectReference) {
memory_manager::add_soft_candidate(&SINGLETON, reff)
}

#[no_mangle]
pub extern "C" fn add_phantom_candidate(reff: ObjectReference, referent: ObjectReference) {
memory_manager::add_phantom_candidate(&SINGLETON, reff, referent)
pub extern "C" fn add_phantom_candidate(reff: ObjectReference) {
memory_manager::add_phantom_candidate(&SINGLETON, reff)
}

// The harness_begin()/end() functions are different than other API functions in terms of the thread state.
Expand Down
1 change: 1 addition & 0 deletions mmtk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ pub struct OpenJDK_Upcalls {
pub number_of_mutators: extern "C" fn() -> usize,
pub schedule_finalizer: extern "C" fn(),
pub prepare_for_roots_re_scanning: extern "C" fn(),
pub enqueue_references: extern "C" fn(objects: &[ObjectReference], len: usize),
}

pub static mut UPCALLS: *const OpenJDK_Upcalls = null_mut();
Expand Down
31 changes: 31 additions & 0 deletions mmtk/src/object_scanning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,38 @@ impl OopIterate for TypeArrayKlass {
impl OopIterate for InstanceRefKlass {
#[inline]
fn oop_iterate(&self, oop: Oop, closure: &mut impl TransitiveClosure) {
use crate::abi::*;
use crate::api::{add_phantom_candidate, add_soft_candidate, add_weak_candidate};
self.instance_klass.oop_iterate(oop, closure);

if Self::should_scan_weak_refs() {
let reference = ObjectReference::from(oop);
match self.instance_klass.reference_type {
ReferenceType::None => {
panic!("oop_iterate on InstanceRefKlass with reference_type as None")
}
ReferenceType::Weak => add_weak_candidate(reference),
ReferenceType::Soft => add_soft_candidate(reference),
ReferenceType::Phantom => add_phantom_candidate(reference),
// Process these two types normally (as if they are strong refs)
// We will handle final reference later
ReferenceType::Final | ReferenceType::Other => {
Self::process_ref_as_strong(oop, closure)
}
}
} else {
Self::process_ref_as_strong(oop, closure);
}
}
}

impl InstanceRefKlass {
#[inline]
fn should_scan_weak_refs() -> bool {
!*SINGLETON.get_options().no_reference_types
}
#[inline]
fn process_ref_as_strong(oop: Oop, closure: &mut impl TransitiveClosure) {
let referent_addr = Self::referent_address(oop);
closure.process_edge(referent_addr);
let discovered_addr = Self::discovered_address(oop);
Expand Down
23 changes: 12 additions & 11 deletions mmtk/src/reference_glue.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
use crate::abi::{InstanceRefKlass, Oop};
use crate::OpenJDK;
use crate::UPCALLS;
use mmtk::util::opaque_pointer::VMWorkerThread;
use mmtk::util::ObjectReference;
use mmtk::vm::ReferenceGlue;
use mmtk::TraceLocal;

pub struct VMReferenceGlue {}

impl ReferenceGlue<OpenJDK> for VMReferenceGlue {
fn set_referent(_reff: ObjectReference, _referent: ObjectReference) {
unimplemented!()
fn set_referent(reff: ObjectReference, referent: ObjectReference) {
let oop = Oop::from(reff);
unsafe { InstanceRefKlass::referent_address(oop).store(referent) };
}
fn get_referent(_object: ObjectReference) -> ObjectReference {
unimplemented!()
fn get_referent(object: ObjectReference) -> ObjectReference {
let oop = Oop::from(object);
unsafe { InstanceRefKlass::referent_address(oop).load::<ObjectReference>() }
}
fn process_reference<T: TraceLocal>(
_trace: &mut T,
_reference: ObjectReference,
_tls: VMWorkerThread,
) -> ObjectReference {
unimplemented!()
fn enqueue_references(references: &[ObjectReference], _tls: VMWorkerThread) {
unsafe {
((*UPCALLS).enqueue_references)(references, references.len());
}
}
}
1 change: 1 addition & 0 deletions openjdk/mmtk.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ typedef struct {
size_t (*number_of_mutators)();
void (*schedule_finalizer)();
void (*prepare_for_roots_re_scanning)();
void (*enqueue_references)(void** objects, size_t len);
} OpenJDK_Upcalls;

extern void openjdk_gc_init(OpenJDK_Upcalls *calls, size_t heap_size);
Expand Down
22 changes: 22 additions & 0 deletions openjdk/mmtkUpcalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,27 @@ static void mmtk_prepare_for_roots_re_scanning() {
#endif
}

static void mmtk_enqueue_references(void** objects, size_t len) {
if (len == 0) {
return;
}

MutexLocker x(Heap_lock);

oop prev = NULL;
for (size_t i = 0; i < len; i++) {
oop reff = (oop) objects[i];
if (prev != NULL) {
HeapAccess<AS_NO_KEEPALIVE>::oop_store_at(prev, java_lang_ref_Reference::discovered_offset, reff);
}
prev = reff;
}

oop old = Universe::swap_reference_pending_list(prev);
HeapAccess<AS_NO_KEEPALIVE>::oop_store_at(prev, java_lang_ref_Reference::discovered_offset, old);
assert(Universe::has_reference_pending_list(), "Reference pending list is empty after swap");
}

OpenJDK_Upcalls mmtk_upcalls = {
mmtk_stop_all_mutators,
mmtk_resume_mutators,
Expand Down Expand Up @@ -360,4 +381,5 @@ OpenJDK_Upcalls mmtk_upcalls = {
mmtk_number_of_mutators,
mmtk_schedule_finalizer,
mmtk_prepare_for_roots_re_scanning,
mmtk_enqueue_references
};
6 changes: 6 additions & 0 deletions openjdk/mmtkVMCompanionThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ void MMTkVMCompanionThread::run() {
_reached_state = _threads_resumed;
_lock->notify_all();
}
{
MutexLocker x(Heap_lock);
if (Universe::has_reference_pending_list()) {
Heap_lock->notify_all();
}
}
}
}

Expand Down