Skip to content
Merged
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
2 changes: 1 addition & 1 deletion mmtk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ edition = "2021"
# Metadata for the Ruby repository
[package.metadata.ci-repos.ruby]
repo = "mmtk/ruby" # This is used by actions/checkout, so the format is "owner/repo", not URL.
rev = "db7b82e33081066233281cdfcc0b7321b29703af"
rev = "f9a0c1de19043485d1c9a26844e716a4953e693d"

[lib]
name = "mmtk_ruby"
Expand Down
1 change: 1 addition & 0 deletions mmtk/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ pub struct RubyUpcalls {
pub is_no_longer_ppp: extern "C" fn(ObjectReference) -> bool,
pub scan_object_ruby_style: extern "C" fn(object: ObjectReference),
pub call_gc_mark_children: extern "C" fn(object: ObjectReference),
pub obj_needs_cleanup_p: extern "C" fn(object: ObjectReference) -> bool,
pub call_obj_free: extern "C" fn(object: ObjectReference),
pub vm_live_bytes: extern "C" fn() -> usize,
pub has_exivar: extern "C" fn(object: ObjectReference) -> bool,
Expand Down
139 changes: 23 additions & 116 deletions mmtk/src/weak_proc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,18 @@ use mmtk::{

use crate::{
abi::{self, GCThreadTLS},
extra_assert, is_mmtk_object_safe, upcalls, Ruby,
extra_assert, is_mmtk_object_safe, upcalls,
weak_proc::weak_global_tables::{
UpdateCCRefinementTable, UpdateCiTable, UpdateFinalizerAndObjIdTables,
UpdateFrozenStringsTable, UpdateGenericFieldsTbl, UpdateGlobalSymbolsTable,
UpdateOverloadedCmeTable,
},
Ruby,
};

pub mod concurrent_set_parallel;
pub mod st_table_parallel;
pub mod weak_global_tables;

/// Set this to true to use chunked processing optimization for the fstring table.
const SPECIALIZE_FSTRING_TABLE_PROCESSING: bool = true;
Expand Down Expand Up @@ -154,6 +161,9 @@ impl GCWork<Ruby> for ProcessObjFreeCandidates {
let old_cands = obj_free_candidates.len();
debug!("Total: {} candidates", old_cands);

let mut freed = 0usize;
let mut elided = 0usize;

// Process obj_free
let mut new_candidates = Vec::new();

Expand All @@ -167,130 +177,27 @@ impl GCWork<Ruby> for ProcessObjFreeCandidates {
new_object
);
new_candidates.push(new_object);
} else {
} else if (upcalls().obj_needs_cleanup_p)(object) {
(upcalls().call_obj_free)(object);
freed += 1;
} else {
elided += 1;
}
}

let new_cands = new_candidates.len();
*obj_free_candidates = new_candidates;
probe!(mmtk_ruby, process_obj_free_candidates, old_cands, new_cands);
}
}

trait GlobalTableProcessingWork {
fn process_table(&mut self);

fn do_work(&mut self, worker: &mut GCWorker<Ruby>, _mmtk: &'static mmtk::MMTK<Ruby>) {
let gc_tls = unsafe { GCThreadTLS::from_vwt_check(worker.tls) };

// `hash_foreach_replace` depends on `gb_object_moved_p` which has to have the semantics
// of `trace_object` due to the way it is used in `UPDATE_IF_MOVED`.
let forward_object = |_worker, object: ObjectReference, _pin| {
extra_assert!(
is_mmtk_object_safe(object.to_raw_address()),
"{} is not an MMTk object",
object
);
let result = object.forward();
trace!("Forwarding reference: {} -> {}", object, result);
result
};

gc_tls
.object_closure
.set_temporarily_and_run_code(forward_object, || {
self.process_table();
});
probe!(
mmtk_ruby,
process_obj_free_candidates,
old_cands,
new_cands,
freed,
elided,
);
}
}

macro_rules! define_global_table_processor {
($name: ident, $code: expr) => {
struct $name;
impl GlobalTableProcessingWork for $name {
fn process_table(&mut self) {
$code
}
}
impl GCWork<Ruby> for $name {
fn do_work(&mut self, worker: &mut GCWorker<Ruby>, mmtk: &'static mmtk::MMTK<Ruby>) {
GlobalTableProcessingWork::do_work(self, worker, mmtk);
}
}
};
}

fn general_update_weak_table(size_getter: extern "C" fn() -> usize, cleaner: extern "C" fn()) {
let old_size = size_getter();
cleaner();
let new_size = size_getter();
probe!(mmtk_ruby, weak_table_size_change, old_size, new_size);
}

///////// BEGIN: Simple table updating work packets ////////
// Note: Follow the order of `rb_gc_vm_weak_table_foreach in `gc.c`

