Skip to content
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

Basic GC Support #36

Draft
wants to merge 71 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
787187d
Add InSpace/InOldSpace checks
wenyuzhao Apr 28, 2021
07f9eb4
Fix space check
wenyuzhao Apr 28, 2021
f028b8d
Paging-GC can do one collection and pass mk-snapshot now
wenyuzhao Apr 30, 2021
f4a7622
cleanup
wenyuzhao Apr 30, 2021
0d1e12c
Update visitors
wenyuzhao May 3, 2021
30ef6c9
Refactor
wenyuzhao May 4, 2021
72bc857
Fix build error
wenyuzhao May 4, 2021
58d1871
Refactor
wenyuzhao May 4, 2021
47decc0
Verifiers
wenyuzhao May 5, 2021
3b21fb2
Update
wenyuzhao May 10, 2021
9417563
Merge branch 'master' into paging-gc
wenyuzhao May 11, 2021
f8373b9
WIP: Drop stub cache
wenyuzhao May 11, 2021
172b85e
WIP: Update weak refs
wenyuzhao May 13, 2021
4bac4f5
Update weakrefs
wenyuzhao May 14, 2021
4d0c6de
Heap::Capacity
wenyuzhao May 17, 2021
1778bee
Fix invalid descriptor-array cache
wenyuzhao May 19, 2021
8d741fe
Fix is_mutator check
wenyuzhao May 20, 2021
a837f14
Update
wenyuzhao May 21, 2021
b33e9d2
Rebase
wenyuzhao May 21, 2021
9fa12ef
forward roots on root-scanning
wenyuzhao May 24, 2021
618692a
WIP: Refactor
wenyuzhao May 25, 2021
d07f808
Simplify object archive
wenyuzhao May 25, 2021
07ffa95
Fix map and immovable object allocation
wenyuzhao May 27, 2021
167584a
WIP
wenyuzhao Jun 7, 2021
29bebe2
Main thread tasks
wenyuzhao Jun 7, 2021
5ceadf6
Fix `OnMoveEvent`
wenyuzhao Jun 9, 2021
6f4d0c9
Minor fix
wenyuzhao Jun 9, 2021
b3fc6e3
Merge branch 'master' into copying-gc
wenyuzhao Jun 10, 2021
3194334
Rename
wenyuzhao Jun 10, 2021
c1368be
StringTable processing
wenyuzhao Jun 10, 2021
2bb3ccb
ClearNonLiveReferences support
wenyuzhao Jun 10, 2021
5901e89
refactor namespace
wenyuzhao Jun 10, 2021
f821926
Process weak fields
wenyuzhao Jun 10, 2021
485a70f
Refactor
wenyuzhao Jun 11, 2021
5fb598b
weak_cell processing
wenyuzhao Jun 11, 2021
46b3d86
Fix weak embedded pointer
wenyuzhao Jun 14, 2021
b6d0cba
WIP
wenyuzhao Jun 16, 2021
038365f
WIP: Switch visitor
wenyuzhao Jun 17, 2021
b4036d8
WIP: Switch visitor
wenyuzhao Jun 17, 2021
b925865
WIP
wenyuzhao Jun 21, 2021
e543fea
[weakref] More progress
wenyuzhao Jun 22, 2021
76df2d4
Ephemeron support
wenyuzhao Jun 25, 2021
ac905fb
WIP
wenyuzhao Jun 28, 2021
b9f5be8
Check
wenyuzhao Jun 28, 2021
7dcd0a8
Fix liveness check
wenyuzhao Jun 29, 2021
bf8c16b
cleanup
wenyuzhao Jun 29, 2021
c7bf052
Fix space check
wenyuzhao Jun 29, 2021
ce8cb54
Merge remote-tracking branch 'origin/master' into copying-gc
wenyuzhao Jun 29, 2021
c4b5554
Fix build error
wenyuzhao Jun 29, 2021
d9d668e
Update to new TPH interface
wenyuzhao Jun 29, 2021
ab95848
Cleanup & remove TPHData
wenyuzhao Jun 29, 2021
b4dac23
VisitMap
wenyuzhao Jun 30, 2021
30dffe9
Several fix
wenyuzhao Jun 30, 2021
cecff38
Update (for gencopy)
wenyuzhao Jun 30, 2021
b4bae75
Redirect IsPendingAllocation
wenyuzhao Jul 1, 2021
ba2492a
Minor fix
wenyuzhao Jul 1, 2021
a017f07
Override V8 weak object visiting code
wenyuzhao Jul 1, 2021
94428f8
no logging
wenyuzhao Jul 6, 2021
664111a
Fix fold-allocated FixedArrays
wenyuzhao Jul 9, 2021
c0bf824
Merge branch 'master' into copying-gc
wenyuzhao Jul 11, 2021
425e92a
update
wenyuzhao Jul 13, 2021
6277776
Fix
wenyuzhao Jul 14, 2021
92883df
Update mmtk-core dependency
wenyuzhao Jul 21, 2021
22cef95
Fix build error
wenyuzhao Jul 23, 2021
9aebd1b
cleanup
wenyuzhao Jul 23, 2021
7560cec
Cleanup
wenyuzhao Jul 23, 2021
fdcc01c
Cleanup
wenyuzhao Jul 23, 2021
fd768aa
Cleanup
wenyuzhao Jul 23, 2021
de973a2
Remove weakref processing code
wenyuzhao Aug 3, 2021
016b440
Merge branch 'master' into gc-support
wenyuzhao Nov 23, 2021
8346d29
minor update
wenyuzhao Nov 25, 2021
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
75 changes: 69 additions & 6 deletions mmtk/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,53 @@ use libc::c_void;
use mmtk::memory_manager;
use mmtk::scheduler::GCWorker;
use mmtk::util::opaque_pointer::*;
use mmtk::util::options::PlanSelector;
use mmtk::util::{Address, ObjectReference};
use mmtk::AllocationSemantics;
use mmtk::Mutator;
use mmtk::MMTK;
use mmtk::policy::space::Space;
use std::ffi::CStr;

