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
1 change: 1 addition & 0 deletions docs/userguide/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
- [Next Steps](portingguide/howto/next_steps.md)
- [Debugging Tips](portingguide/debugging/prefix.md)
- [Enabling Debug Assertions](portingguide/debugging/assertions.md)
- [Print Object Info](portingguide/debugging/print_obj_info.md)
- [Performance Tuning](portingguide/perf_tuning/prefix.md)
- [Link Time Optimization](portingguide/perf_tuning/lto.md)
- [Optimizing Allocation](portingguide/perf_tuning/alloc.md)
Expand Down
30 changes: 30 additions & 0 deletions docs/userguide/src/portingguide/debugging/print_obj_info.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Print MMTk Object Information

MMTk provides a utility function to print object information for debugging, `crate::mmtk::mmtk_debug_print_object`.
The function is marked as `#[no_mangle]`, making it suitable to be used in a debugger.

The following example shows how to use the function to print MMTk's object metadata before and after a single GC in `rr`.

Set up break points before and after a GC.

```console
(rr) b stop_all_mutators
Breakpoint 1 at 0x767cba8f74e8 (14 locations)
(rr) b resume_mutators
Breakpoint 2 at 0x767cba8f8908
```

When the program stops, call `mmtk_debug_print_object`. We might need to
set the language context in the debugger to `C` when we stop in a Rust frame.
Then call `mmtk_debug_print_object` with the interested object.

```console
(rr) set language c
(rr) call mmtk_debug_print_object_info(0x200fffed9f0)
In immix:
marked = false
line marked = false
block state = Unmarked
forwarding bits = 0, forwarding pointer = None
vo bit = true
```
29 changes: 29 additions & 0 deletions src/mmtk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,3 +597,32 @@ impl<VM: VMBinding> MMTK<VM> {
.initialize_object_metadata(object, false)
}
}

/// A non-mangled function to print object information for debugging purposes. This function can be directly
/// called from a debugger.
#[no_mangle]
pub fn mmtk_debug_print_object(object: crate::util::ObjectReference) {
// If the address is unmapped, we cannot access its metadata. Just quit.
if !object.to_raw_address().is_mapped() {
println!("{} is not mapped in MMTk", object);
return;
}

// If the address is not aligned to the object reference size, it is not an object reference.
if !object
.to_raw_address()
.is_aligned_to(crate::util::ObjectReference::ALIGNMENT)
{
println!(
"{} is not properly aligned. It is not an object reference.",
object
);
}

// Forward to the space
let sft = SFT_MAP.get_checked(object.to_raw_address());
// Print the space name
println!("In {}:", sft.name());
// Print object information
sft.debug_print_object_info(object);
}
5 changes: 5 additions & 0 deletions src/policy/copyspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ impl<VM: VMBinding> SFT for CopySpace<VM> {
let worker = worker.into_mut::<VM>();
self.trace_object(queue, object, self.common.copy, worker)
}

fn debug_print_object_info(&self, object: ObjectReference) {
object_forwarding::debug_print_object_forwarding_info::<VM>(object);
self.common.debug_print_object_global_info(object);
}
}

impl<VM: VMBinding> Space<VM> for CopySpace<VM> {
Expand Down
14 changes: 14 additions & 0 deletions src/policy/immix/immixspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,20 @@ impl<VM: VMBinding> SFT for ImmixSpace<VM> {
) -> ObjectReference {
panic!("We do not use SFT to trace objects for Immix. sft_trace_object() cannot be used.")
}

fn debug_print_object_info(&self, object: ObjectReference) {
println!("marked = {}", self.is_marked(object));
println!(
"line marked = {}",
Line::from_unaligned_address(object.to_raw_address()).is_marked(self.mark_state)
);
println!(
"block state = {:?}",
Block::from_unaligned_address(object.to_raw_address()).get_state()
);
object_forwarding::debug_print_object_forwarding_info::<VM>(object);
self.common.debug_print_object_global_info(object);
}
}

