From 41f0c0bac8b44472c73ac91f2e7d64e950b9365f Mon Sep 17 00:00:00 2001 From: Benedikt Meurer Date: Thu, 13 Jan 2022 08:58:31 +0100 Subject: [PATCH] [debug] Simplify async function instrumentation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Maya Lekova Reviewed-by: Simon Zünd Commit-Queue: Benedikt Meurer Cr-Commit-Position: refs/heads/main@{#78599} --- src/builtins/builtins-async-function-gen.cc | 25 ++------ src/builtins/builtins-definitions.h | 4 +- src/compiler/js-operator.cc | 4 +- src/compiler/verifier.cc | 2 - src/debug/interface-types.h | 5 +- src/execution/isolate.cc | 54 +++++++++++++---- src/execution/isolate.h | 9 ++- src/inspector/v8-debugger.cc | 9 +-- src/interpreter/bytecode-generator.cc | 4 +- src/interpreter/interpreter-intrinsics.h | 4 +- src/parsing/parser.cc | 2 - src/runtime/runtime-debug.cc | 28 ++------- src/runtime/runtime-promise.cc | 9 +-- src/runtime/runtime.h | 5 +- .../bytecode_expectations/AsyncModules.golden | 56 +++++++---------- .../bytecode_expectations/ForAwaitOf.golden | 60 +++++++------------ .../bytecode_expectations/ForOfLoop.golden | 24 +++----- .../StandardForLoop.golden | 28 ++++----- 18 files changed, 133 insertions(+), 199 deletions(-) diff --git a/src/builtins/builtins-async-function-gen.cc b/src/builtins/builtins-async-function-gen.cc index 1373e66397..f402e3b286 100644 --- a/src/builtins/builtins-async-function-gen.cc +++ b/src/builtins/builtins-async-function-gen.cc @@ -175,7 +175,6 @@ TF_BUILTIN(AsyncFunctionReject, AsyncFunctionBuiltinsAssembler) { auto async_function_object = Parameter(Descriptor::kAsyncFunctionObject); auto reason = Parameter(Descriptor::kReason); - auto can_suspend = Parameter(Descriptor::kCanSuspend); auto context = Parameter(Descriptor::kContext); TNode promise = LoadObjectField( 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(Descriptor::kAsyncFunctionObject); auto value = Parameter(Descriptor::kValue); - auto can_suspend = Parameter(Descriptor::kCanSuspend); auto context = Parameter(Descriptor::kContext); TNode promise = LoadObjectField( 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(Descriptor::kValue); auto context = Parameter(Descriptor::kContext); - TNode outer_promise = LoadObjectField( - 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 on_resolve_sfi = AsyncFunctionAwaitResolveSharedFunConstant(); TNode on_reject_sfi = AsyncFunctionAwaitRejectSharedFunConstant(); + TNode outer_promise = LoadObjectField( + 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 diff --git a/src/builtins/builtins-definitions.h b/src/builtins/builtins-definitions.h index 638329e56f..27f4142cfc 100644 --- a/src/builtins/builtins-definitions.h +++ b/src/builtins/builtins-definitions.h @@ -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) \ diff --git a/src/compiler/js-operator.cc b/src/compiler/js-operator.cc index a4c6e149bc..bcb9dda671 100644 --- a/src/compiler/js-operator.cc +++ b/src/compiler/js-operator.cc @@ -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) \ diff --git a/src/compiler/verifier.cc b/src/compiler/verifier.cc index 3947e08eb0..47de79dd22 100644 --- a/src/compiler/verifier.cc +++ b/src/compiler/verifier.cc @@ -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: diff --git a/src/debug/interface-types.h b/src/debug/interface-types.h index 8c8d4bf2ad..1737d5e4f1 100644 --- a/src/debug/interface-types.h +++ b/src/debug/interface-types.h @@ -46,13 +46,12 @@ class V8_EXPORT_PRIVATE Location { }; enum DebugAsyncActionType { + kDebugAwait, kDebugPromiseThen, kDebugPromiseCatch, kDebugPromiseFinally, kDebugWillHandle, - kDebugDidHandle, - kAsyncFunctionSuspended, - kAsyncFunctionFinished + kDebugDidHandle }; enum BreakLocationType { diff --git a/src/execution/isolate.cc b/src/execution/isolate.cc index 47f3d22225..bd7b312016 100644 --- a/src/execution/isolate.cc +++ b/src/execution/isolate.cc @@ -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 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 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 promise, + Handle 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 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 promise) { + if (debug()->is_active()) { + PopPromise(); } - async_event_delegate_->AsyncEventOccurred(event, promise->async_task_id(), - false); } void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) { diff --git a/src/execution/isolate.h b/src/execution/isolate.h index a4c0ce5ab0..73a2ebebc5 100644 --- a/src/execution/isolate.h +++ b/src/execution/isolate.h @@ -948,8 +948,13 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory { async_event_delegate_ = delegate; PromiseHookStateUpdated(); } - void OnAsyncFunctionStateChanged(Handle promise, - debug::DebugAsyncActionType); + + // Async function instrumentation support. + void OnAsyncFunctionEntered(Handle promise); + void OnAsyncFunctionSuspended(Handle promise, + Handle parent); + void OnAsyncFunctionResumed(Handle promise); + void OnAsyncFunctionFinished(Handle promise); // Re-throw an exception. This involves no error reporting since error // reporting was handled when the exception was thrown originally. diff --git a/src/inspector/v8-debugger.cc b/src/inspector/v8-debugger.cc index 73454ce5c1..d1c6a45b08 100644 --- a/src/inspector/v8-debugger.cc +++ b/src/inspector/v8-debugger.cc @@ -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 stack(stackIt->second); @@ -628,9 +626,6 @@ void V8Debugger::AsyncEventOccurred(v8::debug::DebugAsyncActionType type, } break; } - case v8::debug::kAsyncFunctionFinished: - asyncTaskCanceledForStack(task); - break; } } diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc index 187ff64f0a..63b449c04a 100644 --- a/src/interpreter/bytecode-generator.cc +++ b/src/interpreter/bytecode-generator.cc @@ -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); } diff --git a/src/interpreter/interpreter-intrinsics.h b/src/interpreter/interpreter-intrinsics.h index 6b82d33154..77ef0c3ee4 100644 --- a/src/interpreter/interpreter-intrinsics.h +++ b/src/interpreter/interpreter-intrinsics.h @@ -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) \ diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc index c84b05ff8e..1531760a52 100644 --- a/src/parsing/parser.cc +++ b/src/parsing/parser.cc @@ -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); } diff --git a/src/runtime/runtime-debug.cc b/src/runtime/runtime-debug.cc index 38f3ef7d90..0a8b7bfacb 100644 --- a/src/runtime/runtime-debug.cc +++ b/src/runtime/runtime-debug.cc @@ -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; } diff --git a/src/runtime/runtime-promise.cc b/src/runtime/runtime-promise.cc index 516a597e56..caa78051f3 100644 --- a/src/runtime/runtime-promise.cc +++ b/src/runtime/runtime-promise.cc @@ -133,14 +133,7 @@ Handle AwaitPromisesInitCommon(Isolate* isolate, // hook for the throwaway promise (passing the {promise} as its // parent). Handle 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 diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 4dd14e697f..d1f35dcbaf 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -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) \ diff --git a/test/cctest/interpreter/bytecode_expectations/AsyncModules.golden b/test/cctest/interpreter/bytecode_expectations/AsyncModules.golden index a7a0a03492..3bc4300e0b 100644 --- a/test/cctest/interpreter/bytecode_expectations/AsyncModules.golden +++ b/test/cctest/interpreter/bytecode_expectations/AsyncModules.golden @@ -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], ] diff --git a/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden b/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden index a11a4aa405..35c48e2f4a 100644 --- a/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden +++ b/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden @@ -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], ] diff --git a/test/cctest/interpreter/bytecode_expectations/ForOfLoop.golden b/test/cctest/interpreter/bytecode_expectations/ForOfLoop.golden index 6dbdbe157f..f5e8496d93 100644 --- a/test/cctest/interpreter/bytecode_expectations/ForOfLoop.golden +++ b/test/cctest/interpreter/bytecode_expectations/ForOfLoop.golden @@ -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], ] diff --git a/test/cctest/interpreter/bytecode_expectations/StandardForLoop.golden b/test/cctest/interpreter/bytecode_expectations/StandardForLoop.golden index c62a6489e7..fb2d478489 100644 --- a/test/cctest/interpreter/bytecode_expectations/StandardForLoop.golden +++ b/test/cctest/interpreter/bytecode_expectations/StandardForLoop.golden @@ -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], ]