use V8_Upcalls;
use UPCALLS;
use V8;

/// Release an address buffer
#[no_mangle]
pub unsafe extern "C" fn mmtk_release_buffer(ptr: *mut Address, length: usize, capacity: usize) {
let _vec = Vec::<Address>::from_raw_parts(ptr, length, capacity);
}

/// Check whether an object is movable.
#[no_mangle]
pub unsafe extern "C" fn mmtk_is_movable(object: ObjectReference) -> i32 {
let object = {
let untagged_word = object.to_address().as_usize() & !0b11usize;
Address::from_usize(untagged_word).to_object_reference()
};
if object.is_movable() { 1 } else { 0 }
}

/// Get the forwarding pointer, or NULL if the object is not forwarded
#[no_mangle]
pub unsafe extern "C" fn mmtk_get_forwarded_object(object: ObjectReference) -> *mut c_void {
let tag = object.to_address().as_usize() & 0b11usize;
let object = {
let untagged_word = object.to_address().as_usize() & !0b11usize;
Address::from_usize(untagged_word).to_object_reference()
};
object.get_forwarded_object().map(|x| (x.to_address().as_usize() | tag) as *mut c_void).unwrap_or(0 as _)
}

#[no_mangle]
pub extern "C" fn v8_new_heap(calls: *const V8_Upcalls, heap_size: usize) -> *mut c_void {
unsafe {
UPCALLS = calls;
};
let mmtk: Box<MMTK<V8>> = Box::new(MMTK::new());
let mmtk: *mut MMTK<V8> = Box::into_raw(mmtk);
memory_manager::gc_init(unsafe { &mut *mmtk }, heap_size);
let mmtk: *const MMTK<V8> = &*crate::SINGLETON;
memory_manager::gc_init(unsafe { &mut *(mmtk as *mut MMTK<V8>) }, heap_size);
initialize_collection(unsafe { &mut *(mmtk as *mut MMTK<V8>) }, VMThread::UNINITIALIZED);

mmtk as *mut c_void
}
Expand All @@ -38,6 +67,25 @@ pub extern "C" fn bind_mutator(
Box::into_raw(memory_manager::bind_mutator(mmtk, tls))
}

