[vm, gc] Incremental compaction, take 2.
- Fix missing store buffer flush when --marker_tasks=0. - Fix passing untagged pointer to store barrier check on ARM/ARM64 (6bc417dd17). - Fix passing uninitialized header to store barrier check on ARM64/RISCV (1447193053). TEST=ci Bug: https://github.com/dart-lang/sdk/issues/52513 Bug: https://github.com/dart-lang/sdk/issues/55754 Change-Id: Id2aa95b6d776b82d83464cde0d00e6f3b29b7b77 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/367202 Commit-Queue: Ryan Macnak <rmacnak@google.com> Reviewed-by: Alexander Aprelev <aam@google.com>
This commit is contained in:
committed by
Commit Queue
parent
fab56db71b
commit
9077bf991f
+6
-7
@@ -95,18 +95,18 @@ But we combine the generational and incremental checks with a shift-and-mask.
|
||||
```c++
|
||||
enum HeaderBits {
|
||||
...
|
||||
kNotMarkedBit, // Incremental barrier target.
|
||||
kNewBit, // Generational barrier target.
|
||||
kAlwaysSetBit, // Incremental barrier source.
|
||||
kOldAndNotRememberedBit, // Generational barrier source.
|
||||
kNotMarkedBit, // Incremental barrier target.
|
||||
kNewOrEvacuationCandidateBit, // Generational barrier target.
|
||||
kAlwaysSetBit, // Incremental barrier source.
|
||||
kOldAndNotRememberedBit, // Generational barrier source.
|
||||
...
|
||||
};
|
||||
|
||||
static constexpr intptr_t kGenerationalBarrierMask = 1 << kNewBit;
|
||||
static constexpr intptr_t kGenerationalBarrierMask = 1 << kNewOrEvacuationCandidateBit;
|
||||
static constexpr intptr_t kIncrementalBarrierMask = 1 << kNotMarkedBit;
|
||||
static constexpr intptr_t kBarrierOverlapShift = 2;
|
||||
COMPILE_ASSERT(kNotMarkedBit + kBarrierOverlapShift == kAlwaysSetBit);
|
||||
COMPILE_ASSERT(kNewBit + kBarrierOverlapShift == kOldAndNotRememberedBit);
|
||||
COMPILE_ASSERT(kNewOrEvacuationCandidateBit + kBarrierOverlapShift == kOldAndNotRememberedBit);
|
||||
|
||||
StorePointer(ObjectPtr source, ObjectPtr* slot, ObjectPtr target) {
|
||||
*slot = target;
|
||||
@@ -178,7 +178,6 @@ We can eliminate these checks when the compiler can prove these cases cannot hap
|
||||
* `value` is a constant. Constants are always old, and they will be marked via the constant pools even if we fail to mark them via `container`.
|
||||
* `value` has the static type bool. All possible values of the bool type (null, false, true) are constants.
|
||||
* `value` is known to be a Smi. Smis are not heap objects.
|
||||
* `container` is the same object as `value`. The GC never needs to retain an additional object if it sees a self-reference, so ignoring a self-reference cannot cause us to free a reachable object.
|
||||
* `container` is known to be a new object or known to be an old object that is in the remembered set and is marked if marking is in progress.
|
||||
|
||||
We can know that `container` meets the last property if `container` is the result of an allocation (instead of a heap load), and there is no instruction that can trigger a GC between the allocation and the store. This is because the allocation stubs ensure the result of AllocateObject is either a new-space object (common case, bump pointer allocation succeeds), or has been preemptively added to the remembered set and marking worklist (uncommon case, entered runtime to allocate object, possibly triggering GC).
|
||||
|
||||
Reference in New Issue
Block a user