summaryrefslogtreecommitdiff
path: root/deps/v8/test/unittests/heap/cppgc/marker-unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/unittests/heap/cppgc/marker-unittest.cc')
-rw-r--r--deps/v8/test/unittests/heap/cppgc/marker-unittest.cc173
1 files changed, 149 insertions, 24 deletions
diff --git a/deps/v8/test/unittests/heap/cppgc/marker-unittest.cc b/deps/v8/test/unittests/heap/cppgc/marker-unittest.cc
index 8944372701..b879d9b989 100644
--- a/deps/v8/test/unittests/heap/cppgc/marker-unittest.cc
+++ b/deps/v8/test/unittests/heap/cppgc/marker-unittest.cc
@@ -18,7 +18,6 @@ namespace cppgc {
namespace internal {
namespace {
-
class MarkerTest : public testing::TestWithHeap {
public:
using MarkingConfig = Marker::MarkingConfig;
@@ -27,14 +26,24 @@ class MarkerTest : public testing::TestWithHeap {
const MarkingConfig config = {MarkingConfig::CollectionType::kMajor,
stack_state};
auto* heap = Heap::From(GetHeap());
- Marker marker(heap->AsBase());
- marker.StartMarking(config);
- marker.FinishMarking(config);
- marker.ProcessWeakness();
+ InitializeMarker(*heap, GetPlatformHandle().get(), config);
+ marker_->FinishMarking(stack_state);
+ marker_->ProcessWeakness();
// Pretend do finish sweeping as StatsCollector verifies that Notify*
// methods are called in the right order.
heap->stats_collector()->NotifySweepingCompleted();
}
+
+ void InitializeMarker(HeapBase& heap, cppgc::Platform* platform,
+ MarkingConfig config) {
+ marker_ =
+ MarkerFactory::CreateAndStartMarking<Marker>(heap, platform, config);
+ }
+
+ Marker* marker() const { return marker_.get(); }
+
+ private:
+ std::unique_ptr<Marker> marker_;
};
class GCed : public GarbageCollected<GCed> {
@@ -216,50 +225,166 @@ class GCedWithCallback : public GarbageCollected<GCedWithCallback> {
} // namespace
TEST_F(MarkerTest, InConstructionObjectIsEventuallyMarkedEmptyStack) {
- Marker marker(Heap::From(GetHeap())->AsBase());
- marker.StartMarking({MarkingConfig::CollectionType::kMajor,
- MarkingConfig::StackState::kMayContainHeapPointers});
+ static const Marker::MarkingConfig config = {
+ MarkingConfig::CollectionType::kMajor,
+ MarkingConfig::StackState::kMayContainHeapPointers};
+ InitializeMarker(*Heap::From(GetHeap()), GetPlatformHandle().get(), config);
GCedWithCallback* object = MakeGarbageCollected<GCedWithCallback>(
- GetAllocationHandle(), [&marker](GCedWithCallback* obj) {
+ GetAllocationHandle(), [marker = marker()](GCedWithCallback* obj) {
Member<GCedWithCallback> member(obj);
- marker.VisitorForTesting().Trace(member);
+ marker->VisitorForTesting().Trace(member);
});
EXPECT_TRUE(HeapObjectHeader::FromPayload(object).IsMarked());
- marker.FinishMarking({MarkingConfig::CollectionType::kMajor,
- MarkingConfig::StackState::kMayContainHeapPointers});
+ marker()->FinishMarking(MarkingConfig::StackState::kMayContainHeapPointers);
EXPECT_TRUE(HeapObjectHeader::FromPayload(object).IsMarked());
}
TEST_F(MarkerTest, InConstructionObjectIsEventuallyMarkedNonEmptyStack) {
- Marker marker(Heap::From(GetHeap())->AsBase());
static const Marker::MarkingConfig config = {
MarkingConfig::CollectionType::kMajor,
MarkingConfig::StackState::kMayContainHeapPointers};
- marker.StartMarking(config);
+ InitializeMarker(*Heap::From(GetHeap()), GetPlatformHandle().get(), config);
MakeGarbageCollected<GCedWithCallback>(
- GetAllocationHandle(), [&marker](GCedWithCallback* obj) {
+ GetAllocationHandle(), [marker = marker()](GCedWithCallback* obj) {
Member<GCedWithCallback> member(obj);
- marker.VisitorForTesting().Trace(member);
+ marker->VisitorForTesting().Trace(member);
EXPECT_TRUE(HeapObjectHeader::FromPayload(obj).IsMarked());
- marker.FinishMarking(config);
+ marker->FinishMarking(
+ MarkingConfig::StackState::kMayContainHeapPointers);
EXPECT_TRUE(HeapObjectHeader::FromPayload(obj).IsMarked());
});
}
TEST_F(MarkerTest, SentinelNotClearedOnWeakPersistentHandling) {
- Marker marker(Heap::From(GetHeap())->AsBase());
- Persistent<GCed> root = MakeGarbageCollected<GCed>(GetAllocationHandle());
- auto* tmp = MakeGarbageCollected<GCed>(GetAllocationHandle());
- root->SetWeakChild(tmp);
static const Marker::MarkingConfig config = {
MarkingConfig::CollectionType::kMajor,
MarkingConfig::StackState::kNoHeapPointers};
- marker.StartMarking(config);
- marker.FinishMarking(config);
+ InitializeMarker(*Heap::From(GetHeap()), GetPlatformHandle().get(), config);
+ Persistent<GCed> root = MakeGarbageCollected<GCed>(GetAllocationHandle());
+ auto* tmp = MakeGarbageCollected<GCed>(GetAllocationHandle());
+ root->SetWeakChild(tmp);
+ marker()->FinishMarking(MarkingConfig::StackState::kNoHeapPointers);
root->SetWeakChild(kSentinelPointer);
- marker.ProcessWeakness();
+ marker()->ProcessWeakness();
EXPECT_EQ(kSentinelPointer, root->weak_child());
}
+// Incremental Marking
+
+class IncrementalMarkingTest : public testing::TestWithHeap {
+ public:
+ using MarkingConfig = Marker::MarkingConfig;
+
+ static constexpr MarkingConfig IncrementalPreciseMarkingConfig = {
+ MarkingConfig::CollectionType::kMajor,
+ MarkingConfig::StackState::kNoHeapPointers,
+ MarkingConfig::MarkingType::kIncremental};
+ static constexpr MarkingConfig IncrementalConservativeMarkingConfig = {
+ MarkingConfig::CollectionType::kMajor,
+ MarkingConfig::StackState::kMayContainHeapPointers,
+ MarkingConfig::MarkingType::kIncremental};
+
+ void FinishSteps(MarkingConfig::StackState stack_state) {
+ while (!SingleStep(stack_state)) {}
+ }
+
+ void FinishMarking() {
+ marker_->FinishMarking(MarkingConfig::StackState::kMayContainHeapPointers);
+ marker_->ProcessWeakness();
+ // Pretend do finish sweeping as StatsCollector verifies that Notify*
+ // methods are called in the right order.
+ Heap::From(GetHeap())->stats_collector()->NotifySweepingCompleted();
+ }
+
+ void InitializeMarker(HeapBase& heap, cppgc::Platform* platform,
+ MarkingConfig config) {
+ marker_ =
+ MarkerFactory::CreateAndStartMarking<Marker>(heap, platform, config);
+ }
+
+ Marker* marker() const { return marker_.get(); }
+
+ private:
+ bool SingleStep(MarkingConfig::StackState stack_state) {
+ return marker_->IncrementalMarkingStepForTesting(stack_state);
+ }
+
+ std::unique_ptr<Marker> marker_;
+};
+
+constexpr IncrementalMarkingTest::MarkingConfig
+ IncrementalMarkingTest::IncrementalPreciseMarkingConfig;
+constexpr IncrementalMarkingTest::MarkingConfig
+ IncrementalMarkingTest::IncrementalConservativeMarkingConfig;
+
+TEST_F(IncrementalMarkingTest, RootIsMarkedAfterMarkingStarted) {
+ Persistent<GCed> root = MakeGarbageCollected<GCed>(GetAllocationHandle());
+ EXPECT_FALSE(HeapObjectHeader::FromPayload(root).IsMarked());
+ InitializeMarker(*Heap::From(GetHeap()), GetPlatformHandle().get(),
+ IncrementalPreciseMarkingConfig);
+ EXPECT_TRUE(HeapObjectHeader::FromPayload(root).IsMarked());
+ FinishMarking();
+}
+
+TEST_F(IncrementalMarkingTest, MemberIsMarkedAfterMarkingSteps) {
+ Persistent<GCed> root = MakeGarbageCollected<GCed>(GetAllocationHandle());
+ root->SetChild(MakeGarbageCollected<GCed>(GetAllocationHandle()));
+ HeapObjectHeader& header = HeapObjectHeader::FromPayload(root->child());
+ EXPECT_FALSE(header.IsMarked());
+ InitializeMarker(*Heap::From(GetHeap()), GetPlatformHandle().get(),
+ IncrementalPreciseMarkingConfig);
+ FinishSteps(MarkingConfig::StackState::kNoHeapPointers);
+ EXPECT_TRUE(header.IsMarked());
+ FinishMarking();
+}
+
+TEST_F(IncrementalMarkingTest,
+ MemberWithWriteBarrierIsMarkedAfterMarkingSteps) {
+ Persistent<GCed> root = MakeGarbageCollected<GCed>(GetAllocationHandle());
+ InitializeMarker(*Heap::From(GetHeap()), GetPlatformHandle().get(),
+ IncrementalPreciseMarkingConfig);
+ root->SetChild(MakeGarbageCollected<GCed>(GetAllocationHandle()));
+ HeapObjectHeader& header = HeapObjectHeader::FromPayload(root->child());
+ EXPECT_FALSE(header.IsMarked());
+ FinishSteps(MarkingConfig::StackState::kNoHeapPointers);
+ EXPECT_TRUE(header.IsMarked());
+ FinishMarking();
+}
+
+namespace {
+class Holder : public GarbageCollected<Holder> {
+ public:
+ void Trace(Visitor* visitor) const { visitor->Trace(member_); }
+
+ Member<GCedWithCallback> member_;
+};
+} // namespace
+
+TEST_F(IncrementalMarkingTest, IncrementalStepDuringAllocation) {
+ Persistent<Holder> holder =
+ MakeGarbageCollected<Holder>(GetAllocationHandle());
+ InitializeMarker(*Heap::From(GetHeap()), GetPlatformHandle().get(),
+ IncrementalPreciseMarkingConfig);
+ const HeapObjectHeader* header;
+ MakeGarbageCollected<GCedWithCallback>(
+ GetAllocationHandle(), [this, &holder, &header](GCedWithCallback* obj) {
+ header = &HeapObjectHeader::FromPayload(obj);
+ holder->member_ = obj;
+ EXPECT_FALSE(header->IsMarked());
+ FinishSteps(MarkingConfig::StackState::kMayContainHeapPointers);
+ EXPECT_TRUE(header->IsMarked());
+ });
+ FinishSteps(MarkingConfig::StackState::kNoHeapPointers);
+ EXPECT_TRUE(header->IsMarked());
+ FinishMarking();
+}
+
+TEST_F(IncrementalMarkingTest, MarkingRunsOutOfWorkEventually) {
+ InitializeMarker(*Heap::From(GetHeap()), GetPlatformHandle().get(),
+ IncrementalPreciseMarkingConfig);
+ FinishSteps(MarkingConfig::StackState::kNoHeapPointers);
+ FinishMarking();
+}
+
} // namespace internal
} // namespace cppgc