Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit b74b214

Browse files
committedMar 30, 2021
deps: backport v8 f19142e6
[top-level-await] Implement the new post-order requirement for async subgraphs Refs: v8/v8@f19142e PR-URL: #37864 Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Colin Ihrig <[email protected]>
1 parent 7a2e80b commit b74b214

18 files changed

+334
-89
lines changed
 

‎common.gypi

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
# Reset this number to 0 on major V8 upgrades.
3838
# Increment by one for each non-official patch applied to deps/v8.
39-
'v8_embedder_string': '-node.20',
39+
'v8_embedder_string': '-node.21',
4040

4141
##### V8 defaults for Node.js #####
4242

‎deps/v8/src/common/globals.h

+3
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,9 @@ constexpr int kUC16Size = sizeof(uc16); // NOLINT
334334
// 128 bit SIMD value size.
335335
constexpr int kSimd128Size = 16;
336336

337+
// Maximum ordinal used for tracking asynchronous module evaluation order.
338+
constexpr unsigned kMaxModuleAsyncEvaluatingOrdinal = (1 << 30) - 1;
339+
337340
// FUNCTION_ADDR(f) gets the address of a C function f.
338341
#define FUNCTION_ADDR(f) (reinterpret_cast<v8::internal::Address>(f))
339342

‎deps/v8/src/diagnostics/objects-debug.cc

+1
Original file line numberDiff line numberDiff line change
@@ -1352,6 +1352,7 @@ void SourceTextModule::SourceTextModuleVerify(Isolate* isolate) {
13521352
(status() == kUninstantiated && code().IsSharedFunctionInfo()));
13531353
CHECK(top_level_capability().IsUndefined() && !AsyncParentModuleCount() &&
13541354
!pending_async_dependencies() && !async_evaluating());
1355+
CHECK(!IsAsyncEvaluating());
13551356
}
13561357

13571358
CHECK_EQ(requested_modules().length(), info().module_requests().length());

‎deps/v8/src/diagnostics/objects-printer.cc

+1
Original file line numberDiff line numberDiff line change
@@ -1622,6 +1622,7 @@ void SourceTextModule::SourceTextModulePrint(std::ostream& os) { // NOLINT
16221622
os << "\n - script: " << Brief(script());
16231623
os << "\n - import_meta: " << Brief(import_meta());
16241624
os << "\n - cycle_root: " << Brief(cycle_root());
1625+
os << "\n - async_evaluating_ordinal: " << async_evaluating_ordinal();
16251626
os << "\n";
16261627
}
16271628

‎deps/v8/src/execution/isolate-inl.h

+30
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,36 @@ Isolate::ExceptionScope::~ExceptionScope() {
117117
isolate_->set_pending_exception(*pending_exception_);
118118
}
119119

