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: per-isolate eternal templates #43802

Closed
wants to merge 1 commit into from
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
34 changes: 27 additions & 7 deletions src/env-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,16 @@ void Environment::set_process_exit_handler(
#undef VY
#undef VP

#define V(PropertyName, TypeName) \
inline v8::Local<TypeName> IsolateData::PropertyName() const { \
return PropertyName##_.Get(isolate_); \
} \
inline void IsolateData::set_##PropertyName(v8::Local<TypeName> value) { \
PropertyName##_.Set(isolate_, value); \
}
PER_ISOLATE_TEMPLATE_PROPERTIES(V)
#undef V

#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
Expand All @@ -891,14 +901,24 @@ void Environment::set_process_exit_handler(
#undef VY
#undef VP

#define V(PropertyName, TypeName) \
inline v8::Local<TypeName> Environment::PropertyName() const { \
return PersistentToLocal::Strong(PropertyName ## _); \
} \
inline void Environment::set_ ## PropertyName(v8::Local<TypeName> value) { \
PropertyName ## _.Reset(isolate(), value); \
#define V(PropertyName, TypeName) \
inline v8::Local<TypeName> Environment::PropertyName() const { \
return isolate_data()->PropertyName(); \
} \
inline void Environment::set_##PropertyName(v8::Local<TypeName> value) { \
DCHECK(isolate_data()->PropertyName().IsEmpty()); \
isolate_data()->set_##PropertyName(value); \
}
PER_ISOLATE_TEMPLATE_PROPERTIES(V)
#undef V

#define V(PropertyName, TypeName) \
inline v8::Local<TypeName> Environment::PropertyName() const { \
return PersistentToLocal::Strong(PropertyName##_); \
} \
inline void Environment::set_##PropertyName(v8::Local<TypeName> value) { \
PropertyName##_.Reset(isolate(), value); \
}
ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V)
ENVIRONMENT_STRONG_PERSISTENT_VALUES(V)
#undef V

