From cc54c05ee7dbf80fe77ef37b04f4f9c46847ebe1 Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Thu, 22 Apr 2021 20:47:09 +0200 Subject: [PATCH] src: allow embedder-provided PageAllocator in NodePlatform For certain embedder use cases there are more complex memory allocation requirements that the default V8 page allocator does not handle. For example, using MAP_JIT when running under a hardened runtime environment on macOS. This allows embedders like Electron to provide their own allocator that does handle these cases. --- src/api/environment.cc | 10 ++++++---- src/node.h | 6 ++++-- src/node_platform.cc | 11 ++++++++++- src/node_platform.h | 5 ++++- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/api/environment.cc b/src/api/environment.cc index 46e3360ef9c023..52d055797b1eef 100644 --- a/src/api/environment.cc +++ b/src/api/environment.cc @@ -464,8 +464,9 @@ MultiIsolatePlatform* CreatePlatform( MultiIsolatePlatform* CreatePlatform( int thread_pool_size, - v8::TracingController* tracing_controller) { - return MultiIsolatePlatform::Create(thread_pool_size, tracing_controller) + v8::TracingController* tracing_controller, + v8::PageAllocator* page_allocator) { + return MultiIsolatePlatform::Create(thread_pool_size, tracing_controller, page_allocator) .release(); } @@ -475,8 +476,9 @@ void FreePlatform(MultiIsolatePlatform* platform) { std::unique_ptr MultiIsolatePlatform::Create( int thread_pool_size, - v8::TracingController* tracing_controller) { - return std::make_unique(thread_pool_size, tracing_controller); + v8::TracingController* tracing_controller, + v8::PageAllocator* page_allocator) { + return std::make_unique(thread_pool_size, tracing_controller, page_allocator); } MaybeLocal GetPerContextExports(Local context) { diff --git a/src/node.h b/src/node.h index 4348dfba5b2be8..53a3e7c231c673 100644 --- a/src/node.h +++ b/src/node.h @@ -310,7 +310,8 @@ class NODE_EXTERN MultiIsolatePlatform : public v8::Platform { static std::unique_ptr Create( int thread_pool_size, - v8::TracingController* tracing_controller = nullptr); + v8::TracingController* tracing_controller = nullptr, + v8::PageAllocator* page_allocator = nullptr); }; enum IsolateSettingsFlags { @@ -485,7 +486,8 @@ NODE_EXTERN MultiIsolatePlatform* GetMultiIsolatePlatform(IsolateData* env); NODE_DEPRECATED("Use MultiIsolatePlatform::Create() instead", NODE_EXTERN MultiIsolatePlatform* CreatePlatform( int thread_pool_size, - v8::TracingController* tracing_controller)); + v8::TracingController* tracing_controller, + v8::PageAllocator* = nullptr)); NODE_DEPRECATED("Use MultiIsolatePlatform::Create() instead", NODE_EXTERN void FreePlatform(MultiIsolatePlatform* platform)); diff --git a/src/node_platform.cc b/src/node_platform.cc index eb918bdd559c40..9787cbb3edc2e2 100644 --- a/src/node_platform.cc +++ b/src/node_platform.cc @@ -324,12 +324,17 @@ void PerIsolatePlatformData::DecreaseHandleCount() { } NodePlatform::NodePlatform(int thread_pool_size, - v8::TracingController* tracing_controller) { + v8::TracingController* tracing_controller, + v8::PageAllocator* page_allocator) { if (tracing_controller != nullptr) { tracing_controller_ = tracing_controller; } else { tracing_controller_ = new v8::TracingController(); } + + // V8 will default to its built in allocator if none is provided. + page_allocator_ = page_allocator; + // TODO(addaleax): It's a bit icky that we use global state here, but we can't // really do anything about it unless V8 starts exposing a way to access the // current v8::Platform instance. @@ -550,6 +555,10 @@ Platform::StackTracePrinter NodePlatform::GetStackTracePrinter() { }; } +v8::PageAllocator* NodePlatform::GetPageAllocator() { + return page_allocator_; +} + template TaskQueue::TaskQueue() : lock_(), tasks_available_(), tasks_drained_(), diff --git a/src/node_platform.h b/src/node_platform.h index a7139ebdcc28d2..4a05f3bba58c8e 100644 --- a/src/node_platform.h +++ b/src/node_platform.h @@ -138,7 +138,8 @@ class WorkerThreadsTaskRunner { class NodePlatform : public MultiIsolatePlatform { public: NodePlatform(int thread_pool_size, - v8::TracingController* tracing_controller); + v8::TracingController* tracing_controller, + v8::PageAllocator* page_allocator = nullptr); ~NodePlatform() override; void DrainTasks(v8::Isolate* isolate) override; @@ -170,6 +171,7 @@ class NodePlatform : public MultiIsolatePlatform { v8::Isolate* isolate) override; Platform::StackTracePrinter GetStackTracePrinter() override; + v8::PageAllocator* GetPageAllocator() override; private: IsolatePlatformDelegate* ForIsolate(v8::Isolate* isolate); @@ -181,6 +183,7 @@ class NodePlatform : public MultiIsolatePlatform { std::unordered_map per_isolate_; v8::TracingController* tracing_controller_; + v8::PageAllocator* page_allocator_; std::shared_ptr worker_thread_task_runner_; bool has_shut_down_ = false; };