Add fxjs/gc interface to Oilpan's CPP GCed heaps.
Only provides one small test since the FX API is expected to
change, but ensures we can link, initialize, and make a heap.
-- Use FXGC naming for parallelism with FXJS.
-- The Oilpan layer will now be initialized for XFA builds.
-- The platform is now only passed to the new FXGC side.
Change-Id: I452050556554bf03fdc319f8e16ec71ff2dac176
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/70510
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fxjs/BUILD.gn b/fxjs/BUILD.gn
index 8f6225f..6ec9276 100644
--- a/fxjs/BUILD.gn
+++ b/fxjs/BUILD.gn
@@ -114,6 +114,8 @@
if (pdf_enable_xfa) {
sources += [
+ "gc/heap.cpp",
+ "gc/heap.h",
"xfa/cfxjse_class.cpp",
"xfa/cfxjse_class.h",
"xfa/cfxjse_context.cpp",
@@ -205,6 +207,7 @@
deps += [
"../xfa/fgas",
"../xfa/fxfa/fm2js",
+ "//v8:cppgc",
]
}
}
@@ -237,16 +240,19 @@
"../fpdfsdk",
]
pdfium_root_dir = "../"
-
if (pdf_enable_xfa) {
sources += [
+ "gc/heap_embeddertest.cpp",
"xfa/cfxjse_app_embeddertest.cpp",
"xfa/cfxjse_formcalc_context_embeddertest.cpp",
"xfa/cfxjse_value_embeddertest.cpp",
"xfa/cjx_hostpseudomodel_embeddertest.cpp",
"xfa/cjx_list_embeddertest.cpp",
]
- deps += [ "../xfa/fxfa" ]
+ deps += [
+ "../xfa/fxfa",
+ "//v8:cppgc",
+ ]
}
}
}
diff --git a/fxjs/cfxjs_engine.cpp b/fxjs/cfxjs_engine.cpp
index cb0cede..ae1a9bc 100644
--- a/fxjs/cfxjs_engine.cpp
+++ b/fxjs/cfxjs_engine.cpp
@@ -14,7 +14,6 @@
#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_runtimedata.h"
#include "third_party/base/stl_util.h"
-#include "v8/include/libplatform/libplatform.h"
#include "v8/include/v8-util.h"
class CFXJS_PerObjectData;
@@ -23,7 +22,6 @@
unsigned int g_embedderDataSlot = 1u;
v8::Isolate* g_isolate = nullptr;
-v8::Platform* g_platform = nullptr;
size_t g_isolate_ref_count = 0;
CFX_V8ArrayBufferAllocator* g_arrayBufferAllocator = nullptr;
v8::Global<v8::ObjectTemplate>* g_DefaultGlobalObjectTemplate = nullptr;
@@ -271,9 +269,7 @@
return pMap ? &pMap->m_map : nullptr;
}
-void FXJS_Initialize(unsigned int embedderDataSlot,
- v8::Isolate* pIsolate,
- v8::Platform* pPlatform) {
+void FXJS_Initialize(unsigned int embedderDataSlot, v8::Isolate* pIsolate) {
if (g_isolate) {
ASSERT(g_embedderDataSlot == embedderDataSlot);
ASSERT(g_isolate == pIsolate);
@@ -281,7 +277,6 @@
}
g_embedderDataSlot = embedderDataSlot;
g_isolate = pIsolate;
- g_platform = pPlatform;
}
void FXJS_Release() {
diff --git a/fxjs/cfxjs_engine.h b/fxjs/cfxjs_engine.h
index cd337fe..933c250 100644
--- a/fxjs/cfxjs_engine.h
+++ b/fxjs/cfxjs_engine.h
@@ -63,9 +63,7 @@
explicit FXJS_PerIsolateData(v8::Isolate* pIsolate);
};
-void FXJS_Initialize(unsigned int embedderDataSlot,
- v8::Isolate* pIsolate,
- v8::Platform* platform);
+void FXJS_Initialize(unsigned int embedderDataSlot, v8::Isolate* pIsolate);
void FXJS_Release();
// Gets the global isolate set by FXJS_Initialize(), or makes a new one each
diff --git a/fxjs/cfxjs_engine_unittest.cpp b/fxjs/cfxjs_engine_unittest.cpp
index d91fcd1..c8e844c 100644
--- a/fxjs/cfxjs_engine_unittest.cpp
+++ b/fxjs/cfxjs_engine_unittest.cpp
@@ -17,7 +17,7 @@
void SetUp() override {
FXV8UnitTest::SetUp();
- FXJS_Initialize(1, isolate(), nullptr);
+ FXJS_Initialize(1, isolate());
engine_ = std::make_unique<CFXJS_Engine>(isolate());
}
diff --git a/fxjs/cjs_runtime.cpp b/fxjs/cjs_runtime.cpp
index b6b5722..d2c30d3 100644
--- a/fxjs/cjs_runtime.cpp
+++ b/fxjs/cjs_runtime.cpp
@@ -52,7 +52,7 @@
pExternalIsolate = static_cast<v8::Isolate*>(pPlatform->m_isolate);
embedderDataSlot = pPlatform->m_v8EmbedderSlot;
}
- FXJS_Initialize(embedderDataSlot, pExternalIsolate, nullptr);
+ FXJS_Initialize(embedderDataSlot, pExternalIsolate);
}
m_isolateManaged = FXJS_GetIsolate(&pIsolate);
SetIsolate(pIsolate);
diff --git a/fxjs/gc/heap.cpp b/fxjs/gc/heap.cpp
new file mode 100644
index 0000000..02319eb
--- /dev/null
+++ b/fxjs/gc/heap.cpp
@@ -0,0 +1,65 @@
+// Copyright 2020 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "fxjs/gc/heap.h"
+
+#include "third_party/base/ptr_util.h"
+
+namespace {
+
+size_t g_platform_ref_count = 0;
+v8::Platform* g_platform = nullptr;
+
+} // namespace
+
+class CFXGC_Platform final : public cppgc::Platform {
+ public:
+ CFXGC_Platform() = default;
+ ~CFXGC_Platform() override = default;
+
+ cppgc::PageAllocator* GetPageAllocator() override {
+ return g_platform->GetPageAllocator();
+ }
+
+ double MonotonicallyIncreasingTime() override {
+ return g_platform->MonotonicallyIncreasingTime();
+ }
+
+ std::shared_ptr<cppgc::TaskRunner> GetForegroundTaskRunner() override {
+ // V8's default platform creates a new task runner when passed the
+ // v8::Isolate pointer the first time. For non-default platforms this will
+ // require getting the appropriate task runner.
+ return g_platform->GetForegroundTaskRunner(nullptr);
+ }
+
+ std::unique_ptr<cppgc::JobHandle> PostJob(
+ cppgc::TaskPriority priority,
+ std::unique_ptr<cppgc::JobTask> job_task) override {
+ return g_platform->PostJob(priority, std::move(job_task));
+ }
+};
+
+void FXGC_Initialize(v8::Platform* platform) {
+ if (platform) {
+ g_platform = platform;
+ cppgc::InitializeProcess(platform->GetPageAllocator());
+ }
+}
+
+void FXGC_Release() {
+ if (g_platform && g_platform_ref_count == 0) {
+ cppgc::ShutdownProcess();
+ g_platform = nullptr;
+ }
+}
+
+std::unique_ptr<cppgc::Heap> FXGC_CreateHeap() {
+ ++g_platform_ref_count;
+ return cppgc::Heap::Create(std::make_shared<CFXGC_Platform>());
+}
+
+void FXGC_ReleaseHeap(std::unique_ptr<cppgc::Heap> heap) {
+ --g_platform_ref_count;
+ // |heap| destroyed when it goes out of scope.
+}
diff --git a/fxjs/gc/heap.h b/fxjs/gc/heap.h
new file mode 100644
index 0000000..2e25517
--- /dev/null
+++ b/fxjs/gc/heap.h
@@ -0,0 +1,19 @@
+// Copyright 2020 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FXJS_GC_HEAP_H_
+#define FXJS_GC_HEAP_H_
+
+#include <memory>
+
+#include "v8/include/cppgc/heap.h"
+#include "v8/include/libplatform/libplatform.h"
+
+void FXGC_Initialize(v8::Platform* platform);
+void FXGC_Release();
+
+std::unique_ptr<cppgc::Heap> FXGC_CreateHeap();
+void FXGC_ReleaseHeap(std::unique_ptr<cppgc::Heap> heap);
+
+#endif // FXJS_GC_HEAP_H_
diff --git a/fxjs/gc/heap_embeddertest.cpp b/fxjs/gc/heap_embeddertest.cpp
new file mode 100644
index 0000000..8ee42ca
--- /dev/null
+++ b/fxjs/gc/heap_embeddertest.cpp
@@ -0,0 +1,31 @@
+// Copyright 2020 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "fxjs/gc/heap.h"
+
+#include <memory>
+
+#include "testing/embedder_test.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class HeapEmbedderTest : public EmbedderTest {};
+
+TEST(HeapEmbedderTest, SeveralHeaps) {
+ FXGC_Initialize(EmbedderTestEnvironment::GetInstance()->platform());
+
+ std::unique_ptr<cppgc::Heap> heap1 = FXGC_CreateHeap();
+ EXPECT_TRUE(heap1);
+
+ std::unique_ptr<cppgc::Heap> heap2 = FXGC_CreateHeap();
+ EXPECT_TRUE(heap2);
+
+ std::unique_ptr<cppgc::Heap> heap3 = FXGC_CreateHeap();
+ EXPECT_TRUE(heap2);
+
+ FXGC_ReleaseHeap(std::move(heap1));
+ FXGC_ReleaseHeap(std::move(heap2));
+ FXGC_ReleaseHeap(std::move(heap3));
+
+ FXGC_Release();
+}
diff --git a/fxjs/ijs_runtime.cpp b/fxjs/ijs_runtime.cpp
index f16385a..05027e4 100644
--- a/fxjs/ijs_runtime.cpp
+++ b/fxjs/ijs_runtime.cpp
@@ -9,7 +9,10 @@
#ifdef PDF_ENABLE_V8
#include "fxjs/cfxjs_engine.h"
#include "fxjs/cjs_runtime.h"
-#endif
+#ifdef PDF_ENABLE_XFA
+#include "fxjs/gc/heap.h"
+#endif // PDF_ENABLE_XFA
+#endif // PDF_ENABLE_V8
IJS_Runtime::ScopedEventContext::ScopedEventContext(IJS_Runtime* pRuntime)
: m_pRuntime(pRuntime), m_pContext(pRuntime->NewEventContext()) {}
@@ -21,16 +24,21 @@
// static
void IJS_Runtime::Initialize(unsigned int slot, void* isolate, void* platform) {
#ifdef PDF_ENABLE_V8
- FXJS_Initialize(slot, static_cast<v8::Isolate*>(isolate),
- static_cast<v8::Platform*>(platform));
-#endif
+ FXJS_Initialize(slot, static_cast<v8::Isolate*>(isolate));
+#ifdef PDF_ENABLE_XFA
+ FXGC_Initialize(static_cast<v8::Platform*>(platform));
+#endif // PDF_ENABLE_XFA
+#endif // PDF_ENABLE_V8
}
// static
void IJS_Runtime::Destroy() {
#ifdef PDF_ENABLE_V8
+#ifdef PDF_ENABL_XFA
+ FXGC_Release();
+#endif // PDF_ENABLE_XFA
FXJS_Release();
-#endif
+#endif // PDF_ENABLE_V8
}
// static