Skip to content

Commit

Permalink
src: include AsyncWrap provider strings in snapshot
Browse files Browse the repository at this point in the history
… and move them to `IsolateData`, because they should exist once
per Isolate.

PR-URL: #32572
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
  • Loading branch information
addaleax authored and BethGriggs committed Apr 7, 2020
1 parent c5763e8 commit 0e9f9b7
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 18 deletions.
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

0 comments on commit 0e9f9b7

Please sign in to comment.