diff --git a/Cargo.lock b/Cargo.lock index dd06c5b..c79290c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + [[package]] name = "anstream" version = "0.6.18" @@ -107,6 +113,12 @@ dependencies = [ "git2", ] +[[package]] +name = "bumpalo" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" + [[package]] name = "bytemuck" version = "1.21.0" @@ -133,6 +145,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + [[package]] name = "cc" version = "1.2.12" @@ -150,6 +168,33 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "clap" version = "4.5.28" @@ -202,6 +247,42 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "criterion" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "is-terminal", + "itertools 0.10.5", + "num-traits", + "once_cell", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools 0.10.5", +] + [[package]] name = "crossbeam" version = "0.8.4" @@ -258,6 +339,12 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crunchy" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" + [[package]] name = "delegate" version = "0.12.0" @@ -390,6 +477,16 @@ dependencies = [ "url", ] +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "heck" version = "0.5.0" @@ -570,6 +667,15 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.12.1" @@ -579,6 +685,12 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + [[package]] name = "jobserver" version = "0.1.32" @@ -588,6 +700,16 @@ dependencies = [ "libc", ] +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -678,7 +800,7 @@ dependencies = [ "enum-map", "env_logger", "is-terminal", - "itertools", + "itertools 0.12.1", "lazy_static", "libc", "log", @@ -806,6 +928,12 @@ version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" +[[package]] +name = "oorandom" +version = "11.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" + [[package]] name = "parking_lot" version = "0.12.3" @@ -841,6 +969,34 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +[[package]] +name = "plotters" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" + +[[package]] +name = "plotters-svg" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" +dependencies = [ + "plotters-backend", +] + [[package]] name = "portable-atomic" version = "1.10.0" @@ -1008,6 +1164,21 @@ version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" +[[package]] +name = "ryu" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -1040,6 +1211,18 @@ dependencies = [ "syn 2.0.98", ] +[[package]] +name = "serde_json" +version = "1.0.138" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + [[package]] name = "shlex" version = "1.3.0" @@ -1155,6 +1338,16 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "unicode-ident" version = "1.0.16" @@ -1210,9 +1403,12 @@ dependencies = [ "bytemuck", "cfg-if", "clap", + "criterion", "easy-bitfield", + "env_logger", "errno", "libc", + "log", "mmtk", "parking_lot", "rand", @@ -1228,6 +1424,16 @@ dependencies = [ "syn 2.0.98", ] +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "wasi" version = "0.13.3+wasi-0.2.2" @@ -1237,6 +1443,74 @@ dependencies = [ "wit-bindgen-rt", ] +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.98", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1253,6 +1527,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index 103205b..5a748cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,7 @@ [workspace] members = ["vmkit", "vmkit-proc"] default-members = ["vmkit"] -resolver = "2" \ No newline at end of file +resolver = "2" + +[workspace.example] +members = ["examples/*"] \ No newline at end of file diff --git a/vmkit/Cargo.toml b/vmkit/Cargo.toml index eb558f0..613d972 100644 --- a/vmkit/Cargo.toml +++ b/vmkit/Cargo.toml @@ -9,8 +9,10 @@ bytemuck = "1.21.0" cfg-if = "1.0.0" clap = { version = "4.5.28", features = ["derive"] } easy-bitfield = "0.1.0" +env_logger = "0.11.6" errno = "0.3.10" libc = "0.2.169" +log = "0.4.25" mmtk = { git = "https://github.com/mmtk/mmtk-core" } parking_lot = "0.12.3" rand = "0.9.0" @@ -31,3 +33,10 @@ full-precise = [] [target.'cfg(windows)'.dependencies] winapi = { version = "0.3.9", features = ["everything"] } + +[dev-dependencies] +criterion = "0.5.1" + +[[bench]] +name = "binarytrees" +harness = false diff --git a/vmkit/benches/binarytrees.rs b/vmkit/benches/binarytrees.rs new file mode 100644 index 0000000..e69de29 diff --git a/vmkit/src/lib.rs b/vmkit/src/lib.rs index d93f247..827e72c 100644 --- a/vmkit/src/lib.rs +++ b/vmkit/src/lib.rs @@ -17,7 +17,7 @@ pub trait VirtualMachine: Sized + 'static + Send + Sync { type Slot: SlotExtra; const MAX_ALIGNMENT: usize = 16; - const MIN_ALIGNMENT: usize = 16; + const MIN_ALIGNMENT: usize = 8; /// Does this VM use conservative tracing? If `true` then VM can /// query VO-bit (valid-object bit) to check if an object is live diff --git a/vmkit/src/main.rs b/vmkit/src/main.rs index c035957..8185fdb 100644 --- a/vmkit/src/main.rs +++ b/vmkit/src/main.rs @@ -1,42 +1,72 @@ -use easy_bitfield::{FromBitfield, ToBitfield}; + use mmtk::{util::options::PlanSelector, vm::slot::SimpleSlot, AllocationSemantics, MMTKBuilder}; +use std::mem::offset_of; use std::sync::OnceLock; use vmkit::{ - mm::{traits::ToSlot, MemoryManager}, - object_model::metadata::{GCMetadata, Metadata, Trace}, + mm::{traits::Trace, MemoryManager}, + object_model::{ + metadata::{GCMetadata, TraceCallback}, + object::VMKitObject, + }, threading::{GCBlockAdapter, Thread, ThreadContext}, VMKit, VirtualMachine, }; -struct TestContext; +const CONSERVATIVE_TRACE_NODE: bool = false; -impl ThreadContext for TestContext { +#[repr(C)] +struct Node { + left: VMKitObject, + right: VMKitObject, + i: usize, + j: usize, +} + +static METADATA: GCMetadata = GCMetadata { + trace: TraceCallback::TraceObject(|object, tracer| unsafe { + let node = object.as_address().as_mut_ref::(); + node.left.trace_object(tracer); + node.right.trace_object(tracer); + }), + instance_size: size_of::(), + compute_size: None, + alignment: 16, +}; + +struct BenchVM { + vmkit: VMKit, +} + +static VM: OnceLock = OnceLock::new(); + +struct ThreadBenchContext; + +impl ThreadContext for ThreadBenchContext { + fn new(_: bool) -> Self { + Self + } fn save_thread_state(&self) {} - fn scan_roots(&self, _factory: impl mmtk::vm::RootsWorkFactory<::Slot>) {} + fn scan_roots( + &self, + _factory: impl mmtk::vm::RootsWorkFactory<::Slot>, + ) { + } fn scan_conservative_roots( &self, - croots: &mut vmkit::mm::conservative_roots::ConservativeRoots, + _croots: &mut vmkit::mm::conservative_roots::ConservativeRoots, ) { - let _ = croots; - } - - fn new(_collector_context: bool) -> Self { - Self } } -static VM_STORAGE: OnceLock = OnceLock::new(); -impl VirtualMachine for VM { - const MAX_ALIGNMENT: usize = 16; - const MIN_ALIGNMENT: usize = 16; - type ThreadContext = TestContext; - type BlockAdapterList = (GCBlockAdapter, ()); - type Metadata = &'static GCMetadata; - type Slot = SimpleSlot; +impl VirtualMachine for BenchVM { + type BlockAdapterList = (GCBlockAdapter, ()); + type Metadata = &'static GCMetadata; + type Slot = SimpleSlot; + type ThreadContext = ThreadBenchContext; fn get() -> &'static Self { - VM_STORAGE.get().unwrap() + VM.get().unwrap() } fn vmkit(&self) -> &VMKit { @@ -45,7 +75,16 @@ impl VirtualMachine for VM { fn prepare_for_roots_re_scanning() {} - fn notify_initial_thread_scan_complete(_partial_scan: bool, _tls: mmtk::util::VMWorkerThread) {} + fn notify_initial_thread_scan_complete(partial_scan: bool, tls: mmtk::util::VMWorkerThread) { + let _ = partial_scan; + let _ = tls; + } + + fn forward_weak_refs( + _worker: &mut mmtk::scheduler::GCWorker>, + _tracer_context: impl mmtk::vm::ObjectTracerContext>, + ) { + } fn scan_roots_in_mutator_thread( _tls: mmtk::util::VMWorkerThread, @@ -63,105 +102,138 @@ impl VirtualMachine for VM { >, ) { } - - fn forward_weak_refs( - _worker: &mut mmtk::scheduler::GCWorker>, - _tracer_context: impl mmtk::vm::ObjectTracerContext>, - ) { - todo!() - } } -struct VM { - vmkit: VMKit, +fn make_node( + thread: &Thread, + left: VMKitObject, + right: VMKitObject, + i: usize, + j: usize, +) -> VMKitObject { + let node = MemoryManager::allocate( + thread, + size_of::(), + 16, + &METADATA, + AllocationSemantics::Default, + ); + + unsafe { + node.set_field_object_no_write_barrier::(offset_of!(Node, left), left); + node.set_field_object_no_write_barrier::(offset_of!(Node, right), right); + node.set_field_usize::(offset_of!(Node, i), i); + node.set_field_usize::(offset_of!(Node, j), j); + } + node } -static METADATA: GCMetadata = GCMetadata { - instance_size: 48, - compute_size: None, - trace: Trace::TraceObject(|object, _tracer| { - println!("tracing {}", object.as_address()); - }), - alignment: 16, -}; - -struct FooMeta; - -impl Metadata for FooMeta { - const METADATA_BIT_SIZE: usize = 56; - fn gc_metadata(&self) -> &'static GCMetadata { - &METADATA - } - - fn is_object(&self) -> bool { - false - } - - fn from_object_reference(_reference: mmtk::util::ObjectReference) -> Self { - unreachable!() - } - - fn to_object_reference(&self) -> Option { - unreachable!() - } +fn tree_size(i: usize) -> usize { + (1 << (i + 1)) - 1 } -impl ToSlot for FooMeta { - fn to_slot(&self) -> Option { - None - } +fn num_iters(stretch_tree_depth: usize, i: usize) -> usize { + 4 + tree_size(stretch_tree_depth) / tree_size(i) } -impl FromBitfield for FooMeta { - fn from_bitfield(_bitfield: u64) -> Self { - FooMeta +fn populate(thread: &Thread, depth: usize, this_node: VMKitObject) { + let mut depth = depth; + if depth <= 0 { + return; } - fn from_i64(_value: i64) -> Self { - FooMeta - } + depth -= 1; + this_node.set_field_object::( + offset_of!(Node, left), + make_node(thread, VMKitObject::NULL, VMKitObject::NULL, 0, 0), + ); + let left = this_node.get_field_object::(offset_of!(Node, left)); + this_node.set_field_object::( + offset_of!(Node, right), + make_node(thread, VMKitObject::NULL, VMKitObject::NULL, 0, 0), + ); + + + + populate( + thread, + depth, + this_node.get_field_object::(offset_of!(Node, left)), + ); + populate( + thread, + depth, + this_node.get_field_object::(offset_of!(Node, right)), + ); } -impl ToBitfield for FooMeta { - fn to_bitfield(self) -> u64 { - 0 +fn make_tree(thread: &Thread, depth: usize) -> VMKitObject { + if depth <= 0 { + return make_node(thread, VMKitObject::NULL, VMKitObject::NULL, 0, 0); } - fn one() -> Self { - FooMeta - } - - fn zero() -> Self { - FooMeta - } + let left = make_tree(thread, depth - 1); + let right = make_tree(thread, depth - 1); + make_node(thread, left, right, 0, 0) } -extern "C-unwind" fn handler(signum: libc::c_int) { - println!("signal {signum}"); - println!("backtrace:\n{}", std::backtrace::Backtrace::force_capture()); - std::process::exit(1); +fn time_construction(thread: &Thread, stretch_tree_depth: usize, depth: usize) { + let i_num_iters = num_iters(stretch_tree_depth, depth); + println!("creating {} trees of depth {}", i_num_iters, depth); + let start = std::time::Instant::now(); + + let mut i = 0; + while i < i_num_iters { + let temp_tree = make_node(thread, VMKitObject::NULL, VMKitObject::NULL, 0, 0); + populate(thread, depth, temp_tree); + i += 1; + } + + let finish = std::time::Instant::now(); + println!("\tTop down construction took: {:04}ms", finish.duration_since(start).as_micros() as f64 / 1000.0); + + + let duration = start.elapsed(); + println!("time_construction: {:?}", duration); } fn main() { - unsafe { - libc::signal(libc::SIGSEGV, handler as usize); - } + env_logger::init(); + let mut options = MMTKBuilder::new(); + options.options.plan.set(PlanSelector::StickyImmix); + options.options.gc_trigger.set(mmtk::util::options::GCTriggerSelector::DynamicHeapSize(64*1024*1024, 8*1024*1024*1024)); + let vm = BenchVM { + vmkit: VMKit::new(options) + }; - let mut mmtk = MMTKBuilder::new(); - mmtk.options.plan.set(PlanSelector::Immix); - mmtk.options.threads.set(1); - VM_STORAGE.get_or_init(|| VM { - vmkit: VMKit::new(mmtk), + VM.set(vm).unwrap_or_else(|_| panic!("Failed to set VM")); + + Thread::::main(ThreadBenchContext, || { + let tls= Thread::::current(); + + let depth = std::env::var("DEPTH").unwrap_or("18".to_string()).parse::().unwrap(); + let long_lived_tree_depth = depth; + + let stretch_tree_depth = depth + 1; + + println!("stretching memory with tree of depth: {}", stretch_tree_depth); + let start = std::time::Instant::now(); + make_tree(tls, stretch_tree_depth as _); + + println!("creating long-lived tree of depth: {}", long_lived_tree_depth); + let long_lived_tree = make_node(tls, VMKitObject::NULL, VMKitObject::NULL, 0, 0); + populate(tls, long_lived_tree_depth as _, long_lived_tree); + + + let mut d = 4; + + while d <= depth { + time_construction(tls, stretch_tree_depth, d); + d += 2; + } + + let finish = std::time::Instant::now(); + println!("total execution time: {:04}ms", finish.duration_since(start).as_micros() as f64 / 1000.0); + }); - - Thread::::main(TestContext, || { - let tls = Thread::::current(); - let my_obj = MemoryManager::allocate(tls, 48, 16, &METADATA, AllocationSemantics::Default); - - println!("Allocated object at {}", my_obj.as_address()); - - MemoryManager::::request_gc(); - - println!("object {} at {:p}", my_obj.as_address(), &my_obj); - }); -} +} \ No newline at end of file diff --git a/vmkit/src/mm.rs b/vmkit/src/mm.rs index e1f9f96..419ca99 100644 --- a/vmkit/src/mm.rs +++ b/vmkit/src/mm.rs @@ -73,11 +73,12 @@ impl MemoryManager { #[inline] pub extern "C-unwind" fn allocate( thread: &Thread, - size: usize, + mut size: usize, alignment: usize, metadata: VM::Metadata, mut semantics: AllocationSemantics, ) -> VMKitObject { + size += size_of::>(); if semantics == AllocationSemantics::Default && size >= thread.max_non_los_default_alloc_bytes() { @@ -103,7 +104,6 @@ impl MemoryManager { }); let object = VMKitObject::from_address(object_start + OBJECT_REF_OFFSET); Self::set_vo_bit(object); - Self::refill_tlab(thread); return object; } diff --git a/vmkit/src/mm/active_plan.rs b/vmkit/src/mm/active_plan.rs index 907ae61..1f0c2db 100644 --- a/vmkit/src/mm/active_plan.rs +++ b/vmkit/src/mm/active_plan.rs @@ -10,6 +10,7 @@ pub struct VMKitActivePlan(PhantomData); impl ActivePlan> for VMKitActivePlan { fn is_mutator(tls: mmtk::util::VMThread) -> bool { + let x = Thread::::from_vm_thread(tls); Thread::::from_vm_thread(tls).active_mutator_context() } diff --git a/vmkit/src/mm/aslr.rs b/vmkit/src/mm/aslr.rs index 3ce2e37..2697e75 100644 --- a/vmkit/src/mm/aslr.rs +++ b/vmkit/src/mm/aslr.rs @@ -34,7 +34,7 @@ fn is_address_maybe_unmapped(addr: Address, size: usize) -> bool { } pub fn aslr_vm_layout(mmtk_options: &mut Options) -> VMLayout { - let mut vm_layout = VMLayout::default(); + /*let mut vm_layout = VMLayout::default(); let options = &*OPTIONS; if options.compressed_pointers { @@ -89,7 +89,9 @@ pub fn aslr_vm_layout(mmtk_options: &mut Options) -> VMLayout { options.max_heap_size, )); - vm_layout + vm_layout*/ + + VMLayout::default() } diff --git a/vmkit/src/mm/scanning.rs b/vmkit/src/mm/scanning.rs index a233643..24bb22c 100644 --- a/vmkit/src/mm/scanning.rs +++ b/vmkit/src/mm/scanning.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use crate::{ mm::MemoryManager, object_model::{ - metadata::{Metadata, Trace}, + metadata::{Metadata, TraceCallback}, object::VMKitObject, }, options::OPTIONS, @@ -57,11 +57,11 @@ impl Scanning> for VMKitScanning { let gc_metadata = metadata.gc_metadata(); let trace = &gc_metadata.trace; match trace { - Trace::ScanSlots(fun) => { + TraceCallback::ScanSlots(fun) => { fun(object, slot_visitor); } - Trace::None => (), - Trace::TraceObject(_) => { + TraceCallback::None => (), + TraceCallback::TraceObject(_) => { unreachable!("TraceObject is not supported for scanning"); } } @@ -77,7 +77,7 @@ impl Scanning> for VMKitScanning { let gc_metadata = metadata.gc_metadata(); let trace = &gc_metadata.trace; match trace { - Trace::ScanSlots(fun) => { + TraceCallback::ScanSlots(fun) => { // wrap object tracer in a trait that implements SlotVisitor // but actually traces the object directly. let mut visitor = TraceSlotVisitor:: { @@ -86,8 +86,8 @@ impl Scanning> for VMKitScanning { }; fun(object, &mut visitor); } - Trace::None => (), - Trace::TraceObject(fun) => { + TraceCallback::None => (), + TraceCallback::TraceObject(fun) => { fun(object, object_tracer); } } @@ -123,7 +123,7 @@ impl Scanning> for VMKitScanning { ) -> bool { let object = VMKitObject::from(object); let metadata = object.header::().metadata(); - matches!(metadata.gc_metadata().trace, Trace::ScanSlots(_)) + matches!(metadata.gc_metadata().trace, TraceCallback::ScanSlots(_)) && (!metadata.is_object() || metadata.to_slot().is_some()) } diff --git a/vmkit/src/mm/tlab.rs b/vmkit/src/mm/tlab.rs index 6bc1103..8e9fb2c 100644 --- a/vmkit/src/mm/tlab.rs +++ b/vmkit/src/mm/tlab.rs @@ -18,9 +18,9 @@ impl TLAB { let aligned_size = raw_align_up(size, alignment); let result = self.cursor.align_up(alignment); if result + aligned_size > self.limit { - return Address::ZERO; } else { + self.cursor = result.add(aligned_size); return result; } diff --git a/vmkit/src/mm/traits.rs b/vmkit/src/mm/traits.rs index 895fe16..c578420 100644 --- a/vmkit/src/mm/traits.rs +++ b/vmkit/src/mm/traits.rs @@ -24,15 +24,15 @@ pub trait ToSlot { } pub trait Trace { - fn trace_object(&mut self, tracer: &mut impl ObjectTracer); + fn trace_object(&mut self, tracer: &mut dyn ObjectTracer); } pub trait Scan { - fn scan_object(&self, visitor: &mut impl SlotVisitor); + fn scan_object(&self, visitor: &mut dyn SlotVisitor); } impl Trace for VMKitObject { - fn trace_object(&mut self, tracer: &mut impl ObjectTracer) { + fn trace_object(&mut self, tracer: &mut dyn ObjectTracer) { if self.is_null() { return; } @@ -45,7 +45,7 @@ impl Trace for VMKitObject { } impl Trace for InternalPointer { - fn trace_object(&mut self, tracer: &mut impl ObjectTracer) { + fn trace_object(&mut self, tracer: &mut dyn ObjectTracer) { #[cfg(feature = "cooperative")] { assert!( @@ -72,7 +72,7 @@ impl Trace for InternalPointer { } impl Scan for VMKitObject { - fn scan_object(&self, visitor: &mut impl SlotVisitor) { + fn scan_object(&self, visitor: &mut dyn SlotVisitor) { if let Some(slot) = self.to_slot() { visitor.visit_slot(slot); } @@ -167,7 +167,7 @@ macro_rules! impl_prim { } impl Scan for $t { - fn scan_object(&self, visitor: &mut impl SlotVisitor) { + fn scan_object(&self, visitor: &mut dyn SlotVisitor) { let _ = visitor; } } @@ -179,7 +179,7 @@ macro_rules! impl_prim { } impl Trace for $t { - fn trace_object(&mut self, tracer: &mut impl ObjectTracer) { + fn trace_object(&mut self, tracer: &mut dyn ObjectTracer) { let _ = tracer; } } @@ -210,7 +210,7 @@ impl SupportsEnqueuing for Result Trace for Option { - fn trace_object(&mut self, tracer: &mut impl ObjectTracer) { + fn trace_object(&mut self, tracer: &mut dyn ObjectTracer) { if let Some(value) = self { value.trace_object(tracer); } @@ -218,7 +218,7 @@ impl Trace for Option { } impl Trace for Vec { - fn trace_object(&mut self, tracer: &mut impl ObjectTracer) { + fn trace_object(&mut self, tracer: &mut dyn ObjectTracer) { for value in self { value.trace_object(tracer); } @@ -226,7 +226,7 @@ impl Trace for Vec { } impl Trace for [T; N] { - fn trace_object(&mut self, tracer: &mut impl ObjectTracer) { + fn trace_object(&mut self, tracer: &mut dyn ObjectTracer) { for value in self { value.trace_object(tracer); } @@ -234,13 +234,13 @@ impl Trace for [T; N] { } impl Trace for Box { - fn trace_object(&mut self, tracer: &mut impl ObjectTracer) { + fn trace_object(&mut self, tracer: &mut dyn ObjectTracer) { (**self).trace_object(tracer); } } impl> Scan for Vec { - fn scan_object(&self, visitor: &mut impl SlotVisitor) { + fn scan_object(&self, visitor: &mut dyn SlotVisitor) { for value in self { value.scan_object(visitor); } @@ -248,7 +248,7 @@ impl> Scan for Vec { } impl, const N: usize> Scan for [T; N] { - fn scan_object(&self, visitor: &mut impl SlotVisitor) { + fn scan_object(&self, visitor: &mut dyn SlotVisitor) { for value in self { value.scan_object(visitor); } @@ -260,7 +260,7 @@ impl SupportsEnqueuing for FatInternalPointer { } impl Scan for FatInternalPointer { - fn scan_object(&self, visitor: &mut impl SlotVisitor) { + fn scan_object(&self, visitor: &mut dyn SlotVisitor) { visitor.visit_slot(self.object().to_slot().expect("never fails")); } } @@ -272,14 +272,14 @@ impl ToSlot for FatInternalPoin } impl Trace for FatInternalPointer { - fn trace_object(&mut self, tracer: &mut impl ObjectTracer) { + fn trace_object(&mut self, tracer: &mut dyn ObjectTracer) { self.object().trace_object(tracer); } } impl Trace for VMKitNarrow { - fn trace_object(&mut self, tracer: &mut impl ObjectTracer) { + fn trace_object(&mut self, tracer: &mut dyn ObjectTracer) { let mut object = self.to_object(); object.trace_object(tracer); *self = VMKitNarrow::encode(object); @@ -287,7 +287,7 @@ impl Trace for VMKitNarrow { } impl Scan for VMKitNarrow { - fn scan_object(&self, visitor: &mut impl SlotVisitor) { + fn scan_object(&self, visitor: &mut dyn SlotVisitor) { let slot = SL::from_narrow(self); visitor.visit_slot(slot); } diff --git a/vmkit/src/object_model.rs b/vmkit/src/object_model.rs index c7a6c5a..839f725 100644 --- a/vmkit/src/object_model.rs +++ b/vmkit/src/object_model.rs @@ -132,6 +132,7 @@ impl ObjectModel> for VMKitObjectModel } impl VMKitObjectModel { fn move_object(from_obj: VMKitObject, mut to: MoveTarget, num_bytes: usize) -> VMKitObject { + log::trace!("move_object: from_obj: {}, to: {}", from_obj.as_address(), to); let mut copy_bytes = num_bytes; let mut obj_ref_offset = OBJECT_REF_OFFSET; let hash_state = from_obj.header::().hash_state(); diff --git a/vmkit/src/object_model/metadata.rs b/vmkit/src/object_model/metadata.rs index 6e0608a..aba87c7 100644 --- a/vmkit/src/object_model/metadata.rs +++ b/vmkit/src/object_model/metadata.rs @@ -10,14 +10,14 @@ use super::object::VMKitObject; #[repr(C)] pub struct GCMetadata { - pub trace: Trace, + pub trace: TraceCallback, pub instance_size: usize, pub compute_size: Option usize>, pub alignment: usize, } #[derive(Debug)] -pub enum Trace { +pub enum TraceCallback { ScanSlots(fn(VMKitObject, &mut dyn SlotVisitor)), TraceObject(fn(VMKitObject, &mut dyn ObjectTracer)), None, diff --git a/vmkit/src/object_model/object.rs b/vmkit/src/object_model/object.rs index 4ee5d6b..bb8cedd 100644 --- a/vmkit/src/object_model/object.rs +++ b/vmkit/src/object_model/object.rs @@ -1,3 +1,5 @@ +use std::fmt; + use crate::mm::traits::SlotExtra; use crate::threading::Thread; use crate::{mm::MemoryManager, VirtualMachine}; @@ -514,6 +516,15 @@ pub enum MoveTarget { ToObject(VMKitObject), } +impl fmt::Display for MoveTarget { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + MoveTarget::ToAddress(addr) => write!(f, "ToAddress({})", addr), + MoveTarget::ToObject(obj) => write!(f, "ToObject({})", obj.as_address()), + } + } +} + /// Narrow pointer to an object. This is used when pointer compression /// is enabled. #[repr(transparent)] diff --git a/vmkit/src/options.rs b/vmkit/src/options.rs index efbd31f..90e2ac4 100644 --- a/vmkit/src/options.rs +++ b/vmkit/src/options.rs @@ -12,7 +12,7 @@ pub struct Options { #[clap(long, default_value_t = 1024)] pub interior_pointer_max_bytes: usize, - #[clap(long, default_value_t = true)] + #[clap(long, default_value_t = false)] pub aslr: bool, #[clap(long, default_value_t = true)]