diff --git a/src/env-inl.h b/src/env-inl.h index 71660a035c8ea7..addfb6a90577ca 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -64,6 +64,10 @@ inline MultiIsolatePlatform* IsolateData::platform() const { return platform_; } +inline v8::Local 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), @@ -86,20 +90,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(#Provider), \ - v8::NewStringType::kInternalized, \ - sizeof(#Provider) - 1).ToLocalChecked()); - NODE_ASYNC_PROVIDER_TYPES(V) -#undef V } inline AliasedUint32Array& AsyncHooks::fields() { return fields_; @@ -118,7 +108,7 @@ inline v8::Local AsyncHooks::execution_async_resources() { } inline v8::Local 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() { diff --git a/src/env.cc b/src/env.cc index ec50d8841ac1e3..c225f97087cd73 100644 --- a/src/env.cc +++ b/src/env.cc @@ -76,6 +76,8 @@ std::vector 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* indexes) { #undef VY #undef VS #undef VP + + for (size_t j = 0; j < AsyncWrap::PROVIDERS_LENGTH; j++) { + MaybeLocal field = + isolate_->GetDataFromSnapshotOnce((*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(#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"); @@ -933,7 +960,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_); diff --git a/src/env.h b/src/env.h index 1349641b6671ae..deeeb2a385ab75 100644 --- a/src/env.h +++ b/src/env.h @@ -511,6 +511,7 @@ class IsolateData : public MemoryRetainer { #undef VY #undef VS #undef VP + inline v8::Local async_wrap_provider(int index) const; std::unordered_map> http2_static_strs; inline v8::Isolate* isolate() const; @@ -535,6 +536,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, AsyncWrap::PROVIDERS_LENGTH> + async_wrap_providers_; v8::Isolate* const isolate_; uv_loop_t* const event_loop_; @@ -692,8 +696,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, 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