src: include AsyncWrap provider strings in snapshot

… and move them to `IsolateData`, because they should exist once
per Isolate.

PR-URL: https://github.com/nodejs/node/pull/32572
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
pull/32617/head
Anna Henningsen 2020-03-21 23:07:03 +01:00
parent 6246f90375
commit 2a885151e9
No known key found for this signature in database
GPG Key ID: A94130F0BFC8EBE9
3 changed files with 36 additions and 18 deletions

View File

@ -73,6 +73,10 @@ inline worker::Worker* IsolateData::worker_context() const {
return worker_context_;
}
inline v8::Local<v8::String> IsolateData::async_wrap_provider(int index) const {
return async_wrap_providers_[index].Get(isolate_);
}
inline AsyncHooks::AsyncHooks()
: async_ids_stack_(env()->isolate(), 16 * 2),
fields_(env()->isolate(), kFieldsCount),
@ -95,20 +99,6 @@ inline AsyncHooks::AsyncHooks()
// 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.
#define V(Provider) \
providers_[AsyncWrap::PROVIDER_ ## Provider].Set( \
env()->isolate(), \
v8::String::NewFromOneByte( \
env()->isolate(), \
reinterpret_cast<const uint8_t*>(#Provider), \
v8::NewStringType::kInternalized, \
sizeof(#Provider) - 1).ToLocalChecked());
NODE_ASYNC_PROVIDER_TYPES(V)
#undef V
}
inline AliasedUint32Array& AsyncHooks::fields() {
return fields_;
@ -127,7 +117,7 @@ inline v8::Local<v8::Array> AsyncHooks::execution_async_resources() {
}
inline v8::Local<v8::String> AsyncHooks::provider_string(int idx) {
return providers_[idx].Get(env()->isolate());
return env()->isolate_data()->async_wrap_provider(idx);
}
inline void AsyncHooks::no_force_checks() {

View File

@ -76,6 +76,8 @@ std::vector<size_t> IsolateData::Serialize(SnapshotCreator* creator) {
#undef VY
#undef VS
#undef VP
for (size_t i = 0; i < AsyncWrap::PROVIDERS_LENGTH; i++)
indexes.push_back(creator->AddData(async_wrap_provider(i)));
return indexes;
}
@ -103,6 +105,15 @@ void IsolateData::DeserializeProperties(const std::vector<size_t>* indexes) {
#undef VY
#undef VS
#undef VP
for (size_t j = 0; j < AsyncWrap::PROVIDERS_LENGTH; j++) {
MaybeLocal<String> field =
isolate_->GetDataFromSnapshotOnce<String>((*indexes)[i++]);
if (field.IsEmpty()) {
fprintf(stderr, "Failed to deserialize AsyncWrap provider %zu\n", j);
}
async_wrap_providers_[j].Set(isolate_, field.ToLocalChecked());
}
}
void IsolateData::CreateProperties() {
@ -153,6 +164,20 @@ void IsolateData::CreateProperties() {
.ToLocalChecked());
PER_ISOLATE_STRING_PROPERTIES(V)
#undef V
// 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.
#define V(Provider) \
async_wrap_providers_[AsyncWrap::PROVIDER_ ## Provider].Set( \
isolate_, \
v8::String::NewFromOneByte( \
isolate_, \
reinterpret_cast<const uint8_t*>(#Provider), \
v8::NewStringType::kInternalized, \
sizeof(#Provider) - 1).ToLocalChecked());
NODE_ASYNC_PROVIDER_TYPES(V)
#undef V
}
IsolateData::IsolateData(Isolate* isolate,
@ -190,6 +215,8 @@ void IsolateData::MemoryInfo(MemoryTracker* tracker) const {
PER_ISOLATE_STRING_PROPERTIES(V)
#undef V
tracker->TrackField("async_wrap_providers", async_wrap_providers_);
if (node_allocator_ != nullptr) {
tracker->TrackFieldWithSize(
"node_allocator", sizeof(*node_allocator_), "NodeArrayBufferAllocator");
@ -951,7 +978,6 @@ void TickInfo::MemoryInfo(MemoryTracker* tracker) const {
}
void AsyncHooks::MemoryInfo(MemoryTracker* tracker) const {
tracker->TrackField("providers", providers_);
tracker->TrackField("async_ids_stack", async_ids_stack_);
tracker->TrackField("fields", fields_);
tracker->TrackField("async_id_fields", async_id_fields_);

View File

@ -512,6 +512,7 @@ class IsolateData : public MemoryRetainer {
#undef VY
#undef VS
#undef VP
inline v8::Local<v8::String> async_wrap_provider(int index) const;
std::unordered_map<const char*, v8::Eternal<v8::String>> http_static_strs;
inline v8::Isolate* isolate() const;
@ -536,6 +537,9 @@ class IsolateData : public MemoryRetainer {
#undef VY
#undef VS
#undef VP
// Keep a list of all Persistent strings used for AsyncWrap Provider types.
std::array<v8::Eternal<v8::String>, AsyncWrap::PROVIDERS_LENGTH>
async_wrap_providers_;
v8::Isolate* const isolate_;
uv_loop_t* const event_loop_;
@ -694,8 +698,6 @@ class AsyncHooks : public MemoryRetainer {
private:
friend class Environment; // So we can call the constructor.
inline AsyncHooks();
// Keep a list of all Persistent strings used for Provider types.
std::array<v8::Eternal<v8::String>, AsyncWrap::PROVIDERS_LENGTH> providers_;
// Stores the ids of the current execution context stack.
AliasedFloat64Array async_ids_stack_;
// Attached to a Uint32Array that tracks the number of active hooks for