diff --git a/mmtk/Cargo.toml b/mmtk/Cargo.toml index b610bb2f..ddc82b91 100644 --- a/mmtk/Cargo.toml +++ b/mmtk/Cargo.toml @@ -20,7 +20,7 @@ lazy_static = "1.1" # - 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 = "4ebb6b68f54a55bf8794ea01db3f2d0f28d15f4d" } +mmtk = { git = "https://github.com/mmtk/mmtk-core.git", rev = "29afb0c2fc8896db95e967062a892d39589bae4d" } # Uncomment the following to build locally # mmtk = { path = "../repos/mmtk-core" } diff --git a/mmtk/src/api.rs b/mmtk/src/api.rs index 5dd69ec6..7c8b3adc 100644 --- a/mmtk/src/api.rs +++ b/mmtk/src/api.rs @@ -5,6 +5,7 @@ use crate::UPCALLS; use libc::c_char; use mmtk::memory_manager; use mmtk::plan::BarrierSelector; +use mmtk::scheduler::GCController; use mmtk::scheduler::GCWorker; use mmtk::util::alloc::AllocatorSelector; use mmtk::util::opaque_pointer::*; @@ -49,11 +50,6 @@ pub extern "C" fn openjdk_gc_init(calls: *const OpenJDK_Upcalls, heap_size: usiz memory_manager::gc_init(singleton_mut, heap_size); } -#[no_mangle] -pub extern "C" fn start_control_collector(tls: VMWorkerThread) { - memory_manager::start_control_collector(&SINGLETON, tls); -} - #[no_mangle] pub extern "C" fn bind_mutator(tls: VMMutatorThread) -> *mut Mutator { Box::into_raw(memory_manager::bind_mutator(&SINGLETON, tls)) @@ -116,12 +112,23 @@ pub extern "C" fn will_never_move(object: ObjectReference) -> bool { !object.is_movable() } +#[no_mangle] +// We trust the gc_collector pointer is valid. +#[allow(clippy::not_unsafe_ptr_arg_deref)] +pub extern "C" fn start_control_collector( + tls: VMWorkerThread, + gc_controller: *mut GCController, +) { + let mut gc_controller = unsafe { Box::from_raw(gc_controller) }; + memory_manager::start_control_collector(&SINGLETON, tls, &mut gc_controller); +} + #[no_mangle] // We trust the worker pointer is valid. #[allow(clippy::not_unsafe_ptr_arg_deref)] pub extern "C" fn start_worker(tls: VMWorkerThread, worker: *mut GCWorker) { let mut worker = unsafe { Box::from_raw(worker) }; - memory_manager::start_worker::(tls, &mut worker, &SINGLETON) + memory_manager::start_worker::(&SINGLETON, tls, &mut worker) } #[no_mangle] diff --git a/mmtk/src/collection.rs b/mmtk/src/collection.rs index 59c8c978..f7da78a6 100644 --- a/mmtk/src/collection.rs +++ b/mmtk/src/collection.rs @@ -1,7 +1,7 @@ -use mmtk::scheduler::{GCWorker, WorkBucketStage}; +use mmtk::scheduler::WorkBucketStage; use mmtk::scheduler::{ProcessEdgesWork, ScanStackRoot}; use mmtk::util::opaque_pointer::*; -use mmtk::vm::{Collection, Scanning, VMBinding}; +use mmtk::vm::{Collection, GCThreadContext, Scanning, VMBinding}; use mmtk::{Mutator, MutatorContext}; use crate::OpenJDK; @@ -19,6 +19,9 @@ extern "C" fn create_mutator_scan_work>( ); } +const GC_THREAD_KIND_CONTROLLER: libc::c_int = 0; +const GC_THREAD_KIND_WORKER: libc::c_int = 1; + impl Collection for VMCollection { /// With the presence of the "VM companion thread", /// the OpenJDK binding allows any MMTk GC thread to stop/start the world. @@ -49,14 +52,18 @@ impl Collection for VMCollection { } } - fn spawn_worker_thread(tls: VMThread, ctx: Option>>) { - let ctx_ptr = if let Some(r) = ctx { - Box::into_raw(r) - } else { - std::ptr::null_mut() + fn spawn_gc_thread(tls: VMThread, ctx: GCThreadContext) { + let (ctx_ptr, kind) = match ctx { + GCThreadContext::Controller(c) => ( + Box::into_raw(c) as *mut libc::c_void, + GC_THREAD_KIND_CONTROLLER, + ), + GCThreadContext::Worker(w) => { + (Box::into_raw(w) as *mut libc::c_void, GC_THREAD_KIND_WORKER) + } }; unsafe { - ((*UPCALLS).spawn_worker_thread)(tls, ctx_ptr as usize as _); + ((*UPCALLS).spawn_gc_thread)(tls, kind, ctx_ptr); } } diff --git a/mmtk/src/lib.rs b/mmtk/src/lib.rs index bec61235..7f52b961 100644 --- a/mmtk/src/lib.rs +++ b/mmtk/src/lib.rs @@ -13,7 +13,6 @@ extern crate lazy_static; use std::ptr::null_mut; use libc::{c_char, c_void, uintptr_t}; -use mmtk::scheduler::GCWorker; use mmtk::util::opaque_pointer::*; use mmtk::util::{Address, ObjectReference}; use mmtk::vm::VMBinding; @@ -45,7 +44,7 @@ pub struct OpenJDK_Upcalls { create_stack_scan_work: *const extern "C" fn(&'static mut Mutator), ), pub resume_mutators: extern "C" fn(tls: VMWorkerThread), - pub spawn_worker_thread: extern "C" fn(tls: VMThread, ctx: *mut GCWorker), + pub spawn_gc_thread: extern "C" fn(tls: VMThread, kind: libc::c_int, ctx: *mut libc::c_void), pub block_for_gc: extern "C" fn(), pub get_next_mutator: extern "C" fn() -> *mut Mutator, pub reset_mutator_iterator: extern "C" fn(), diff --git a/openjdk/mmtk.h b/openjdk/mmtk.h index 61a108a2..0d3a9c2f 100644 --- a/openjdk/mmtk.h +++ b/openjdk/mmtk.h @@ -78,7 +78,7 @@ extern bool process_bulk(char* options); extern void scan_region(); extern void handle_user_collection_request(void *tls); -extern void start_control_collector(void *tls); +extern void start_control_collector(void *tls, void *context); extern void start_worker(void *tls, void* worker); /** @@ -100,7 +100,7 @@ typedef NewBuffer (*ProcessEdgesFn)(void** buf, size_t len, size_t cap); typedef struct { void (*stop_all_mutators) (void *tls, void (*create_stack_scan_work)(void* mutator)); void (*resume_mutators) (void *tls); - void (*spawn_collector_thread) (void *tls, void *ctx); + void (*spawn_collector_thread) (void *tls, int kind, void *ctx); void (*block_for_gc) (); void* (*get_next_mutator) (); void (*reset_mutator_iterator) (); diff --git a/openjdk/mmtkContextThread.cpp b/openjdk/mmtkContextThread.cpp index 6d5cee2a..6ff533c6 100644 --- a/openjdk/mmtkContextThread.cpp +++ b/openjdk/mmtkContextThread.cpp @@ -26,11 +26,11 @@ #include "mmtk.h" #include "mmtkContextThread.hpp" -MMTkContextThread::MMTkContextThread() : NamedThread() { +MMTkContextThread::MMTkContextThread(void *context) : NamedThread(), context_(context) { set_name("MMTk Controller Context Thread"); } void MMTkContextThread::run() { this->initialize_named_thread(); - start_control_collector((void*) this); + start_control_collector((void*) this, context_); } diff --git a/openjdk/mmtkContextThread.hpp b/openjdk/mmtkContextThread.hpp index 4a3c55c3..87962070 100644 --- a/openjdk/mmtkContextThread.hpp +++ b/openjdk/mmtkContextThread.hpp @@ -29,9 +29,10 @@ #include "runtime/thread.hpp" class MMTkContextThread: public NamedThread { + void* context_; public: // Constructor - MMTkContextThread(); + MMTkContextThread(void* context); // No destruction allowed ~MMTkContextThread() { diff --git a/openjdk/mmtkUpcalls.cpp b/openjdk/mmtkUpcalls.cpp index 1ab5fbc8..9a831dfc 100644 --- a/openjdk/mmtkUpcalls.cpp +++ b/openjdk/mmtkUpcalls.cpp @@ -86,22 +86,33 @@ static void mmtk_resume_mutators(void *tls) { log_debug(gc)("Mutators notified."); } -static void mmtk_spawn_collector_thread(void* tls, void* ctx) { - if (ctx == NULL) { - MMTkContextThread* t = new MMTkContextThread(); - if (!os::create_thread(t, os::pgc_thread)) { - printf("Failed to create thread"); - guarantee(false, "panic"); +static const int GC_THREAD_KIND_CONTROLLER = 0; +static const int GC_THREAD_KIND_WORKER = 1; +static void mmtk_spawn_collector_thread(void* tls, int kind, void* ctx) { + switch (kind) { + case GC_THREAD_KIND_CONTROLLER: { + MMTkContextThread* t = new MMTkContextThread(ctx); + if (!os::create_thread(t, os::pgc_thread)) { + printf("Failed to create thread"); + guarantee(false, "panic"); + } + os::start_thread(t); + break; + } + case GC_THREAD_KIND_WORKER: { + MMTkHeap::heap()->new_collector_thread(); + MMTkCollectorThread* t = new MMTkCollectorThread(ctx); + if (!os::create_thread(t, os::pgc_thread)) { + printf("Failed to create thread"); + guarantee(false, "panic"); + } + os::start_thread(t); + break; } - os::start_thread(t); - } else { - MMTkHeap::heap()->new_collector_thread(); - MMTkCollectorThread* t = new MMTkCollectorThread(ctx); - if (!os::create_thread(t, os::pgc_thread)) { - printf("Failed to create thread"); + default: { + printf("Unexpected thread kind: %d\n", kind); guarantee(false, "panic"); } - os::start_thread(t); } }