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

Use SimpleEdge #73

Draft
wants to merge 3 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
12 changes: 10 additions & 2 deletions julia/mmtk_julia.c
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ const bool PRINT_OBJ_TYPE = false;
* directly (not an edge), specifying whether to scan the object or not; and only scan the object
* (necessary for boot image / non-MMTk objects)
**/
JL_DLLEXPORT void scan_julia_obj(void* obj_raw, closure_pointer closure, ProcessEdgeFn process_edge, ProcessOffsetEdgeFn process_offset_edge)
JL_DLLEXPORT void scan_julia_obj(void* obj_raw, closure_pointer closure, ProcessEdgeFn process_edge, TraceObjectImmediatelyFn trace_object_immediately)
{
jl_value_t* obj = (jl_value_t*) obj_raw;
uintptr_t tag = (uintptr_t)jl_typeof(obj);
Expand Down Expand Up @@ -756,7 +756,15 @@ JL_DLLEXPORT void scan_julia_obj(void* obj_raw, closure_pointer closure, Process

if (flags.how == 1) { // julia-allocated buffer that needs to be marked
long offset = a->offset * a->elsize;
process_offset_edge(closure, &a->data, offset);
if (offset == 0) {
process_edge(closure, &a->data);
} else {
// Special case: we need to deal with offset edge.
// We trace object immediately here.
uint8_t* data = (uint8_t*)(a->data);
uint8_t* new_obj = (uint8_t*)trace_object_immediately(closure, data - offset);
a->data = new_obj + offset;
}
}
if (flags.how == 2) { // malloc-allocated pointer this array object manages
// should be processed below if it contains pointers
Expand Down
4 changes: 2 additions & 2 deletions mmtk/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion mmtk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,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 = "f1a0bb7fbec97dd84e35a40e8be01cf5018f2f9e" }
mmtk = { git = "https://github.com/qinsoon/mmtk-core.git", rev = "28bde92892d699cea0e1e179931d3aeeee25e982" }
# Uncomment the following to build locally
# mmtk = { path = "../repos/mmtk-core" }
log = {version = "0.4", features = ["max_level_trace", "release_max_level_off"] }
Expand Down
3 changes: 2 additions & 1 deletion mmtk/api/mmtk.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ typedef void* MMTk_Mutator;
typedef void* MMTk_TraceLocal;
typedef void (*ProcessEdgeFn)(closure_pointer closure, void* slot);
typedef void (*ProcessOffsetEdgeFn)(closure_pointer closure, void* slot, int offset);
typedef void* (*TraceObjectImmediatelyFn)(closure_pointer closure, void* object);

/**
* Allocation
Expand Down Expand Up @@ -77,7 +78,7 @@ extern const void* MMTK_SIDE_LOG_BIT_BASE_ADDRESS;
// * int is 4 bytes
// * size_t is 8 bytes
typedef struct {
void (* scan_julia_obj) (void* obj, closure_pointer closure, ProcessEdgeFn process_edge, ProcessOffsetEdgeFn process_offset_edge);
void (* scan_julia_obj) (void* obj, closure_pointer closure, ProcessEdgeFn process_edge, TraceObjectImmediatelyFn trace_object_immediately);
void (* scan_julia_exc_obj) (void* obj, closure_pointer closure, ProcessEdgeFn process_edge);
void* (* get_stackbase) (int16_t tid);
void (* calculate_roots) (void* tls);
Expand Down
8 changes: 2 additions & 6 deletions mmtk/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,9 +545,7 @@ pub extern "C" fn mmtk_object_reference_write_post(
memory_manager::object_reference_write_post(
mutator,
src,
crate::edges::JuliaVMEdge::Simple(mmtk::vm::edge_shape::SimpleEdge::from_address(
Address::ZERO,
)),
mmtk::vm::edge_shape::SimpleEdge::from_address(Address::ZERO),
target,
)
}
Expand All @@ -561,9 +559,7 @@ pub extern "C" fn mmtk_object_reference_write_slow(
use mmtk::MutatorContext;
mutator.barrier().object_reference_write_slow(
src,
crate::edges::JuliaVMEdge::Simple(mmtk::vm::edge_shape::SimpleEdge::from_address(
Address::ZERO,
)),
mmtk::vm::edge_shape::SimpleEdge::from_address(Address::ZERO),
target,
);
}
Expand Down
76 changes: 3 additions & 73 deletions mmtk/src/edges.rs
Original file line number Diff line number Diff line change
@@ -1,79 +1,9 @@
use atomic::Atomic;
use mmtk::{
util::{Address, ObjectReference},
vm::edge_shape::{Edge, SimpleEdge},
vm::edge_shape::SimpleEdge,
};

/// If a VM supports multiple kinds of edges, we can use tagged union to represent all of them.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum JuliaVMEdge {
Simple(SimpleEdge),
Offset(OffsetEdge),
}

unsafe impl Send for JuliaVMEdge {}

impl Edge for JuliaVMEdge {
fn load(&self) -> ObjectReference {
match self {
JuliaVMEdge::Simple(e) => e.load(),
JuliaVMEdge::Offset(e) => e.load(),
}
}

fn store(&self, object: ObjectReference) {
match self {
JuliaVMEdge::Simple(e) => e.store(object),
JuliaVMEdge::Offset(e) => e.store(object),
}
}
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct OffsetEdge {
slot_addr: *mut Atomic<Address>,
offset: usize,
}

unsafe impl Send for OffsetEdge {}

impl OffsetEdge {
pub fn new_no_offset(address: Address) -> Self {
Self {
slot_addr: address.to_mut_ptr(),
offset: 0,
}
}

pub fn new_with_offset(address: Address, offset: usize) -> Self {
Self {
slot_addr: address.to_mut_ptr(),
offset,
}
}

pub fn slot_address(&self) -> Address {
Address::from_mut_ptr(self.slot_addr)
}

pub fn offset(&self) -> usize {
self.offset
}
}

impl Edge for OffsetEdge {
fn load(&self) -> ObjectReference {
let middle = unsafe { (*self.slot_addr).load(atomic::Ordering::Relaxed) };
let begin = middle - self.offset;
ObjectReference::from_raw_address(begin)
}

fn store(&self, object: ObjectReference) {
let begin = object.to_raw_address();
let middle = begin + self.offset;
unsafe { (*self.slot_addr).store(middle, atomic::Ordering::Relaxed) }
}
}
pub type JuliaVMEdge = SimpleEdge;

#[derive(Hash, Clone, PartialEq, Eq, Debug)]
pub struct JuliaMemorySlice {
Expand Down Expand Up @@ -157,7 +87,7 @@ impl Iterator for JuliaMemorySliceEdgeIterator {
} else {
let edge = self.cursor;
self.cursor = self.cursor.shift::<ObjectReference>(1);
Some(JuliaVMEdge::Simple(SimpleEdge::from_address(edge)))
Some(mmtk::vm::edge_shape::SimpleEdge::from_address(edge))
}
}
}
19 changes: 7 additions & 12 deletions mmtk/src/julia_scanning.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::api::*;
use crate::edges::JuliaVMEdge;
use crate::edges::OffsetEdge;
use crate::julia_types::*;
use crate::UPCALLS;
use mmtk::util::{Address, ObjectReference};
Expand Down Expand Up @@ -57,9 +56,10 @@ pub unsafe fn scan_julia_object(addr: Address, closure: &mut dyn EdgeVisitor<Jul

if flags.how() == 1 {
// julia-allocated buffer that needs to be marked
let offset = ((*addr.to_ptr::<mmtk_jl_array_t>()).offset as u16
* (*addr.to_ptr::<mmtk_jl_array_t>()).elsize) as usize;
process_offset_edge(closure, addr, offset);
// let offset = ((*addr.to_ptr::<mmtk_jl_array_t>()).offset as u16
// * (*addr.to_ptr::<mmtk_jl_array_t>()).elsize) as usize;
// process_offset_edge(closure, addr, offset);
unimplemented!();
} else if flags.how() == 3 {
// has a pointer to the object that owns the data
#[allow(deref_nullptr)]
Expand Down Expand Up @@ -318,17 +318,12 @@ fn read_stack(addr: Address, offset: usize, lb: usize, ub: usize) -> Address {
#[inline(always)]
pub fn process_edge(closure: &mut dyn EdgeVisitor<JuliaVMEdge>, slot: Address) {
let simple_edge = SimpleEdge::from_address(slot);
closure.visit_edge(JuliaVMEdge::Simple(simple_edge));
closure.visit_edge(simple_edge);
}

#[inline(always)]
pub fn process_offset_edge(
closure: &mut dyn EdgeVisitor<JuliaVMEdge>,
slot: Address,
offset: usize,
) {
let offset_edge = OffsetEdge::new_with_offset(slot, offset);
closure.visit_edge(JuliaVMEdge::Offset(offset_edge));
pub fn trace_object_immediately(closure: &mut dyn EdgeVisitor<JuliaVMEdge>, object: ObjectReference) -> ObjectReference {
closure.visit_object_immediately(object)
}

#[inline(always)]
Expand Down
6 changes: 3 additions & 3 deletions mmtk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,16 +122,16 @@ extern "C" {
type ProcessEdgeFn =
*const extern "C" fn(closure: &mut dyn EdgeVisitor<JuliaVMEdge>, slot: Address);

type ProcessOffsetEdgeFn =
*const extern "C" fn(closure: &mut dyn EdgeVisitor<JuliaVMEdge>, slot: Address, offset: usize);
type TraceObjectImmediatelyFn =
*const extern "C" fn(closure: &mut dyn EdgeVisitor<JuliaVMEdge>, object: ObjectReference) -> ObjectReference;

#[repr(C)]
pub struct Julia_Upcalls {
pub scan_julia_obj: extern "C" fn(
obj: Address,
closure: &mut dyn EdgeVisitor<JuliaVMEdge>,
process_edge: ProcessEdgeFn,
process_offset_edge: ProcessOffsetEdgeFn,
trace_object_immediately: TraceObjectImmediatelyFn,
),
pub scan_julia_exc_obj: extern "C" fn(
obj: Address,
Expand Down
8 changes: 5 additions & 3 deletions mmtk/src/scanning.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use crate::edges::JuliaVMEdge;
#[cfg(feature = "scan_obj_c")]
use crate::julia_scanning::process_edge;
// #[cfg(feature = "scan_obj_c")]
// use crate::julia_scanning::process_offset_edge;
#[cfg(feature = "scan_obj_c")]
use crate::julia_scanning::process_offset_edge;
use crate::julia_scanning::trace_object_immediately;
use crate::FINALIZER_ROOTS;
use crate::{ROOT_EDGES, ROOT_NODES, SINGLETON, UPCALLS};
use mmtk::memory_manager;
Expand Down Expand Up @@ -69,7 +71,7 @@ impl Scanning<JuliaVM> for VMScanning {
.lock()
.unwrap()
.drain()
.map(|e| JuliaVMEdge::Simple(mmtk::vm::edge_shape::SimpleEdge::from_address(e)))
.map(|e| mmtk::vm::edge_shape::SimpleEdge::from_address(e))
.collect();
info!("{} thread root edges", roots.len());
factory.create_process_edge_roots_work(roots);
Expand Down Expand Up @@ -106,7 +108,7 @@ pub fn process_object(object: ObjectReference, closure: &mut dyn EdgeVisitor<Jul
#[cfg(feature = "scan_obj_c")]
{
unsafe {
((*UPCALLS).scan_julia_obj)(addr, closure, process_edge as _, process_offset_edge as _)
((*UPCALLS).scan_julia_obj)(addr, closure, process_edge as _, trace_object_immediately as _)
};
}

Expand Down