#[no_mangle]
pub unsafe extern "C" fn mmtk_in_space(mmtk: &'static MMTK<V8>, object: ObjectReference, space: AllocationSemantics) -> i32 {
match space {
AllocationSemantics::Default => {
(object.is_mapped()
&& mmtk_in_space(mmtk, object, AllocationSemantics::ReadOnly) == 0
&& mmtk_in_space(mmtk, object, AllocationSemantics::Immortal) == 0
&& mmtk_in_space(mmtk, object, AllocationSemantics::Los) == 0
&& mmtk_in_space(mmtk, object, AllocationSemantics::Code) == 0
&& mmtk_in_space(mmtk, object, AllocationSemantics::LargeCode) == 0) as _
},
AllocationSemantics::ReadOnly => mmtk.plan.base().ro_space.in_space(object) as _,
AllocationSemantics::Immortal => mmtk.plan.common().immortal.in_space(object) as _,
AllocationSemantics::Los => mmtk.plan.common().los.in_space(object) as _,
AllocationSemantics::Code => mmtk.plan.base().code_space.in_space(object) as _,
AllocationSemantics::LargeCode => mmtk.plan.base().code_lo_space.in_space(object) as _,
}
}

#[no_mangle]
// It is fine we turn the pointer back to box, as we turned a boxed value to the raw pointer in bind_mutator()
#[allow(clippy::not_unsafe_ptr_arg_deref)]
Expand All @@ -53,7 +101,18 @@ pub extern "C" fn alloc(
offset: isize,
semantics: AllocationSemantics,
) -> Address {
memory_manager::alloc::<V8>(mutator, size, align, offset, semantics)
let a = memory_manager::alloc::<V8>(mutator, size, align, offset, semantics);
unsafe { memory_manager::post_alloc::<V8>(mutator, a.to_object_reference(), size, semantics); }
if PlanSelector::PageProtect == mutator.plan.options().plan && AllocationSemantics::Default == semantics {
// Possible `array_header_size` values that can be passed to [AllocateUninitializedJSArrayWithElements](https://source.chromium.org/chromium/chromium/src/+/main:v8/src/codegen/code-stub-assembler.h;l=1884).
let array_header_sizes = [0x20, 0x50, 0x58];
for array_header_size in array_header_sizes {
unsafe {
memory_manager::post_alloc::<V8>(mutator, a.add(array_header_size).to_object_reference(), 0, semantics);
}
}
}
a
}

#[no_mangle]
Expand Down Expand Up @@ -107,8 +166,12 @@ pub extern "C" fn scan_region(mmtk: &mut MMTK<V8>) {
}

