Skip to content
Open
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
1 change: 1 addition & 0 deletions .github/scripts/ci-common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ dummyvm_toml=$project_root/docs/dummyvm/Cargo.toml

# Pin certain deps for our MSRV
cargo update -p [email protected] --precise 0.5.5 # This can be removed once we move to Rust 1.81 or newer
cargo update -p [email protected] --precise 0.5.5 # This requires Rust edition 2024

# Repeat a command for all the features. Requires the command as one argument (with double quotes)
for_all_features() {
Expand Down
6 changes: 3 additions & 3 deletions .github/scripts/ci-style.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ else
fi

# mock tests
cargo clippy --features mock_test
cargo clippy --features mock_test --tests
cargo clippy --features mock_test --benches
cargo clippy --features mock_test,mock_test_side_metadata
cargo clippy --features mock_test,mock_test_side_metadata --tests
cargo clippy --features mock_test,mock_test_side_metadata --benches

# non-mock benchmarks
cargo clippy --features test_private --benches
Expand Down
3 changes: 2 additions & 1 deletion .github/scripts/ci-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ find ./src ./tests -type f -name "mock_test_*" | while read -r file; do

# Run the test with each plan it needs.
for MMTK_PLAN in $PLANS; do
env MMTK_PLAN=$MMTK_PLAN cargo test --features mock_test,"$FEATURES" -- $t;
# Currently run all tests with side metadata
env MMTK_PLAN=$MMTK_PLAN cargo test --features mock_test,mock_test_side_metadata,"$FEATURES" -- $t;
done
done

Expand Down
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ static_assertions = "1.1.0"
strum = "0.27.1"
strum_macros = "0.27.1"
sysinfo = "0.33.1"
thread-id = { version = "5.0.0", optional = true } # Only used by mock VM

[dev-dependencies]
paste = "1.0.8"
Expand Down Expand Up @@ -116,7 +117,9 @@ perf_counter = ["dep:pfm"]

# This feature is only used for tests with MockVM.
# CI scripts run those tests with this feature.
mock_test = ["test_private"]
mock_test = ["test_private", "dep:thread-id"]
mock_test_header_metadata = ["mock_test"]
mock_test_side_metadata = ["mock_test"]

# This feature will expose some private functions for testings or benchmarking.
test_private = []
Expand Down
19 changes: 7 additions & 12 deletions benches/mock_bench/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,23 @@ use criterion::Criterion;

use mmtk::memory_manager;
use mmtk::util::test_util::fixtures::*;
use mmtk::util::test_util::mock_method::*;
use mmtk::util::test_util::mock_vm::{write_mockvm, MockVM};
use mmtk::util::test_util::mock_vm::*;
use mmtk::AllocationSemantics;

pub fn bench(c: &mut Criterion) {
// Setting a larger heap, although the GC should be disabled in the MockVM
let mut fixture = MutatorFixture::create_with_heapsize(1 << 30);
{
write_mockvm(|mock| {
*mock = {
MockVM {
is_collection_enabled: MockMethod::new_fixed(Box::new(|_| false)),
..MockVM::default()
}
}
init_mockvm(MockVM {
is_collection_enabled: MockMethod::new_fixed(Box::new(|_| false)),
..MockVM::default()
});
}
// Setting a larger heap, although the GC should be disabled in the MockVM
let fixture = MutatorFixture::create_with_heapsize(1 << 30);

c.bench_function("alloc", |b| {
b.iter(|| {
let _addr =
memory_manager::alloc(&mut fixture.mutator, 8, 8, 0, AllocationSemantics::Default);
memory_manager::alloc(fixture.mutator(), 8, 8, 0, AllocationSemantics::Default);
})
});
}
11 changes: 5 additions & 6 deletions benches/mock_bench/internal_pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ use criterion::Criterion;

#[cfg(feature = "is_mmtk_object")]
use mmtk::util::test_util::fixtures::*;
use mmtk::util::test_util::mock_method::*;
use mmtk::util::test_util::mock_vm::{write_mockvm, MockVM};
use mmtk::util::test_util::mock_vm::*;

pub fn bench(c: &mut Criterion) {
// Setting a larger heap, although the GC should be disabled in the MockVM
Expand All @@ -27,15 +26,15 @@ pub fn bench(c: &mut Criterion) {
use mmtk::memory_manager;
use mmtk::AllocationSemantics;
let addr = memory_manager::alloc(
&mut fixture.mutator,
fixture.mutator(),
NORMAL_OBJECT_SIZE,
8,
0,
AllocationSemantics::Default,
);
let obj_ref = MockVM::object_start_to_ref(addr);
memory_manager::post_alloc(
&mut fixture.mutator,
fixture.mutator(),
obj_ref,
NORMAL_OBJECT_SIZE,
AllocationSemantics::Default,
Expand Down Expand Up @@ -65,15 +64,15 @@ pub fn bench(c: &mut Criterion) {
use mmtk::memory_manager;
use mmtk::AllocationSemantics;
let addr = memory_manager::alloc(
&mut fixture.mutator,
fixture.mutator(),
LARGE_OBJECT_SIZE,
8,
0,
AllocationSemantics::Los,
);
let obj_ref = MockVM::object_start_to_ref(addr);
memory_manager::post_alloc(
&mut fixture.mutator,
fixture.mutator(),
obj_ref,
LARGE_OBJECT_SIZE,
AllocationSemantics::Los,
Expand Down
12 changes: 3 additions & 9 deletions benches/mock_bench/mmapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,17 @@ use mmtk::{
};

pub fn bench(c: &mut Criterion) {
let mut fixture = MutatorFixture::create_with_heapsize(1 << 30);
let fixture = MutatorFixture::create_with_heapsize(1 << 30);

let regular = memory_manager::alloc(
&mut fixture.mutator,
fixture.mutator(),
40,
0,
0,
mmtk::AllocationSemantics::Default,
);

let large = memory_manager::alloc(
&mut fixture.mutator,
40,
0,
0,
mmtk::AllocationSemantics::Los,
);
let large = memory_manager::alloc(fixture.mutator(), 40, 0, 0, mmtk::AllocationSemantics::Los);

let low = unsafe { Address::from_usize(42usize) };
let high = unsafe { Address::from_usize(usize::MAX - 1024usize) };
Expand Down
4 changes: 2 additions & 2 deletions benches/mock_bench/sft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use mmtk::util::test_util::mock_vm::*;
use mmtk::AllocationSemantics;

pub fn bench(c: &mut Criterion) {
let mut fixture = MutatorFixture::create();
let addr = memory_manager::alloc(&mut fixture.mutator, 8, 8, 0, AllocationSemantics::Default);
let fixture = MutatorFixture::create();
let addr = memory_manager::alloc(fixture.mutator(), 8, 8, 0, AllocationSemantics::Default);
let obj = MockVM::object_start_to_ref(addr);

c.bench_function("sft read", |b| {
Expand Down
1 change: 1 addition & 0 deletions src/policy/space.rs
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,7 @@ impl<VM: VMBinding> CommonSpace<VM> {
.try_map_metadata_address_range(rtn.start, rtn.extent, rtn.name)
.unwrap_or_else(|e| {
// TODO(Javad): handle meta space allocation failure
warn!("{}", memory::get_process_memory_maps());
panic!("failed to mmap meta memory: {e}");
});

Expand Down
13 changes: 10 additions & 3 deletions src/util/heap/monotonepageresource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,15 +261,19 @@ impl<VM: VMBinding> MonotonePageResource<VM> {
}
}*/

pub fn reset_cursor(&self, top: Address) {
// top might be Address::ZERO
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where I think Option<NonZeroAddress> can be useful. See #1223

pub fn reset_cursor(&self, mut top: Address) {
if self.common.contiguous {
let mut guard = self.sync.lock().unwrap();
let cursor = top.align_up(crate::util::constants::BYTES_IN_PAGE);
let chunk = chunk_align_down(top);
let space_start = match guard.conditional {
MonotonePageResourceConditional::Contiguous { start, .. } => start,
_ => unreachable!(),
};
if top.is_zero() {
top = space_start;
}
let cursor = top.align_up(crate::util::constants::BYTES_IN_PAGE);
let chunk = chunk_align_down(top);
let pages = bytes_to_pages_up(top - space_start);
self.common.accounting.reset();
self.common.accounting.reserve_and_commit(pages);
Expand All @@ -284,6 +288,9 @@ impl<VM: VMBinding> MonotonePageResource<VM> {
+ (self.common.vm_map.get_contiguous_region_chunks(chunk_start)
<< LOG_BYTES_IN_CHUNK);
let next_chunk_start = self.common.vm_map.get_next_contiguous_region(chunk_start);
if top.is_zero() {
top = chunk_start;
}
if top >= chunk_start && top < chunk_end {
// This is the last live chunk
debug_assert!(!release_regions);
Expand Down
4 changes: 4 additions & 0 deletions src/util/linear_scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ impl<VM: VMBinding, S: LinearScanObjectSize, const ATOMIC_LOAD_VO_BIT: bool> std

fn next(&mut self) -> Option<<Self as Iterator>::Item> {
while self.cursor < self.end {
if !self.cursor.is_aligned_to(ObjectReference::ALIGNMENT) {
self.cursor += VM::MIN_ALIGNMENT;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently ObjectReference is required to be aligned to ObjectReference::ALIGNMENT. So even if VM::MIN_ALIGNMENT is smaller than ObjectReference::ALIGNMENT, VO bits can only be set at addresses which are multiples of ObjectReference::ALIGNMENT. I think the algorithm here is wrong (or just outdated). It is pointless to increment the cursor by VM::MIN_ALIGNMENT. It should simply align the cursor up to the next multiple of ObjectReference::ALIGNMENT. And I wonder whether find_last_non_zero_bit_in_metadata_bytes could be more efficient (needs to search forward instead of backward).

continue;
}
let is_object = if ATOMIC_LOAD_VO_BIT {
vo_bit::is_vo_bit_set_for_addr(self.cursor)
} else {
Expand Down
7 changes: 6 additions & 1 deletion src/util/metadata/side_metadata/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,16 @@ pub const GLOBAL_SIDE_METADATA_BASE_ADDRESS: Address = unsafe { Address::from_us
// is less likely to overlap with any space. But it does not solve the problem completely.
// If there are more spaces, it will still overlap with some spaces.
// See: https://github.com/mmtk/mmtk-core/issues/458
#[cfg(target_pointer_width = "64")]
#[cfg(all(target_pointer_width = "64", not(feature = "mock_test")))]
/// Global side metadata start address
pub const GLOBAL_SIDE_METADATA_BASE_ADDRESS: Address =
unsafe { Address::from_usize(0x0000_0c00_0000_0000usize) };

#[cfg(all(target_pointer_width = "64", feature = "mock_test"))]
/// Global side metadata start address
pub const GLOBAL_SIDE_METADATA_BASE_ADDRESS: Address =
unsafe { Address::from_usize(0x0000_0100_0000_0000usize) };

pub(crate) const GLOBAL_SIDE_METADATA_BASE_OFFSET: SideMetadataOffset =
SideMetadataOffset::addr(GLOBAL_SIDE_METADATA_BASE_ADDRESS);

Expand Down
8 changes: 8 additions & 0 deletions src/util/metadata/side_metadata/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,14 @@ pub(super) fn try_mmap_contiguous_metadata_space(
)
}
.map(|_| mmap_size)
.map_err(|e| {
warn!(
"Failed to mmap metadata space: {} - {}",
mmap_start,
mmap_start + mmap_size
);
e
})
} else {
Ok(0)
}
Expand Down
8 changes: 8 additions & 0 deletions src/util/metadata/side_metadata/helpers_32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,12 @@ pub(super) fn try_mmap_metadata_chunk(
anno,
)
}
.map_err(|e| {
warn!(
"Failed to mmap per-chunk metadata: {} - {}",
policy_meta_start,
policy_meta_start + local_per_chunk
);
e
})
}
8 changes: 4 additions & 4 deletions src/util/opaque_pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use libc::c_void;
/// For example, a pointer to the thread or the thread local storage is an opaque pointer for MMTK.
/// The type does not provide any method for dereferencing.
#[repr(transparent)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct OpaquePointer(*mut c_void);

// We never really dereference an opaque pointer in mmtk-core.
Expand Down Expand Up @@ -44,7 +44,7 @@ impl OpaquePointer {
/// so the VM knows the context.
/// A VMThread may be a VMMutatorThread, a VMWorkerThread, or any VMThread.
#[repr(transparent)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct VMThread(pub OpaquePointer);

impl VMThread {
Expand All @@ -56,12 +56,12 @@ impl VMThread {
/// When a VMMutatorThread is used as an argument or a field of a type, it generally means
/// the function or the functions for the type is executed in the context of the mutator thread.
#[repr(transparent)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct VMMutatorThread(pub VMThread);

/// A VMWorkerThread is a VMThread that is associates with a [`crate::scheduler::GCWorker`].
/// When a VMWorkerThread is used as an argument or a field of a type, it generally means
/// the function or the functions for the type is executed in the context of the mutator thread.
#[repr(transparent)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct VMWorkerThread(pub VMThread);
Loading
Loading