-
Notifications
You must be signed in to change notification settings - Fork 39
Fix root scanning #165
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
Fix root scanning #165
Changes from 7 commits
fa1a26e
084a127
f6e121d
55f1317
07f180d
d359b0b
7ce923f
334e0ac
8aadcbc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,8 +3,12 @@ extern crate mmtk; | |
#[macro_use] | ||
extern crate lazy_static; | ||
extern crate once_cell; | ||
extern crate spin; | ||
|
||
use std::collections::HashMap; | ||
use std::ptr::null_mut; | ||
use std::sync::atomic::AtomicUsize; | ||
use std::sync::Mutex; | ||
|
||
use libc::{c_char, c_void, uintptr_t}; | ||
use mmtk::util::alloc::AllocationError; | ||
|
@@ -58,9 +62,6 @@ pub struct OpenJDK_Upcalls { | |
pub out_of_memory: extern "C" fn(tls: VMThread, err_kind: AllocationError), | ||
pub get_next_mutator: extern "C" fn() -> *mut Mutator<OpenJDK>, | ||
pub reset_mutator_iterator: extern "C" fn(), | ||
pub compute_static_roots: extern "C" fn(trace: *mut c_void, tls: OpaquePointer), | ||
pub compute_global_roots: extern "C" fn(trace: *mut c_void, tls: OpaquePointer), | ||
pub compute_thread_roots: extern "C" fn(trace: *mut c_void, tls: OpaquePointer), | ||
pub scan_object: extern "C" fn(trace: *mut c_void, object: ObjectReference, tls: OpaquePointer), | ||
pub dump_object: extern "C" fn(object: ObjectReference), | ||
pub get_object_size: extern "C" fn(object: ObjectReference) -> usize, | ||
|
@@ -74,8 +75,8 @@ pub struct OpenJDK_Upcalls { | |
pub referent_offset: extern "C" fn() -> i32, | ||
pub discovered_offset: extern "C" fn() -> i32, | ||
pub dump_object_string: extern "C" fn(object: ObjectReference) -> *const c_char, | ||
pub scan_thread_roots: extern "C" fn(closure: EdgesClosure), | ||
pub scan_thread_root: extern "C" fn(closure: EdgesClosure, tls: VMMutatorThread), | ||
pub scan_all_thread_roots: extern "C" fn(closure: EdgesClosure), | ||
pub scan_thread_roots: extern "C" fn(closure: EdgesClosure, tls: VMMutatorThread), | ||
pub scan_universe_roots: extern "C" fn(closure: EdgesClosure), | ||
pub scan_jni_handle_roots: extern "C" fn(closure: EdgesClosure), | ||
pub scan_object_synchronizer_roots: extern "C" fn(closure: EdgesClosure), | ||
|
@@ -142,3 +143,11 @@ lazy_static! { | |
#[no_mangle] | ||
pub static MMTK_MARK_COMPACT_HEADER_RESERVED_IN_BYTES: usize = | ||
mmtk::util::alloc::MarkCompactAllocator::<OpenJDK>::HEADER_RESERVED_IN_BYTES; | ||
|
||
lazy_static! { | ||
/// A global storage for all the cached CodeCache root pointers | ||
static ref CODE_CACHE_ROOTS: Mutex<HashMap<Address, Vec<Address>>> = Mutex::new(HashMap::new()); | ||
} | ||
|
||
/// A counter tracking the total size of the `CODE_CACHE_ROOTS`. | ||
static CODE_CACHE_ROOTS_SIZE: AtomicUsize = AtomicUsize::new(0); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we need this as a separate global variable. Whenever you change this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, The consistency is ensured by separating the writes and reads. Apart from tracking There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
You can just calculate the total size of the let code_cache_roots = CODE_CACHE_ROOTS.lock().unwrap();
let size = code_cache_roots.values().map(|vec| vec.len()).sum();
let mut vec = Vec::with_capacity(size);
for roots in code_cache_roots.values() {
for r in roots {
vec.push(*r)
}
} My point is that if you have acquired the lock to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm afraid calculating the size in a loop may slow down the GC time. If I can calculate the total size cheaply ahead of time, simply using the pre-calculated size here is the fastest way. This makes me realize that if I move the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you always access the struct CodeCacheRoots {
hash_map: HashMap<Address, Vec<Address>>,
size: usize,
}
lazy_static! {
static ref CODE_CACHE_ROOTS: Mutex<CodeCacheRoots> = Mutex::new(CodeCacheRoots {
hash_map: HashMap::new(),
size: 0,
});
} When using, you lock the mutex and have access to both {
let mut lock_guard = CODE_CACHE_ROOTS.lock().unwrap();
*lock_guard.size += slots.len();
lock_guard.hash_map.insert(nm, slots);
} |
Uh oh!
There was an error while loading. Please reload this page.