-
Notifications
You must be signed in to change notification settings - Fork 77
Heap introspection API for debugging #1302
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I am also curious whether we should actually make this public for bindings. On one hand, those seem too specific to MMTk core, and the bindings cannot use those info for anything at the binding side. On the other hand, some analysis code only makes sense for a given binding (e.g. pinning stats for Julia), and might be irrelevant to others who use MMTk core. The API you proposed overlaps with MMTk core's internal API, such as We have something called |
I think we may isolate this API into a separate module, such as
It may work, but we must be careful not to transitively expose details that we don't want to expose to the user. The point is that those And we must prevent the VM bindings from modifying the states. The Some methods of
The But a related topic is runtime monitoring (#1303). The JMX can emit notifications, and it can be used as some kind of GC logs, too. |
We discussed this today. We don't need the Concretely, for OpenJDK, the VM can easily initiate a STW by executing a The VM binding can also use this API at the beginning or the end of a STW GC , at which time the world has already stopped. |
In #803, we proposed that we need a heap traversal API for the purpose of debugging GC algorithms. We already introduced the
MMTK::enumerate_objects
method for VMs to implement user-level traversal APIs. But this API is not enough for debugging GC. GC developers want the capability of introspecting the concrete structure of each policy, such as the chunk/block/line structure ofImmixSpace
.#1300 is one attempt of exposing the block structure of
MallocSpace
andImmixSpace
. But it is too much for a simple user-facing object-enumerating API, but not rich enough for GC developers.We can provide an API for this kind of fine-grained introspection. For example,
The key of this API is those opaque introspectors, including
ImmixSpaceInspector
,ImmixBlockInspector
andImmixLineInspector
, which allows the VM binding to introspect the heap structure in controlled ways.For other spaces, we provide other inspectors, such as
MarkSweepSpaceInspector
,MarkSweepBlockInspector
andMarkSweepCellInspector
.And the invocation ofUpdate: mmtk-core doesn't have to initiate STW. Instead we require that VM bindings can only call this API when no mutators can mutate the heap, which is the same requirement ofmmtk.inspect_heap();
will stop the world, allowing the VM to do all the introspection when no mutators can mutate the heap.MMTK::enumerate_objects
.Should this API be public?
We need to call those APIs in the VM binding, so they should be public.
It is debatable whether this API should be always available, or guarded behind a Cargo feature. Most of the features provided by this API should have no performance impact. But we may need additional metadata to make some of the introspection possible at mutator time. If such cases exist, we may add a Cargo feature
"advanced_introspection"
which enables more introspection methods at the cost of some space/time overhead.List of API methods
Here is an incomplete list of types and methods we can expose.
HeapInspector
: The main object for heap inspection / introspection.spaces()
: Itereate over spaces.space(name)
: Get an abstractSpaceInspector
for a given space.mutators()
: Iterate over mutators.SpaceInspector
: The trait for all space inspectors.name()
: Get the nameranges()
: Go through all contiguous chunk ranges allocated to that space. For Map64, that's just one contiguous range of chunks.objects()
: Itereate over all objectsImmixSpaceInspector
: For ImmixSpace. ImplementsSpaceInspector
, with Immix-specific methods.blocks()
: Iterate over Immix blocksImmixBlockInspector
: A block in ImmixSpace.start()
: starting addressend()
: ending address (exclusive)lines()
: Iterate over all linesobjects()
: Iterate over all objectsImmixLineInspector
: A line in ImmixSpace block.start()
: starting addressend()
: ending address (exclusive)objects()
: Iterate over all objectsis_used()
: Return whether the line is in use. (TODO: Is this decidable at mutator time?)MarkSweepSpaceInspector
: For the native MarkSweepSpace. ImplementsSpaceInspector
, with MarkSweep-specific methods.blocks()
: Iterate over Immix blocks.blocks_in_size_class(size_class_index)
: Iterate over all blocks of a given size class.MarkSweepBlockInspector
: A block in MarkSweepSpace.start()
: starting addressend()
: ending address (exclusive)size_class()
: The size classcells()
: Iterate over all linesobjects()
: Iterate over all objectsMarkSweepCellInspector
: A cell in a MarkSweepSpace block.start()
: starting addressend()
: ending address (exclusive)objects()
: Iterate over all objectsis_used()
: Return whether the cell is in use. (TODO: Is this decidable at mutator time?)MutatorInspector
: Inspect a mutatorbump_pointers()
: Iterate through allBumpPointer
this mutator is using.allocators()
: Iterate through all allocatorsallocator(index)
: Get an allocator inspectorAllocatorInspector
: The abstract trait for inspecting allocators.BumpAllocatorInspector
: For BumpAllocatorbump_pointer()
: Get a reference to its bump pointer.ImmixAllocatorInspector
: For ImmixAllocatorbump_pointer()
: Get a reference to its bump pointer.large_bump_pointer()
: Get a reference to the bump pointer for medium objects.MarkSweepAllocatorInspector
: For MarkSweepAllocatorblocks()
: Iterate over locally cached blocks.blocks_in_size_class(size_class_index)
: Iterate over locally cached blocks of a given size classThe text was updated successfully, but these errors were encountered: