Skip to content

Commit be02c18

Browse files
committed
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.
1 parent 8baf372 commit be02c18

File tree

4 files changed

+75
-41
lines changed

4 files changed

+75
-41
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

+32-26
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,19 @@ std::vector<size_t> IsolateData::Serialize(SnapshotCreator* creator) {
259259
#undef VY
260260
#undef VS
261261
#undef VP
262+
263+
#define V(PropertyName, TypeName) \
264+
do { \
265+
Local<TypeName> field = PropertyName(); \
266+
if (field.IsEmpty()) { \
267+
indexes.push_back(0); \
268+
} else { \
269+
indexes.push_back(creator->AddData(field)); \
270+
} \
271+
} while (0);
272+
PER_ISOLATE_TEMPLATE_PROPERTIES(V)
273+
#undef V
274+
262275
for (size_t i = 0; i < AsyncWrap::PROVIDERS_LENGTH; i++)
263276
indexes.push_back(creator->AddData(async_wrap_provider(i)));
264277

@@ -290,6 +303,22 @@ void IsolateData::DeserializeProperties(const std::vector<size_t>* indexes) {
290303
#undef VS
291304
#undef VP
292305

306+
#define V(PropertyName, TypeName) \
307+
do { \
308+
size_t index = (*indexes)[i++]; \
309+
if (index != 0) { \
310+
MaybeLocal<TypeName> maybe_field = \
311+
isolate_->GetDataFromSnapshotOnce<TypeName>(index); \
312+
Local<TypeName> field; \
313+
if (!maybe_field.ToLocal(&field)) { \
314+
fprintf(stderr, "Failed to deserialize " #PropertyName "\n"); \
315+
} \
316+
PropertyName##_.Set(isolate_, field); \
317+
} \
318+
} while (0);
319+
PER_ISOLATE_TEMPLATE_PROPERTIES(V)
320+
#undef V
321+
293322
for (size_t j = 0; j < AsyncWrap::PROVIDERS_LENGTH; j++) {
294323
MaybeLocal<String> maybe_field =
295324
isolate_->GetDataFromSnapshotOnce<String>((*indexes)[i++]);
@@ -1749,19 +1778,6 @@ EnvSerializeInfo Environment::Serialize(SnapshotCreator* creator) {
17491778
should_abort_on_uncaught_toggle_.Serialize(ctx, creator);
17501779

17511780
size_t id = 0;
1752-
#define V(PropertyName, TypeName) \
1753-
do { \
1754-
Local<TypeName> field = PropertyName(); \
1755-
if (!field.IsEmpty()) { \
1756-
size_t index = creator->AddData(field); \
1757-
info.persistent_templates.push_back({#PropertyName, id, index}); \
1758-
} \
1759-
id++; \
1760-
} while (0);
1761-
ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V)
1762-
#undef V
1763-
1764-
id = 0;
17651781
#define V(PropertyName, TypeName) \
17661782
do { \
17671783
Local<TypeName> field = PropertyName(); \
@@ -1818,9 +1834,6 @@ std::ostream& operator<<(std::ostream& output, const EnvSerializeInfo& i) {
18181834
<< i.stream_base_state << ", // stream_base_state\n"
18191835
<< i.should_abort_on_uncaught_toggle
18201836
<< ", // should_abort_on_uncaught_toggle\n"
1821-
<< "// -- persistent_templates begins --\n"
1822-
<< i.persistent_templates << ",\n"
1823-
<< "// persistent_templates ends --\n"
18241837
<< "// -- persistent_values begins --\n"
18251838
<< i.persistent_values << ",\n"
18261839
<< "// -- persistent_values ends --\n"
@@ -1869,7 +1882,7 @@ void Environment::DeserializeProperties(const EnvSerializeInfo* info) {
18691882
std::cerr << *info << "\n";
18701883
}
18711884

1872-
const std::vector<PropInfo>& templates = info->persistent_templates;
1885+
const std::vector<PropInfo>& values = info->persistent_values;
18731886
size_t i = 0; // index to the array
18741887
size_t id = 0;
18751888
#define SetProperty(PropertyName, TypeName, vector, type, from) \
@@ -1888,16 +1901,9 @@ void Environment::DeserializeProperties(const EnvSerializeInfo* info) {
18881901
set_##PropertyName(field); \
18891902
i++; \
18901903
} \
1891-
} while (0); \
1892-
id++;
1893-
#define V(PropertyName, TypeName) SetProperty(PropertyName, TypeName, \
1894-
templates, template, isolate_)
1895-
ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V);
1896-
#undef V
1904+
id++; \
1905+
} while (0);
18971906

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

src/env.h

+14-5
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ class NoArrayBufferZeroFillScope {
469469
V(x_forwarded_string, "x-forwarded-for") \
470470
V(zero_return_string, "ZERO_RETURN")
471471

472-
#define ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V) \
472+
#define PER_ISOLATE_TEMPLATE_PROPERTIES(V) \
473473
V(async_wrap_ctor_template, v8::FunctionTemplate) \
474474
V(async_wrap_object_ctor_template, v8::FunctionTemplate) \
475475
V(base_object_ctor_template, v8::FunctionTemplate) \
@@ -609,6 +609,13 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer {
609609
#undef VY
610610
#undef VS
611611
#undef VP
612+
613+
#define V(PropertyName, TypeName) \
614+
inline v8::Local<TypeName> PropertyName() const; \
615+
inline void set_##PropertyName(v8::Local<TypeName> value);
616+
PER_ISOLATE_TEMPLATE_PROPERTIES(V)
617+
#undef V
618+
612619
inline v8::Local<v8::String> async_wrap_provider(int index) const;
613620

614621
size_t max_young_gen_size = 1;
@@ -627,14 +634,18 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer {
627634
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
628635
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
629636
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
637+
#define VT(PropertyName, TypeName) V(TypeName, PropertyName)
630638
#define V(TypeName, PropertyName) \
631639
v8::Eternal<TypeName> PropertyName ## _;
632640
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
633641
PER_ISOLATE_SYMBOL_PROPERTIES(VY)
634642
PER_ISOLATE_STRING_PROPERTIES(VS)
643+
PER_ISOLATE_TEMPLATE_PROPERTIES(VT)
635644
#undef V
636-
#undef VY
645+
#undef V
646+
#undef VT
637647
#undef VS
648+
#undef VY
638649
#undef VP
639650
// Keep a list of all Persistent strings used for AsyncWrap Provider types.
640651
std::array<v8::Eternal<v8::String>, AsyncWrap::PROVIDERS_LENGTH>
@@ -955,7 +966,6 @@ struct EnvSerializeInfo {
955966
AliasedBufferIndex stream_base_state;
956967
AliasedBufferIndex should_abort_on_uncaught_toggle;
957968

958-
std::vector<PropInfo> persistent_templates;
959969
std::vector<PropInfo> persistent_values;
960970

961971
SnapshotIndex context;
@@ -1342,8 +1352,8 @@ class Environment : public MemoryRetainer {
13421352
#define V(PropertyName, TypeName) \
13431353
inline v8::Local<TypeName> PropertyName() const; \
13441354
inline void set_ ## PropertyName(v8::Local<TypeName> value);
1355+
PER_ISOLATE_TEMPLATE_PROPERTIES(V)
13451356
ENVIRONMENT_STRONG_PERSISTENT_VALUES(V)
1346-
ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V)
13471357
#undef V
13481358

13491359
inline v8::Local<v8::Context> context() const;
@@ -1646,7 +1656,6 @@ class Environment : public MemoryRetainer {
16461656

16471657
#define V(PropertyName, TypeName) v8::Global<TypeName> PropertyName ## _;
16481658
ENVIRONMENT_STRONG_PERSISTENT_VALUES(V)
1649-
ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V)
16501659
#undef V
16511660

16521661
v8::Global<v8::Context> context_;

src/node_snapshotable.cc

+2-3
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,6 @@ int SnapshotBuilder::Generate(SnapshotData* out,
222222
}
223223
});
224224

225-
out->isolate_data_indices =
226-
main_instance->isolate_data()->Serialize(&creator);
227-
228225
// The default context with only things created by V8.
229226
Local<Context> default_context = Context::New(isolate);
230227

@@ -285,6 +282,8 @@ int SnapshotBuilder::Generate(SnapshotData* out,
285282
}
286283

287284
// Serialize the native states
285+
out->isolate_data_indices =
286+
main_instance->isolate_data()->Serialize(&creator);
288287
out->env_info = env->Serialize(&creator);
289288

290289
#ifdef NODE_USE_NODE_CODE_CACHE

0 commit comments

Comments
 (0)