From 973e698d7d5ea4d9ad6b056491eec2d5c5eee059 Mon Sep 17 00:00:00 2001 From: landerlyoung Date: Sat, 27 May 2023 14:42:26 +0800 Subject: [PATCH] add fine-grained operation to control V8 Platform instance lifecycle. --- backend/V8/V8Helper.hpp | 26 ++++++++++++++++++++++++++ backend/V8/V8Platform.cc | 17 +++++++++++++++++ backend/V8/V8Platform.h | 2 ++ 3 files changed, 45 insertions(+) diff --git a/backend/V8/V8Helper.hpp b/backend/V8/V8Helper.hpp index ca6812a9..e4234b10 100644 --- a/backend/V8/V8Helper.hpp +++ b/backend/V8/V8Helper.hpp @@ -97,6 +97,32 @@ struct v8_interop { static ArgumentsData extractArguments(const Arguments& args) { return ArgumentsData{args.callbackInfo_.first, args.callbackInfo_.second}; } + + struct Critical { + /** + * DANGEROUS OPERATION!!! + * By default the v8 platform is a process-level singleton, which will be destroyed during + * process exit. In some C++ guide, it's recommended not to relay on static variable + * destruction. + * + * By call this method, it is guaranteed not to destroy the platform instance (actually by + * making the singleton leak). + */ + static void neverDestroyPlatform(); + + /** + * DANGEROUS OPERATION!!! + * By default the v8 platform is a process-level singleton, which will be destroyed during + * process exit. In some case, if you are sure not to use V8 in the process again (never + * re-create a instance), you can call this method to destroy the platform immediately. Once + * destroyed, V8 usually shuts down thread pool, etc to release resources. + * + * In face, if there is still running V8Engine instance, the platform will be destroy + * afterwords. + * + */ + static void immediatelyDestroyPlatform(); + }; }; } // namespace script \ No newline at end of file diff --git a/backend/V8/V8Platform.cc b/backend/V8/V8Platform.cc index 07138764..06c1df22 100644 --- a/backend/V8/V8Platform.cc +++ b/backend/V8/V8Platform.cc @@ -17,8 +17,10 @@ #include "V8Platform.h" #include +#include #include "../../src/Utils.h" #include "V8Engine.h" +#include "V8Helper.hpp" namespace script::v8_backend { @@ -198,3 +200,18 @@ bool V8Platform::OnCriticalMemoryPressure(size_t length) { #endif } // namespace script::v8_backend + +void script::v8_interop::Critical::neverDestroyPlatform() { + using script::v8_backend::V8Platform; + auto platform = V8Platform::getPlatform(); + + // make the shared_ptr leak + std::aligned_storage_t)> buffer; + new (&buffer) std::shared_ptr(platform); +} + +void script::v8_interop::Critical::immediatelyDestroyPlatform() { + using script::v8_backend::V8Platform; + std::lock_guard lock(V8Platform::lock_); + V8Platform::singletonInstance_ = nullptr; +} diff --git a/backend/V8/V8Platform.h b/backend/V8/V8Platform.h index 161103bd..8db71957 100644 --- a/backend/V8/V8Platform.h +++ b/backend/V8/V8Platform.h @@ -144,6 +144,8 @@ class V8Platform : public v8::Platform { void addEngineInstance(v8::Isolate* isolate, V8Engine* engine); void removeEngineInstance(v8::Isolate* isolate); + + friend struct script::v8_interop; }; } // namespace script::v8_backend