diff --git a/src/heap/basic-memory-chunk.cc b/src/heap/basic-memory-chunk.cc
index 4f4bc4814c..fc271cdb81 100644
--- a/src/heap/basic-memory-chunk.cc
+++ b/src/heap/basic-memory-chunk.cc
@@ -64,7 +64,9 @@ BasicMemoryChunk::BasicMemoryChunk(Heap* heap, BaseSpace* space,
high_water_mark_(area_start - reinterpret_cast
(this)),
owner_(space),
reservation_(std::move(reservation)) {
- marking_bitmap()->Clear();
+ if (space->identity() != RO_SPACE) {
+ marking_bitmap()->Clear();
+ }
}
bool BasicMemoryChunk::InOldSpace() const {
diff --git a/src/heap/basic-memory-chunk.h b/src/heap/basic-memory-chunk.h
index dfcbdca5a8..864c803975 100644
--- a/src/heap/basic-memory-chunk.h
+++ b/src/heap/basic-memory-chunk.h
@@ -306,6 +306,8 @@ class BasicMemoryChunk {
template
ConcurrentBitmap* marking_bitmap() const {
+ // TODO(olivf) Change to DCHECK once we have some coverage
+ CHECK(!InReadOnlySpace());
return static_cast*>(
Bitmap::FromAddress(address() + kMarkingBitmapOffset));
}
diff --git a/src/heap/concurrent-marking.cc b/src/heap/concurrent-marking.cc
index 73eff30596..72f60b2dcd 100644
--- a/src/heap/concurrent-marking.cc
+++ b/src/heap/concurrent-marking.cc
@@ -263,7 +263,7 @@ class YoungGenerationConcurrentMarkingVisitor final
marking_state_(heap->isolate(), memory_chunk_data) {}
bool ShouldMarkObject(HeapObject object) const {
- return !object.InSharedHeap();
+ return !object.InSharedHeap() && !object.InReadOnlySpace();
}
void SynchronizePageAccess(HeapObject heap_object) {
@@ -787,6 +787,7 @@ void ConcurrentMarking::RunMajor(JobDelegate* delegate,
done = true;
break;
}
+ DCHECK(!object.InReadOnlySpace());
objects_processed++;
Address new_space_top = kNullAddress;
diff --git a/src/heap/mark-compact-inl.h b/src/heap/mark-compact-inl.h
index 7168b7350a..da353373cc 100644
--- a/src/heap/mark-compact-inl.h
+++ b/src/heap/mark-compact-inl.h
@@ -86,6 +86,7 @@ void MarkCompactCollector::AddTransitionArray(TransitionArray array) {
}
bool MarkCompactCollector::ShouldMarkObject(HeapObject object) const {
+ if (object.InReadOnlySpace()) return false;
if (V8_LIKELY(!uses_shared_heap_)) return true;
if (v8_flags.shared_space) {
if (is_shared_heap_isolate_) return true;
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index c805d98b1c..06793449ce 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -293,7 +293,8 @@ class FullMarkingVerifier : public MarkingVerifier {
CHECK(heap_->SharedHeapContains(heap_object));
}
- CHECK(marking_state_->IsBlack(heap_object));
+ CHECK(heap_object.InReadOnlySpace() ||
+ marking_state_->IsBlack(heap_object));
}
V8_INLINE bool ShouldVerifyObject(HeapObject heap_object) {
@@ -626,14 +627,6 @@ void MarkCompactCollector::CollectGarbage() {
}
#ifdef VERIFY_HEAP
-void MarkCompactCollector::VerifyMarkbitsAreDirty(ReadOnlySpace* space) {
- ReadOnlyHeapObjectIterator iterator(space);
- for (HeapObject object = iterator.Next(); !object.is_null();
- object = iterator.Next()) {
- CHECK(non_atomic_marking_state()->IsBlack(object));
- }
-}
-
void MarkCompactCollector::VerifyMarkbitsAreClean(PagedSpaceBase* space) {
for (Page* p : *space) {
CHECK(non_atomic_marking_state()->bitmap(p)->IsClean());
@@ -667,9 +660,6 @@ void MarkCompactCollector::VerifyMarkbitsAreClean() {
VerifyMarkbitsAreClean(heap_->old_space());
VerifyMarkbitsAreClean(heap_->code_space());
VerifyMarkbitsAreClean(heap_->new_space());
- // Read-only space should always be black since we never collect any objects
- // in it or linked from it.
- VerifyMarkbitsAreDirty(heap_->read_only_space());
VerifyMarkbitsAreClean(heap_->lo_space());
VerifyMarkbitsAreClean(heap_->code_lo_space());
VerifyMarkbitsAreClean(heap_->new_lo_space());
@@ -1338,7 +1328,8 @@ class InternalizedStringTableCleaner final : public RootVisitor {
if (o.IsHeapObject()) {
HeapObject heap_object = HeapObject::cast(o);
DCHECK(!Heap::InYoungGeneration(heap_object));
- if (marking_state->IsWhite(heap_object)) {
+ if (!heap_object.InReadOnlySpace() &&
+ marking_state->IsWhite(heap_object)) {
pointers_removed_++;
// Set the entry to the_hole_value (as deleted).
p.store(StringTable::deleted_element());
@@ -2729,7 +2720,8 @@ bool ShouldRetainMap(MarkingState* marking_state, Map map, int age) {
}
Object constructor = map.GetConstructor();
if (!constructor.IsHeapObject() ||
- marking_state->IsWhite(HeapObject::cast(constructor))) {
+ (!HeapObject::cast(constructor).InReadOnlySpace() &&
+ marking_state->IsWhite(HeapObject::cast(constructor)))) {
// The constructor is dead, no new objects with this map can
// be created. Do not retain this map.
return false;
@@ -2768,7 +2760,8 @@ void MarkCompactCollector::RetainMaps() {
}
Object prototype = map.prototype();
if (age > 0 && prototype.IsHeapObject() &&
- marking_state()->IsWhite(HeapObject::cast(prototype))) {
+ (!HeapObject::cast(prototype).InReadOnlySpace() &&
+ marking_state()->IsWhite(HeapObject::cast(prototype)))) {
// The prototype is not marked, age the map.
new_age = age - 1;
} else {
@@ -2980,7 +2973,10 @@ class StringForwardingTableCleaner final {
String original_string = String::cast(original);
if (marking_state_->IsBlack(original_string)) {
Object forward = record->ForwardStringObjectOrHash(isolate_);
- if (!forward.IsHeapObject()) return;
+ if (!forward.IsHeapObject() ||
+ HeapObject::cast(forward).InReadOnlySpace()) {
+ return;
+ }
marking_state_->WhiteToBlack(HeapObject::cast(forward));
} else {
DisposeExternalResource(record);
@@ -3036,11 +3032,15 @@ class StringForwardingTableCleaner final {
StringForwardingTable::Record* record) {
if (original_string.IsInternalizedString()) return;
Object forward = record->ForwardStringObjectOrHash(isolate_);
- if (!forward.IsHeapObject()) return;
+ if (!forward.IsHeapObject()) {
+ return;
+ }
String forward_string = String::cast(forward);
// Mark the forwarded string to keep it alive.
- marking_state_->WhiteToBlack(forward_string);
+ if (!forward_string.InReadOnlySpace()) {
+ marking_state_->WhiteToBlack(forward_string);
+ }
// Transition the original string to a ThinString and override the
// forwarding index with the correct hash.
original_string.MakeThin(isolate_, forward_string);
@@ -3679,7 +3679,8 @@ void MarkCompactCollector::ClearJSWeakRefs() {
JSWeakRef weak_ref;
while (local_weak_objects()->js_weak_refs_local.Pop(&weak_ref)) {
HeapObject target = HeapObject::cast(weak_ref.target());
- if (!non_atomic_marking_state()->IsBlackOrGrey(target)) {
+ if (!target.InReadOnlySpace() &&
+ !non_atomic_marking_state()->IsBlackOrGrey(target)) {
weak_ref.set_target(ReadOnlyRoots(isolate()).undefined_value());
} else {
// The value of the JSWeakRef is alive.
@@ -3696,7 +3697,8 @@ void MarkCompactCollector::ClearJSWeakRefs() {
}
};
HeapObject target = HeapObject::cast(weak_cell.target());
- if (!non_atomic_marking_state()->IsBlackOrGrey(target)) {
+ if (!target.InReadOnlySpace() &&
+ !non_atomic_marking_state()->IsBlackOrGrey(target)) {
DCHECK(target.CanBeHeldWeakly());
// The value of the WeakCell is dead.
JSFinalizationRegistry finalization_registry =
@@ -3718,7 +3720,8 @@ void MarkCompactCollector::ClearJSWeakRefs() {
}
HeapObject unregister_token = weak_cell.unregister_token();
- if (!non_atomic_marking_state()->IsBlackOrGrey(unregister_token)) {
+ if (!unregister_token.InReadOnlySpace() &&
+ !non_atomic_marking_state()->IsBlackOrGrey(unregister_token)) {
DCHECK(unregister_token.CanBeHeldWeakly());
// The unregister token is dead. Remove any corresponding entries in the
// key map. Multiple WeakCell with the same token will have all their
diff --git a/src/heap/mark-compact.h b/src/heap/mark-compact.h
index e1fe165346..fbf460b798 100644
--- a/src/heap/mark-compact.h
+++ b/src/heap/mark-compact.h
@@ -420,7 +420,6 @@ class MarkCompactCollector final : public CollectorBase {
void VerifyMarking();
#ifdef VERIFY_HEAP
void VerifyMarkbitsAreClean();
- void VerifyMarkbitsAreDirty(ReadOnlySpace* space);
void VerifyMarkbitsAreClean(PagedSpaceBase* space);
void VerifyMarkbitsAreClean(NewSpace* space);
void VerifyMarkbitsAreClean(LargeObjectSpace* space);
diff --git a/src/heap/marking-barrier-inl.h b/src/heap/marking-barrier-inl.h
index 4a9761abd4..37c31c515b 100644
--- a/src/heap/marking-barrier-inl.h
+++ b/src/heap/marking-barrier-inl.h
@@ -14,6 +14,8 @@ namespace v8 {
namespace internal {
void MarkingBarrier::MarkValue(HeapObject host, HeapObject value) {
+ if (value.InReadOnlySpace()) return;
+
DCHECK(IsCurrentMarkingBarrier(host));
DCHECK(is_activated_ || shared_heap_worklist_.has_value());
diff --git a/src/heap/marking-visitor-inl.h b/src/heap/marking-visitor-inl.h
index 9f47e8f071..b877819184 100644
--- a/src/heap/marking-visitor-inl.h
+++ b/src/heap/marking-visitor-inl.h
@@ -257,6 +257,7 @@ int MarkingVisitorBase::
if (end < size) {
// The object can be pushed back onto the marking worklist only after
// progress bar was updated.
+ DCHECK(ShouldMarkObject(object));
local_marking_worklists_->Push(object);
}
}
@@ -372,7 +373,8 @@ int MarkingVisitorBase::VisitEphemeronHashTable(
// WeakMaps and WeakSets and therefore cannot be ephemeron keys. See also
// MarkCompactCollector::ProcessEphemeron.
DCHECK(!key.InSharedWritableHeap());
- if (concrete_visitor()->marking_state()->IsBlackOrGrey(key)) {
+ if (key.InReadOnlySpace() ||
+ concrete_visitor()->marking_state()->IsBlackOrGrey(key)) {
VisitPointer(table, value_slot);
} else {
Object value_obj = table.ValueAt(i);
@@ -405,7 +407,8 @@ int MarkingVisitorBase::VisitJSWeakRef(
if (weak_ref.target().IsHeapObject()) {
HeapObject target = HeapObject::cast(weak_ref.target());
SynchronizePageAccess(target);
- if (concrete_visitor()->marking_state()->IsBlackOrGrey(target)) {
+ if (target.InReadOnlySpace() ||
+ concrete_visitor()->marking_state()->IsBlackOrGrey(target)) {
// Record the slot inside the JSWeakRef, since the
// VisitJSObjectSubclass above didn't visit it.
ObjectSlot slot = weak_ref.RawField(JSWeakRef::kTargetOffset);
@@ -432,8 +435,10 @@ int MarkingVisitorBase::VisitWeakCell(
HeapObject unregister_token = weak_cell.relaxed_unregister_token();
SynchronizePageAccess(target);
SynchronizePageAccess(unregister_token);
- if (concrete_visitor()->marking_state()->IsBlackOrGrey(target) &&
- concrete_visitor()->marking_state()->IsBlackOrGrey(unregister_token)) {
+ if ((target.InReadOnlySpace() ||
+ concrete_visitor()->marking_state()->IsBlackOrGrey(target)) &&
+ (unregister_token.InReadOnlySpace() ||
+ concrete_visitor()->marking_state()->IsBlackOrGrey(unregister_token))) {
// Record the slots inside the WeakCell, since the IterateBody above
// didn't visit it.
ObjectSlot slot = weak_cell.RawField(WeakCell::kTargetOffset);
@@ -458,6 +463,7 @@ int MarkingVisitorBase::VisitWeakCell(
template
int MarkingVisitorBase::MarkDescriptorArrayBlack(
DescriptorArray descriptors) {
+ if (descriptors.InReadOnlySpace()) return 0;
concrete_visitor()->marking_state()->WhiteToGrey(descriptors);
if (concrete_visitor()->marking_state()->GreyToBlack(descriptors)) {
VisitMapPointer(descriptors);
diff --git a/src/heap/marking-visitor.h b/src/heap/marking-visitor.h
index 58463a267c..39c502e395 100644
--- a/src/heap/marking-visitor.h
+++ b/src/heap/marking-visitor.h
@@ -122,6 +122,7 @@ class MarkingVisitorBase : public HeapVisitor {
}
bool ShouldMarkObject(HeapObject object) const {
+ if (object.InReadOnlySpace()) return false;
if (should_mark_shared_heap_) return true;
return !object.InSharedHeap();
}
diff --git a/src/heap/object-stats.cc b/src/heap/object-stats.cc
index 40e29e41db..c04fda22c2 100644
--- a/src/heap/object-stats.cc
+++ b/src/heap/object-stats.cc
@@ -846,8 +846,12 @@ bool ObjectStatsCollectorImpl::IsCowArray(FixedArrayBase array) {
}
bool ObjectStatsCollectorImpl::SameLiveness(HeapObject obj1, HeapObject obj2) {
- return obj1.is_null() || obj2.is_null() ||
- marking_state_->Color(obj1) == marking_state_->Color(obj2);
+ if (obj1.is_null() || obj2.is_null()) return true;
+ auto col1 = obj1.InReadOnlySpace() ? Marking::ObjectColor::BLACK_OBJECT
+ : marking_state_->Color(obj1);
+ auto col2 = obj2.InReadOnlySpace() ? Marking::ObjectColor::BLACK_OBJECT
+ : marking_state_->Color(obj2);
+ return col1 == col2;
}
void ObjectStatsCollectorImpl::RecordVirtualMapDetails(Map map) {
@@ -1093,7 +1097,7 @@ class ObjectStatsVisitor {
phase_(phase) {}
void Visit(HeapObject obj) {
- if (marking_state_->IsBlack(obj)) {
+ if (obj.InReadOnlySpace() || marking_state_->IsBlack(obj)) {
live_collector_->CollectStatistics(
obj, phase_, ObjectStatsCollectorImpl::CollectFieldStats::kYes);
} else {
diff --git a/src/heap/read-only-spaces.cc b/src/heap/read-only-spaces.cc
index e85c2bca6b..26db3d2f53 100644
--- a/src/heap/read-only-spaces.cc
+++ b/src/heap/read-only-spaces.cc
@@ -338,7 +338,6 @@ ReadOnlyPage::ReadOnlyPage(Heap* heap, BaseSpace* space, size_t chunk_size,
std::move(reservation)) {
allocated_bytes_ = 0;
SetFlags(Flag::NEVER_EVACUATE | Flag::READ_ONLY_HEAP);
- heap->non_atomic_marking_state()->bitmap(this)->MarkAllBits();
}
void ReadOnlyPage::MakeHeaderRelocatable() {
@@ -545,11 +544,6 @@ void ReadOnlySpace::FreeLinearAllocationArea() {
return;
}
- // Clear the bits in the unused black area.
- ReadOnlyPage* page = pages_.back();
- heap()->marking_state()->bitmap(page)->ClearRange(
- page->AddressToMarkbitIndex(top_), page->AddressToMarkbitIndex(limit_));
-
heap()->CreateFillerObjectAt(top_, static_cast(limit_ - top_));
BasicMemoryChunk::UpdateHighWaterMark(top_);
@@ -662,15 +656,9 @@ AllocationResult ReadOnlySpace::AllocateRawUnaligned(int size_in_bytes) {
AllocationResult ReadOnlySpace::AllocateRaw(int size_in_bytes,
AllocationAlignment alignment) {
- AllocationResult result =
- USE_ALLOCATION_ALIGNMENT_BOOL && alignment != kTaggedAligned
- ? AllocateRawAligned(size_in_bytes, alignment)
- : AllocateRawUnaligned(size_in_bytes);
- HeapObject heap_obj;
- if (result.To(&heap_obj)) {
- DCHECK(heap()->marking_state()->IsBlack(heap_obj));
- }
- return result;
+ return USE_ALLOCATION_ALIGNMENT_BOOL && alignment != kTaggedAligned
+ ? AllocateRawAligned(size_in_bytes, alignment)
+ : AllocateRawUnaligned(size_in_bytes);
}
size_t ReadOnlyPage::ShrinkToHighWaterMark() {
diff --git a/src/objects/heap-object.h b/src/objects/heap-object.h
index 2e0ea5fe02..26b5b10ee9 100644
--- a/src/objects/heap-object.h
+++ b/src/objects/heap-object.h
@@ -95,6 +95,8 @@ class HeapObject : public Object {
V8_INLINE bool InSharedWritableHeap() const;
+ V8_INLINE bool InReadOnlySpace() const;
+
#define IS_TYPE_FUNCTION_DECL(Type) \
V8_INLINE bool Is##Type() const; \
V8_INLINE bool Is##Type(PtrComprCageBase cage_base) const;
diff --git a/src/objects/objects-inl.h b/src/objects/objects-inl.h
index 03bf938775..1aca9a80a8 100644
--- a/src/objects/objects-inl.h
+++ b/src/objects/objects-inl.h
@@ -207,6 +207,8 @@ bool HeapObject::InSharedWritableHeap() const {
return BasicMemoryChunk::FromHeapObject(*this)->InSharedHeap();
}
+bool HeapObject::InReadOnlySpace() const { return IsReadOnlyHeapObject(*this); }
+
bool HeapObject::IsJSObjectThatCanBeTrackedAsPrototype() const {
// Do not optimize objects in the shared heap because it is not
// threadsafe. Objects in the shared heap have fixed layouts and their maps
diff --git a/test/cctest/heap/test-concurrent-marking.cc b/test/cctest/heap/test-concurrent-marking.cc
index e57fa68f37..c4e2089c8e 100644
--- a/test/cctest/heap/test-concurrent-marking.cc
+++ b/test/cctest/heap/test-concurrent-marking.cc
@@ -26,6 +26,11 @@ void PublishSegment(MarkingWorklist& worklist, HeapObject object) {
local.Publish();
}
+HeapObject ObjectForTesting(i::Isolate* isolate) {
+ return HeapObject::cast(
+ isolate->roots_table().slot(RootIndex::kFirstStrongRoot).load(isolate));
+}
+
TEST(ConcurrentMarking) {
if (!i::v8_flags.concurrent_marking) return;
CcTest::InitializeVM();
@@ -42,7 +47,7 @@ TEST(ConcurrentMarking) {
new ConcurrentMarking(heap, &weak_objects);
MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector();
PublishSegment(*collector->marking_worklists()->shared(),
- ReadOnlyRoots(heap).undefined_value());
+ ObjectForTesting(heap->isolate()));
concurrent_marking->ScheduleJob(GarbageCollector::MARK_COMPACTOR);
concurrent_marking->Join();
delete concurrent_marking;
@@ -64,11 +69,11 @@ TEST(ConcurrentMarkingReschedule) {
new ConcurrentMarking(heap, &weak_objects);
MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector();
PublishSegment(*collector->marking_worklists()->shared(),
- ReadOnlyRoots(heap).undefined_value());
+ ObjectForTesting(heap->isolate()));
concurrent_marking->ScheduleJob(GarbageCollector::MARK_COMPACTOR);
concurrent_marking->Join();
PublishSegment(*collector->marking_worklists()->shared(),
- ReadOnlyRoots(heap).undefined_value());
+ ObjectForTesting(heap->isolate()));
concurrent_marking->RescheduleJobIfNeeded(GarbageCollector::MARK_COMPACTOR);
concurrent_marking->Join();
delete concurrent_marking;
@@ -91,12 +96,12 @@ TEST(ConcurrentMarkingPreemptAndReschedule) {
MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector();
for (int i = 0; i < 5000; i++)
PublishSegment(*collector->marking_worklists()->shared(),
- ReadOnlyRoots(heap).undefined_value());
+ ObjectForTesting(heap->isolate()));
concurrent_marking->ScheduleJob(GarbageCollector::MARK_COMPACTOR);
concurrent_marking->Pause();
for (int i = 0; i < 5000; i++)
PublishSegment(*collector->marking_worklists()->shared(),
- ReadOnlyRoots(heap).undefined_value());
+ ObjectForTesting(heap->isolate()));
concurrent_marking->RescheduleJobIfNeeded(GarbageCollector::MARK_COMPACTOR);
concurrent_marking->Join();
delete concurrent_marking;
diff --git a/test/cctest/heap/test-heap.cc b/test/cctest/heap/test-heap.cc
index 3bd7942a16..0ed33aa57b 100644
--- a/test/cctest/heap/test-heap.cc
+++ b/test/cctest/heap/test-heap.cc
@@ -5811,7 +5811,7 @@ TEST(Regress598319) {
// progress bar, we would fail here.
for (int i = 0; i < arr.get().length(); i++) {
HeapObject arr_value = HeapObject::cast(arr.get().get(i));
- CHECK(marking_state->IsBlack(arr_value));
+ CHECK(arr_value.InReadOnlySpace() || marking_state->IsBlack(arr_value));
}
}
diff --git a/test/unittests/heap/marking-worklist-unittest.cc b/test/unittests/heap/marking-worklist-unittest.cc
index c6eabd85b4..45bbdad4be 100644
--- a/test/unittests/heap/marking-worklist-unittest.cc
+++ b/test/unittests/heap/marking-worklist-unittest.cc
@@ -22,7 +22,10 @@ TEST_F(MarkingWorklistTest, PushPop) {
MarkingWorklists holder;
MarkingWorklists::Local worklists(&holder);
HeapObject pushed_object =
- ReadOnlyRoots(i_isolate()->heap()).undefined_value();
+ HeapObject::cast(i_isolate()
+ ->roots_table()
+ .slot(RootIndex::kFirstStrongRoot)
+ .load(i_isolate()));
worklists.Push(pushed_object);
HeapObject popped_object;
EXPECT_TRUE(worklists.Pop(&popped_object));
@@ -33,7 +36,10 @@ TEST_F(MarkingWorklistTest, PushPopOnHold) {
MarkingWorklists holder;
MarkingWorklists::Local worklists(&holder);
HeapObject pushed_object =
- ReadOnlyRoots(i_isolate()->heap()).undefined_value();
+ HeapObject::cast(i_isolate()
+ ->roots_table()
+ .slot(RootIndex::kFirstStrongRoot)
+ .load(i_isolate()));
worklists.PushOnHold(pushed_object);
HeapObject popped_object;
EXPECT_TRUE(worklists.PopOnHold(&popped_object));
@@ -45,7 +51,10 @@ TEST_F(MarkingWorklistTest, MergeOnHold) {
MarkingWorklists::Local main_worklists(&holder);
MarkingWorklists::Local worker_worklists(&holder);
HeapObject pushed_object =
- ReadOnlyRoots(i_isolate()->heap()).undefined_value();
+ HeapObject::cast(i_isolate()
+ ->roots_table()
+ .slot(RootIndex::kFirstStrongRoot)
+ .load(i_isolate()));
worker_worklists.PushOnHold(pushed_object);
worker_worklists.Publish();
main_worklists.MergeOnHold();
@@ -59,7 +68,10 @@ TEST_F(MarkingWorklistTest, ShareWorkIfGlobalPoolIsEmpty) {
MarkingWorklists::Local main_worklists(&holder);
MarkingWorklists::Local worker_worklists(&holder);
HeapObject pushed_object =
- ReadOnlyRoots(i_isolate()->heap()).undefined_value();
+ HeapObject::cast(i_isolate()
+ ->roots_table()
+ .slot(RootIndex::kFirstStrongRoot)
+ .load(i_isolate()));
main_worklists.Push(pushed_object);
main_worklists.ShareWork();
HeapObject popped_object;
@@ -73,7 +85,10 @@ TEST_F(MarkingWorklistTest, ContextWorklistsPushPop) {
holder.CreateContextWorklists({context});
MarkingWorklists::Local worklists(&holder);
HeapObject pushed_object =
- ReadOnlyRoots(i_isolate()->heap()).undefined_value();
+ HeapObject::cast(i_isolate()
+ ->roots_table()
+ .slot(RootIndex::kFirstStrongRoot)
+ .load(i_isolate()));
worklists.SwitchToContext(context);
worklists.Push(pushed_object);
worklists.SwitchToSharedForTesting();
@@ -89,7 +104,10 @@ TEST_F(MarkingWorklistTest, ContextWorklistsEmpty) {
holder.CreateContextWorklists({context});
MarkingWorklists::Local worklists(&holder);
HeapObject pushed_object =
- ReadOnlyRoots(i_isolate()->heap()).undefined_value();
+ HeapObject::cast(i_isolate()
+ ->roots_table()
+ .slot(RootIndex::kFirstStrongRoot)
+ .load(i_isolate()));
worklists.SwitchToContext(context);
worklists.Push(pushed_object);
EXPECT_FALSE(worklists.IsEmpty());
@@ -110,7 +128,10 @@ TEST_F(MarkingWorklistTest, ContextWorklistCrossTask) {
MarkingWorklists::Local main_worklists(&holder);
MarkingWorklists::Local worker_worklists(&holder);
HeapObject pushed_object =
- ReadOnlyRoots(i_isolate()->heap()).undefined_value();
+ HeapObject::cast(i_isolate()
+ ->roots_table()
+ .slot(RootIndex::kFirstStrongRoot)
+ .load(i_isolate()));
main_worklists.SwitchToContext(context1);
main_worklists.Push(pushed_object);
main_worklists.ShareWork();