Skip to content

Commit d084150

Browse files
legendecasdanielleadams
authored andcommitted
src: per-isolate eternal template properties
`FunctionTemplate` and `ObjectTemplate` can be shared across realms. They should be per-isolate eternal handles and can not be modified. As these templates are lazily initialized, their setters are still exposed with DCHECK on their value presence. PR-URL: #43802 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Joyee Cheung <[email protected]>
1 parent 17a4e5e commit d084150

File tree

5 files changed

+162
-99
lines changed

5 files changed

+162
-99
lines changed

src/env-inl.h

+27-7
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,16 @@ void Environment::set_process_exit_handler(
876876
#undef VY
877877
#undef VP
878878

879+
#define V(PropertyName, TypeName) \
880+
inline v8::Local<TypeName> IsolateData::PropertyName() const { \
881+
return PropertyName##_.Get(isolate_); \
882+
} \
883+
inline void IsolateData::set_##PropertyName(v8::Local<TypeName> value) { \
884+
PropertyName##_.Set(isolate_, value); \
885+
}
886+
PER_ISOLATE_TEMPLATE_PROPERTIES(V)
887+
#undef V
888+
879889
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
880890
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
881891
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
@@ -891,14 +901,24 @@ void Environment::set_process_exit_handler(
891901
#undef VY
892902
#undef VP
893903

894-
#define V(PropertyName, TypeName) \
895-
inline v8::Local<TypeName> Environment::PropertyName() const { \
896-
return PersistentToLocal::Strong(PropertyName ## _); \
897-
} \
898-
inline void Environment::set_ ## PropertyName(v8::Local<TypeName> value) { \
899-
PropertyName ## _.Reset(isolate(), value); \
904+
#define V(PropertyName, TypeName) \
905+
inline v8::Local<TypeName> Environment::PropertyName() const { \
906+
return isolate_data()->PropertyName(); \
907+
} \
908+
inline void Environment::set_##PropertyName(v8::Local<TypeName> value) { \
909+
DCHECK(isolate_data()->PropertyName().IsEmpty()); \
910+
isolate_data()->set_##PropertyName(value); \
911+
}
912+
PER_ISOLATE_TEMPLATE_PROPERTIES(V)
913+
#undef V
914+
915+
#define V(PropertyName, TypeName) \
916+
inline v8::Local<TypeName> Environment::PropertyName() const { \
917+
return PersistentToLocal::Strong(PropertyName##_); \
918+
} \
919+
inline void Environment::set_##PropertyName(v8::Local<TypeName> value) { \
920+
PropertyName##_.Reset(isolate(), value); \
900921
}
901-
ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V)
902922
ENVIRONMENT_STRONG_PERSISTENT_VALUES(V)
903923
#undef V
904924

src/env.cc