#[no_mangle]
pub extern "C" fn is_live_object(object: ObjectReference) -> bool {
object.is_live()
pub extern "C" fn mmtk_object_is_live(object: ObjectReference) -> usize {
debug_assert_eq!(object.to_address().as_usize() & 0b11, 0);
if crate::SINGLETON.plan.base().ro_space.in_space(object) {
return 1;
}
if object.is_reachable() { 1 } else { 0 }
}

#[no_mangle]
Expand Down
39 changes: 32 additions & 7 deletions mmtk/src/collection.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
use mmtk::scheduler::GCWorker;
use mmtk::util::*;
use mmtk::scheduler::ProcessEdgesWork;
use mmtk::util::opaque_pointer::*;
use mmtk::vm::Collection;
use mmtk::MutatorContext;
use mmtk::{MutatorContext, MMTK};

use UPCALLS;
use V8;

use crate::object_archive::global_object_archive;
use crate::scanning::ROOT_OBJECTS;
use crate::scanning::flush_roots;
use crate::scanning::trace_root;

pub struct VMCollection {}

impl Collection<V8> for VMCollection {
Expand All @@ -28,15 +33,20 @@ impl Collection<V8> for VMCollection {
}
}

fn spawn_worker_thread(tls: VMThread, ctx: Option<&GCWorker<V8>>) {
fn spawn_worker_thread(_tls: VMThread, ctx: Option<&GCWorker<V8>>) {
let ctx_ptr = if let Some(r) = ctx {
r as *const GCWorker<V8> as *mut GCWorker<V8>
} else {
std::ptr::null_mut()
};
unsafe {
((*UPCALLS).spawn_worker_thread)(tls, ctx_ptr as usize as _);
}
} as usize;
std::thread::spawn(move || {
let mmtk: *mut MMTK<V8> = &*crate::SINGLETON as *const MMTK<V8> as *mut MMTK<V8>;
if ctx_ptr == 0 {
crate::api::start_control_collector(unsafe { &mut *mmtk }, VMWorkerThread(VMThread::UNINITIALIZED));
} else {
crate::api::start_worker(unsafe { &mut *mmtk }, VMWorkerThread(VMThread::UNINITIALIZED), unsafe { &mut *(ctx_ptr as *mut GCWorker<V8>) });
}
});
}

fn prepare_mutator<T: MutatorContext<V8>>(
Expand All @@ -46,4 +56,19 @@ impl Collection<V8> for VMCollection {
) {
unimplemented!()
}

fn vm_release() {
global_object_archive().update();
}

fn process_weak_refs<E: ProcessEdgesWork<VM = V8>>(worker: &mut GCWorker<V8>) {
unsafe {
debug_assert!(ROOT_OBJECTS.is_empty());
((*UPCALLS).process_weak_refs)(trace_root::<E> as _, worker as *mut _ as _);
if !ROOT_OBJECTS.is_empty() {
flush_roots::<E>(worker);
}
debug_assert!(ROOT_OBJECTS.is_empty());
}
}
}
33 changes: 30 additions & 3 deletions mmtk/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#![feature(vec_into_raw_parts)]
#![feature(thread_local)]
#![feature(const_option)]

extern crate libc;
extern crate mmtk;
#[macro_use]
Expand All @@ -6,6 +10,7 @@ extern crate lazy_static;
#[macro_use]
extern crate log;

use std::env;
use std::ptr::null_mut;

use libc::c_void;
Expand All @@ -22,6 +27,17 @@ mod object_archive;
pub mod object_model;
pub mod reference_glue;
pub mod scanning;
use mmtk::util::{Address};

#[repr(C)]
pub struct NewBuffer {
pub ptr: *mut Address,
pub capacity: usize,
}

type ProcessEdgesFn = *const extern "C" fn(buf: *mut Address, size: usize, cap: usize) -> NewBuffer;
type TraceRootFn = *const extern "C" fn(slot: Address, ctx: &'static mut GCWorker<V8>) -> Address;
type TraceFieldFn = *const extern "C" fn(slot: Address, ctx: &'static mut GCWorker<V8>) -> Address;

#[repr(C)]
pub struct V8_Upcalls {
Expand All @@ -39,6 +55,11 @@ pub struct V8_Upcalls {
pub get_object_size: extern "C" fn(object: ObjectReference) -> usize,
pub get_mmtk_mutator: extern "C" fn(tls: VMMutatorThread) -> *mut Mutator<V8>,
pub is_mutator: extern "C" fn(tls: VMThread) -> bool,
pub scan_roots: extern "C" fn(trace_root: TraceRootFn, context: *mut c_void, task_id: usize),
pub scan_objects: extern "C" fn(objects: *const ObjectReference, count: usize, process_edges: ProcessEdgesFn, trace_field: TraceFieldFn, context: *mut c_void, task_id: usize),
pub process_weak_refs: extern "C" fn(trace_root: TraceRootFn, context: *mut c_void),
pub on_move_event: extern "C" fn(from: ObjectReference, to: ObjectReference, size: usize),
pub process_ephemerons: extern "C" fn(trace_root: TraceRootFn, context: *mut c_void, task_id: usize),
}

pub static mut UPCALLS: *const V8_Upcalls = null_mut();
Expand All @@ -58,9 +79,15 @@ impl VMBinding for V8 {

lazy_static! {
pub static ref SINGLETON: MMTK<V8> = {
#[cfg(feature = "nogc")]
std::env::set_var("MMTK_PLAN", "NoGC");

// V8 can only support up to 8 worker threads.
// Set MMTK_THREADS = 7 here to exclude the main thread -- it undertakes part of the worker's job.
if let Ok(threads) = env::var("MMTK_THREADS").map(|x| x.parse::<usize>().unwrap()) {
if threads > 7 {
env::set_var("MMTK_THREADS", "7");
}
} else {
env::set_var("MMTK_THREADS", "7");
}
MMTK::new()
};
}
Loading