| // 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 "core/fxcrt/fx_system.h" |
| #include "third_party/base/ptr_util.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) { |
| ASSERT(!g_platform); |
| g_platform = platform; |
| g_isolate = isolate; |
| cppgc::InitializeProcess(platform->GetPageAllocator()); |
| } |
| } |
| |
| void FXGC_Release() { |
| if (g_platform && g_platform_ref_count == 0) { |
| cppgc::ShutdownProcess(); |
| 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>()); |
| return FXGCScopedHeap(heap.release()); |
| } |
| |
| void FXGC_ForceGarbageCollection(cppgc::Heap* heap) { |
| heap->ForceGarbageCollectionSlow("FXGC", "ForceGarbageCollection", |
| cppgc::Heap::StackState::kNoHeapPointers); |
| } |
| |
| void FXGCHeapDeleter::operator()(cppgc::Heap* heap) { |
| ASSERT(heap); |
| ASSERT(g_platform_ref_count > 0); |
| --g_platform_ref_count; |
| |
| FXGC_ForceGarbageCollection(heap); |
| delete heap; |
| } |