+96-66
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,43 @@ AsyncHooks::DefaultTriggerAsyncIdScope::DefaultTriggerAsyncIdScope(
238238
: DefaultTriggerAsyncIdScope(async_wrap->env(),
239239
async_wrap->get_async_id()) {}
240240

241-
std::vector<size_t> IsolateData::Serialize(SnapshotCreator* creator) {
241+
std::ostream& operator<<(std::ostream& output,
242+
const std::vector<SnapshotIndex>& v) {
243+
output << "{ ";
244+
for (const SnapshotIndex i : v) {
245+
output << i << ", ";
246+
}
247+
output << " }";
248+
return output;
249+
}
250+
251+
std::ostream& operator<<(std::ostream& output,
252+
const std::vector<PropInfo>& vec) {
253+
output << "{\n";
254+
for (const auto& info : vec) {
255+
output << " { \"" << info.name << "\", " << std::to_string(info.id) << ", "
256+
<< std::to_string(info.index) << " },\n";
257+
}
258+
output << "}";
259+
return output;
260+
}
261+
262+
std::ostream& operator<<(std::ostream& output,
263+
const IsolateDataSerializeInfo& i) {
264+
output << "{\n"
265+
<< "// -- primitive begins --\n"
266+
<< i.primitive_values << ",\n"
267+
<< "// -- primitive ends --\n"
268+
<< "// -- template_values begins --\n"
269+
<< i.template_values << ",\n"
270+
<< "// -- template_values ends --\n"
271+
<< "}";
272+
return output;
273+
}
274+
275+
IsolateDataSerializeInfo IsolateData::Serialize(SnapshotCreator* creator) {
242276
Isolate* isolate = creator->GetIsolate();
243-
std::vector<size_t> indexes;
277+
IsolateDataSerializeInfo info;
244278
HandleScope handle_scope(isolate);
245279
// XXX(joyeecheung): technically speaking, the indexes here should be
246280
// consecutive and we could just return a range instead of an array,
@@ -251,21 +285,36 @@ std::vector<size_t> IsolateData::Serialize(SnapshotCreator* creator) {
251285
#define VY(PropertyName, StringValue) V(Symbol, PropertyName)
252286
#define VS(PropertyName, StringValue) V(String, PropertyName)
253287
#define V(TypeName, PropertyName) \
254-
indexes.push_back(creator->AddData(PropertyName##_.Get(isolate)));
288+
info.primitive_values.push_back( \
289+
creator->AddData(PropertyName##_.Get(isolate)));
255290
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
256291
PER_ISOLATE_SYMBOL_PROPERTIES(VY)
257292
PER_ISOLATE_STRING_PROPERTIES(VS)
258293
#undef V
259294
#undef VY
260295
#undef VS
261296
#undef VP
297+
262298
for (size_t i = 0; i < AsyncWrap::PROVIDERS_LENGTH; i++)
263-
indexes.push_back(creator->AddData(async_wrap_provider(i)));
299+
info.primitive_values.push_back(creator->AddData(async_wrap_provider(i)));
300+
301+
size_t id = 0;
302+
#define V(PropertyName, TypeName) \
303+
do { \
304+
Local<TypeName> field = PropertyName(); \
305+
if (!field.IsEmpty()) { \
306+
size_t index = creator->AddData(field); \
307+
info.template_values.push_back({#PropertyName, id, index}); \
308+
} \
309+
id++; \
310+
} while (0);
311+
PER_ISOLATE_TEMPLATE_PROPERTIES(V)
312+
#undef V
264313

265-
return indexes;
314+
return info;
266315
}
267316

268-
void IsolateData::DeserializeProperties(const std::vector<size_t>* indexes) {
317+
void IsolateData::DeserializeProperties(const IsolateDataSerializeInfo* info) {
269318
size_t i = 0;
270319
HandleScope handle_scope(isolate_);
271320

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

293343
for (size_t j = 0; j < AsyncWrap::PROVIDERS_LENGTH; j++) {
294344
MaybeLocal<String> maybe_field =
295-
isolate_->GetDataFromSnapshotOnce<String>((*indexes)[i++]);
345+
isolate_->GetDataFromSnapshotOnce<String>(info->primitive_values[i++]);
296346
Local<String> field;
297347
if (!maybe_field.ToLocal(&field)) {
298348
fprintf(stderr, "Failed to deserialize AsyncWrap provider %zu\n", j);
299349
}
300350
async_wrap_providers_[j].Set(isolate_, field);
301351
}
352+
353+
const std::vector<PropInfo>& values = info->template_values;
354+
i = 0; // index to the array
355+
size_t id = 0;
356+
#define V(PropertyName, TypeName) \
357+
do { \
358+
if (values.size() > i && id == values[i].id) { \
359+
const PropInfo& d = values[i]; \
360+
DCHECK_EQ(d.name, #PropertyName); \
361+
MaybeLocal<TypeName> maybe_field = \
362+
isolate_->GetDataFromSnapshotOnce<TypeName>(d.index); \
363+
Local<TypeName> field; \
364+
if (!maybe_field.ToLocal(&field)) { \
365+
fprintf(stderr, \
366+
"Failed to deserialize isolate data template " #PropertyName \
367+
"\n"); \
368+
} \
369+
set_##PropertyName(field); \
370+
i++; \
371+
} \
372+
id++; \
373+
} while (0);
374+
375+
PER_ISOLATE_TEMPLATE_PROPERTIES(V);
376+
#undef V
302377
}
303378

304379
void IsolateData::CreateProperties() {
@@ -363,13 +438,15 @@ void IsolateData::CreateProperties() {
363438
sizeof(#Provider) - 1).ToLocalChecked());
364439
NODE_ASYNC_PROVIDER_TYPES(V)
365440
#undef V
441+
442+
// TODO(legendecas): eagerly create per isolate templates.
366443
}
367444

368445
IsolateData::IsolateData(Isolate* isolate,
369446
uv_loop_t* event_loop,
370447
MultiIsolatePlatform* platform,
371448
ArrayBufferAllocator* node_allocator,
372-
const std::vector<size_t>* indexes)
449+
const IsolateDataSerializeInfo* isolate_data_info)
373450
: isolate_(isolate),
374451
event_loop_(event_loop),
375452
node_allocator_(node_allocator == nullptr ? nullptr
@@ -378,10 +455,10 @@ IsolateData::IsolateData(Isolate* isolate,
378455
options_.reset(
379456
new PerIsolateOptions(*(per_process::cli_options->per_isolate)));
380457

381-
if (indexes == nullptr) {
458+
if (isolate_data_info == nullptr) {
382459
CreateProperties();
383460
} else {
384-
DeserializeProperties(indexes);
461+
DeserializeProperties(isolate_data_info);
385462
}
386463
}
387464

@@ -1527,16 +1604,6 @@ void AsyncHooks::Deserialize(Local<Context> context) {
15271604
info_ = nullptr;
15281605
}
15291606

1530-
std::ostream& operator<<(std::ostream& output,
1531-
const std::vector<SnapshotIndex>& v) {
1532-
output << "{ ";
1533-
for (const SnapshotIndex i : v) {
1534-
output << i << ", ";
1535-
}
1536-
output << " }";
1537-
return output;
1538-
}
1539-
15401607
std::ostream& operator<<(std::ostream& output,
15411608
const AsyncHooks::SerializeInfo& i) {
15421609
output << "{\n"
@@ -1748,19 +1815,6 @@ EnvSerializeInfo Environment::Serialize(SnapshotCreator* creator) {
17481815
should_abort_on_uncaught_toggle_.Serialize(ctx, creator);
17491816

17501817
size_t id = 0;
1751-
#define V(PropertyName, TypeName) \
1752-
do { \
1753-
Local<TypeName> field = PropertyName(); \
1754-
if (!field.IsEmpty()) { \
1755-
size_t index = creator->AddData(field); \
1756-
info.persistent_templates.push_back({#PropertyName, id, index}); \
1757-
} \
1758-
id++; \
1759-
} while (0);
1760-
ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V)
1761-
#undef V
1762-
1763-
id = 0;
17641818
#define V(PropertyName, TypeName) \
17651819
do { \
17661820
Local<TypeName> field = PropertyName(); \
@@ -1777,17 +1831,6 @@ EnvSerializeInfo Environment::Serialize(SnapshotCreator* creator) {
17771831
return info;
17781832
}
17791833

1780-
std::ostream& operator<<(std::ostream& output,
1781-
const std::vector<PropInfo>& vec) {
1782-
output << "{\n";
1783-
for (const auto& info : vec) {
1784-
output << " { \"" << info.name << "\", " << std::to_string(info.id) << ", "
1785-
<< std::to_string(info.index) << " },\n";
1786-
}
1787-
output << "}";
1788-
return output;
1789-
}
1790-
17911834
std::ostream& operator<<(std::ostream& output,
17921835
const std::vector<std::string>& vec) {
17931836
output << "{\n";
@@ -1817,9 +1860,6 @@ std::ostream& operator<<(std::ostream& output, const EnvSerializeInfo& i) {
18171860
<< i.stream_base_state << ", // stream_base_state\n"
18181861
<< i.should_abort_on_uncaught_toggle
18191862
<< ", // should_abort_on_uncaught_toggle\n"
1820-
<< "// -- persistent_templates begins --\n"
1821-
<< i.persistent_templates << ",\n"
1822-
<< "// persistent_templates ends --\n"
18231863
<< "// -- persistent_values begins --\n"
18241864
<< i.persistent_values << ",\n"
18251865
<< "// -- persistent_values ends --\n"
@@ -1868,40 +1908,30 @@ void Environment::DeserializeProperties(const EnvSerializeInfo* info) {
18681908
std::cerr << *info << "\n";
18691909
}
18701910

1871-
const std::vector<PropInfo>& templates = info->persistent_templates;
1911+
const std::vector<PropInfo>& values = info->persistent_values;
18721912
size_t i = 0; // index to the array
18731913
size_t id = 0;
1874-
#define SetProperty(PropertyName, TypeName, vector, type, from) \
1914+
#define V(PropertyName, TypeName) \
18751915
do { \
1876-
if (vector.size() > i && id == vector[i].id) { \
1877-
const PropInfo& d = vector[i]; \
1916+
if (values.size() > i && id == values[i].id) { \
1917+
const PropInfo& d = values[i]; \
18781918
DCHECK_EQ(d.name, #PropertyName); \
18791919
MaybeLocal<TypeName> maybe_field = \
1880-
from->GetDataFromSnapshotOnce<TypeName>(d.index); \
1920+
ctx->GetDataFromSnapshotOnce<TypeName>(d.index); \
18811921
Local<TypeName> field; \
18821922
if (!maybe_field.ToLocal(&field)) { \
18831923
fprintf(stderr, \
1884-
"Failed to deserialize environment " #type " " #PropertyName \
1924+
"Failed to deserialize environment value " #PropertyName \
18851925
"\n"); \
18861926
} \
18871927
set_##PropertyName(field); \
18881928
i++; \
18891929
} \
1890-
} while (0); \
1891-
id++;
1892-
#define V(PropertyName, TypeName) SetProperty(PropertyName, TypeName, \
1893-
templates, template, isolate_)
1894-
ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V);
1895-
#undef V
1930+
id++; \
1931+
} while (0);
18961932

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

19061936
MaybeLocal<Context> maybe_ctx_from_snapshot =
19071937
ctx->GetDataFromSnapshotOnce<Context>(info->context);

0 commit comments

Comments
 (0)