aboutsummaryrefslogtreecommitdiff
path: root/fxjs/gc/heap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fxjs/gc/heap.cpp')
-rw-r--r--fxjs/gc/heap.cpp98
1 files changed, 98 insertions, 0 deletions
diff --git a/fxjs/gc/heap.cpp b/fxjs/gc/heap.cpp
new file mode 100644
index 000000000..301018fe0
--- /dev/null
+++ b/fxjs/gc/heap.cpp
@@ -0,0 +1,98 @@
+// Copyright 2020 The PDFium Authors
+// 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 <utility>
+
+#include "core/fxcrt/fx_system.h"
+#include "third_party/base/check.h"
+#include "v8/include/cppgc/heap.h"
+
+namespace {
+
+size_t g_platform_ref_count = 0;
+v8::Platform* g_platform = nullptr;
+v8::Isolate* g_isolate = nullptr;
+
+} // namespace
+
+// Taken from v8/samples/cppgc/cppgc-for-v8-embedders.cc.
+// Adaptper that makes the global v8::Platform compatible with a
+// cppgc::Platform.
+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(g_isolate);
+ }
+
+ 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, v8::Isolate* isolate) {
+ if (platform) {
+ DCHECK(!g_platform);
+ g_platform = platform;
+ g_isolate = isolate;
+ }
+}
+
+void FXGC_Release() {
+ if (g_platform && g_platform_ref_count == 0) {
+ g_platform = nullptr;
+ g_isolate = nullptr;
+ }
+}
+
+FXGCScopedHeap FXGC_CreateHeap() {
+ // If XFA is included at compile-time, but JS is disabled at run-time,
+ // we may still attempt to build a CPDFXFA_Context which will want a
+ // heap. But we can't make one because JS is disabled.
+ // TODO(tsepez): Stop the context from even being created.
+ if (!g_platform)
+ return nullptr;
+
+ ++g_platform_ref_count;
+ auto heap = cppgc::Heap::Create(
+ std::make_shared<CFXGC_Platform>(),
+ cppgc::Heap::HeapOptions{
+ {},
+ cppgc::Heap::StackSupport::kNoConservativeStackScan,
+ cppgc::Heap::MarkingType::kAtomic,
+ cppgc::Heap::SweepingType::kIncrementalAndConcurrent,
+ {}});
+ return FXGCScopedHeap(heap.release());
+}
+
+void FXGC_ForceGarbageCollection(cppgc::Heap* heap) {
+ heap->ForceGarbageCollectionSlow("FXGC", "ForceGarbageCollection",
+ cppgc::Heap::StackState::kNoHeapPointers);
+}
+
+void FXGCHeapDeleter::operator()(cppgc::Heap* heap) {
+ DCHECK(heap);
+ DCHECK(g_platform_ref_count > 0);
+ --g_platform_ref_count;
+
+ FXGC_ForceGarbageCollection(heap);
+ delete heap;
+}