Commit 443230c2 authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[heap] Fix an assertion in MarkingBarrier::MarkValue

The host object may have an impossible markbit pattern if it is a
one-word filler followed by an already marked object.

Bug: v8:10698
Change-Id: I498e6f0768fbdb181fc893f98f224dd3cd0e37e6
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2295600Reviewed-by: 's avatarDominik Inführ <dinfuehr@chromium.org>
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68848}
parent 832fac51
......@@ -15,7 +15,13 @@ namespace internal {
bool MarkingBarrier::MarkValue(HeapObject host, HeapObject value) {
DCHECK(is_activated_);
DCHECK(!marking_state_.IsImpossible(value));
DCHECK(!marking_state_.IsImpossible(host));
// Host may have an impossible markbit pattern if manual allocation folding
// is performed and host happens to be the last word of an allocated region.
// In that case host has only one markbit and the second markbit belongs to
// another object. We can detect that case by checking if value is a one word
// filler map.
DCHECK(!marking_state_.IsImpossible(host) ||
value == ReadOnlyRoots(heap_->isolate()).one_pointer_filler_map());
if (!V8_CONCURRENT_MARKING_BOOL && marking_state_.IsBlack(host)) {
// The value will be marked and the slot will be recorded when the marker
// visits the host object.
......
......@@ -7154,6 +7154,29 @@ TEST(GarbageCollectionWithLocalHeap) {
CcTest::CollectGarbage(OLD_SPACE);
}
TEST(Regress10698) {
ManualGCScope manual_gc_scope;
CcTest::InitializeVM();
Heap* heap = CcTest::i_isolate()->heap();
Factory* factory = CcTest::i_isolate()->factory();
HandleScope handle_scope(CcTest::i_isolate());
// This is modeled after the manual allocation folding of heap numbers in
// JSON parser (See commit ba7b25e).
// Step 1. Allocate a byte array in the old space.
Handle<ByteArray> array =
factory->NewByteArray(kTaggedSize, AllocationType::kOld);
// Step 2. Start incremental marking.
SimulateIncrementalMarking(heap, false);
// Step 3. Allocate another byte array. It will be black.
factory->NewByteArray(kTaggedSize, AllocationType::kOld);
Address address = reinterpret_cast<Address>(array->GetDataStartAddress());
HeapObject filler = HeapObject::FromAddress(address);
// Step 4. Set the filler at the end of the first array.
// It will have an impossible markbit pattern because the second markbit
// will be taken from the second array.
filler.set_map_after_allocation(*factory->one_pointer_filler_map());
}
} // namespace heap
} // namespace internal
} // namespace v8
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment