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

src: include AsyncWrap provider strings in snapshot #32572

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
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
20 changes: 5 additions & 15 deletions src/env-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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_;
Expand All @@ -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() {
Expand Down
28 changes: 27 additions & 1 deletion src/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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_);
Expand Down
6 changes: 4 additions & 2 deletions src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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_;
Expand Down Expand Up @@ -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
Expand Down