[debug] Simplify async function instrumentation.

This unifies and simplifies the way we instrument async functions for
the purpose of async stack traces and async stepping. It does so while
retaining the observable behavior on the inspector level (for now).

Previously we'd mark the implicit promise of the async function object
with the async task ID, and whenever we awaited, we'd copy the async
task ID to the throwaway promise that is created by the `await`. This
however made things unnecessarily interesting in the following regards:

1. We'd see `DebugDidHandle` and `DebugWillHandle` events after the
`AsyncFunctionFinished` events, coming from the throwaway promises,
while the implicit promise is "done". This is especially confusing
with rejection propagation and requires very complex stepping logic
for async functions (after this CL it'll be possible to unify and
simplify the stepping logic).
2. We have to thread through the "can suspend" information from the
Parser all the way through AsyncFunctionReject/AsyncFunctionResolve
to the async function instrumentation to decide whether to cancel the
pending task when the async function finishes.

This CL changes the instrumentation to only happen (non recurringly) for
the throwaway promises allocated upon `await`. This solves both problems
mentioned above, and works because upon the first `await` the stack
captured for the throwaway promise will include the synchronous part as
expected, while upon later `await`s the synchronous part will be empty
and the asynchronous part will be the stack captured for the previous
throwaway promise (and the V8Debugger automatically short circuits
stacks with empty synchronous part).

Bug: chromium:1280519, chromium:1277451, chromium:1246867
Change-Id: Id604dabc19ea133ea2e9dd63181b1fc33ccb5eda
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3383775
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Maya Lekova <mslekova@chromium.org>
Reviewed-by: Simon Zünd <szuend@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78599}
This commit is contained in:
Benedikt Meurer 2022-01-13 08:58:31 +01:00 committed by V8 LUCI CQ
parent a54f38e1fd
commit 41f0c0bac8
18 changed files with 133 additions and 199 deletions

View File

