Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v8.x] backport some V8 platform changes #20901

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 7 additions & 39 deletions src/env-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,41 +37,9 @@

namespace node {

inline IsolateData::IsolateData(v8::Isolate* isolate, uv_loop_t* event_loop,
uint32_t* zero_fill_field) :

// Create string and private symbol properties as internalized one byte strings.
//
// Internalized because it makes property lookups a little faster and because
// the string is created in the old space straight away. It's going to end up
// in the old space sooner or later anyway but now it doesn't go through
// v8::Eternal's new space handling first.
//
// One byte because our strings are ASCII and we can safely skip V8's UTF-8
// decoding step. It's a one-time cost, but why pay it when you don't have to?
#define V(PropertyName, StringValue) \
PropertyName ## _( \
isolate, \
v8::Private::New( \
isolate, \
v8::String::NewFromOneByte( \
isolate, \
reinterpret_cast<const uint8_t*>(StringValue), \
v8::NewStringType::kInternalized, \
sizeof(StringValue) - 1).ToLocalChecked())),
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V)
#undef V
#define V(PropertyName, StringValue) \
PropertyName ## _( \
isolate, \
v8::String::NewFromOneByte( \
isolate, \
reinterpret_cast<const uint8_t*>(StringValue), \
v8::NewStringType::kInternalized, \
sizeof(StringValue) - 1).ToLocalChecked()),
PER_ISOLATE_STRING_PROPERTIES(V)
#undef V
event_loop_(event_loop), zero_fill_field_(zero_fill_field) {}
inline v8::Isolate* IsolateData::isolate() const {
return isolate_;
}

inline uv_loop_t* IsolateData::event_loop() const {
return event_loop_;
Expand All @@ -81,6 +49,10 @@ inline uint32_t* IsolateData::zero_fill_field() const {
return zero_fill_field_;
}

inline MultiIsolatePlatform* IsolateData::platform() const {
return platform_;
}

inline Environment::AsyncHooks::AsyncHooks()
: async_ids_stack_(env()->isolate(), 16 * 2),
fields_(env()->isolate(), kFieldsCount),
Expand All @@ -93,10 +65,6 @@ inline Environment::AsyncHooks::AsyncHooks()
// which is different from a default context.
async_id_fields_[AsyncHooks::kDefaultTriggerAsyncId] = -1;

// kAsyncIdCounter should start at 1 because that'll be the id the execution
// context during bootstrap (code that runs before entering uv_run()).
async_id_fields_[AsyncHooks::kAsyncIdCounter] = 1;

// Create all the provider strings that will be passed to JS. Place them in
// an array so the array index matches the PROVIDER id offset. This way the
// strings can be retrieved quickly.
Expand Down
61 changes: 61 additions & 0 deletions src/env.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
#include "node_internals.h"
#include "async_wrap.h"
#include "v8-profiler.h"
#include "node_buffer.h"
#include "req-wrap-inl.h"
#include "node_platform.h"

#if defined(_MSC_VER)
#define getpid GetCurrentProcessId
#else
#include <unistd.h>
#endif

#include <stdio.h>
#include <algorithm>
Expand All @@ -10,10 +19,62 @@ namespace node {
using v8::Context;
using v8::FunctionTemplate;
using v8::HandleScope;
using v8::Isolate;
using v8::Local;
using v8::Message;
using v8::Private;
using v8::StackFrame;
using v8::StackTrace;
using v8::String;

IsolateData::IsolateData(Isolate* isolate,
uv_loop_t* event_loop,
MultiIsolatePlatform* platform,
uint32_t* zero_fill_field) :

// Create string and private symbol properties as internalized one byte strings.
//
// Internalized because it makes property lookups a little faster and because
// the string is created in the old space straight away. It's going to end up
// in the old space sooner or later anyway but now it doesn't go through
// v8::Eternal's new space handling first.
//
// One byte because our strings are ASCII and we can safely skip V8's UTF-8
// decoding step. It's a one-time cost, but why pay it when you don't have to?
#define V(PropertyName, StringValue) \
PropertyName ## _( \
isolate, \
Private::New( \
isolate, \
String::NewFromOneByte( \
isolate, \
reinterpret_cast<const uint8_t*>(StringValue), \
v8::NewStringType::kInternalized, \
sizeof(StringValue) - 1).ToLocalChecked())),
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V)
#undef V
#define V(PropertyName, StringValue) \
PropertyName ## _( \
isolate, \
String::NewFromOneByte( \
isolate, \
reinterpret_cast<const uint8_t*>(StringValue), \
v8::NewStringType::kInternalized, \
sizeof(StringValue) - 1).ToLocalChecked()),
PER_ISOLATE_STRING_PROPERTIES(V)
#undef V
isolate_(isolate),
event_loop_(event_loop),
zero_fill_field_(zero_fill_field),
platform_(platform) {
if (platform_ != nullptr)
platform_->RegisterIsolate(this, event_loop);
}

