mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +00:00
LibJS: Stop having AsyncFunctionDriverWrapper leak itself
Some checks are pending
CI / Lagom (false, FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (true, NO_FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Push notes / build (push) Waiting to run
Some checks are pending
CI / Lagom (false, FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (true, NO_FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Push notes / build (push) Waiting to run
Async functions whose promise is never resolved were leaking, since they had a strong root JS::Handle on themselves. This doesn't appear to actually be necessary, since the wrapper will be kept alive as long as it's reachable (and if it's not reachable, nobody is going to resolve/reject the promise either). This fixes the vast majority of leaks on Speedometer, bringing memory usage at the end of a full run from ~12 GiB to ~3 GiB.
This commit is contained in:
parent
10724a7cb3
commit
b6a5b7e186
Notes:
github-actions[bot]
2024-11-12 16:39:22 +00:00
Author: https://github.com/awesomekling Commit: https://github.com/LadybirdBrowser/ladybird/commit/b6a5b7e1862 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2301 Reviewed-by: https://github.com/Hendiadyoin1
2 changed files with 1 additions and 11 deletions
|
@ -20,8 +20,7 @@ JS_DEFINE_ALLOCATOR(AsyncFunctionDriverWrapper);
|
|||
NonnullGCPtr<Promise> AsyncFunctionDriverWrapper::create(Realm& realm, GeneratorObject* generator_object)
|
||||
{
|
||||
auto top_level_promise = Promise::create(realm);
|
||||
// Note: This generates a handle to itself, which it clears upon completing its execution
|
||||
// The top_level_promise is also kept alive by this Wrapper
|
||||
// Note: The top_level_promise is also kept alive by this Wrapper
|
||||
auto wrapper = realm.heap().allocate<AsyncFunctionDriverWrapper>(realm, realm, *generator_object, *top_level_promise);
|
||||
// Prime the generator:
|
||||
// This runs until the first `await value;`
|
||||
|
@ -34,7 +33,6 @@ AsyncFunctionDriverWrapper::AsyncFunctionDriverWrapper(Realm& realm, NonnullGCPt
|
|||
: Promise(realm.intrinsics().promise_prototype())
|
||||
, m_generator_object(generator_object)
|
||||
, m_top_level_promise(top_level_promise)
|
||||
, m_self_handle(make_handle(*this))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -140,10 +138,6 @@ void AsyncFunctionDriverWrapper::continue_async_execution(VM& vm, Value value, b
|
|||
auto promise_value = TRY(result.get(vm, vm.names.value));
|
||||
|
||||
if (TRY(result.get(vm, vm.names.done)).to_boolean()) {
|
||||
|
||||
// We should not execute anymore, so we are safe to allow ourselves to be GC'd.
|
||||
m_self_handle = {};
|
||||
|
||||
// When returning a promise, we need to unwrap it.
|
||||
if (promise_value.is_object() && is<Promise>(promise_value.as_object())) {
|
||||
auto& returned_promise = static_cast<Promise&>(promise_value.as_object());
|
||||
|
@ -175,9 +169,6 @@ void AsyncFunctionDriverWrapper::continue_async_execution(VM& vm, Value value, b
|
|||
|
||||
if (result.is_throw_completion()) {
|
||||
m_top_level_promise->reject(result.throw_completion().value().value_or(js_undefined()));
|
||||
|
||||
// We should not execute anymore, so we are safe to allow our selfs to be GC'd
|
||||
m_self_handle = {};
|
||||
}
|
||||
|
||||
// For the initial execution, the execution context will be popped for us later on by ECMAScriptFunctionObject.
|
||||
|
|
|
@ -38,7 +38,6 @@ private:
|
|||
NonnullGCPtr<GeneratorObject> m_generator_object;
|
||||
NonnullGCPtr<Promise> m_top_level_promise;
|
||||
GCPtr<Promise> m_current_promise { nullptr };
|
||||
Handle<AsyncFunctionDriverWrapper> m_self_handle;
|
||||
OwnPtr<ExecutionContext> m_suspended_execution_context;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue