Skip to content

Commit 0c1e878

Browse files
committed
deps: backport v8 f19142e6
[top-level-await] Implement the new post-order requirement for async subgraphs Refs: v8/v8@f19142e PR-URL: #37864 Backport-PR-URL: #37973 Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Colin Ihrig <[email protected]>
1 parent dd5da30 commit 0c1e878

18 files changed

+337
-88
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.28',
39+
'v8_embedder_string': '-node.29',
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

+2-1
Original file line numberDiff line numberDiff line change
@@ -1351,7 +1351,8 @@ void SourceTextModule::SourceTextModuleVerify(Isolate* isolate) {
13511351
(status() == kPreInstantiating && code().IsSharedFunctionInfo()) ||
13521352
(status() == kUninstantiated && code().IsSharedFunctionInfo()));
13531353
CHECK(top_level_capability().IsUndefined() && !AsyncParentModuleCount() &&
1354-
!pending_async_dependencies() && !async_evaluating());
1354+
!pending_async_dependencies());
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

+31
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "src/objects/property-cell.h"
1313
#include "src/objects/regexp-match-info.h"
1414
#include "src/objects/shared-function-info.h"
15+
#include "src/objects/source-text-module.h"
1516

1617
namespace v8 {
1718
namespace internal {
@@ -117,6 +118,36 @@ Isolate::ExceptionScope::~ExceptionScope() {
117118
isolate_->set_pending_exception(*pending_exception_);
118119
}
119120

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

deps/v8/src/execution/isolate.cc

+3
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
#include "src/objects/prototype.h"
6767
#include "src/objects/slots.h"
6868
#include "src/objects/smi.h"
69+
#include "src/objects/source-text-module.h"
6970
#include "src/objects/stack-frame-info-inl.h"
7071
#include "src/objects/visitors.h"
7172
#include "src/profiler/heap-profiler.h"
@@ -2792,6 +2793,8 @@ Isolate::Isolate(std::unique_ptr<i::IsolateAllocator> isolate_allocator)
27922793
#if V8_SFI_HAS_UNIQUE_ID
27932794
next_unique_sfi_id_(0),
27942795
#endif
2796+
next_module_async_evaluating_ordinal_(
2797+
SourceTextModule::kFirstAsyncEvaluatingOrdinal),
27952798
cancelable_task_manager_(new CancelableTaskManager()) {
27962799
TRACE_ISOLATE(constructor);
27972800
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-1
Original file line numberDiff line numberDiff line change
@@ -2485,7 +2485,7 @@ Handle<SourceTextModule> Factory::NewSourceTextModule(
24852485
module->set_top_level_capability(roots.undefined_value());
24862486
module->set_flags(0);
24872487
module->set_async(IsAsyncModule(code->kind()));
2488-
module->set_async_evaluating(false);
2488+
module->set_async_evaluating_ordinal(SourceTextModule::kNotAsyncEvaluated);
24892489
module->set_cycle_root(roots.the_hole_value());
24902490
module->set_async_parent_modules(*async_parent_modules);
24912491
module->set_pending_async_dependencies(0);

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

+6-2
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ SMI_ACCESSORS(Module, status, kStatusOffset)
3737
SMI_ACCESSORS(Module, hash, kHashOffset)
3838

3939
BOOL_ACCESSORS(SourceTextModule, flags, async, AsyncBit::kShift)
40-
BOOL_ACCESSORS(SourceTextModule, flags, async_evaluating,
41-
AsyncEvaluatingBit::kShift)
40+
BIT_FIELD_ACCESSORS(SourceTextModule, flags, async_evaluating_ordinal,
41+
SourceTextModule::AsyncEvaluatingOrdinalBits)
4242
ACCESSORS(SourceTextModule, async_parent_modules, ArrayList,
4343
kAsyncParentModulesOffset)
4444
ACCESSORS(SourceTextModule, top_level_capability, HeapObject,
@@ -141,6 +141,10 @@ int SourceTextModule::AsyncParentModuleCount() {
141141
return async_parent_modules().Length();
142142
}
143143

144+
bool SourceTextModule::IsAsyncEvaluating() const {
145+
return async_evaluating_ordinal() >= kFirstAsyncEvaluatingOrdinal;
146+
}
147+
144148
bool SourceTextModule::HasPendingAsyncDependencies() {
145149
DCHECK_GE(pending_async_dependencies(), 0);
146150
return pending_async_dependencies() > 0;

0 commit comments

Comments
 (0)