Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions src/vm/scanning.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use crate::plan::Mutator;
use crate::util::Address;
use crate::util::ObjectReference;
use crate::util::VMWorkerThread;
use crate::vm::edge_shape::Edge;
use crate::vm::VMBinding;
use crate::AllocationSemantics;

/// Callback trait of scanning functions that report edges.
pub trait EdgeVisitor<ES: Edge> {
Expand Down Expand Up @@ -31,6 +33,46 @@ impl<F: FnMut(ObjectReference) -> ObjectReference> ObjectTracer for F {
}
}

pub trait BufferHandler {
/// Call this function to retain buffers.
///
/// Arguments:
/// * `buffer`: The address of the buffer
/// * `size`: The size of the buffer
/// * `alignment`: The alignment of the buffer
/// * `offset`: Offset associated with the alignment.
///
/// Returns the new address of the buffer. Copying GC may move the buffer to a different
/// place, but will preserve its size, alignment and copy its content. If that happens, the
/// return value is the new address. If the buffer is not copied, the return value is the
/// original address.
fn retain_buffer(
&mut self,
buffer: Address,
size: usize,
alignment: usize,
offset: isize,
) -> Address;

/// Call this function to allocate a new buffer during GC.
///
/// Arguments:
/// * `size`: The size of the buffer
/// * `alignment`: The alignment of the buffer
/// * `semantics`: The allocation semantics of the buffer.
/// * `offset`: Offset associated with the alignment.
/// May be different from the owning object.
///
/// Returns the address of the new buffer.
fn allocate_buffer(
&mut self,
size: usize,
alignment: usize,
offset: isize,
semantics: AllocationSemantics,
) -> Address;
}

/// Root-scanning methods use this trait to create work packets for processing roots.
///
/// Notes on the required traits:
Expand Down Expand Up @@ -139,6 +181,30 @@ pub trait Scanning<VM: VMBinding> {
unreachable!("scan_object_and_trace_edges() will not be called when support_edge_enqueue() is always true.")
}

/// Return `true` if an object owns any buffers.
///
/// If `true`, MMTk core will call `handle_buffers` on the object.
fn has_buffers(_object: ObjectReference) -> bool {
false
}

/// Handle buffers in the object.
///
/// If the VM wants to retain a buffer owned by the object, it shall call
/// `handler.retain_buffer` on each field that holds a pointer to a buffer, and re-assign the
/// returned value to that field.
///
/// If the VM wants to discard a buffer, it simply ignores the buffer. MMTk core will consider
/// the buffer dead if not retained.
///
/// If the VM wants to resize a buffer, it shall allocate a new buffer using
/// `handler.allocate_buffer`, and keep its pointer in one of is fields so that it can be
/// retained in subsequent GCs. Note that this function is called by a **GC worker thread**,
/// and GC threads cannot call `Mutator::alloc` (or its alias `memory_manager::alloc`).
fn handle_buffers(_object: ObjectReference, _handler: impl BufferHandler) {
unreachable!("retain_buffers() will not be called when has_buffers() is always false.")
}

/// MMTk calls this method at the first time during a collection that thread's stacks
/// have been scanned. This can be used (for example) to clean up
/// obsolete compiled methods that are no longer being executed.
Expand Down