Add Oilpan cppgc object allocation tests.
Creates an object and tracks that it is destroyed by GC.
Change-Id: I573787d0e413a40d2b0816f3bb2b93c5b1bdd6a9
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/70570
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fxjs/gc/heap_embeddertest.cpp b/fxjs/gc/heap_embeddertest.cpp
index 2696a91..381bd13 100644
--- a/fxjs/gc/heap_embeddertest.cpp
+++ b/fxjs/gc/heap_embeddertest.cpp
@@ -5,11 +5,82 @@
#include "fxjs/gc/heap.h"
#include <memory>
+#include <set>
#include "testing/embedder_test.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/base/stl_util.h"
+#include "v8/include/cppgc/allocation.h"
+#include "v8/include/cppgc/persistent.h"
+#include "v8/include/v8.h"
-TEST_F(EmbedderTest, SeveralHeaps) {
+namespace {
+
+class PseudoCollectible : public cppgc::GarbageCollected<PseudoCollectible> {
+ public:
+ static cppgc::Persistent<PseudoCollectible> s_persistent_;
+
+ static void Clear() {
+ s_live_.clear();
+ s_dead_.clear();
+ s_persistent_ = nullptr;
+ }
+ static size_t LiveCount() { return s_live_.size(); }
+ static size_t DeadCount() { return s_dead_.size(); }
+
+ PseudoCollectible() { s_live_.insert(this); }
+ virtual ~PseudoCollectible() {
+ s_live_.erase(this);
+ s_dead_.insert(this);
+ }
+
+ bool IsLive() const { return pdfium::Contains(s_live_, this); }
+
+ virtual void Trace(cppgc::Visitor* visitor) const {}
+
+ private:
+ static std::set<const PseudoCollectible*> s_live_;
+ static std::set<const PseudoCollectible*> s_dead_;
+};
+
+std::set<const PseudoCollectible*> PseudoCollectible::s_live_;
+std::set<const PseudoCollectible*> PseudoCollectible::s_dead_;
+cppgc::Persistent<PseudoCollectible> PseudoCollectible::s_persistent_;
+
+struct V8IsolateDeleter {
+ inline void operator()(v8::Isolate* ptr) { ptr->Dispose(); }
+};
+
+} // namespace
+
+class HeapEmbedderTest : public EmbedderTest {
+ public:
+ void SetUp() override {
+ v8::Isolate::CreateParams params;
+ params.array_buffer_allocator = static_cast<v8::ArrayBuffer::Allocator*>(
+ FPDF_GetArrayBufferAllocatorSharedInstance());
+ isolate_.reset(v8::Isolate::New(params));
+ EmbedderTest::SetExternalIsolate(isolate_.get());
+ EmbedderTest::SetUp();
+ }
+
+ void TearDown() override {
+ EmbedderTest::TearDown();
+ isolate_.reset();
+ }
+
+ void PumpPlatformMessageLoop() {
+ while (v8::platform::PumpMessageLoop(
+ EmbedderTestEnvironment::GetInstance()->platform(), isolate_.get())) {
+ continue;
+ }
+ }
+
+ private:
+ std::unique_ptr<v8::Isolate, V8IsolateDeleter> isolate_;
+};
+
+TEST_F(HeapEmbedderTest, SeveralHeaps) {
FXGCScopedHeap heap1 = FXGC_CreateHeap();
EXPECT_TRUE(heap1);
@@ -19,3 +90,41 @@
FXGCScopedHeap heap3 = FXGC_CreateHeap();
EXPECT_TRUE(heap2);
}
+
+TEST_F(HeapEmbedderTest, NoReferences) {
+ FXGCScopedHeap heap1 = FXGC_CreateHeap();
+ ASSERT_TRUE(heap1);
+
+ PseudoCollectible::s_persistent_ =
+ cppgc::MakeGarbageCollected<PseudoCollectible>(heap1.get());
+ EXPECT_TRUE(PseudoCollectible::s_persistent_->IsLive());
+ EXPECT_EQ(1u, PseudoCollectible::LiveCount());
+ EXPECT_EQ(0u, PseudoCollectible::DeadCount());
+
+ PseudoCollectible::s_persistent_ = nullptr;
+ heap1->ForceGarbageCollectionSlow("NoReferences", "test",
+ cppgc::Heap::StackState::kNoHeapPointers);
+ PumpPlatformMessageLoop();
+ EXPECT_EQ(0u, PseudoCollectible::LiveCount());
+ EXPECT_EQ(1u, PseudoCollectible::DeadCount());
+ PseudoCollectible::Clear();
+}
+
+TEST_F(HeapEmbedderTest, HasReferences) {
+ FXGCScopedHeap heap1 = FXGC_CreateHeap();
+ ASSERT_TRUE(heap1);
+
+ PseudoCollectible::s_persistent_ =
+ cppgc::MakeGarbageCollected<PseudoCollectible>(heap1.get());
+ EXPECT_TRUE(PseudoCollectible::s_persistent_->IsLive());
+ EXPECT_EQ(1u, PseudoCollectible::LiveCount());
+ EXPECT_EQ(0u, PseudoCollectible::DeadCount());
+
+ heap1->ForceGarbageCollectionSlow("HasReferences", "test",
+ cppgc::Heap::StackState::kNoHeapPointers);
+ PumpPlatformMessageLoop();
+ EXPECT_TRUE(PseudoCollectible::s_persistent_->IsLive());
+ EXPECT_EQ(1u, PseudoCollectible::LiveCount());
+ EXPECT_EQ(0u, PseudoCollectible::DeadCount());
+ PseudoCollectible::Clear();
+}