diff --git a/mmtk/Cargo.lock b/mmtk/Cargo.lock index 3c42ff2..3d146f6 100644 --- a/mmtk/Cargo.lock +++ b/mmtk/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.18" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" dependencies = [ "anstyle", "anstyle-parse", @@ -28,33 +28,33 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" dependencies = [ "windows-sys", ] [[package]] name = "anstyle-wincon" -version = "3.0.8" +version = "3.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6680de5231bd6ee4c6191b8a1325daa282b415391ec9d3a37bd34f2060dc73fa" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" dependencies = [ "anstyle", "once_cell_polyfill", @@ -63,9 +63,9 @@ dependencies = [ [[package]] name = "atomic" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d818003e740b63afc82337e3160717f4f63078720a810b7b903e70a5d1d2994" +checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340" dependencies = [ "bytemuck", ] @@ -88,9 +88,9 @@ checksum = "41e67cd8309bbd06cd603a9e693a784ac2e5d1e955f11286e355089fcab3047c" [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "bitflags" @@ -109,9 +109,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.23.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c" +checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" dependencies = [ "bytemuck_derive", ] @@ -124,14 +124,14 @@ checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] name = "cc" -version = "1.2.24" +version = "1.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16595d3be041c03b09d08d0858631facccee9221e579704070e6e9e4915d3bc7" +checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362" dependencies = [ "jobserver", "libc", @@ -140,15 +140,15 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "colorchoice" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "core-foundation-sys" @@ -220,7 +220,7 @@ checksum = "b9b6483c2bbed26f97861cf57651d4f2b731964a28cd2257f934a4b452480d21" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -252,7 +252,7 @@ checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -320,15 +320,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.9" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hermit-abi" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "idna" @@ -367,7 +361,7 @@ version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ - "hermit-abi 0.5.1", + "hermit-abi", "libc", "windows-sys", ] @@ -389,9 +383,9 @@ dependencies = [ [[package]] name = "jiff" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a194df1107f33c79f4f93d02c80798520551949d59dfad22b6157048a88cca93" +checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" dependencies = [ "jiff-static", "log", @@ -402,13 +396,13 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c6e1db7ed32c6c71b759497fae34bf7933636f75a251b9e736555da426f6442" +checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -429,15 +423,15 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.172" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libgit2-sys" -version = "0.18.1+1.9.0" +version = "0.18.2+1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1dcb20f84ffcdd825c7a311ae347cce604a6f084a767dec4a4929829645290e" +checksum = "1c42fe03df2bd3c53a3a9c7317ad91d80c81cd1fb0caec8d7cc4cd2bfa10c222" dependencies = [ "cc", "libc", @@ -459,9 +453,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" dependencies = [ "autocfg", "scopeguard", @@ -475,9 +469,9 @@ checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "memoffset" @@ -491,7 +485,7 @@ dependencies = [ [[package]] name = "mmtk" version = "0.31.0" -source = "git+https://github.com/mmtk/mmtk-core.git?rev=d538987ecb3270d89343382dc5464c263adae3e5#d538987ecb3270d89343382dc5464c263adae3e5" +source = "git+https://github.com/mmtk/mmtk-core.git?rev=efe7b41785eeb07473cbadc93b58d4e1e532353d#efe7b41785eeb07473cbadc93b58d4e1e532353d" dependencies = [ "atomic", "atomic-traits", @@ -529,12 +523,12 @@ dependencies = [ [[package]] name = "mmtk-macros" version = "0.31.0" -source = "git+https://github.com/mmtk/mmtk-core.git?rev=d538987ecb3270d89343382dc5464c263adae3e5#d538987ecb3270d89343382dc5464c263adae3e5" +source = "git+https://github.com/mmtk/mmtk-core.git?rev=efe7b41785eeb07473cbadc93b58d4e1e532353d#efe7b41785eeb07473cbadc93b58d4e1e532353d" dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -571,11 +565,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi", "libc", ] @@ -605,9 +599,9 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "portable-atomic" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" [[package]] name = "portable-atomic-util" @@ -668,9 +662,9 @@ dependencies = [ [[package]] name = "r-efi" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "rayon" @@ -765,7 +759,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -776,9 +770,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "smallvec" -version = "1.15.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "spin" @@ -811,7 +805,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -826,9 +820,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.101" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -987,7 +981,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -998,7 +992,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] diff --git a/mmtk/Cargo.toml b/mmtk/Cargo.toml index 2bc2b10..47de184 100644 --- a/mmtk/Cargo.toml +++ b/mmtk/Cargo.toml @@ -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 = "820a028762342fb44b34954a49fa2faec8563198" +rev = "3051b4d4f3808e7301351e0fc9621cd162d8e0b3" [lib] name = "mmtk_ruby" @@ -37,7 +37,7 @@ features = ["is_mmtk_object", "object_pinning", "sticky_immix_non_moving_nursery # Uncomment the following lines to use mmtk-core from the official repository. git = "https://github.com/mmtk/mmtk-core.git" -rev = "d538987ecb3270d89343382dc5464c263adae3e5" +rev = "efe7b41785eeb07473cbadc93b58d4e1e532353d" # Uncomment the following line to use mmtk-core from a local repository. #path = "../../mmtk-core" diff --git a/mmtk/src/abi.rs b/mmtk/src/abi.rs index 8e07198..f9e1272 100644 --- a/mmtk/src/abi.rs +++ b/mmtk/src/abi.rs @@ -11,9 +11,6 @@ pub const GC_THREAD_KIND_WORKER: libc::c_int = 1; pub const HIDDEN_SIZE_MASK: usize = 0x0000FFFFFFFFFFFF; -// Should keep in sync with C code. -const RUBY_FL_EXIVAR: usize = 1 << 10; - // An opaque type for the C counterpart. #[allow(non_camel_case_types)] pub struct st_table; @@ -92,8 +89,8 @@ impl RubyObjectAccess { unsafe { self.flags_field().load::() } } - pub fn has_exivar_flag(&self) -> bool { - (self.load_flags() & RUBY_FL_EXIVAR) != 0 + pub fn has_exivar(&self) -> bool { + (upcalls().has_exivar)(self.objref) } pub fn prefix_size() -> usize { @@ -109,29 +106,6 @@ impl RubyObjectAccess { pub fn object_size(&self) -> usize { Self::prefix_size() + self.payload_size() + Self::suffix_size() } - - pub fn get_gen_fields_tbl(&self) -> *mut libc::c_void { - self.get_original_gen_fields_tbl() - .or_else(|| { - let moved_gen_fields_tables = crate::binding().moved_gen_fields_tables.lock().unwrap(); - moved_gen_fields_tables.get(&self.objref).map(|entry| entry.gen_fields_tbl) - }) - .unwrap_or_else(|| { - panic!( - "The gen_fields_tbl of object {} is not found in generic_fields_tbl_ or binding().moved_gen_fields_tables", - self.objref - ) - }) - } - - pub fn get_original_gen_fields_tbl(&self) -> Option<*mut libc::c_void> { - let addr = (upcalls().get_original_gen_fields_tbl)(self.objref); - if addr.is_null() { - None - } else { - Some(addr) - } - } } type ObjectClosureFunction = @@ -359,23 +333,28 @@ pub struct RubyUpcalls { pub scan_object_ruby_style: extern "C" fn(object: ObjectReference), pub call_gc_mark_children: extern "C" fn(object: ObjectReference), pub call_obj_free: extern "C" fn(object: ObjectReference), - pub cleanup_generic_fields_tbl: extern "C" fn(), - pub get_original_gen_fields_tbl: extern "C" fn(object: ObjectReference) -> *mut libc::c_void, - pub reinsert_generic_fields_tbl_entry: - extern "C" fn(old_objref: ObjectReference, new_objref: ObjectReference), pub vm_live_bytes: extern "C" fn() -> usize, - pub update_frozen_strings_table: extern "C" fn(), - pub update_finalizer_and_obj_id_tables: extern "C" fn(), - pub update_global_symbols_table: extern "C" fn(), - pub update_overloaded_cme_table: extern "C" fn(), + pub has_exivar: extern "C" fn(object: ObjectReference) -> bool, + // Simple table size query and update functions + // Follow the order of `rb_gc_vm_weak_table_foreach` in `gc.c` + pub get_ci_table_size: extern "C" fn() -> usize, pub update_ci_table: extern "C" fn(), - pub get_generic_fields_tbl: extern "C" fn() -> *mut st_table, - pub get_num_fstrings: extern "C" fn() -> usize, - pub get_finalizer_table: extern "C" fn() -> *mut st_table, - pub get_id2ref_table: extern "C" fn() -> *mut st_table, + pub get_overloaded_cme_table_size: extern "C" fn() -> usize, + pub update_overloaded_cme_table: extern "C" fn(), + pub get_global_symbols_table_size: extern "C" fn() -> usize, + pub update_global_symbols_table: extern "C" fn(), + pub get_finalizer_table_size: extern "C" fn() -> usize, + pub get_id2ref_table_size: extern "C" fn() -> usize, + pub update_finalizer_and_obj_id_tables: extern "C" fn(), + pub get_generic_fields_tbl_size: extern "C" fn() -> usize, + pub update_generic_fields_table: extern "C" fn(), + pub get_frozen_strings_table_size: extern "C" fn() -> usize, + pub update_frozen_strings_table: extern "C" fn(), + pub get_cc_refinement_table_size: extern "C" fn() -> usize, + pub update_cc_refinement_table: extern "C" fn(), + // Get tables for specialized processing pub get_global_symbols_table: extern "C" fn() -> *mut st_table, - pub get_overloaded_cme_table: extern "C" fn() -> *mut st_table, - pub get_ci_table: extern "C" fn() -> *mut st_table, + // Detailed table info queries and operations pub st_get_num_entries: extern "C" fn(table: *const st_table) -> usize, pub st_get_size_info: extern "C" fn( table: *const st_table, diff --git a/mmtk/src/api.rs b/mmtk/src/api.rs index aa1cefb..53d5a86 100644 --- a/mmtk/src/api.rs +++ b/mmtk/src/api.rs @@ -9,7 +9,6 @@ use crate::abi; use crate::abi::HiddenHeader; use crate::abi::RawVecOfObjRef; use crate::abi::RubyBindingOptions; -use crate::abi::RubyObjectAccess; use crate::binding; use crate::binding::RubyBinding; use crate::mmtk; @@ -320,9 +319,9 @@ pub unsafe extern "C" fn mmtk_register_ppps(objects: *const ObjectReference, len } #[no_mangle] -pub extern "C" fn mmtk_get_gen_fields_tbl_during_gc(object: ObjectReference) -> *mut libc::c_void { - let acc = RubyObjectAccess::from_objref(object); - acc.get_gen_fields_tbl() +pub extern "C" fn mmtk_get_backwarded_object(object: ObjectReference) -> ObjectReference { + let backwarding_table = crate::binding().backwarding_table.lock().unwrap(); + backwarding_table.get(&object).copied().unwrap_or(object) } #[no_mangle] diff --git a/mmtk/src/binding.rs b/mmtk/src/binding.rs index cde3733..2ec0335 100644 --- a/mmtk/src/binding.rs +++ b/mmtk/src/binding.rs @@ -5,7 +5,6 @@ use std::sync::atomic::AtomicBool; use std::sync::Mutex; use std::thread::JoinHandle; -use libc::c_void; use mmtk::util::ObjectReference; use mmtk::MMTK; @@ -49,11 +48,6 @@ impl RubyBindingFastMut { } } -pub(crate) struct MovedGenFieldsTablesEntry { - pub old_objref: ObjectReference, - pub gen_fields_tbl: *mut c_void, -} - pub struct RubyBinding { pub mmtk: &'static MMTK, pub options: RubyBindingOptions, @@ -61,7 +55,9 @@ pub struct RubyBinding { pub plan_name: Mutex>, pub weak_proc: WeakProcessor, pub ppp_registry: PPPRegistry, - pub(crate) moved_gen_fields_tables: Mutex>, + /// A "backwarding" table that can look up the old addresses of some moved objects, + /// specifically objects using generic fields table. + pub(crate) backwarding_table: Mutex>, pub gc_thread_join_handles: Mutex>>, pub wb_unprotected_objects: Mutex>, pub st_entries_chunk_size: usize, @@ -104,7 +100,7 @@ impl RubyBinding { plan_name: Mutex::new(None), weak_proc: WeakProcessor::new(), ppp_registry: PPPRegistry::new(), - moved_gen_fields_tables: Default::default(), + backwarding_table: Default::default(), gc_thread_join_handles: Default::default(), wb_unprotected_objects: Default::default(), st_entries_chunk_size, diff --git a/mmtk/src/collection.rs b/mmtk/src/collection.rs index ad4da8b..c300b4b 100644 --- a/mmtk/src/collection.rs +++ b/mmtk/src/collection.rs @@ -1,7 +1,7 @@ use crate::abi::GCThreadTLS; use crate::api::RubyMutator; -use crate::{mmtk, upcalls, Ruby}; +use crate::{binding, mmtk, upcalls, Ruby}; use mmtk::memory_manager; use mmtk::scheduler::*; use mmtk::util::{VMMutatorThread, VMThread, VMWorkerThread}; @@ -74,6 +74,14 @@ impl Collection for VMCollection { fn vm_live_bytes() -> usize { (upcalls().vm_live_bytes)() } + + fn post_forwarding(_tls: VMWorkerThread) { + let mut backwarding_table = binding() + .backwarding_table + .try_lock() + .expect("Should not have race during post_forwarding"); + backwarding_table.clear(); + } } impl VMCollection { diff --git a/mmtk/src/object_model.rs b/mmtk/src/object_model.rs index 5fb7cef..217f057 100644 --- a/mmtk/src/object_model.rs +++ b/mmtk/src/object_model.rs @@ -43,11 +43,7 @@ impl ObjectModel for VMObjectModel { copy_context: &mut GCWorkerCopyContext, ) -> ObjectReference { let from_acc = RubyObjectAccess::from_objref(from); - let maybe_gen_fields_tbl = from_acc.has_exivar_flag().then(|| { - from_acc - .get_original_gen_fields_tbl() - .unwrap_or_else(|| panic!("Object {} has FL_EXIVAR but no gen_fields_tbl.", from)) - }); + let has_exivar = from_acc.has_exivar(); let from_start = from_acc.obj_start(); let object_size = from_acc.object_size(); let to_start = copy_context.alloc_copy(from, object_size, MIN_OBJ_ALIGN, 0, semantics); @@ -74,16 +70,12 @@ impl ObjectModel for VMObjectModel { unsafe { std::ptr::write_bytes::(from_start.to_mut_ptr(), 0, object_size) } } - if let Some(gen_fields_tbl) = maybe_gen_fields_tbl { - let mut moved_gen_fields_tables = - crate::binding().moved_gen_fields_tables.lock().unwrap(); - moved_gen_fields_tables.insert( - to_obj, - crate::binding::MovedGenFieldsTablesEntry { - old_objref: from, - gen_fields_tbl, - }, - ); + if has_exivar { + let mut backwarding_table = crate::binding().backwarding_table.lock().unwrap(); + trace!("Inserting into backwarding table: from: {from} <- to_obj: {to_obj}"); + backwarding_table.insert(to_obj, from); + } else { + trace!("No exivar: from: {from} <- to_obj: {to_obj}"); } to_obj diff --git a/mmtk/src/weak_proc.rs b/mmtk/src/weak_proc.rs index 9e12299..74e7c9d 100644 --- a/mmtk/src/weak_proc.rs +++ b/mmtk/src/weak_proc.rs @@ -8,12 +8,14 @@ use mmtk::{ use crate::{ abi::{st_table, GCThreadTLS}, - binding::MovedGenFieldsTablesEntry, extra_assert, is_mmtk_object_safe, upcalls, utils::AfterAll, Ruby, }; +/// Set this to true to use chunked processing optimization for the global symbols table. +const SPECIALIZE_GLOBAL_SYMBOLS_TABLE_PROCESSING: bool = true; + pub struct WeakProcessor { /// Objects that needs `obj_free` called when dying. /// If it is a bottleneck, replace it with a lock-free data structure, @@ -65,25 +67,34 @@ impl WeakProcessor { worker.add_work(WorkBucketStage::VMRefClosure, ProcessObjFreeCandidates); worker.scheduler().work_buckets[WorkBucketStage::VMRefClosure].bulk_add(vec![ + // BEGIN: Weak tables + // Note: Follow the order of `rb_gc_vm_weak_table_foreach in `gc.c` + Box::new(UpdateCiTable) as _, + Box::new(UpdateOverloadedCmeTable) as _, + // global symbols table specialized + Box::new(UpdateFinalizerAndObjIdTables) as _, Box::new(UpdateGenericFieldsTbl) as _, Box::new(UpdateFrozenStringsTable) as _, - Box::new(UpdateFinalizerAndObjIdTables) as _, - // Box::new(UpdateGlobalSymbolsTable) as _, - Box::new(UpdateOverloadedCmeTable) as _, - Box::new(UpdateCiTable) as _, + Box::new(UpdateCCRefinementTable) as _, + // END: Weak tables Box::new(UpdateWbUnprotectedObjectsList) as _, ]); let forward = crate::mmtk().get_plan().current_gc_may_move_object(); - Self::process_weak_table_chunked( - "global symbols", - (upcalls().get_global_symbols_table)(), - false, - true, - forward, - worker, - ); + if SPECIALIZE_GLOBAL_SYMBOLS_TABLE_PROCESSING { + Self::process_weak_table_chunked( + "global symbols", + (upcalls().get_global_symbols_table)(), + false, + true, + forward, + worker, + ); + } else { + worker.scheduler().work_buckets[WorkBucketStage::VMRefClosure] + .add_boxed(Box::new(UpdateGlobalSymbolsTable) as _); + } } pub fn process_weak_table_chunked( @@ -157,51 +168,6 @@ impl WeakProcessor { worker.scheduler().work_buckets[WorkBucketStage::VMRefClosure].bulk_add(entries_packets); } - - /// Update generic instance variable tables. - /// - /// Objects moved during GC should have their entries in the global `generic_fields_tbl_` hash - /// table updated, and dead objects should have their entries removed. - fn update_generic_fields_tbl() { - // Update `generic_fields_tbl_` entries for moved objects. We could update the entries in - // `ObjectModel::move`. However, because `st_table` is not thread-safe, we postpone the - // update until now in the VMRefClosure stage. - log::debug!("Updating generic_fields_tbl_ entries..."); - let items_moved = { - let mut moved_gen_fields_tables = crate::binding() - .moved_gen_fields_tables - .try_lock() - .expect("Should have no race in weak_proc"); - let items_moved = moved_gen_fields_tables.len(); - for (new_objref, MovedGenFieldsTablesEntry { old_objref, .. }) in - moved_gen_fields_tables.drain() - { - trace!( - " generic_fields_tbl_ entry: {} -> {}", - old_objref, - new_objref - ); - (upcalls().reinsert_generic_fields_tbl_entry)(old_objref, new_objref); - } - items_moved - }; - log::debug!("Updated generic_fields_tbl_ entries. {items_moved} items moved."); - - // Clean up entries for dead objects. - let generic_fields_tbl = (upcalls().get_generic_fields_tbl)(); - let old_size = (upcalls().st_get_num_entries)(generic_fields_tbl); - log::debug!("Cleaning up generic_fields_tbl_ entries ({old_size} entries before)..."); - (crate::upcalls().cleanup_generic_fields_tbl)(); - let new_size = (upcalls().st_get_num_entries)(generic_fields_tbl); - log::debug!("Cleaned up generic_fields_tbl_ entries ({new_size} entries after)."); - probe!( - mmtk_ruby, - update_generic_fields_tbl, - items_moved, - old_size, - new_size - ); - } } struct ProcessObjFreeCandidates; @@ -285,55 +251,42 @@ macro_rules! define_global_table_processor { }; } -define_global_table_processor!(UpdateGenericFieldsTbl, { - WeakProcessor::update_generic_fields_tbl(); -}); - -define_global_table_processor!(UpdateFrozenStringsTable, { - let old_size = (upcalls().get_num_fstrings)(); - (upcalls().update_frozen_strings_table)(); - let new_size = (upcalls().get_num_fstrings)(); - probe!(mmtk_ruby, weak_table_size_change, old_size, new_size); -}); - -fn general_update_weak_table(getter: extern "C" fn() -> *mut st_table, cleaner: extern "C" fn()) { - let table = getter(); - let old_size = (upcalls().st_get_num_entries)(table); +fn general_update_weak_table(size_getter: extern "C" fn() -> usize, cleaner: extern "C" fn()) { + let old_size = size_getter(); cleaner(); - let new_size = (upcalls().st_get_num_entries)(table); + let new_size = size_getter(); probe!(mmtk_ruby, weak_table_size_change, old_size, new_size); } -#[allow(dead_code)] -mod unused { - use super::*; - define_global_table_processor!(UpdateGlobalSymbolsTable, { - general_update_weak_table( - upcalls().get_global_symbols_table, - upcalls().update_global_symbols_table, - ); - }); -} +///////// BEGIN: Simple table updating work packets //////// +// Note: Follow the order of `rb_gc_vm_weak_table_foreach in `gc.c` -fn st_get_num_entries_maybe_null(table: *const st_table) -> usize { - if table.is_null() { - 0 - } else { - (upcalls().st_get_num_entries)(table) - } -} +define_global_table_processor!(UpdateCiTable, { + general_update_weak_table(upcalls().get_ci_table_size, upcalls().update_ci_table); +}); -define_global_table_processor!(UpdateFinalizerAndObjIdTables, { - let finalizer_table = (upcalls().get_finalizer_table)(); - let id2ref_table = (upcalls().get_id2ref_table)(); +define_global_table_processor!(UpdateOverloadedCmeTable, { + general_update_weak_table( + upcalls().get_overloaded_cme_table_size, + upcalls().update_overloaded_cme_table, + ); +}); - let old_size_finalizer = (upcalls().st_get_num_entries)(finalizer_table); - let old_size_id_to_obj = st_get_num_entries_maybe_null(id2ref_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().st_get_num_entries)(finalizer_table); - let new_size_id_to_obj = st_get_num_entries_maybe_null(id2ref_table); + let new_size_finalizer = (upcalls().get_finalizer_table_size)(); + let new_size_id_to_obj = (upcalls().get_id2ref_table_size)(); probe!( mmtk_ruby, @@ -345,17 +298,29 @@ define_global_table_processor!(UpdateFinalizerAndObjIdTables, { ); }); -define_global_table_processor!(UpdateOverloadedCmeTable, { +define_global_table_processor!(UpdateGenericFieldsTbl, { general_update_weak_table( - upcalls().get_overloaded_cme_table, - upcalls().update_overloaded_cme_table, + upcalls().get_generic_fields_tbl_size, + upcalls().update_generic_fields_table, ); }); -define_global_table_processor!(UpdateCiTable, { - general_update_weak_table(upcalls().get_ci_table, upcalls().update_ci_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 UpdateTableEntriesParallel { name: &'static str, table: *mut st_table,