[JSC] do not reference AwaitExpression Promises in async function Promise chain
authorcaitp@igalia.com <caitp@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 15 Nov 2016 04:28:45 +0000 (04:28 +0000)
committercaitp@igalia.com <caitp@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 15 Nov 2016 04:28:45 +0000 (04:28 +0000)
commit651a91bcbe47e19ff7e9e4eb7053b01034c46b98
tree61508da5d72ba2c0800ce942dbd84fcc2053e1b3
parent09a99f40ebcde1dd897613b9a3f3770b7c208e13
[JSC] do not reference AwaitExpression Promises in async function Promise chain
https://bugs.webkit.org/show_bug.cgi?id=164753

Reviewed by Yusuke Suzuki.

JSTests:

* asyncFunctionTests.yaml:
* stress/async-await-long-loop.js: Added.
(shouldBe):
(async.longLoop):
* stress/async-await-throw-loop.js: Added.
(shouldBe):
(async.thrower):
(async.throwLoop):

Source/JavaScriptCore:

Previously, long-running async functions which contained many AwaitExpressions
would allocate and retain references to intermediate Promise objects for each `await`,
resulting in a memory leak.

To mitigate this leak, a reference to the original Promise (and its resolve and reject
functions) associated with the async function are kept, and passed to each call to
@asyncFunctionResume, while intermediate Promises are discarded. This is done by adding
a new Register to the BytecodeGenerator to hold the PromiseCapability object associated
with an async function wrapper. The capability is used to reject the Promise if an
exception is thrown during parameter initialization, and is used to store the resulting
value once the async function has terminated.

* builtins/AsyncFunctionPrototype.js:
(globalPrivate.asyncFunctionResume):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::promiseCapabilityRegister):
* bytecompiler/NodesCodegen.cpp:
(JSC::FunctionNode::emitBytecode):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208726 268f45cc-cd09-0410-ab3c-d52691b4dbfc
JSTests/ChangeLog
JSTests/asyncFunctionTests.yaml
JSTests/stress/async-await-long-loop.js [new file with mode: 0644]
JSTests/stress/async-await-throw-loop.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/builtins/AsyncFunctionPrototype.js
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp