• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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