120+
void Isolate::DidFinishModuleAsyncEvaluation(unsigned ordinal) {
121+
// To address overflow, the ordinal is reset when the async module with the
122+
// largest vended ordinal finishes evaluating. Modules are evaluated in
123+
// ascending order of their async_evaluating_ordinal.
124+
//
125+
// While the specification imposes a global total ordering, the intention is
126+
// that for each async module, all its parents are totally ordered by when
127+
// they first had their [[AsyncEvaluating]] bit set.
128+
//
129+
// The module with largest vended ordinal finishes evaluating implies that the
130+
// async dependency as well as all other modules in that module's graph
131+
// depending on async dependencies are finished evaluating.
132+
//
133+
// If the async dependency participates in other module graphs (e.g. via
134+
// dynamic import, or other <script type=module> tags), those module graphs
135+
// must have been evaluated either before or after the async dependency is
136+
// settled, as the concrete Evaluate() method on cyclic module records is
137+
// neither reentrant nor performs microtask checkpoints during its
138+
// evaluation. If before, then all modules that depend on the async
139+
// dependencies were given an ordinal that ensure they are relatively ordered,
140+
// before the global ordinal was reset. If after, then the async evaluating
141+
// ordering does not apply, as the dependency is no longer asynchronous.
142+
//
143+
// https://tc39.es/ecma262/#sec-moduleevaluation
144+
if (ordinal + 1 == next_module_async_evaluating_ordinal_) {
145+
next_module_async_evaluating_ordinal_ =
146+
SourceTextModule::kFirstAsyncEvaluatingOrdinal;
147+
}
148+
}
149+
120150
#define NATIVE_CONTEXT_FIELD_ACCESSOR(index, type, name) \
121151
Handle<type> Isolate::name() { \
122152
return Handle<type>(raw_native_context().name(), this); \

‎deps/v8/src/execution/isolate.cc

+2
Original file line numberDiff line numberDiff line change
@@ -2792,6 +2792,8 @@ Isolate::Isolate(std::unique_ptr<i::IsolateAllocator> isolate_allocator)
27922792
#if V8_SFI_HAS_UNIQUE_ID
27932793
next_unique_sfi_id_(0),
27942794
#endif
2795+
next_module_async_evaluating_ordinal_(
2796+
SourceTextModule::kFirstAsyncEvaluatingOrdinal),
27952797
cancelable_task_manager_(new CancelableTaskManager()) {
27962798
TRACE_ISOLATE(constructor);
27972799
CheckIsolateLayout();

‎deps/v8/src/execution/isolate.h

+18
Original file line numberDiff line numberDiff line change
@@ -1264,6 +1264,22 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
12641264
return id;
12651265
}
12661266

1267+
// https://github.com/tc39/proposal-top-level-await/pull/159
1268+
// TODO(syg): Update to actual spec link once merged.
1269+
//
1270+
// According to the spec, modules that depend on async modules (i.e. modules
1271+
// with top-level await) must be evaluated in order in which their
1272+
// [[AsyncEvaluating]] flags were set to true. V8 tracks this global total
1273+
// order with next_module_async_evaluating_ordinal_. Each module that sets its
1274+
// [[AsyncEvaluating]] to true grabs the next ordinal.
1275+
unsigned NextModuleAsyncEvaluatingOrdinal() {
1276+
unsigned ordinal = next_module_async_evaluating_ordinal_++;
1277+
CHECK_LT(ordinal, kMaxModuleAsyncEvaluatingOrdinal);
1278+
return ordinal;
1279+
}
1280+
1281+
inline void DidFinishModuleAsyncEvaluation(unsigned ordinal);
1282+
12671283
void AddNearHeapLimitCallback(v8::NearHeapLimitCallback, void* data);
12681284
void RemoveNearHeapLimitCallback(v8::NearHeapLimitCallback callback,
12691285
size_t heap_limit);
@@ -1788,6 +1804,8 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
17881804
std::atomic<int> next_unique_sfi_id_;
17891805
#endif
17901806

1807+
unsigned next_module_async_evaluating_ordinal_;
1808+
17911809
// Vector of callbacks before a Call starts execution.
17921810
std::vector<BeforeCallEnteredCallback> before_call_entered_callbacks_;
17931811

‎deps/v8/src/heap/factory.cc

+1-2
Original file line numberDiff line numberDiff line change
@@ -2484,8 +2484,7 @@ Handle<SourceTextModule> Factory::NewSourceTextModule(
24842484
module->set_dfs_ancestor_index(-1);
24852485
module->set_top_level_capability(roots.undefined_value());
24862486
module->set_flags(0);
2487-
module->set_async(IsAsyncModule(code->kind()));
2488-
module->set_async_evaluating(false);
2487+
module->set_async_evaluating_ordinal(SourceTextModule::kNotAsyncEvaluated);
24892488
module->set_cycle_root(roots.the_hole_value());
24902489
module->set_async_parent_modules(*async_parent_modules);
24912490
module->set_pending_async_dependencies(0);

‎deps/v8/src/objects/module-inl.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,8 @@ ACCESSORS(Module, exception, Object, kExceptionOffset)
3636
SMI_ACCESSORS(Module, status, kStatusOffset)
3737
SMI_ACCESSORS(Module, hash, kHashOffset)
3838

39-
BOOL_ACCESSORS(SourceTextModule, flags, async, AsyncBit::kShift)
40-
BOOL_ACCESSORS(SourceTextModule, flags, async_evaluating,
41-
AsyncEvaluatingBit::kShift)
39+
BIT_FIELD_ACCESSORS(SourceTextModule, flags, async_evaluating_ordinal,
40+
SourceTextModule::AsyncEvaluatingOrdinalBits)
4241
ACCESSORS(SourceTextModule, async_parent_modules, ArrayList,
4342
kAsyncParentModulesOffset)
4443
ACCESSORS(SourceTextModule, top_level_capability, HeapObject,
@@ -141,6 +140,10 @@ int SourceTextModule::AsyncParentModuleCount() {
141140
return async_parent_modules().Length();
142141
}
143142

143+
bool SourceTextModule::IsAsyncEvaluating() const {
144+
return async_evaluating_ordinal() >= kFirstAsyncEvaluatingOrdinal;
145+
}
146+
144147
bool SourceTextModule::HasPendingAsyncDependencies() {
145148
DCHECK_GE(pending_async_dependencies(), 0);
146149
return pending_async_dependencies() > 0;

0 commit comments

Comments
 (0)