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 <utility>
8
9 #include "core/fxcrt/fx_system.h"
10 #include "third_party/base/check.h"
11 #include "v8/include/cppgc/heap.h"
12
13 namespace {
14
15 size_t g_platform_ref_count = 0;
16 v8::Platform* g_platform = nullptr;
17 v8::Isolate* g_isolate = nullptr;
18
19 } // namespace
20
21 // Taken from v8/samples/cppgc/cppgc-for-v8-embedders.cc.
22 // Adaptper that makes the global v8::Platform compatible with a
23 // cppgc::Platform.
24 class CFXGC_Platform final : public cppgc::Platform {
25 public:
26 CFXGC_Platform() = default;
27 ~CFXGC_Platform() override = default;
28
GetPageAllocator()29 cppgc::PageAllocator* GetPageAllocator() override {
30 return g_platform->GetPageAllocator();
31 }
32
MonotonicallyIncreasingTime()33 double MonotonicallyIncreasingTime() override {
34 return g_platform->MonotonicallyIncreasingTime();
35 }
36
GetForegroundTaskRunner()37 std::shared_ptr<cppgc::TaskRunner> GetForegroundTaskRunner() override {
38 // V8's default platform creates a new task runner when passed the
39 // v8::Isolate pointer the first time. For non-default platforms this will
40 // require getting the appropriate task runner.
41 return g_platform->GetForegroundTaskRunner(g_isolate);
42 }
43
PostJob(cppgc::TaskPriority priority,std::unique_ptr<cppgc::JobTask> job_task)44 std::unique_ptr<cppgc::JobHandle> PostJob(
45 cppgc::TaskPriority priority,
46 std::unique_ptr<cppgc::JobTask> job_task) override {
47 return g_platform->PostJob(priority, std::move(job_task));
48 }
49 };
50
FXGC_Initialize(v8::Platform * platform,v8::Isolate * isolate)51 void FXGC_Initialize(v8::Platform* platform, v8::Isolate* isolate) {
52 if (platform) {
53 DCHECK(!g_platform);
54 g_platform = platform;
55 g_isolate = isolate;
56 }
57 }
58
FXGC_Release()59 void FXGC_Release() {
60 if (g_platform && g_platform_ref_count == 0) {
61 g_platform = nullptr;
62 g_isolate = nullptr;
63 }
64 }
65
FXGC_CreateHeap()66 FXGCScopedHeap FXGC_CreateHeap() {
67 // If XFA is included at compile-time, but JS is disabled at run-time,
68 // we may still attempt to build a CPDFXFA_Context which will want a
69 // heap. But we can't make one because JS is disabled.
70 // TODO(tsepez): Stop the context from even being created.
71 if (!g_platform)
72 return nullptr;
73
74 ++g_platform_ref_count;
75 auto heap = cppgc::Heap::Create(
76 std::make_shared<CFXGC_Platform>(),
77 cppgc::Heap::HeapOptions{
78 {},
79 cppgc::Heap::StackSupport::kNoConservativeStackScan,
80 cppgc::Heap::MarkingType::kAtomic,
81 cppgc::Heap::SweepingType::kIncrementalAndConcurrent,
82 {}});
83 return FXGCScopedHeap(heap.release());
84 }
85
FXGC_ForceGarbageCollection(cppgc::Heap * heap)86 void FXGC_ForceGarbageCollection(cppgc::Heap* heap) {
87 heap->ForceGarbageCollectionSlow("FXGC", "ForceGarbageCollection",
88 cppgc::Heap::StackState::kNoHeapPointers);
89 }
90
operator ()(cppgc::Heap * heap)91 void FXGCHeapDeleter::operator()(cppgc::Heap* heap) {
92 DCHECK(heap);
93 DCHECK(g_platform_ref_count > 0);
94 --g_platform_ref_count;
95
96 FXGC_ForceGarbageCollection(heap);
97 delete heap;
98 }
99