mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-26 20:23:09 +00:00
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.
44 lines
1.3 KiB
C++
44 lines
1.3 KiB
C++
/*
|
|
* Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <LibJS/Bytecode/Interpreter.h>
|
|
#include <LibJS/Runtime/ECMAScriptFunctionObject.h>
|
|
#include <LibJS/Runtime/GeneratorObject.h>
|
|
#include <LibJS/Runtime/Object.h>
|
|
#include <LibJS/Runtime/Promise.h>
|
|
|
|
namespace JS {
|
|
|
|
class AsyncFunctionDriverWrapper final : public Promise {
|
|
JS_OBJECT(AsyncFunctionDriverWrapper, Promise);
|
|
JS_DECLARE_ALLOCATOR(AsyncFunctionDriverWrapper);
|
|
|
|
public:
|
|
enum class IsInitialExecution {
|
|
No,
|
|
Yes,
|
|
};
|
|
|
|
[[nodiscard]] static NonnullGCPtr<Promise> create(Realm&, GeneratorObject*);
|
|
|
|
virtual ~AsyncFunctionDriverWrapper() override = default;
|
|
void visit_edges(Cell::Visitor&) override;
|
|
|
|
void continue_async_execution(VM&, Value, bool is_successful, IsInitialExecution is_initial_execution = IsInitialExecution::No);
|
|
|
|
private:
|
|
AsyncFunctionDriverWrapper(Realm&, NonnullGCPtr<GeneratorObject>, NonnullGCPtr<Promise> top_level_promise);
|
|
ThrowCompletionOr<void> await(Value);
|
|
|
|
NonnullGCPtr<GeneratorObject> m_generator_object;
|
|
NonnullGCPtr<Promise> m_top_level_promise;
|
|
GCPtr<Promise> m_current_promise { nullptr };
|
|
OwnPtr<ExecutionContext> m_suspended_execution_context;
|
|
};
|
|
|
|
}
|