@ -175,7 +175,6 @@ TF_BUILTIN(AsyncFunctionReject, AsyncFunctionBuiltinsAssembler) {
auto async_function_object =
Parameter<JSAsyncFunctionObject>(Descriptor::kAsyncFunctionObject);
auto reason = Parameter<Object>(Descriptor::kReason);
auto can_suspend = Parameter<Oddball>(Descriptor::kCanSuspend);
auto context = Parameter<Context>(Descriptor::kContext);
TNode<JSPromise> promise = LoadObjectField<JSPromise>(
async_function_object, JSAsyncFunctionObject::kPromiseOffset);
@ -187,20 +186,17 @@ TF_BUILTIN(AsyncFunctionReject, AsyncFunctionBuiltinsAssembler) {
FalseConstant());
Label if_debugging(this, Label::kDeferred);
GotoIf(HasAsyncEventDelegate(), &if_debugging);
GotoIf(IsDebugActive(), &if_debugging);
Return(promise);
BIND(&if_debugging);
TailCallRuntime(Runtime::kDebugAsyncFunctionFinished, context, can_suspend,
promise);
TailCallRuntime(Runtime::kDebugAsyncFunctionFinished, context, promise);
}
TF_BUILTIN(AsyncFunctionResolve, AsyncFunctionBuiltinsAssembler) {
auto async_function_object =
Parameter<JSAsyncFunctionObject>(Descriptor::kAsyncFunctionObject);
auto value = Parameter<Object>(Descriptor::kValue);
auto can_suspend = Parameter<Oddball>(Descriptor::kCanSuspend);
auto context = Parameter<Context>(Descriptor::kContext);
TNode<JSPromise> promise = LoadObjectField<JSPromise>(
async_function_object, JSAsyncFunctionObject::kPromiseOffset);
@ -208,13 +204,11 @@ TF_BUILTIN(AsyncFunctionResolve, AsyncFunctionBuiltinsAssembler) {
CallBuiltin(Builtin::kResolvePromise, context, promise, value);
Label if_debugging(this, Label::kDeferred);
GotoIf(HasAsyncEventDelegate(), &if_debugging);
GotoIf(IsDebugActive(), &if_debugging);
Return(promise);
BIND(&if_debugging);
TailCallRuntime(Runtime::kDebugAsyncFunctionFinished, context, can_suspend,
promise);
TailCallRuntime(Runtime::kDebugAsyncFunctionFinished, context, promise);
}
// AsyncFunctionReject and AsyncFunctionResolve are both required to return
@ -260,29 +254,18 @@ void AsyncFunctionBuiltinsAssembler::AsyncFunctionAwait(
auto value = Parameter<Object>(Descriptor::kValue);
auto context = Parameter<Context>(Descriptor::kContext);
TNode<JSPromise> outer_promise = LoadObjectField<JSPromise>(
async_function_object, JSAsyncFunctionObject::kPromiseOffset);
Label after_debug_hook(this), call_debug_hook(this, Label::kDeferred);
GotoIf(HasAsyncEventDelegate(), &call_debug_hook);
GotoIf(IsDebugActive(), &call_debug_hook);
Goto(&after_debug_hook);
BIND(&after_debug_hook);
TNode<SharedFunctionInfo> on_resolve_sfi =
AsyncFunctionAwaitResolveSharedFunConstant();
TNode<SharedFunctionInfo> on_reject_sfi =
AsyncFunctionAwaitRejectSharedFunConstant();
TNode<JSPromise> outer_promise = LoadObjectField<JSPromise>(
async_function_object, JSAsyncFunctionObject::kPromiseOffset);
Await(context, async_function_object, value, outer_promise, on_resolve_sfi,
on_reject_sfi, is_predicted_as_caught);
// Return outer promise to avoid adding an load of the outer promise before
// suspending in BytecodeGenerator.
Return(outer_promise);
BIND(&call_debug_hook);
CallRuntime(Runtime::kDebugAsyncFunctionSuspended, context, outer_promise);
Goto(&after_debug_hook);
}
// Called by the parser from the desugaring of 'await' when catch

View File

@ -423,8 +423,8 @@ namespace internal {
\
/* AsyncFunction */ \
TFS(AsyncFunctionEnter, kClosure, kReceiver) \
TFS(AsyncFunctionReject, kAsyncFunctionObject, kReason, kCanSuspend) \
TFS(AsyncFunctionResolve, kAsyncFunctionObject, kValue, kCanSuspend) \
TFS(AsyncFunctionReject, kAsyncFunctionObject, kReason) \
TFS(AsyncFunctionResolve, kAsyncFunctionObject, kValue) \
TFC(AsyncFunctionLazyDeoptContinuation, AsyncFunctionStackParameter) \
TFS(AsyncFunctionAwaitCaught, kAsyncFunctionObject, kValue) \
TFS(AsyncFunctionAwaitUncaught, kAsyncFunctionObject, kValue) \

View File

@ -754,8 +754,8 @@ Type JSWasmCallNode::TypeForWasmReturnType(const wasm::ValueType& type) {
V(OrdinaryHasInstance, Operator::kNoProperties, 2, 1) \
V(ForInEnumerate, Operator::kNoProperties, 1, 1) \
V(AsyncFunctionEnter, Operator::kNoProperties, 2, 1) \
V(AsyncFunctionReject, Operator::kNoDeopt | Operator::kNoThrow, 3, 1) \
V(AsyncFunctionResolve, Operator::kNoDeopt | Operator::kNoThrow, 3, 1) \
V(AsyncFunctionReject, Operator::kNoDeopt | Operator::kNoThrow, 2, 1) \
V(AsyncFunctionResolve, Operator::kNoDeopt | Operator::kNoThrow, 2, 1) \
V(LoadMessage, Operator::kNoThrow | Operator::kNoWrite, 0, 1) \
V(StoreMessage, Operator::kNoRead | Operator::kNoThrow, 1, 0) \
V(GeneratorRestoreContinuation, Operator::kNoThrow, 1, 1) \

View File

@ -880,13 +880,11 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
case IrOpcode::kJSAsyncFunctionReject:
CheckValueInputIs(node, 0, Type::Any());
CheckValueInputIs(node, 1, Type::Any());
CheckValueInputIs(node, 2, Type::Boolean());
CheckTypeIs(node, Type::OtherObject());
break;
case IrOpcode::kJSAsyncFunctionResolve:
CheckValueInputIs(node, 0, Type::Any());
CheckValueInputIs(node, 1, Type::Any());
CheckValueInputIs(node, 2, Type::Boolean());
CheckTypeIs(node, Type::OtherObject());
break;
case IrOpcode::kJSFulfillPromise:

View File

@ -46,13 +46,12 @@ class V8_EXPORT_PRIVATE Location {
};
enum DebugAsyncActionType {
kDebugAwait,
kDebugPromiseThen,
kDebugPromiseCatch,
kDebugPromiseFinally,
kDebugWillHandle,
kDebugDidHandle,
kAsyncFunctionSuspended,
kAsyncFunctionFinished
kDebugDidHandle
};
enum BreakLocationType {

View File

@ -4871,9 +4871,8 @@ void Isolate::RunPromiseHookForAsyncEventDelegate(PromiseHookType type,
// We should not report PromiseThen and PromiseCatch which is called
// indirectly, e.g. Promise.all calls Promise.then internally.
if (last_frame_was_promise_builtin) {
if (!promise->async_task_id()) {
promise->set_async_task_id(++async_task_count_);
}
DCHECK_EQ(0, promise->async_task_id());
promise->set_async_task_id(++async_task_count_);
async_event_delegate_->AsyncEventOccurred(
action_type, promise->async_task_id(),
debug()->IsBlackboxed(info));
@ -4900,14 +4899,49 @@ void Isolate::RunPromiseHookForAsyncEventDelegate(PromiseHookType type,
}
}
void Isolate::OnAsyncFunctionStateChanged(Handle<JSPromise> promise,
debug::DebugAsyncActionType event) {
if (!async_event_delegate_) return;
if (!promise->async_task_id()) {
promise->set_async_task_id(++async_task_count_);
void Isolate::OnAsyncFunctionEntered(Handle<JSPromise> promise) {
if (HasIsolatePromiseHooks()) {
DCHECK_NE(nullptr, promise_hook_);
promise_hook_(PromiseHookType::kInit, v8::Utils::PromiseToLocal(promise),
v8::Utils::ToLocal(factory()->undefined_value()));
}
OnAsyncFunctionResumed(promise);
}
void Isolate::OnAsyncFunctionSuspended(Handle<JSPromise> promise,
Handle<JSPromise> parent) {
DCHECK_EQ(0, promise->async_task_id());
if (HasIsolatePromiseHooks()) {
DCHECK_NE(nullptr, promise_hook_);
promise_hook_(PromiseHookType::kInit, v8::Utils::PromiseToLocal(promise),
v8::Utils::PromiseToLocal(parent));
}
if (HasAsyncEventDelegate()) {
DCHECK_NE(nullptr, async_event_delegate_);
promise->set_async_task_id(++async_task_count_);
async_event_delegate_->AsyncEventOccurred(debug::kDebugAwait,
promise->async_task_id(), false);
}
if (debug()->is_active()) {
// We are about to suspend execution of the current async function,
// so pop the outer promise from the isolate's promise stack.
PopPromise();
}
}
void Isolate::OnAsyncFunctionResumed(Handle<JSPromise> promise) {
if (debug()->is_active()) {
// While we are executing an async function, we need to
// have the implicit promise on the stack to get the catch
// prediction right.
PushPromise(promise);
}
}
void Isolate::OnAsyncFunctionFinished(Handle<JSPromise> promise) {
if (debug()->is_active()) {
PopPromise();
}
async_event_delegate_->AsyncEventOccurred(event, promise->async_task_id(),
false);
}
void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {

View File

@ -948,8 +948,13 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
async_event_delegate_ = delegate;
PromiseHookStateUpdated();
}
void OnAsyncFunctionStateChanged(Handle<JSPromise> promise,
debug::DebugAsyncActionType);
// Async function instrumentation support.
void OnAsyncFunctionEntered(Handle<JSPromise> promise);
void OnAsyncFunctionSuspended(Handle<JSPromise> promise,
Handle<JSPromise> parent);
void OnAsyncFunctionResumed(Handle<JSPromise> promise);
void OnAsyncFunctionFinished(Handle<JSPromise> promise);
// Re-throw an exception. This involves no error reporting since error
// reporting was handled when the exception was thrown originally.

View File

@ -617,10 +617,8 @@ void V8Debugger::AsyncEventOccurred(v8::debug::DebugAsyncActionType type,
asyncTaskFinishedForStack(task);
asyncTaskFinishedForStepping(task);
break;
case v8::debug::kAsyncFunctionSuspended: {
if (m_asyncTaskStacks.find(task) == m_asyncTaskStacks.end()) {
asyncTaskScheduledForStack(toStringView("await"), task, true, true);
}
case v8::debug::kDebugAwait: {
asyncTaskScheduledForStack(toStringView("await"), task, false, true);
auto stackIt = m_asyncTaskStacks.find(task);
if (stackIt != m_asyncTaskStacks.end() && !stackIt->second.expired()) {
std::shared_ptr<AsyncStackTrace> stack(stackIt->second);
@ -628,9 +626,6 @@ void V8Debugger::AsyncEventOccurred(v8::debug::DebugAsyncActionType type,
}
break;
}
case v8::debug::kAsyncFunctionFinished:
asyncTaskCanceledForStack(task);
break;
}
}

View File

@ -3626,12 +3626,10 @@ void BytecodeGenerator::BuildAsyncReturn(int source_position) {
} else {
DCHECK(IsAsyncFunction(info()->literal()->kind()) ||
IsAsyncModule(info()->literal()->kind()));
RegisterList args = register_allocator()->NewRegisterList(3);
RegisterList args = register_allocator()->NewRegisterList(2);
builder()
->MoveRegister(generator_object(), args[0]) // generator
.StoreAccumulatorInRegister(args[1]) // value
.LoadBoolean(info()->literal()->CanSuspend())
.StoreAccumulatorInRegister(args[2]) // can_suspend
.CallRuntime(Runtime::kInlineAsyncFunctionResolve, args);
}

View File

@ -17,8 +17,8 @@ namespace interpreter {
V(AsyncFunctionAwaitCaught, async_function_await_caught, 2) \
V(AsyncFunctionAwaitUncaught, async_function_await_uncaught, 2) \
V(AsyncFunctionEnter, async_function_enter, 2) \
V(AsyncFunctionReject, async_function_reject, 3) \
V(AsyncFunctionResolve, async_function_resolve, 3) \
V(AsyncFunctionReject, async_function_reject, 2) \
V(AsyncFunctionResolve, async_function_resolve, 2) \
V(AsyncGeneratorAwaitCaught, async_generator_await_caught, 2) \
V(AsyncGeneratorAwaitUncaught, async_generator_await_uncaught, 2) \
V(AsyncGeneratorReject, async_generator_reject, 2) \

View File

@ -2873,8 +2873,6 @@ Block* Parser::BuildRejectPromiseOnException(Block* inner_block,
args.Add(factory()->NewVariableProxy(
function_state_->scope()->generator_object_var()));
args.Add(factory()->NewVariableProxy(catch_scope->catch_variable()));
args.Add(factory()->NewBooleanLiteral(function_state_->CanSuspend(),
kNoSourcePosition));
reject_promise = factory()->NewCallRuntime(
Runtime::kInlineAsyncFunctionReject, args, kNoSourcePosition);
}

View File

@ -822,18 +822,7 @@ RUNTIME_FUNCTION(Runtime_DebugAsyncFunctionEntered) {
DCHECK_EQ(1, args.length());
HandleScope scope(isolate);
CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
isolate->RunPromiseHook(PromiseHookType::kInit, promise,
isolate->factory()->undefined_value());
if (isolate->debug()->is_active()) isolate->PushPromise(promise);
return ReadOnlyRoots(isolate).undefined_value();
}
RUNTIME_FUNCTION(Runtime_DebugAsyncFunctionSuspended) {
DCHECK_EQ(1, args.length());
HandleScope scope(isolate);
CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
isolate->PopPromise();
isolate->OnAsyncFunctionStateChanged(promise, debug::kAsyncFunctionSuspended);
isolate->OnAsyncFunctionEntered(promise);
return ReadOnlyRoots(isolate).undefined_value();
}
@ -841,20 +830,15 @@ RUNTIME_FUNCTION(Runtime_DebugAsyncFunctionResumed) {
DCHECK_EQ(1, args.length());
HandleScope scope(isolate);
CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
isolate->PushPromise(promise);
isolate->OnAsyncFunctionResumed(promise);
return ReadOnlyRoots(isolate).undefined_value();
}
RUNTIME_FUNCTION(Runtime_DebugAsyncFunctionFinished) {
DCHECK_EQ(2, args.length());
HandleScope scope(isolate);
CONVERT_BOOLEAN_ARG_CHECKED(has_suspend, 0);
CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 1);
isolate->PopPromise();
if (has_suspend) {
isolate->OnAsyncFunctionStateChanged(promise,
debug::kAsyncFunctionFinished);
}
DCHECK_EQ(1, args.length());
HandleScope shs(isolate);
CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
isolate->OnAsyncFunctionFinished(promise);
return *promise;
}

View File

@ -133,14 +133,7 @@ Handle<JSPromise> AwaitPromisesInitCommon(Isolate* isolate,
// hook for the throwaway promise (passing the {promise} as its
// parent).
Handle<JSPromise> throwaway = isolate->factory()->NewJSPromiseWithoutHook();
isolate->RunAllPromiseHooks(PromiseHookType::kInit, throwaway, promise);
// On inspector side we capture async stack trace and store it by
// outer_promise->async_task_id when async function is suspended first time.
// To use captured stack trace later throwaway promise should have the same
// async_task_id as outer_promise since we generate WillHandle and DidHandle
// events using throwaway promise.
throwaway->set_async_task_id(outer_promise->async_task_id());
isolate->OnAsyncFunctionSuspended(throwaway, promise);
// The Promise will be thrown away and not handled, but it
// shouldn't trigger unhandled reject events as its work is done

View File

@ -124,7 +124,6 @@ namespace internal {
F(ClearStepping, 0, 1) \
F(CollectGarbage, 1, 1) \
F(DebugAsyncFunctionEntered, 1, 1) \
F(DebugAsyncFunctionSuspended, 1, 1) \
F(DebugAsyncFunctionResumed, 1, 1) \
F(DebugAsyncFunctionFinished, 2, 1) \
F(DebugBreakAtEntry, 1, 1) \
@ -184,8 +183,8 @@ namespace internal {
I(AsyncFunctionAwaitCaught, 2, 1) \
I(AsyncFunctionAwaitUncaught, 2, 1) \
I(AsyncFunctionEnter, 2, 1) \
I(AsyncFunctionReject, 3, 1) \
I(AsyncFunctionResolve, 3, 1) \
I(AsyncFunctionReject, 2, 1) \
I(AsyncFunctionResolve, 2, 1) \
I(AsyncGeneratorAwaitCaught, 2, 1) \
I(AsyncGeneratorAwaitUncaught, 2, 1) \
F(AsyncGeneratorHasCatchHandlerForPC, 1, 1) \

View File

@ -11,9 +11,9 @@ top level: yes
snippet: "
await 42;
"
frame size: 7
frame size: 6
parameter count: 1
bytecode array length: 116
bytecode array length: 112
bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
B(Mov), R(closure), R(2),
@ -48,10 +48,8 @@ bytecodes: [
B(ReThrow),
B(LdaUndefined),
B(Star4),
B(LdaTrue),
B(Star5),
B(Mov), R(0), R(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(3), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(3), U8(2),
/* 10 S> */ B(Return),
B(Star3),
B(CreateCatchContext), R(3), U8(4),
@ -62,10 +60,8 @@ bytecodes: [
B(PushContext), R(3),
B(LdaImmutableCurrentContextSlot), U8(2),
B(Star5),
B(LdaTrue),
B(Star6),
B(Mov), R(0), R(4),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(4), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(4), U8(2),
B(Return),
]
constant pool: [
@ -76,16 +72,16 @@ constant pool: [
SCOPE_INFO_TYPE,
]
handlers: [
[47, 92, 92],
[47, 90, 90],
]
---
snippet: "
await import(\"foo\");
"
frame size: 7
frame size: 6
parameter count: 1
bytecode array length: 125
bytecode array length: 121
bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
B(Mov), R(closure), R(2),
@ -123,10 +119,8 @@ bytecodes: [
B(ReThrow),
B(LdaUndefined),
B(Star4),
B(LdaTrue),
B(Star5),
B(Mov), R(0), R(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(3), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(3), U8(2),
/* 21 S> */ B(Return),
B(Star3),
B(CreateCatchContext), R(3), U8(5),
@ -137,10 +131,8 @@ bytecodes: [
B(PushContext), R(3),
B(LdaImmutableCurrentContextSlot), U8(2),
B(Star5),
B(LdaTrue),
B(Star6),
B(Mov), R(0), R(4),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(4), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(4), U8(2),
B(Return),
]
constant pool: [
@ -152,7 +144,7 @@ constant pool: [
SCOPE_INFO_TYPE,
]
handlers: [
[47, 101, 101],
[47, 99, 99],
]
---
@ -163,9 +155,9 @@ snippet: "
}
foo();
"
frame size: 8
frame size: 7
parameter count: 1
bytecode array length: 126
bytecode array length: 122
bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
B(Mov), R(closure), R(3),
@ -204,10 +196,8 @@ bytecodes: [
/* 47 S> */ B(CallUndefinedReceiver0), R(1), U8(0),
B(LdaUndefined),
B(Star5),
B(LdaTrue),
B(Star6),
B(Mov), R(0), R(4),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(4), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(4), U8(2),
/* 54 S> */ B(Return),
B(Star4),
B(CreateCatchContext), R(4), U8(5),
@ -218,10 +208,8 @@ bytecodes: [
B(PushContext), R(4),
B(LdaImmutableCurrentContextSlot), U8(2),
B(Star6),
B(LdaTrue),
B(Star7),
B(Mov), R(0), R(5),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(5), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(5), U8(2),
B(Return),
]
constant pool: [
@ -233,7 +221,7 @@ constant pool: [
SCOPE_INFO_TYPE,
]
handlers: [
[54, 102, 102],
[54, 100, 100],
]
---
@ -241,9 +229,9 @@ snippet: "
import * as foo from \"bar\";
await import(\"goo\");
"
frame size: 8
frame size: 7
parameter count: 1
bytecode array length: 135
bytecode array length: 131
bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
B(Mov), R(closure), R(3),
@ -286,10 +274,8 @@ bytecodes: [
B(ReThrow),
B(LdaUndefined),
B(Star5),
B(LdaTrue),
B(Star6),
B(Mov), R(0), R(4),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(4), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(4), U8(2),
/* 49 S> */ B(Return),
B(Star4),
B(CreateCatchContext), R(4), U8(5),
@ -300,10 +286,8 @@ bytecodes: [
B(PushContext), R(4),
B(LdaImmutableCurrentContextSlot), U8(2),
B(Star6),
B(LdaTrue),
B(Star7),
B(Mov), R(0), R(5),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(5), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(5), U8(2),
B(Return),
]
constant pool: [
@ -315,6 +299,6 @@ constant pool: [
SCOPE_INFO_TYPE,
]
handlers: [
[57, 111, 111],
[57, 109, 109],
]

View File

@ -16,7 +16,7 @@ snippet: "
"
frame size: 19
parameter count: 1
bytecode array length: 272
bytecode array length: 268
bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
B(Mov), R(closure), R(4),
@ -123,10 +123,8 @@ bytecodes: [
B(ReThrow),
B(LdaUndefined),
B(Star6),
B(LdaTrue),
B(Star7),
B(Mov), R(0), R(5),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(5), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(5), U8(2),
/* 57 S> */ B(Return),
B(Star5),
B(CreateCatchContext), R(5), U8(9),
@ -137,10 +135,8 @@ bytecodes: [
B(PushContext), R(5),
B(LdaImmutableCurrentContextSlot), U8(2),
B(Star7),
B(LdaTrue),
B(Star8),
B(Mov), R(0), R(6),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(6), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(6), U8(2),
B(Return),
]
constant pool: [
@ -156,7 +152,7 @@ constant pool: [
SCOPE_INFO_TYPE,
]
handlers: [
[18, 248, 248],
[18, 246, 246],
[66, 139, 145],
[158, 214, 216],
]
@ -170,7 +166,7 @@ snippet: "
"
frame size: 19
parameter count: 1
bytecode array length: 292
bytecode array length: 285
bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
B(Mov), R(closure), R(4),
@ -274,21 +270,17 @@ bytecodes: [
B(SetPendingMessage),
B(Ldar), R(8),
B(SwitchOnSmiNoFeedback), U8(9), U8(2), I8(0),
B(Jump), U8(19),
B(Jump), U8(16),
B(Ldar), R(9),
B(ReThrow),
B(LdaTrue),
B(Star), R(16),
B(Mov), R(0), R(14),
B(Mov), R(9), R(15),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(14), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(14), U8(2),
B(Return),
B(LdaUndefined),
B(Star6),
B(LdaTrue),
B(Star7),
B(Mov), R(0), R(5),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(5), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(5), U8(2),
/* 68 S> */ B(Return),
B(Star5),
B(CreateCatchContext), R(5), U8(11),
@ -299,10 +291,8 @@ bytecodes: [
B(PushContext), R(5),
B(LdaImmutableCurrentContextSlot), U8(2),
B(Star7),
B(LdaTrue),
B(Star8),
B(Mov), R(0), R(6),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(6), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(6), U8(2),
B(Return),
]
constant pool: [
@ -320,7 +310,7 @@ constant pool: [
SCOPE_INFO_TYPE,
]
handlers: [
[18, 268, 268],
[18, 263, 263],
[66, 142, 148],
[161, 217, 219],
]
@ -337,7 +327,7 @@ snippet: "
"
frame size: 19
parameter count: 1
bytecode array length: 288
bytecode array length: 284
bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
B(Mov), R(closure), R(4),
@ -451,10 +441,8 @@ bytecodes: [
B(ReThrow),
B(LdaUndefined),
B(Star6),
B(LdaTrue),
B(Star7),
B(Mov), R(0), R(5),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(5), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(5), U8(2),
/* 114 S> */ B(Return),
B(Star5),
B(CreateCatchContext), R(5), U8(9),
@ -465,10 +453,8 @@ bytecodes: [
B(PushContext), R(5),
B(LdaImmutableCurrentContextSlot), U8(2),
B(Star7),
B(LdaTrue),
B(Star8),
B(Mov), R(0), R(6),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(6), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(6), U8(2),
B(Return),
]
constant pool: [
@ -484,7 +470,7 @@ constant pool: [
SCOPE_INFO_TYPE,
]
handlers: [
[18, 264, 264],
[18, 262, 262],
[66, 155, 161],
[174, 230, 232],
]
@ -499,7 +485,7 @@ snippet: "
"
frame size: 14
parameter count: 1
bytecode array length: 204
bytecode array length: 198
bytecodes: [
B(Mov), R(closure), R(2),
B(Mov), R(this), R(3),
@ -570,21 +556,17 @@ bytecodes: [
B(SetPendingMessage),
B(Ldar), R(6),
B(SwitchOnSmiNoFeedback), U8(7), U8(2), I8(0),
B(Jump), U8(18),
B(Jump), U8(16),
B(Ldar), R(7),
B(ReThrow),
B(LdaFalse),
B(Star13),
B(Mov), R(0), R(11),
B(Mov), R(7), R(12),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(11), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(11), U8(2),
B(Return),
B(LdaUndefined),
B(Star4),
B(LdaFalse),
B(Star5),
B(Mov), R(0), R(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(3), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(3), U8(2),
/* 96 S> */ B(Return),
B(Star3),
B(CreateCatchContext), R(3), U8(9),
@ -595,10 +577,8 @@ bytecodes: [
B(PushContext), R(3),
B(LdaImmutableCurrentContextSlot), U8(2),
B(Star5),
B(LdaFalse),
B(Star6),
B(Mov), R(0), R(4),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(4), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(4), U8(2),
B(Return),
]
constant pool: [
@ -614,7 +594,7 @@ constant pool: [
SCOPE_INFO_TYPE,
]
handlers: [
[14, 180, 180],
[14, 176, 176],
[46, 92, 98],
[111, 130, 132],
]

View File

@ -639,7 +639,7 @@ snippet: "
"
frame size: 16
parameter count: 2
bytecode array length: 173
bytecode array length: 169
bytecodes: [
B(Mov), R(closure), R(5),
B(Mov), R(this), R(6),
@ -708,10 +708,8 @@ bytecodes: [
B(ReThrow),
B(LdaUndefined),
B(Star7),
B(LdaFalse),
B(Star8),
B(Mov), R(0), R(6),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(6), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(6), U8(2),
/* 60 S> */ B(Return),
B(Star6),
B(CreateCatchContext), R(6), U8(4),
@ -722,10 +720,8 @@ bytecodes: [
B(PushContext), R(6),
B(LdaImmutableCurrentContextSlot), U8(2),
B(Star8),
B(LdaFalse),
B(Star9),
B(Mov), R(0), R(7),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(7), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(7), U8(2),
B(Return),
]
constant pool: [
@ -736,7 +732,7 @@ constant pool: [
SCOPE_INFO_TYPE,
]
handlers: [
[14, 149, 149],
[14, 147, 147],
[36, 77, 83],
[96, 115, 117],
]
@ -750,7 +746,7 @@ snippet: "
"
frame size: 15
parameter count: 2
bytecode array length: 207
bytecode array length: 203
bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(1),
B(Mov), R(closure), R(4),
@ -832,10 +828,8 @@ bytecodes: [
B(ReThrow),
B(LdaUndefined),
B(Star6),
B(LdaTrue),
B(Star7),
B(Mov), R(0), R(5),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(5), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(5), U8(2),
/* 54 S> */ B(Return),
B(Star5),
B(CreateCatchContext), R(5), U8(5),
@ -846,10 +840,8 @@ bytecodes: [
B(PushContext), R(5),
B(LdaImmutableCurrentContextSlot), U8(2),
B(Star7),
B(LdaTrue),
B(Star8),
B(Mov), R(0), R(6),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(6), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(6), U8(2),
B(Return),
]
constant pool: [
@ -861,7 +853,7 @@ constant pool: [
SCOPE_INFO_TYPE,
]
handlers: [
[18, 183, 183],
[18, 181, 181],
[40, 111, 117],
[130, 149, 151],
]

View File

@ -355,9 +355,9 @@ snippet: "
}
f();
"
frame size: 8
frame size: 7
parameter count: 1
bytecode array length: 70
bytecode array length: 66
bytecodes: [
B(Mov), R(closure), R(3),
B(Mov), R(this), R(4),
@ -376,10 +376,8 @@ bytecodes: [
/* 23 E> */ B(JumpLoop), U8(15), I8(0),
B(LdaUndefined),
B(Star5),
B(LdaFalse),
B(Star6),
B(Mov), R(0), R(4),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(4), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(4), U8(2),
/* 67 S> */ B(Return),
B(Star4),
B(CreateCatchContext), R(4), U8(0),
@ -390,17 +388,15 @@ bytecodes: [
B(PushContext), R(4),
B(LdaImmutableCurrentContextSlot), U8(2),
B(Star6),
B(LdaFalse),
B(Star7),
B(Mov), R(0), R(5),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(5), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(5), U8(2),
B(Return),
]
constant pool: [
SCOPE_INFO_TYPE,
]
handlers: [
[14, 46, 46],
[14, 44, 44],
]
---
@ -410,9 +406,9 @@ snippet: "
}
f();
"
frame size: 7
frame size: 6
parameter count: 1
bytecode array length: 104
bytecode array length: 100
bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(1),
B(Mov), R(closure), R(2),
@ -444,10 +440,8 @@ bytecodes: [
/* 23 E> */ B(JumpLoop), U8(45), I8(0),
B(LdaUndefined),
B(Star4),
B(LdaTrue),
B(Star5),
B(Mov), R(0), R(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(3), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(3), U8(2),
/* 61 S> */ B(Return),
B(Star3),
B(CreateCatchContext), R(3), U8(1),
@ -458,10 +452,8 @@ bytecodes: [
B(PushContext), R(3),
B(LdaImmutableCurrentContextSlot), U8(2),
B(Star5),
B(LdaTrue),
B(Star6),
B(Mov), R(0), R(4),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(4), U8(3),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(4), U8(2),
B(Return),
]
constant pool: [
@ -469,6 +461,6 @@ constant pool: [
SCOPE_INFO_TYPE,
]
handlers: [
[18, 80, 80],
[18, 78, 78],
]