define_global_table_processor!(UpdateCiTable, {
general_update_weak_table(upcalls().get_ci_table_size, upcalls().update_ci_table);
});

define_global_table_processor!(UpdateOverloadedCmeTable, {
general_update_weak_table(
upcalls().get_overloaded_cme_table_size,
upcalls().update_overloaded_cme_table,
);
});

define_global_table_processor!(UpdateGlobalSymbolsTable, {
general_update_weak_table(
upcalls().get_global_symbols_table_size,
upcalls().update_global_symbols_table,
);
});

define_global_table_processor!(UpdateFinalizerAndObjIdTables, {
let old_size_finalizer = (upcalls().get_finalizer_table_size)();
let old_size_id_to_obj = (upcalls().get_id2ref_table_size)();

(upcalls().update_finalizer_and_obj_id_tables)();

let new_size_finalizer = (upcalls().get_finalizer_table_size)();
let new_size_id_to_obj = (upcalls().get_id2ref_table_size)();

probe!(
mmtk_ruby,
update_finalizer_and_obj_id_tables,
old_size_finalizer,
new_size_finalizer,
old_size_id_to_obj,
new_size_id_to_obj,
);
});

define_global_table_processor!(UpdateGenericFieldsTbl, {
general_update_weak_table(
upcalls().get_generic_fields_tbl_size,
upcalls().update_generic_fields_table,
);
});

define_global_table_processor!(UpdateFrozenStringsTable, {
general_update_weak_table(
upcalls().get_frozen_strings_table_size,
upcalls().update_frozen_strings_table,
);
});

define_global_table_processor!(UpdateCCRefinementTable, {
general_update_weak_table(
upcalls().get_cc_refinement_table_size,
upcalls().update_cc_refinement_table,
);
});

///////// END: Simple table updating work packets ////////

struct UpdateWbUnprotectedObjectsList;

