@@ -238,9 +238,43 @@ AsyncHooks::DefaultTriggerAsyncIdScope::DefaultTriggerAsyncIdScope( |
238 | 238 | : DefaultTriggerAsyncIdScope(async_wrap->env(), |
239 | 239 | async_wrap->get_async_id()) {} |
240 | 240 |
|
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) { |
242 | 276 | Isolate* isolate = creator->GetIsolate(); |
243 | | - std::vector<size_t> indexes; |
| 277 | + IsolateDataSerializeInfo info; |
244 | 278 | HandleScope handle_scope(isolate); |
245 | 279 | // XXX(joyeecheung): technically speaking, the indexes here should be |
246 | 280 | // consecutive and we could just return a range instead of an array, |
@@ -251,21 +285,36 @@ std::vector<size_t> IsolateData::Serialize(SnapshotCreator* creator) { |
251 | 285 | #define VY(PropertyName, StringValue) V(Symbol, PropertyName) |
252 | 286 | #define VS(PropertyName, StringValue) V(String, PropertyName) |
253 | 287 | #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))); |
255 | 290 | PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) |
256 | 291 | PER_ISOLATE_SYMBOL_PROPERTIES(VY) |
257 | 292 | PER_ISOLATE_STRING_PROPERTIES(VS) |
258 | 293 | #undef V |
259 | 294 | #undef VY |
260 | 295 | #undef VS |
261 | 296 | #undef VP |
| 297 | + |
262 | 298 | 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 |
264 | 313 |
|
265 | | - return indexes; |
| 314 | + return info; |
266 | 315 | } |
267 | 316 |
|
268 | | -void IsolateData::DeserializeProperties(const std::vector<size_t>* indexes) { |
| 317 | +void IsolateData::DeserializeProperties(const IsolateDataSerializeInfo* info) { |
269 | 318 | size_t i = 0; |
270 | 319 | HandleScope handle_scope(isolate_); |
271 | 320 |
|
@@ -275,7 +324,8 @@ void IsolateData::DeserializeProperties(const std::vector<size_t>* indexes) { |
275 | 324 | #define V(TypeName, PropertyName) \ |
276 | 325 | do { \ |
277 | 326 | MaybeLocal<TypeName> maybe_field = \ |
278 | | - isolate_->GetDataFromSnapshotOnce<TypeName>((*indexes)[i++]); \ |
| 327 | + isolate_->GetDataFromSnapshotOnce<TypeName>( \ |
| 328 | + info->primitive_values[i++]); \ |
279 | 329 | Local<TypeName> field; \ |
280 | 330 | if (!maybe_field.ToLocal(&field)) { \ |
281 | 331 | fprintf(stderr, "Failed to deserialize " #PropertyName "\n"); \ |
@@ -292,13 +342,38 @@ void IsolateData::DeserializeProperties(const std::vector<size_t>* indexes) { |
292 | 342 |
|
293 | 343 | for (size_t j = 0; j < AsyncWrap::PROVIDERS_LENGTH; j++) { |
294 | 344 | MaybeLocal<String> maybe_field = |
295 | | - isolate_->GetDataFromSnapshotOnce<String>((*indexes)[i++]); |
| 345 | + isolate_->GetDataFromSnapshotOnce<String>(info->primitive_values[i++]); |
296 | 346 | Local<String> field; |
297 | 347 | if (!maybe_field.ToLocal(&field)) { |
298 | 348 | fprintf(stderr, "Failed to deserialize AsyncWrap provider %zu\n", j); |
299 | 349 | } |
300 | 350 | async_wrap_providers_[j].Set(isolate_, field); |
301 | 351 | } |
| 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 |
302 | 377 | } |
303 | 378 |
|
304 | 379 | void IsolateData::CreateProperties() { |
@@ -363,13 +438,15 @@ void IsolateData::CreateProperties() { |
363 | 438 | sizeof(#Provider) - 1).ToLocalChecked()); |
364 | 439 | NODE_ASYNC_PROVIDER_TYPES(V) |
365 | 440 | #undef V |
| 441 | + |
| 442 | + // TODO(legendecas): eagerly create per isolate templates. |
366 | 443 | } |
367 | 444 |
|
368 | 445 | IsolateData::IsolateData(Isolate* isolate, |
369 | 446 | uv_loop_t* event_loop, |
370 | 447 | MultiIsolatePlatform* platform, |
371 | 448 | ArrayBufferAllocator* node_allocator, |
372 | | - const std::vector<size_t>* indexes) |
| 449 | + const IsolateDataSerializeInfo* isolate_data_info) |
373 | 450 | : isolate_(isolate), |
374 | 451 | event_loop_(event_loop), |
375 | 452 | node_allocator_(node_allocator == nullptr ? nullptr |
@@ -378,10 +455,10 @@ IsolateData::IsolateData(Isolate* isolate, |
378 | 455 | options_.reset( |
379 | 456 | new PerIsolateOptions(*(per_process::cli_options->per_isolate))); |
380 | 457 |
|
381 | | - if (indexes == nullptr) { |
| 458 | + if (isolate_data_info == nullptr) { |
382 | 459 | CreateProperties(); |
383 | 460 | } else { |
384 | | - DeserializeProperties(indexes); |
| 461 | + DeserializeProperties(isolate_data_info); |
385 | 462 | } |
386 | 463 | } |
387 | 464 |
|
@@ -1527,16 +1604,6 @@ void AsyncHooks::Deserialize(Local<Context> context) { |
1527 | 1604 | info_ = nullptr; |
1528 | 1605 | } |
1529 | 1606 |
|
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 | | - |
1540 | 1607 | std::ostream& operator<<(std::ostream& output, |
1541 | 1608 | const AsyncHooks::SerializeInfo& i) { |
1542 | 1609 | output << "{\n" |
@@ -1748,19 +1815,6 @@ EnvSerializeInfo Environment::Serialize(SnapshotCreator* creator) { |
1748 | 1815 | should_abort_on_uncaught_toggle_.Serialize(ctx, creator); |
1749 | 1816 |
|
1750 | 1817 | 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; |
1764 | 1818 | #define V(PropertyName, TypeName) \ |
1765 | 1819 | do { \ |
1766 | 1820 | Local<TypeName> field = PropertyName(); \ |
@@ -1777,17 +1831,6 @@ EnvSerializeInfo Environment::Serialize(SnapshotCreator* creator) { |
1777 | 1831 | return info; |
1778 | 1832 | } |
1779 | 1833 |
|
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 | | - |
1791 | 1834 | std::ostream& operator<<(std::ostream& output, |
1792 | 1835 | const std::vector<std::string>& vec) { |
1793 | 1836 | output << "{\n"; |
@@ -1817,9 +1860,6 @@ std::ostream& operator<<(std::ostream& output, const EnvSerializeInfo& i) { |
1817 | 1860 | << i.stream_base_state << ", // stream_base_state\n" |
1818 | 1861 | << i.should_abort_on_uncaught_toggle |
1819 | 1862 | << ", // should_abort_on_uncaught_toggle\n" |
1820 | | - << "// -- persistent_templates begins --\n" |
1821 | | - << i.persistent_templates << ",\n" |
1822 | | - << "// persistent_templates ends --\n" |
1823 | 1863 | << "// -- persistent_values begins --\n" |
1824 | 1864 | << i.persistent_values << ",\n" |
1825 | 1865 | << "// -- persistent_values ends --\n" |
@@ -1868,40 +1908,30 @@ void Environment::DeserializeProperties(const EnvSerializeInfo* info) { |
1868 | 1908 | std::cerr << *info << "\n"; |
1869 | 1909 | } |
1870 | 1910 |
|
1871 | | - const std::vector<PropInfo>& templates = info->persistent_templates; |
| 1911 | + const std::vector<PropInfo>& values = info->persistent_values; |
1872 | 1912 | size_t i = 0; // index to the array |
1873 | 1913 | size_t id = 0; |
1874 | | -#define SetProperty(PropertyName, TypeName, vector, type, from) \ |
| 1914 | +#define V(PropertyName, TypeName) \ |
1875 | 1915 | 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]; \ |
1878 | 1918 | DCHECK_EQ(d.name, #PropertyName); \ |
1879 | 1919 | MaybeLocal<TypeName> maybe_field = \ |
1880 | | - from->GetDataFromSnapshotOnce<TypeName>(d.index); \ |
| 1920 | + ctx->GetDataFromSnapshotOnce<TypeName>(d.index); \ |
1881 | 1921 | Local<TypeName> field; \ |
1882 | 1922 | if (!maybe_field.ToLocal(&field)) { \ |
1883 | 1923 | fprintf(stderr, \ |
1884 | | - "Failed to deserialize environment " #type " " #PropertyName \ |
| 1924 | + "Failed to deserialize environment value " #PropertyName \ |
1885 | 1925 | "\n"); \ |
1886 | 1926 | } \ |
1887 | 1927 | set_##PropertyName(field); \ |
1888 | 1928 | i++; \ |
1889 | 1929 | } \ |
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); |
1896 | 1932 |
|
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) |
1902 | 1933 | ENVIRONMENT_STRONG_PERSISTENT_VALUES(V); |
1903 | 1934 | #undef V |
1904 | | -#undef SetProperty |
1905 | 1935 |
|
1906 | 1936 | MaybeLocal<Context> maybe_ctx_from_snapshot = |
1907 | 1937 | ctx->GetDataFromSnapshotOnce<Context>(info->context); |
|