Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
heap_unittest.cpp
Go to the documentation of this file.
1// Copyright 2020 The PDFium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "fxjs/gc/heap.h"
6
7#include <memory>
8#include <set>
9
10#include "testing/fxgc_unittest.h"
11#include "testing/gtest/include/gtest/gtest.h"
12#include "testing/v8_test_environment.h"
13#include "third_party/base/containers/contains.h"
14#include "v8/include/cppgc/allocation.h"
15#include "v8/include/cppgc/persistent.h"
16
17namespace {
18
19class PseudoCollectible : public cppgc::GarbageCollected<PseudoCollectible> {
20 public:
21 static void ClearCounts() {
22 s_live_.clear();
23 s_dead_.clear();
24 }
25 static size_t LiveCount() { return s_live_.size(); }
26 static size_t DeadCount() { return s_dead_.size(); }
27
28 PseudoCollectible() { s_live_.insert(this); }
29 virtual ~PseudoCollectible() {
30 s_live_.erase(this);
31 s_dead_.insert(this);
32 }
33
34 bool IsLive() const { return pdfium::Contains(s_live_, this); }
35
36 virtual void Trace(cppgc::Visitor* visitor) const {}
37
38 private:
39 static std::set<const PseudoCollectible*> s_live_;
40 static std::set<const PseudoCollectible*> s_dead_;
41};
42
43std::set<const PseudoCollectible*> PseudoCollectible::s_live_;
44std::set<const PseudoCollectible*> PseudoCollectible::s_dead_;
45
46class CollectibleHolder {
47 public:
48 explicit CollectibleHolder(PseudoCollectible* holdee) : holdee_(holdee) {}
49 ~CollectibleHolder() = default;
50
51 PseudoCollectible* holdee() const { return holdee_; }
52
53 private:
54 cppgc::Persistent<PseudoCollectible> holdee_;
55};
56
57class Bloater : public cppgc::GarbageCollected<Bloater> {
58 public:
59 void Trace(cppgc::Visitor* visitor) const {}
60 uint8_t bloat_[65536];
61};
62
63} // namespace
64
65class HeapUnitTest : public FXGCUnitTest {
66 public:
67 HeapUnitTest() = default;
68 ~HeapUnitTest() override = default;
69
70 // FXGCUnitTest:
72 PseudoCollectible::ClearCounts();
74 }
75};
76
78 FXGCScopedHeap heap1 = FXGC_CreateHeap();
79 EXPECT_TRUE(heap1);
80
81 FXGCScopedHeap heap2 = FXGC_CreateHeap();
82 EXPECT_TRUE(heap2);
83
84 FXGCScopedHeap heap3 = FXGC_CreateHeap();
85 EXPECT_TRUE(heap3);
86
87 // Test manually destroying the heap.
88 heap3.reset();
89 EXPECT_FALSE(heap3);
90 heap3.reset();
91 EXPECT_FALSE(heap3);
92}
93
95 FXGCScopedHeap heap1 = FXGC_CreateHeap();
96 ASSERT_TRUE(heap1);
97 {
98 auto holder = std::make_unique<CollectibleHolder>(
99 cppgc::MakeGarbageCollected<PseudoCollectible>(
100 heap1->GetAllocationHandle()));
101
102 EXPECT_TRUE(holder->holdee()->IsLive());
103 EXPECT_EQ(1u, PseudoCollectible::LiveCount());
104 EXPECT_EQ(0u, PseudoCollectible::DeadCount());
105 }
106 FXGC_ForceGarbageCollection(heap1.get());
107 EXPECT_EQ(0u, PseudoCollectible::LiveCount());
108 EXPECT_EQ(1u, PseudoCollectible::DeadCount());
109}
110
112 FXGCScopedHeap heap1 = FXGC_CreateHeap();
113 ASSERT_TRUE(heap1);
114 {
115 auto holder = std::make_unique<CollectibleHolder>(
116 cppgc::MakeGarbageCollected<PseudoCollectible>(
117 heap1->GetAllocationHandle()));
118
119 EXPECT_TRUE(holder->holdee()->IsLive());
120 EXPECT_EQ(1u, PseudoCollectible::LiveCount());
121 EXPECT_EQ(0u, PseudoCollectible::DeadCount());
122
123 FXGC_ForceGarbageCollection(heap1.get());
124 EXPECT_TRUE(holder->holdee()->IsLive());
125 EXPECT_EQ(1u, PseudoCollectible::LiveCount());
126 EXPECT_EQ(0u, PseudoCollectible::DeadCount());
127 }
128}
129
130// TODO(tsepez): enable when CPPGC fixes this segv.
132 FXGCScopedHeap heap1 = FXGC_CreateHeap();
133 ASSERT_TRUE(heap1);
134 {
135 auto holder = std::make_unique<CollectibleHolder>(
136 cppgc::MakeGarbageCollected<PseudoCollectible>(
137 heap1->GetAllocationHandle()));
138
139 EXPECT_TRUE(holder->holdee()->IsLive());
140 EXPECT_EQ(1u, PseudoCollectible::LiveCount());
141 EXPECT_EQ(0u, PseudoCollectible::DeadCount());
142
143 heap1.reset();
144
145 // Maybe someday magically nulled by heap destruction.
146 EXPECT_FALSE(holder->holdee());
147 EXPECT_EQ(1u, PseudoCollectible::LiveCount());
148 EXPECT_EQ(0u, PseudoCollectible::DeadCount());
149 }
150}
151
153 FXGCScopedHeap heap1 = FXGC_CreateHeap();
154 ASSERT_TRUE(heap1);
155 {
156 auto holder = std::make_unique<CollectibleHolder>(
157 cppgc::MakeGarbageCollected<PseudoCollectible>(
158 heap1->GetAllocationHandle()));
159
160 EXPECT_TRUE(holder->holdee()->IsLive());
161 EXPECT_EQ(1u, PseudoCollectible::LiveCount());
162 EXPECT_EQ(0u, PseudoCollectible::DeadCount());
163 }
164 heap1.reset();
165 EXPECT_EQ(0u, PseudoCollectible::LiveCount());
166 EXPECT_EQ(1u, PseudoCollectible::DeadCount());
167}
168
170 ASSERT_TRUE(heap());
171 for (int i = 0; i < 100000; ++i) {
172 cppgc::MakeGarbageCollected<Bloater>(heap()->GetAllocationHandle());
173 Pump(); // Do not force GC, must happen implicitly when space required.
174 }
175}
void TearDown() override
void TearDown() override
HeapUnitTest()=default
~HeapUnitTest() override=default
TEST_F(HeapUnitTest, SeveralHeaps)