impl GCWork<Ruby> for UpdateWbUnprotectedObjectsList {
Expand Down
121 changes: 121 additions & 0 deletions mmtk/src/weak_proc/weak_global_tables.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
use mmtk::{
scheduler::{GCWork, GCWorker},
util::ObjectReference,
};

use crate::{
abi::GCThreadTLS, extra_assert, is_mmtk_object_safe, upcalls, weak_proc::Forwardable, Ruby,
};

pub trait GlobalTableProcessingWork {
fn process_table(&mut self);

fn do_work(&mut self, worker: &mut GCWorker<Ruby>, _mmtk: &'static mmtk::MMTK<Ruby>) {
let gc_tls = unsafe { GCThreadTLS::from_vwt_check(worker.tls) };

// `hash_foreach_replace` depends on `gb_object_moved_p` which has to have the semantics
// of `trace_object` due to the way it is used in `UPDATE_IF_MOVED`.
let forward_object = |_worker, object: ObjectReference, _pin| {
extra_assert!(
is_mmtk_object_safe(object.to_raw_address()),
"{} is not an MMTk object",
object
);
let result = object.forward();
trace!("Forwarding reference: {} -> {}", object, result);
result
};

gc_tls
.object_closure
.set_temporarily_and_run_code(forward_object, || {
self.process_table();
});
}
}

macro_rules! define_global_table_processor {
($name: ident, $code: expr) => {
pub struct $name;
impl GlobalTableProcessingWork for $name {
fn process_table(&mut self) {
$code
}
}
impl GCWork<Ruby> for $name {
fn do_work(&mut self, worker: &mut GCWorker<Ruby>, mmtk: &'static mmtk::MMTK<Ruby>) {
GlobalTableProcessingWork::do_work(self, worker, mmtk);
}
}
};
}

fn general_update_weak_table(size_getter: extern "C" fn() -> usize, cleaner: extern "C" fn()) {
let old_size = size_getter();
cleaner();
let new_size = size_getter();
probe!(mmtk_ruby, weak_table_size_change, old_size, new_size);
}

///////// BEGIN: Simple table updating work packets ////////
// Note: Follow the order of `rb_gc_vm_weak_table_foreach in `gc.c`

define_global_table_processor!(UpdateCiTable, {
general_update_weak_table(upcalls().get_ci_table_size, upcalls().update_ci_table);
});

define_global_table_processor!(UpdateOverloadedCmeTable, {
general_update_weak_table(
upcalls().get_overloaded_cme_table_size,
upcalls().update_overloaded_cme_table,
);
});

define_global_table_processor!(UpdateGlobalSymbolsTable, {
general_update_weak_table(
upcalls().get_global_symbols_table_size,
upcalls().update_global_symbols_table,
);
});

define_global_table_processor!(UpdateFinalizerAndObjIdTables, {
let old_size_finalizer = (upcalls().get_finalizer_table_size)();
let old_size_id_to_obj = (upcalls().get_id2ref_table_size)();

(upcalls().update_finalizer_and_obj_id_tables)();

let new_size_finalizer = (upcalls().get_finalizer_table_size)();
let new_size_id_to_obj = (upcalls().get_id2ref_table_size)();

probe!(
mmtk_ruby,
update_finalizer_and_obj_id_tables,
old_size_finalizer,
new_size_finalizer,
old_size_id_to_obj,
new_size_id_to_obj,
);
});

define_global_table_processor!(UpdateGenericFieldsTbl, {
general_update_weak_table(
upcalls().get_generic_fields_tbl_size,
upcalls().update_generic_fields_table,
);
});

define_global_table_processor!(UpdateFrozenStringsTable, {
general_update_weak_table(
upcalls().get_frozen_strings_table_size,
upcalls().update_frozen_strings_table,
);
});

define_global_table_processor!(UpdateCCRefinementTable, {
general_update_weak_table(
upcalls().get_cc_refinement_table_size,
upcalls().update_cc_refinement_table,
);
});

///////// END: Simple table updating work packets ////////
56 changes: 29 additions & 27 deletions tools/tracing/timeline/capture_ruby.bt
Original file line number Diff line number Diff line change
Expand Up @@ -61,36 +61,38 @@ usdt:$MMTK:mmtk_ruby:weak_cs_par_entries_end {
}

// Weak st table optimization

usdt:$MMTK:mmtk_ruby:weak_st_par_init {
if (@enable_print) {
printf("weak_st_par_init,meta,%d,%lu,%lu,%lu,%lu,%lu,%s\n", tid, nsecs, arg0, arg1, arg2, arg3, str(arg4, arg5));
}
}

usdt:$MMTK:mmtk_ruby:weak_st_par_final {
if (@enable_print) {
printf("weak_st_par_final,meta,%d,%lu,%lu,%s\n", tid, nsecs, arg0, str(arg1, arg2));
}
}

usdt:$MMTK:mmtk_ruby:weak_st_par_entries {
if (@enable_print) {
printf("weak_st_par_entries,meta,%d,%lu,%lu,%lu,%lu,%s\n", tid, nsecs, arg0, arg1, arg2, str(arg3, arg4));
}
}

usdt:$MMTK:mmtk_ruby:weak_st_par_bins {
if (@enable_print) {
printf("weak_st_par_bins,meta,%d,%lu,%lu,%lu,%lu,%s\n", tid, nsecs, arg0, arg1, arg2, str(arg3, arg4));
}
}
// We currently don't have weak st_tables to process in parallel.
// But if we need, we can uncomment the following probes.
//
// usdt:$MMTK:mmtk_ruby:weak_st_par_init {
// if (@enable_print) {
// printf("weak_st_par_init,meta,%d,%lu,%lu,%lu,%lu,%lu,%s\n", tid, nsecs, arg0, arg1, arg2, arg3, str(arg4, arg5));
// }
// }
//
// usdt:$MMTK:mmtk_ruby:weak_st_par_final {
// if (@enable_print) {
// printf("weak_st_par_final,meta,%d,%lu,%lu,%s\n", tid, nsecs, arg0, str(arg1, arg2));
// }
// }
//
// usdt:$MMTK:mmtk_ruby:weak_st_par_entries {
// if (@enable_print) {
// printf("weak_st_par_entries,meta,%d,%lu,%lu,%lu,%lu,%s\n", tid, nsecs, arg0, arg1, arg2, str(arg3, arg4));
// }
// }
//
// usdt:$MMTK:mmtk_ruby:weak_st_par_bins {
// if (@enable_print) {
// printf("weak_st_par_bins,meta,%d,%lu,%lu,%lu,%lu,%s\n", tid, nsecs, arg0, arg1, arg2, str(arg3, arg4));
// }
// }

// Other work packets

usdt:$MMTK:mmtk_ruby:process_obj_free_candidates {
if (@enable_print) {
printf("process_obj_free_candidates,meta,%d,%lu,%lu,%lu\n", tid, nsecs, arg0, arg1);
printf("process_obj_free_candidates,meta,%d,%lu,%lu,%lu,%lu,%lu\n", tid, nsecs, arg0, arg1, arg2, arg3);
}
}

Expand All @@ -100,8 +102,8 @@ usdt:$MMTK:mmtk_ruby:update_wb_unprotected_objects_list {
}
}

usdt:$MMTK:mmtk_ruby:update_weak_fields {
usdt:$MMTK:mmtk_ruby:process_weak_references {
if (@enable_print) {
printf("update_weak_fields,meta,%d,%lu,%lu,%lu,%lu\n", tid, nsecs, arg0, arg1, arg2);
printf("process_weak_references,meta,%d,%lu,%lu,%lu\n", tid, nsecs, arg0, arg1);
}
}
Loading