ef8c18613a
This is a reland of 21c0d77e15
Original change's description:
> [async] Optimize await and AsyncFromSyncIterator
>
> Simplify the promise wrapping in await and
> %AsyncFromSyncIteratorPrototype%.next/return/throw to reuse the PromiseResolve
> primitive. Now await takes 1 tick instead of 3 on the microtask queue.
>
> Change-Id: I7e99b8689eb8fcb09c48915b11c1e06684dc0f1a
> Reviewed-on: https://chromium-review.googlesource.com/1090272
> Commit-Queue: Maya Lekova <mslekova@chromium.org>
> Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org>
> Reviewed-by: Aleksey Kozyatinskiy <kozyatinskiy@chromium.org>
> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
> Reviewed-by: Mathias Bynens <mathias@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#53853}
Cq-Include-Trybots: luci.chromium.try:linux_chromium_headless_rel;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: Ifa5b2fb8b2fb84b635b2dc1b6455d6aaf154cbfd
Reviewed-on: https://chromium-review.googlesource.com/1106977
Commit-Queue: Maya Lekova <mslekova@chromium.org>
Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53900}
188 lines
4.7 KiB
JavaScript
188 lines
4.7 KiB
JavaScript
// Copyright 2018 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// Flags: --harmony-await-optimization
|
|
|
|
let {session, contextGroup, Protocol} =
|
|
InspectorTest.start('stepOut async function');
|
|
|
|
session.setupScriptMap();
|
|
|
|
Protocol.Runtime.enable();
|
|
|
|
InspectorTest.runAsyncTestSuite([
|
|
async function testTrivial() {
|
|
InspectorTest.log('Check that we have proper async stack at return');
|
|
contextGroup.addInlineScript(`
|
|
async function test() {
|
|
await Promise.resolve();
|
|
await foo();
|
|
}
|
|
|
|
async function foo() {
|
|
await Promise.resolve();
|
|
await bar();
|
|
}
|
|
|
|
async function bar() {
|
|
await Promise.resolve();
|
|
debugger;
|
|
}`, 'testTrivial.js');
|
|
await runTestAndStepAction('stepOut');
|
|
},
|
|
|
|
async function testStepOutPrecision() {
|
|
InspectorTest.log('Check that stepOut go to resumed outer generator');
|
|
contextGroup.addInlineScript(`
|
|
function wait() {
|
|
return new Promise(resolve => setTimeout(resolve, 0));
|
|
}
|
|
function floodWithTimeouts(a) {
|
|
if (!a.stop)
|
|
setTimeout(floodWithTimeouts.bind(this, a), 0);
|
|
}
|
|
|
|
async function test() {
|
|
let a = {};
|
|
floodWithTimeouts(a)
|
|
await wait();
|
|
await foo();
|
|
await wait();
|
|
a.stop = true;
|
|
}
|
|
|
|
async function foo() {
|
|
await Promise.resolve();
|
|
await bar();
|
|
await wait();
|
|
}
|
|
|
|
async function bar() {
|
|
await Promise.resolve();
|
|
debugger;
|
|
await wait();
|
|
}`, 'testStepOutPrecision.js');
|
|
await runTestAndStepAction('stepOut');
|
|
},
|
|
|
|
async function testStepIntoAtReturn() {
|
|
InspectorTest.log('Check that stepInto at return go to resumed outer generator');
|
|
contextGroup.addInlineScript(`
|
|
function wait() {
|
|
return new Promise(resolve => setTimeout(resolve, 0));
|
|
}
|
|
function floodWithTimeouts(a) {
|
|
if (!a.stop)
|
|
setTimeout(floodWithTimeouts.bind(this, a), 0);
|
|
}
|
|
|
|
async function test() {
|
|
let a = {};
|
|
floodWithTimeouts(a)
|
|
await wait();
|
|
await foo();
|
|
a.stop = true;
|
|
}
|
|
|
|
async function foo() {
|
|
await Promise.resolve();
|
|
await bar();
|
|
}
|
|
|
|
async function bar() {
|
|
await Promise.resolve();
|
|
debugger;
|
|
}`, 'testStepIntoAtReturn.js');
|
|
await runTestAndStepAction('stepInto');
|
|
},
|
|
|
|
async function testStepOverAtReturn() {
|
|
InspectorTest.log('Check that stepOver at return go to resumed outer generator');
|
|
contextGroup.addInlineScript(`
|
|
function wait() {
|
|
return new Promise(resolve => setTimeout(resolve, 0));
|
|
}
|
|
function floodWithTimeouts(a) {
|
|
if (!a.stop)
|
|
setTimeout(floodWithTimeouts.bind(this, a), 0);
|
|
}
|
|
|
|
async function test() {
|
|
let a = {};
|
|
floodWithTimeouts(a)
|
|
await wait();
|
|
await foo();
|
|
a.stop = true;
|
|
}
|
|
|
|
async function foo() {
|
|
await Promise.resolve();
|
|
await bar();
|
|
}
|
|
|
|
async function bar() {
|
|
await Promise.resolve();
|
|
debugger;
|
|
}`, 'testStepIntoAtReturn.js');
|
|
await runTestAndStepAction('stepOver');
|
|
},
|
|
|
|
async function testStepOutFromNotAwaitedCall() {
|
|
InspectorTest.log('Checks stepOut from not awaited call');
|
|
contextGroup.addInlineScript(`
|
|
function wait() {
|
|
return new Promise(resolve => setTimeout(resolve, 0));
|
|
}
|
|
function floodWithTimeouts(a) {
|
|
if (!a.stop)
|
|
setTimeout(floodWithTimeouts.bind(this, a), 0);
|
|
}
|
|
|
|
async function test() {
|
|
let a = {};
|
|
floodWithTimeouts(a)
|
|
await wait();
|
|
await foo();
|
|
a.stop = true;
|
|
}
|
|
|
|
async function foo() {
|
|
let a = {};
|
|
floodWithTimeouts(a);
|
|
await Promise.resolve();
|
|
bar();
|
|
a.stop = true;
|
|
}
|
|
|
|
async function bar() {
|
|
await Promise.resolve();
|
|
debugger;
|
|
}`, 'testStepIntoAtReturn.js');
|
|
await runTestAndStepAction('stepOut');
|
|
}
|
|
|
|
]);
|
|
|
|
async function runTestAndStepAction(action) {
|
|
Protocol.Debugger.enable();
|
|
Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128});
|
|
let finished =
|
|
Protocol.Runtime.evaluate({expression: 'test()', awaitPromise: true})
|
|
.then(() => false);
|
|
while (true) {
|
|
const r = await Promise.race([finished, waitPauseAndDumpStack()]);
|
|
if (!r) break;
|
|
Protocol.Debugger[action]();
|
|
}
|
|
await Protocol.Debugger.disable();
|
|
}
|
|
|
|
async function waitPauseAndDumpStack() {
|
|
const {params} = await Protocol.Debugger.oncePaused();
|
|
session.logCallFrames(params.callFrames);
|
|
session.logAsyncStackTrace(params.asyncStackTrace);
|
|
InspectorTest.log('');
|
|
return true;
|
|
}
|