From bdaf51bae79a655e69ed8608008c72e9352ba806 Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Thu, 22 Apr 2021 20:47:09 +0200 Subject: [PATCH] src: allow custom 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. PR-URL: https://github.com/nodejs/node/pull/38362 Reviewed-By: James M Snell Reviewed-By: Anna Henningsen Reviewed-By: Rich Trott --- src/api/environment.cc | 10 +++++++--- src/node.h | 3 ++- src/node_platform.cc | 11 ++++++++++- src/node_platform.h | 5 ++++- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/api/environment.cc b/src/api/environment.cc index 46e3360ef9c023..3d061d38a5717a 100644 --- a/src/api/environment.cc +++ b/src/api/environment.cc @@ -465,7 +465,8 @@ MultiIsolatePlatform* CreatePlatform( MultiIsolatePlatform* CreatePlatform( int thread_pool_size, v8::TracingController* tracing_controller) { - return MultiIsolatePlatform::Create(thread_pool_size, tracing_controller) + return MultiIsolatePlatform::Create(thread_pool_size, + tracing_controller) .release(); } @@ -475,8 +476,11 @@ 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..066c0eadfb6b05 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 { 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; };