blob: d550253792ca6f041ca835fe66b5fb99fc6c0982 [file] [log] [blame]
// 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/check.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) {
DCHECK(!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>(),
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;
}