IsolateData::~IsolateData() {
if (platform_ != nullptr)
platform_->UnregisterIsolate(this);
}

void Environment::Start(int argc,
const char* const* argv,
Expand Down
10 changes: 8 additions & 2 deletions src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,10 +346,13 @@ class Environment;

class IsolateData {
public:
inline IsolateData(v8::Isolate* isolate, uv_loop_t* event_loop,
uint32_t* zero_fill_field = nullptr);
IsolateData(v8::Isolate* isolate, uv_loop_t* event_loop,
MultiIsolatePlatform* platform = nullptr,
uint32_t* zero_fill_field = nullptr);
~IsolateData();
inline uv_loop_t* event_loop() const;
inline uint32_t* zero_fill_field() const;
inline MultiIsolatePlatform* platform() const;

#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
Expand All @@ -362,6 +365,7 @@ class IsolateData {
#undef VP

std::unordered_map<nghttp2_rcbuf*, v8::Eternal<v8::String>> http2_static_strs;
inline v8::Isolate* isolate() const;

private:
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
Expand All @@ -374,8 +378,10 @@ class IsolateData {
#undef VS
#undef VP

v8::Isolate* const isolate_;
uv_loop_t* const event_loop_;
uint32_t* const zero_fill_field_;
MultiIsolatePlatform* platform_;

DISALLOW_COPY_AND_ASSIGN(IsolateData);
};
Expand Down
2 changes: 1 addition & 1 deletion src/inspector_agent.cc
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ class NodeInspectorClient : public V8InspectorClient {
terminated_ = false;
running_nested_loop_ = true;
while (!terminated_ && channel_->waitForFrontendMessage()) {
platform_->FlushForegroundTasksInternal();
platform_->FlushForegroundTasks(env_->isolate());
}
terminated_ = false;
running_nested_loop_ = false;
Expand Down
43 changes: 31 additions & 12 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -273,17 +273,17 @@ node::DebugOptions debug_options;

static struct {
#if NODE_USE_V8_PLATFORM
void Initialize(int thread_pool_size, uv_loop_t* loop) {
void Initialize(int thread_pool_size) {
if (trace_enabled) {
tracing_agent_.reset(new tracing::Agent(trace_file_pattern));
platform_ = new NodePlatform(thread_pool_size, loop,
platform_ = new NodePlatform(thread_pool_size,
tracing_agent_->GetTracingController());
V8::InitializePlatform(platform_);
tracing::TraceEventHelper::SetTracingController(
tracing_agent_->GetTracingController());
} else {
tracing_agent_.reset(nullptr);
platform_ = new NodePlatform(thread_pool_size, loop, nullptr);
platform_ = new NodePlatform(thread_pool_size, nullptr);
V8::InitializePlatform(platform_);
tracing::TraceEventHelper::SetTracingController(
new v8::TracingController());
Expand All @@ -297,8 +297,8 @@ static struct {
tracing_agent_.reset(nullptr);
}

void DrainVMTasks() {
platform_->DrainBackgroundTasks();
void DrainVMTasks(Isolate* isolate) {
platform_->DrainBackgroundTasks(isolate);
}

#if HAVE_INSPECTOR
Expand All @@ -323,12 +323,16 @@ static struct {
tracing_agent_->Stop();
}

NodePlatform* Platform() {
return platform_;
}

std::unique_ptr<tracing::Agent> tracing_agent_;
NodePlatform* platform_;
#else // !NODE_USE_V8_PLATFORM
void Initialize(int thread_pool_size, uv_loop_t* loop) {}
void Initialize(int thread_pool_size) {}
void Dispose() {}
void DrainVMTasks() {}
void DrainVMTasks(Isolate* isolate) {}
bool StartInspector(Environment *env, const char* script_path,
const node::DebugOptions& options) {
env->ThrowError("Node compiled with NODE_USE_V8_PLATFORM=0");
Expand All @@ -340,6 +344,10 @@ static struct {
"so event tracing is not available.\n");
}
void StopTracingAgent() {}

NodePlatform* Platform() {
return nullptr;
}
#endif // !NODE_USE_V8_PLATFORM

#if !NODE_USE_V8_PLATFORM || !HAVE_INSPECTOR
Expand Down Expand Up @@ -4734,7 +4742,14 @@ int EmitExit(Environment* env) {


IsolateData* CreateIsolateData(Isolate* isolate, uv_loop_t* loop) {
return new IsolateData(isolate, loop);
return new IsolateData(isolate, loop, nullptr);
}

IsolateData* CreateIsolateData(
Isolate* isolate,
uv_loop_t* loop,
MultiIsolatePlatform* platform) {
return new IsolateData(isolate, loop, platform);
}


Expand Down Expand Up @@ -4802,7 +4817,7 @@ inline int Start(Isolate* isolate, IsolateData* isolate_data,
do {
uv_run(env.event_loop(), UV_RUN_DEFAULT);

v8_platform.DrainVMTasks();
v8_platform.DrainVMTasks(isolate);

more = uv_loop_alive(env.event_loop());
if (more)
Expand All @@ -4823,7 +4838,7 @@ inline int Start(Isolate* isolate, IsolateData* isolate_data,
RunAtExit(&env);
uv_key_delete(&thread_local_env);

v8_platform.DrainVMTasks();
v8_platform.DrainVMTasks(isolate);
WaitForInspectorDisconnect(&env);
#if defined(LEAK_SANITIZER)
__lsan_do_leak_check();
Expand Down Expand Up @@ -4866,7 +4881,11 @@ inline int Start(uv_loop_t* event_loop,
Locker locker(isolate);
Isolate::Scope isolate_scope(isolate);
HandleScope handle_scope(isolate);
IsolateData isolate_data(isolate, event_loop, allocator.zero_fill_field());
IsolateData isolate_data(
isolate,
event_loop,
v8_platform.Platform(),
allocator.zero_fill_field());
exit_code = Start(isolate, &isolate_data, argc, argv, exec_argc, exec_argv);
}

Expand Down Expand Up @@ -4913,7 +4932,7 @@ int Start(int argc, char** argv) {
V8::SetEntropySource(crypto::EntropySource);
#endif // HAVE_OPENSSL

v8_platform.Initialize(v8_thread_pool_size, uv_default_loop());
v8_platform.Initialize(v8_thread_pool_size);
// Enable tracing when argv has --trace-events-enabled.
if (trace_enabled) {
fprintf(stderr, "Warning: Trace event is an experimental feature "
Expand Down
24 changes: 22 additions & 2 deletions src/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
#endif

#include "v8.h" // NOLINT(build/include_order)
#include "v8-platform.h" // NOLINT(build/include_order)
#include "node_version.h" // NODE_MODULE_VERSION

#define NODE_MAKE_VERSION(major, minor, patch) \
Expand Down Expand Up @@ -208,8 +209,27 @@ NODE_EXTERN void Init(int* argc,
class IsolateData;
class Environment;

NODE_EXTERN IsolateData* CreateIsolateData(v8::Isolate* isolate,
struct uv_loop_s* loop);
class MultiIsolatePlatform : public v8::Platform {
public:
virtual ~MultiIsolatePlatform() { }
virtual void DrainBackgroundTasks(v8::Isolate* isolate) = 0;

// These will be called by the `IsolateData` creation/destruction functions.
virtual void RegisterIsolate(IsolateData* isolate_data,
struct uv_loop_s* loop) = 0;
virtual void UnregisterIsolate(IsolateData* isolate_data) = 0;
};

// If `platform` is passed, it will be used to register new Worker instances.
// It can be `nullptr`, in which case creating new Workers inside of
// Environments that use this `IsolateData` will not work.
NODE_EXTERN IsolateData* CreateIsolateData(
v8::Isolate* isolate,
struct uv_loop_s* loop);
NODE_EXTERN IsolateData* CreateIsolateData(
v8::Isolate* isolate,
struct uv_loop_s* loop,
MultiIsolatePlatform* platform);
NODE_EXTERN void FreeIsolateData(IsolateData* isolate_data);

NODE_EXTERN Environment* CreateEnvironment(IsolateData* isolate_data,
Expand Down
Loading