Expand Down
162 changes: 96 additions & 66 deletions src/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,43 @@ AsyncHooks::DefaultTriggerAsyncIdScope::DefaultTriggerAsyncIdScope(
: DefaultTriggerAsyncIdScope(async_wrap->env(),
async_wrap->get_async_id()) {}

std::vector<size_t> IsolateData::Serialize(SnapshotCreator* creator) {
std::ostream& operator<<(std::ostream& output,
const std::vector<SnapshotIndex>& v) {
output << "{ ";
for (const SnapshotIndex i : v) {
output << i << ", ";
}
output << " }";
return output;
}

std::ostream& operator<<(std::ostream& output,
const std::vector<PropInfo>& vec) {
output << "{\n";
for (const auto& info : vec) {
output << " { \"" << info.name << "\", " << std::to_string(info.id) << ", "
<< std::to_string(info.index) << " },\n";
}
output << "}";
return output;
}

std::ostream& operator<<(std::ostream& output,
const IsolateDataSerializeInfo& i) {
output << "{\n"
<< "// -- primitive begins --\n"
<< i.primitive_values << ",\n"
<< "// -- primitive ends --\n"
<< "// -- template_values begins --\n"
<< i.template_values << ",\n"
<< "// -- template_values ends --\n"
<< "}";
return output;
}

IsolateDataSerializeInfo IsolateData::Serialize(SnapshotCreator* creator) {
Isolate* isolate = creator->GetIsolate();
std::vector<size_t> indexes;
IsolateDataSerializeInfo info;
HandleScope handle_scope(isolate);
// XXX(joyeecheung): technically speaking, the indexes here should be
// consecutive and we could just return a range instead of an array,
Expand All @@ -251,21 +285,36 @@ std::vector<size_t> IsolateData::Serialize(SnapshotCreator* creator) {
#define VY(PropertyName, StringValue) V(Symbol, PropertyName)
#define VS(PropertyName, StringValue) V(String, PropertyName)
#define V(TypeName, PropertyName) \
indexes.push_back(creator->AddData(PropertyName##_.Get(isolate)));
info.primitive_values.push_back( \
creator->AddData(PropertyName##_.Get(isolate)));
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
PER_ISOLATE_SYMBOL_PROPERTIES(VY)
PER_ISOLATE_STRING_PROPERTIES(VS)
#undef V
#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)));
info.primitive_values.push_back(creator->AddData(async_wrap_provider(i)));

size_t id = 0;
#define V(PropertyName, TypeName) \
legendecas marked this conversation as resolved.
Show resolved Hide resolved
do { \
Local<TypeName> field = PropertyName(); \
if (!field.IsEmpty()) { \
size_t index = creator->AddData(field); \
info.template_values.push_back({#PropertyName, id, index}); \
} \
id++; \
} while (0);
PER_ISOLATE_TEMPLATE_PROPERTIES(V)
#undef V

return indexes;
return info;
}

void IsolateData::DeserializeProperties(const std::vector<size_t>* indexes) {
void IsolateData::DeserializeProperties(const IsolateDataSerializeInfo* info) {
size_t i = 0;
HandleScope handle_scope(isolate_);

Expand All @@ -275,7 +324,8 @@ void IsolateData::DeserializeProperties(const std::vector<size_t>* indexes) {
#define V(TypeName, PropertyName) \
do { \
MaybeLocal<TypeName> maybe_field = \
isolate_->GetDataFromSnapshotOnce<TypeName>((*indexes)[i++]); \
isolate_->GetDataFromSnapshotOnce<TypeName>( \
info->primitive_values[i++]); \
Local<TypeName> field; \
if (!maybe_field.ToLocal(&field)) { \
fprintf(stderr, "Failed to deserialize " #PropertyName "\n"); \
Expand All @@ -292,13 +342,38 @@ void IsolateData::DeserializeProperties(const std::vector<size_t>* indexes) {

for (size_t j = 0; j < AsyncWrap::PROVIDERS_LENGTH; j++) {
MaybeLocal<String> maybe_field =
isolate_->GetDataFromSnapshotOnce<String>((*indexes)[i++]);
isolate_->GetDataFromSnapshotOnce<String>(info->primitive_values[i++]);
Local<String> field;
if (!maybe_field.ToLocal(&field)) {
fprintf(stderr, "Failed to deserialize AsyncWrap provider %zu\n", j);
}
async_wrap_providers_[j].Set(isolate_, field);
}

const std::vector<PropInfo>& values = info->template_values;
i = 0; // index to the array
size_t id = 0;
#define V(PropertyName, TypeName) \
do { \
if (values.size() > i && id == values[i].id) { \
const PropInfo& d = values[i]; \
DCHECK_EQ(d.name, #PropertyName); \
MaybeLocal<TypeName> maybe_field = \
isolate_->GetDataFromSnapshotOnce<TypeName>(d.index); \
Local<TypeName> field; \
if (!maybe_field.ToLocal(&field)) { \
fprintf(stderr, \
"Failed to deserialize isolate data template " #PropertyName \
"\n"); \
} \
set_##PropertyName(field); \
i++; \
} \
id++; \
} while (0);

PER_ISOLATE_TEMPLATE_PROPERTIES(V);
#undef V
}

void IsolateData::CreateProperties() {
Expand Down Expand Up @@ -363,13 +438,15 @@ void IsolateData::CreateProperties() {
sizeof(#Provider) - 1).ToLocalChecked());
NODE_ASYNC_PROVIDER_TYPES(V)
#undef V

// TODO(legendecas): eagerly create per isolate templates.
}

IsolateData::IsolateData(Isolate* isolate,
uv_loop_t* event_loop,
MultiIsolatePlatform* platform,
ArrayBufferAllocator* node_allocator,
const std::vector<size_t>* indexes)
const IsolateDataSerializeInfo* isolate_data_info)
: isolate_(isolate),
event_loop_(event_loop),
node_allocator_(node_allocator == nullptr ? nullptr
Expand All @@ -378,10 +455,10 @@ IsolateData::IsolateData(Isolate* isolate,
options_.reset(
new PerIsolateOptions(*(per_process::cli_options->per_isolate)));

if (indexes == nullptr) {
if (isolate_data_info == nullptr) {
CreateProperties();
} else {
DeserializeProperties(indexes);
DeserializeProperties(isolate_data_info);
}
}

Expand Down Expand Up @@ -1528,16 +1605,6 @@ void AsyncHooks::Deserialize(Local<Context> context) {
info_ = nullptr;
}

std::ostream& operator<<(std::ostream& output,
const std::vector<SnapshotIndex>& v) {
output << "{ ";
for (const SnapshotIndex i : v) {
output << i << ", ";
}
output << " }";
return output;
}

std::ostream& operator<<(std::ostream& output,
const AsyncHooks::SerializeInfo& i) {
output << "{\n"
Expand Down Expand Up @@ -1749,19 +1816,6 @@ EnvSerializeInfo Environment::Serialize(SnapshotCreator* creator) {
should_abort_on_uncaught_toggle_.Serialize(ctx, creator);

size_t id = 0;
#define V(PropertyName, TypeName) \
do { \
Local<TypeName> field = PropertyName(); \
if (!field.IsEmpty()) { \
size_t index = creator->AddData(field); \
info.persistent_templates.push_back({#PropertyName, id, index}); \
} \
id++; \
} while (0);
ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V)
#undef V

id = 0;
#define V(PropertyName, TypeName) \
do { \
Local<TypeName> field = PropertyName(); \
Expand All @@ -1778,17 +1832,6 @@ EnvSerializeInfo Environment::Serialize(SnapshotCreator* creator) {
return info;
}

std::ostream& operator<<(std::ostream& output,
const std::vector<PropInfo>& vec) {
output << "{\n";
for (const auto& info : vec) {
output << " { \"" << info.name << "\", " << std::to_string(info.id) << ", "
<< std::to_string(info.index) << " },\n";
}
output << "}";
return output;
}

std::ostream& operator<<(std::ostream& output,
const std::vector<std::string>& vec) {
output << "{\n";
Expand Down Expand Up @@ -1818,9 +1861,6 @@ std::ostream& operator<<(std::ostream& output, const EnvSerializeInfo& i) {
<< i.stream_base_state << ", // stream_base_state\n"
<< i.should_abort_on_uncaught_toggle
<< ", // should_abort_on_uncaught_toggle\n"
<< "// -- persistent_templates begins --\n"
<< i.persistent_templates << ",\n"
<< "// persistent_templates ends --\n"
<< "// -- persistent_values begins --\n"
<< i.persistent_values << ",\n"
<< "// -- persistent_values ends --\n"
Expand Down Expand Up @@ -1869,40 +1909,30 @@ void Environment::DeserializeProperties(const EnvSerializeInfo* info) {
std::cerr << *info << "\n";
}

const std::vector<PropInfo>& templates = info->persistent_templates;
const std::vector<PropInfo>& values = info->persistent_values;
size_t i = 0; // index to the array
size_t id = 0;
#define SetProperty(PropertyName, TypeName, vector, type, from) \
#define V(PropertyName, TypeName) \
do { \
if (vector.size() > i && id == vector[i].id) { \
const PropInfo& d = vector[i]; \
if (values.size() > i && id == values[i].id) { \
const PropInfo& d = values[i]; \
DCHECK_EQ(d.name, #PropertyName); \
MaybeLocal<TypeName> maybe_field = \
from->GetDataFromSnapshotOnce<TypeName>(d.index); \
ctx->GetDataFromSnapshotOnce<TypeName>(d.index); \
Local<TypeName> field; \
if (!maybe_field.ToLocal(&field)) { \
fprintf(stderr, \
"Failed to deserialize environment " #type " " #PropertyName \
"Failed to deserialize environment value " #PropertyName \
"\n"); \
} \
set_##PropertyName(field); \
i++; \
} \
} while (0); \
id++;
#define V(PropertyName, TypeName) SetProperty(PropertyName, TypeName, \
templates, template, isolate_)
ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V);
#undef V
id++; \
} while (0);

i = 0; // index to the array
id = 0;
const std::vector<PropInfo>& values = info->persistent_values;
#define V(PropertyName, TypeName) SetProperty(PropertyName, TypeName, \
values, value, ctx)
ENVIRONMENT_STRONG_PERSISTENT_VALUES(V);
#undef V
#undef SetProperty

MaybeLocal<Context> maybe_ctx_from_snapshot =
ctx->GetDataFromSnapshotOnce<Context>(info->context);
Expand Down
Loading