impl<VM: VMBinding> Space<VM> for ImmixSpace<VM> {
Expand Down
6 changes: 6 additions & 0 deletions src/policy/largeobjectspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ impl<VM: VMBinding> SFT for LargeObjectSpace<VM> {
) -> ObjectReference {
self.trace_object(queue, object)
}

fn debug_print_object_info(&self, object: ObjectReference) {
println!("marked = {}", self.test_mark_bit(object, self.mark_state));
println!("nursery = {}", self.is_in_nursery(object));
self.common.debug_print_object_global_info(object);
}
}

impl<VM: VMBinding> Space<VM> for LargeObjectSpace<VM> {
Expand Down
9 changes: 9 additions & 0 deletions src/policy/markcompactspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,15 @@ impl<VM: VMBinding> SFT for MarkCompactSpace<VM> {
// Depending on which trace it is, we should manually call either trace_mark or trace_forward.
panic!("sft_trace_object() cannot be used with mark compact space")
}

fn debug_print_object_info(&self, object: ObjectReference) {
println!("marked = {}", MarkCompactSpace::<VM>::is_marked(object));
println!(
"head forwarding pointer = {:?}",
MarkCompactSpace::<VM>::get_header_forwarding_pointer(object)
);
self.common.debug_print_object_global_info(object);
}
}

impl<VM: VMBinding> Space<VM> for MarkCompactSpace<VM> {
Expand Down
6 changes: 6 additions & 0 deletions src/policy/sft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ pub trait SFT {
object: ObjectReference,
worker: GCWorkerMutRef,
) -> ObjectReference;

/// Print debug info for the object. The implementer should print one line at a time so in case of an unexpected error,
/// we still print something.
fn debug_print_object_info(&self, _object: ObjectReference) {
println!("This policy does not implement debug_print_object_info.");
}
}

// Create erased VM refs for these types that will be used in `sft_trace_object()`.
Expand Down
16 changes: 16 additions & 0 deletions src/policy/space.rs
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,22 @@ impl<VM: VMBinding> CommonSpace<VM> {
},
}
}

pub(crate) fn debug_print_object_global_info(&self, object: ObjectReference) {
#[cfg(feature = "vo_bit")]
println!(
"vo bit = {}",
crate::util::metadata::vo_bit::is_vo_bit_set(object)
);
if self.needs_log_bit {
use crate::vm::object_model::ObjectModel;
use std::sync::atomic::Ordering;
println!(
"log bit = {}",
VM::VMObjectModel::GLOBAL_LOG_BIT_SPEC.is_unlogged::<VM>(object, Ordering::Relaxed),
);
}
}
}

fn get_frac_available(frac: f32) -> usize {
Expand Down
13 changes: 13 additions & 0 deletions src/util/object_forwarding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,16 @@ pub(super) fn forwarding_bits_offset_in_forwarding_pointer<VM: VMBinding>() -> O
pub(super) fn forwarding_bits_offset_in_forwarding_pointer<VM: VMBinding>() -> Option<isize> {
unimplemented!()
}

pub(crate) fn debug_print_object_forwarding_info<VM: VMBinding>(object: ObjectReference) {
let forwarding_bits = get_forwarding_status::<VM>(object);
println!(
"forwarding bits = {:?}, forwarding pointer = {:?}",
forwarding_bits,
if state_is_forwarded_or_being_forwarded(forwarding_bits) {
Some(read_forwarding_pointer::<VM>(object))
} else {
None
}
)
}
15 changes: 15 additions & 0 deletions src/vm/tests/mock_tests/mock_test_debug_get_object_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// GITHUB-CI: MMTK_PLAN=all

use super::mock_test_prelude::*;

#[test]
pub fn debug_print_object_info() {
with_mockvm(
default_setup,
|| {
let fixture = SingleObject::create();
crate::mmtk::mmtk_debug_print_object(fixture.objref);
},
no_cleanup,
)
}
1 change: 1 addition & 0 deletions src/vm/tests/mock_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ mod mock_test_allocator_info;
mod mock_test_barrier_slow_path_assertion;
#[cfg(feature = "is_mmtk_object")]
mod mock_test_conservatism;
mod mock_test_debug_get_object_info;
#[cfg(target_os = "linux")]
mod mock_test_handle_mmap_conflict;
mod mock_test_handle_mmap_oom;
Expand Down