mmtk/plan/
plan_constraints.rs

1//! Plan-specific constraints.
2
3use crate::plan::barriers::BarrierSelector;
4use crate::util::constants::*;
5
6/// This struct defines plan-specific constraints.
7/// Most of the constraints are constants. Each plan should declare a constant of this struct,
8/// and use the constant wherever possible. However, for plan-neutral implementations,
9/// these constraints are not constant.
10#[derive(Clone, Debug)]
11pub struct PlanConstraints {
12    /// Does the plan collect garbage? Obviously most plans do, but NoGC does not collect.
13    pub collects_garbage: bool,
14    /// True if the plan moves objects.
15    pub moves_objects: bool,
16    /// Size (in bytes) beyond which new regular objects must be allocated to the LOS.
17    /// This usually depends on the restriction of the default allocator, e.g. block size for Immix,
18    /// nursery size, max possible cell for freelist, etc.
19    pub max_non_los_default_alloc_bytes: usize,
20    /// Size (in bytes) beyond which copied objects must be copied to the LOS.
21    /// This depends on the copy allocator.
22    pub max_non_los_copy_bytes: usize,
23    /// Does this plan use the log bit? See vm::ObjectModel::GLOBAL_LOG_BIT_SPEC.
24    pub needs_log_bit: bool,
25    /// Does this plan use the field-level (rather than object-level) unlogged bit for its write barrier?
26    /// See vm::ObjectModel::GLOBAL_FIELD_UNLOG_BIT_SPEC.
27    pub needs_field_log_bit: bool,
28    /// Some plans may allow benign race for testing mark bit, and this will lead to trace the same
29    /// edge multiple times. If a plan allows tracing duplicated edges, we will not run duplicate
30    /// edge check in extreme_assertions.
31    ///
32    /// Note: Both [`crate::vm::Scanning::scan_object`] (which enqueues slots) and
33    /// [`crate::vm::Scanning::scan_object_and_trace_edges`] (which traces the targets directly) are
34    /// affected by such benign races.  But our current duplicate edge check in extreme_assertions
35    /// only identifies duplicated slots.
36    pub may_trace_duplicate_edges: bool,
37    /// The barrier this plan uses. A binding may check this and know what kind of write barrier is in use
38    /// if they would like to implement the barrier fast path in the binding side.
39    pub barrier: BarrierSelector,
40    // the following seems unused for now
41    /// True if this plan requires linear scanning. This is unused and may be incorrect.
42    pub needs_linear_scan: bool,
43    /// True if this plan requires concurrent worker threads. This is unused and may be incorrect.
44    pub needs_concurrent_workers: bool,
45    /// Some policies do object forwarding after the first liveness transitive closure, such as mark compact.
46    /// For plans that use those policies, they should set this as true.
47    pub needs_forward_after_liveness: bool,
48    /// True if this plan is reference-counting based (e.g. LXR), rather than tracing-only.
49    pub rc_enabled: bool,
50    /// Some (in fact, most) plans do nothing when preparing mutators before tracing (i.e. in
51    /// `MutatorConfig::prepare_func`).  Those plans can set this to `false` so that the
52    /// `PrepareMutator` work packets will not be created at all.
53    pub needs_prepare_mutator: bool,
54    /// Is this plan generational?
55    pub generational: bool,
56}
57
58impl PlanConstraints {
59    /// A const function to create the default plan constraints.
60    pub const fn default() -> Self {
61        PlanConstraints {
62            collects_garbage: true,
63            moves_objects: false,
64            // No limit by default.  All objects can go to non-LOS space.
65            max_non_los_default_alloc_bytes: usize::MAX,
66            // No limit by default.  All objects can go to non-LOS space.
67            max_non_los_copy_bytes: usize::MAX,
68            // As `LAZY_SWEEP` is true, needs_linear_scan is true for all the plans. This is strange.
69            // https://github.com/mmtk/mmtk-core/issues/1027 tracks the issue.
70            needs_linear_scan: crate::util::constants::SUPPORT_CARD_SCANNING
71                || crate::util::constants::LAZY_SWEEP,
72            needs_concurrent_workers: false,
73            // We may trace duplicate edges in mark sweep. If we use mark sweep as the non moving policy, it will be included in every
74            may_trace_duplicate_edges: cfg!(feature = "marksweep_as_nonmoving"),
75            needs_forward_after_liveness: false,
76            needs_log_bit: false,
77            needs_field_log_bit: false,
78            barrier: BarrierSelector::NoBarrier,
79            rc_enabled: false,
80            // If we use mark sweep as non moving space, we need to prepare mutator. See [`common_prepare_func`].
81            needs_prepare_mutator: cfg!(feature = "marksweep_as_nonmoving"),
82            generational: false,
83        }
84    }
85}
86
87/// The default plan constraints. Each plan should define their own plan constraints.
88/// They can start from the default constraints and explicitly set some of the fields.
89pub(crate) const DEFAULT_PLAN_CONSTRAINTS: PlanConstraints = PlanConstraints::default();
90
91// Use two pages as the size limit for non-LOS objects to avoid copying large objects
92pub const MAX_NON_LOS_ALLOC_BYTES_COPYING_PLAN: usize = 2 << LOG_BYTES_IN_PAGE;