diff --git a/vmbindings/dummyvm/Cargo.toml b/vmbindings/dummyvm/Cargo.toml index 674dff7dc0..a1a3af254b 100644 --- a/vmbindings/dummyvm/Cargo.toml +++ b/vmbindings/dummyvm/Cargo.toml @@ -7,7 +7,9 @@ edition = "2021" [lib] name = "mmtk_dummyvm" # be careful - LTO is only allowed for certain crate types -crate-type = ["cdylib"] +# We know that cdylib should work for LTO. +# We keep rlib here as we need to use the crate from benches. +crate-type = ["cdylib", "rlib"] [profile.release] lto = true @@ -20,6 +22,13 @@ atomic_refcell = "0.1.7" atomic = "0.4.6" log = "0.4" +[dev-dependencies] +criterion = "0.4" + +[[bench]] +name = "main" +harness = false + [features] default = [] is_mmtk_object = ["mmtk/is_mmtk_object"] @@ -27,3 +36,7 @@ malloc_counted_size = ["mmtk/malloc_counted_size"] malloc_mark_sweep = ["mmtk/malloc_mark_sweep"] vo_bit = ["mmtk/vo_bit"] extreme_assertions = ["mmtk/extreme_assertions"] + +# Feature to control which benchmarks to run. See benches/main.rs +bench_sft = [] +bench_alloc = [] diff --git a/vmbindings/dummyvm/benches/bench_alloc.rs b/vmbindings/dummyvm/benches/bench_alloc.rs new file mode 100644 index 0000000000..482cfee33f --- /dev/null +++ b/vmbindings/dummyvm/benches/bench_alloc.rs @@ -0,0 +1,18 @@ +use criterion::{criterion_group, Criterion}; + +use mmtk::plan::AllocationSemantics; +use mmtk_dummyvm::api; +use mmtk_dummyvm::test_fixtures::MutatorFixture; + +fn alloc(c: &mut Criterion) { + println!("Init MMTK in alloc bench"); + // 1GB so we are unlikely to OOM + let fixture = MutatorFixture::create_with_heapsize(1 << 30); + c.bench_function("alloc", |b| { + b.iter(|| { + let _addr = api::mmtk_alloc(fixture.mutator, 8, 8, 0, AllocationSemantics::Default); + }) + }); +} + +criterion_group!(benches, alloc); diff --git a/vmbindings/dummyvm/benches/bench_sft.rs b/vmbindings/dummyvm/benches/bench_sft.rs new file mode 100644 index 0000000000..40ccf01406 --- /dev/null +++ b/vmbindings/dummyvm/benches/bench_sft.rs @@ -0,0 +1,20 @@ +use criterion::{black_box, criterion_group, Criterion}; + +use mmtk::plan::AllocationSemantics; +use mmtk::vm::ObjectModel; +use mmtk_dummyvm::api; +use mmtk_dummyvm::test_fixtures::FixtureContent; +use mmtk_dummyvm::test_fixtures::MutatorFixture; + +fn sft(c: &mut Criterion) { + println!("Init MMTK in sft bench"); + let fixture = MutatorFixture::create(); + let addr = api::mmtk_alloc(fixture.mutator, 8, 8, 0, AllocationSemantics::Default); + let obj = mmtk_dummyvm::object_model::VMObjectModel::address_to_ref(addr); + + c.bench_function("sft read", |b| { + b.iter(|| api::mmtk_is_in_mmtk_spaces(black_box(obj))) + }); +} + +criterion_group!(benches, sft); diff --git a/vmbindings/dummyvm/benches/main.rs b/vmbindings/dummyvm/benches/main.rs new file mode 100644 index 0000000000..804379ee1b --- /dev/null +++ b/vmbindings/dummyvm/benches/main.rs @@ -0,0 +1,15 @@ +use criterion::criterion_main; + +// As we can only initialize one MMTk instance, we have to run each benchmark separately. +// Filtering like `cargo bench -- sft` won't work, as it still evalutes all the benchmark groups (which initialize MMTk). +// We can use conditional compilation, and run with `cargo bench --features bench_sft`. The features are defined in the dummy VM crate. + +#[cfg(feature = "bench_sft")] +mod bench_sft; +#[cfg(feature = "bench_sft")] +criterion_main!(bench_sft::benches); + +#[cfg(feature = "bench_alloc")] +mod bench_alloc; +#[cfg(feature = "bench_alloc")] +criterion_main!(bench_alloc::benches); diff --git a/vmbindings/dummyvm/src/lib.rs b/vmbindings/dummyvm/src/lib.rs index ab13607e24..57e630f222 100644 --- a/vmbindings/dummyvm/src/lib.rs +++ b/vmbindings/dummyvm/src/lib.rs @@ -14,6 +14,8 @@ pub mod object_model; pub mod reference_glue; pub mod scanning; +pub mod test_fixtures; + mod edges; #[cfg(test)] mod tests; diff --git a/vmbindings/dummyvm/src/tests/fixtures/mod.rs b/vmbindings/dummyvm/src/test_fixtures.rs similarity index 94% rename from vmbindings/dummyvm/src/tests/fixtures/mod.rs rename to vmbindings/dummyvm/src/test_fixtures.rs index ccda59970f..4e400bc6d2 100644 --- a/vmbindings/dummyvm/src/tests/fixtures/mod.rs +++ b/vmbindings/dummyvm/src/test_fixtures.rs @@ -43,6 +43,12 @@ impl Fixture { } } +impl Default for Fixture { + fn default() -> Self { + Self::new() + } +} + /// SerialFixture ensures all `with_fixture()` calls will be executed serially. pub struct SerialFixture { content: Mutex>>, @@ -85,6 +91,12 @@ impl SerialFixture { } } +impl Default for SerialFixture { + fn default() -> Self { + Self::new() + } +} + pub struct SingleObject { pub objref: ObjectReference, } @@ -171,8 +183,13 @@ pub struct MutatorFixture { impl FixtureContent for MutatorFixture { fn create() -> Self { const MB: usize = 1024 * 1024; - // 1MB heap - mmtk_init(MB); + Self::create_with_heapsize(MB) + } +} + +impl MutatorFixture { + pub fn create_with_heapsize(size: usize) -> Self { + mmtk_init(size); mmtk_initialize_collection(VMThread::UNINITIALIZED); // Make sure GC does not run during test. mmtk_disable_collection(); diff --git a/vmbindings/dummyvm/src/tests/allocate_align_offset.rs b/vmbindings/dummyvm/src/tests/allocate_align_offset.rs index c68cac7378..ed39c5ce20 100644 --- a/vmbindings/dummyvm/src/tests/allocate_align_offset.rs +++ b/vmbindings/dummyvm/src/tests/allocate_align_offset.rs @@ -1,7 +1,7 @@ // GITHUB-CI: MMTK_PLAN=all use crate::api; -use crate::tests::fixtures::{MutatorFixture, SerialFixture}; +use crate::test_fixtures::{MutatorFixture, SerialFixture}; use crate::DummyVM; use log::info; use mmtk::plan::AllocationSemantics; diff --git a/vmbindings/dummyvm/src/tests/barrier_slow_path_assertion.rs b/vmbindings/dummyvm/src/tests/barrier_slow_path_assertion.rs index f8394a48ab..063c053dcd 100644 --- a/vmbindings/dummyvm/src/tests/barrier_slow_path_assertion.rs +++ b/vmbindings/dummyvm/src/tests/barrier_slow_path_assertion.rs @@ -4,8 +4,8 @@ // Run the test with any plan that uses object barrier, and we also need both VO bit and extreme assertions. use crate::object_model::OBJECT_REF_OFFSET; -use crate::tests::fixtures::FixtureContent; -use crate::tests::fixtures::MMTKSingleton; +use crate::test_fixtures::FixtureContent; +use crate::test_fixtures::MMTKSingleton; use crate::{api::*, edges}; use atomic::Atomic; use mmtk::util::{Address, ObjectReference}; diff --git a/vmbindings/dummyvm/src/tests/conservatism.rs b/vmbindings/dummyvm/src/tests/conservatism.rs index b2ef84c1cf..6262769888 100644 --- a/vmbindings/dummyvm/src/tests/conservatism.rs +++ b/vmbindings/dummyvm/src/tests/conservatism.rs @@ -3,7 +3,7 @@ use crate::api::*; use crate::object_model::OBJECT_REF_OFFSET; -use crate::tests::fixtures::{Fixture, SingleObject}; +use crate::test_fixtures::{Fixture, SingleObject}; use mmtk::util::constants::LOG_BITS_IN_WORD; use mmtk::util::is_mmtk_object::VO_BIT_REGION_SIZE; use mmtk::util::*; diff --git a/vmbindings/dummyvm/src/tests/edges_test.rs b/vmbindings/dummyvm/src/tests/edges_test.rs index 92c50dbbb4..f927e420a6 100644 --- a/vmbindings/dummyvm/src/tests/edges_test.rs +++ b/vmbindings/dummyvm/src/tests/edges_test.rs @@ -8,7 +8,7 @@ use mmtk::{ use crate::{ edges::{DummyVMEdge, OffsetEdge, TaggedEdge}, - tests::fixtures::{Fixture, TwoObjects}, + test_fixtures::{Fixture, TwoObjects}, }; #[cfg(target_pointer_width = "64")] diff --git a/vmbindings/dummyvm/src/tests/is_in_mmtk_spaces.rs b/vmbindings/dummyvm/src/tests/is_in_mmtk_spaces.rs index 7e14fb9bc9..8a41f4116f 100644 --- a/vmbindings/dummyvm/src/tests/is_in_mmtk_spaces.rs +++ b/vmbindings/dummyvm/src/tests/is_in_mmtk_spaces.rs @@ -1,7 +1,7 @@ // GITHUB-CI: MMTK_PLAN=all use crate::api::mmtk_is_in_mmtk_spaces as is_in_mmtk_spaces; -use crate::tests::fixtures::{Fixture, SingleObject}; +use crate::test_fixtures::{Fixture, SingleObject}; use mmtk::util::*; lazy_static! { diff --git a/vmbindings/dummyvm/src/tests/issue867_allocate_unrealistically_large_object.rs b/vmbindings/dummyvm/src/tests/issue867_allocate_unrealistically_large_object.rs index 3cdaf12d8d..8822506413 100644 --- a/vmbindings/dummyvm/src/tests/issue867_allocate_unrealistically_large_object.rs +++ b/vmbindings/dummyvm/src/tests/issue867_allocate_unrealistically_large_object.rs @@ -1,7 +1,7 @@ // GITHUB-CI: MMTK_PLAN=all use crate::api; -use crate::tests::fixtures::{MutatorFixture, SerialFixture}; +use crate::test_fixtures::{MutatorFixture, SerialFixture}; use mmtk::plan::AllocationSemantics; lazy_static! { diff --git a/vmbindings/dummyvm/src/tests/malloc_counted.rs b/vmbindings/dummyvm/src/tests/malloc_counted.rs index d5d8ef678a..c7c6639d0c 100644 --- a/vmbindings/dummyvm/src/tests/malloc_counted.rs +++ b/vmbindings/dummyvm/src/tests/malloc_counted.rs @@ -1,7 +1,7 @@ // GITHUB-CI: FEATURES=malloc_counted_size use crate::api::*; -use crate::tests::fixtures::{MMTKSingleton, SerialFixture}; +use crate::test_fixtures::{MMTKSingleton, SerialFixture}; lazy_static! { static ref MMTK_SINGLETON: SerialFixture = SerialFixture::new(); diff --git a/vmbindings/dummyvm/src/tests/mod.rs b/vmbindings/dummyvm/src/tests/mod.rs index acc48a3eb5..f6eb288ca0 100644 --- a/vmbindings/dummyvm/src/tests/mod.rs +++ b/vmbindings/dummyvm/src/tests/mod.rs @@ -13,7 +13,6 @@ mod barrier_slow_path_assertion; #[cfg(feature = "is_mmtk_object")] mod conservatism; mod edges_test; -mod fixtures; #[cfg(target_os = "linux")] mod handle_mmap_conflict; mod handle_mmap_oom; diff --git a/vmbindings/dummyvm/src/tests/vm_layout_default.rs b/vmbindings/dummyvm/src/tests/vm_layout_default.rs index 9d95c314ca..38fa24a10e 100644 --- a/vmbindings/dummyvm/src/tests/vm_layout_default.rs +++ b/vmbindings/dummyvm/src/tests/vm_layout_default.rs @@ -4,7 +4,7 @@ use mmtk::util::heap::vm_layout::VMLayout; pub fn test_with_vm_layout(layout: Option) { use crate::api; - use crate::tests::fixtures::VMLayoutFixture; + use crate::test_fixtures::VMLayoutFixture; use mmtk::plan::AllocationSemantics; use mmtk::vm::ObjectModel;