LibGC+Everywhere: Factor out a LibGC from LibJS

Resulting in a massive rename across almost everywhere! Alongside the
namespace change, we now have the following names:

 * JS::NonnullGCPtr -> GC::Ref
 * JS::GCPtr -> GC::Ptr
 * JS::HeapFunction -> GC::Function
 * JS::CellImpl -> GC::Cell
 * JS::Handle -> GC::Root
This commit is contained in:
Shannon Booth 2024-11-15 04:01:23 +13:00 committed by Andreas Kling
parent ce23efc5f6
commit f87041bf3a
Notes: github-actions[bot] 2024-11-15 13:50:17 +00:00
1722 changed files with 9939 additions and 9906 deletions

View file

@ -25,7 +25,7 @@
namespace Web::HTML {
JS_DEFINE_ALLOCATOR(EventLoop);
GC_DEFINE_ALLOCATOR(EventLoop);
EventLoop::EventLoop(Type type)
: m_type(type)
@ -33,7 +33,7 @@ EventLoop::EventLoop(Type type)
m_task_queue = heap().allocate<TaskQueue>(*this);
m_microtask_queue = heap().allocate<TaskQueue>(*this);
m_rendering_task_function = JS::create_heap_function(heap(), [this] {
m_rendering_task_function = GC::create_function(heap(), [this] {
update_the_rendering();
});
}
@ -54,7 +54,7 @@ void EventLoop::visit_edges(Visitor& visitor)
void EventLoop::schedule()
{
if (!m_system_event_loop_timer) {
m_system_event_loop_timer = Platform::Timer::create_single_shot(heap(), 0, JS::create_heap_function(heap(), [this] {
m_system_event_loop_timer = Platform::Timer::create_single_shot(heap(), 0, GC::create_function(heap(), [this] {
process();
}));
}
@ -69,7 +69,7 @@ EventLoop& main_thread_event_loop()
}
// https://html.spec.whatwg.org/multipage/webappapis.html#spin-the-event-loop
void EventLoop::spin_until(JS::NonnullGCPtr<JS::HeapFunction<bool()>> goal_condition)
void EventLoop::spin_until(GC::Ref<GC::Function<bool()>> goal_condition)
{
// FIXME: The spec wants us to do the rest of the enclosing algorithm (i.e. the caller)
// in the context of the currently running task on entry. That's not possible with this implementation.
@ -92,7 +92,7 @@ void EventLoop::spin_until(JS::NonnullGCPtr<JS::HeapFunction<bool()>> goal_condi
// 2. Perform any steps that appear after this spin the event loop instance in the original algorithm.
// NOTE: This is achieved by returning from the function.
Platform::EventLoopPlugin::the().spin_until(JS::create_heap_function(heap(), [this, goal_condition] {
Platform::EventLoopPlugin::the().spin_until(GC::create_function(heap(), [this, goal_condition] {
if (goal_condition->function()())
return true;
if (m_task_queue->has_runnable_tasks()) {
@ -109,7 +109,7 @@ void EventLoop::spin_until(JS::NonnullGCPtr<JS::HeapFunction<bool()>> goal_condi
// NOTE: This is achieved by returning from the function.
}
void EventLoop::spin_processing_tasks_with_source_until(Task::Source source, JS::NonnullGCPtr<JS::HeapFunction<bool()>> goal_condition)
void EventLoop::spin_processing_tasks_with_source_until(Task::Source source, GC::Ref<GC::Function<bool()>> goal_condition)
{
auto& vm = this->vm();
vm.save_execution_context_stack();
@ -120,7 +120,7 @@ void EventLoop::spin_processing_tasks_with_source_until(Task::Source source, JS:
// NOTE: HTML event loop processing steps could run a task with arbitrary source
m_skip_event_loop_processing_steps = true;
Platform::EventLoopPlugin::the().spin_until(JS::create_heap_function(heap(), [this, source, goal_condition] {
Platform::EventLoopPlugin::the().spin_until(GC::create_function(heap(), [this, source, goal_condition] {
if (goal_condition->function()())
return true;
if (m_task_queue->has_runnable_tasks()) {
@ -154,7 +154,7 @@ void EventLoop::process()
return;
// 1. Let oldestTask and taskStartTime be null.
JS::GCPtr<Task> oldest_task;
GC::Ptr<Task> oldest_task;
[[maybe_unused]] double task_start_time = 0;
// 2. If the event loop has a task queue with at least one runnable task, then:
@ -404,7 +404,7 @@ void EventLoop::update_the_rendering()
}
// https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task
TaskID queue_a_task(HTML::Task::Source source, JS::GCPtr<EventLoop> event_loop, JS::GCPtr<DOM::Document> document, JS::NonnullGCPtr<JS::HeapFunction<void()>> steps)
TaskID queue_a_task(HTML::Task::Source source, GC::Ptr<EventLoop> event_loop, GC::Ptr<DOM::Document> document, GC::Ref<GC::Function<void()>> steps)
{
// 1. If event loop was not given, set event loop to the implied event loop.
if (!event_loop)
@ -429,7 +429,7 @@ TaskID queue_a_task(HTML::Task::Source source, JS::GCPtr<EventLoop> event_loop,
}
// https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-global-task
TaskID queue_global_task(HTML::Task::Source source, JS::Object& global_object, JS::NonnullGCPtr<JS::HeapFunction<void()>> steps)
TaskID queue_global_task(HTML::Task::Source source, JS::Object& global_object, GC::Ref<GC::Function<void()>> steps)
{
// 1. Let event loop be global's relevant agent's event loop.
auto& global_custom_data = verify_cast<Bindings::WebEngineCustomData>(*global_object.vm().custom_data());
@ -447,7 +447,7 @@ TaskID queue_global_task(HTML::Task::Source source, JS::Object& global_object, J
}
// https://html.spec.whatwg.org/#queue-a-microtask
void queue_a_microtask(DOM::Document const* document, JS::NonnullGCPtr<JS::HeapFunction<void()>> steps)
void queue_a_microtask(DOM::Document const* document, GC::Ref<GC::Function<void()>> steps)
{
// 1. If event loop was not given, set event loop to the implied event loop.
auto& event_loop = HTML::main_thread_event_loop();
@ -515,14 +515,14 @@ void EventLoop::perform_a_microtask_checkpoint()
// FIXME: 8. Record timing info for microtask checkpoint.
}
Vector<JS::Handle<DOM::Document>> EventLoop::documents_in_this_event_loop() const
Vector<GC::Root<DOM::Document>> EventLoop::documents_in_this_event_loop() const
{
Vector<JS::Handle<DOM::Document>> documents;
Vector<GC::Root<DOM::Document>> documents;
for (auto& document : m_documents) {
VERIFY(document);
if (document->is_decoded_svg())
continue;
documents.append(JS::make_handle(*document));
documents.append(GC::make_root(*document));
}
return documents;
}
@ -565,12 +565,12 @@ void EventLoop::unregister_environment_settings_object(Badge<EnvironmentSettings
}
// https://html.spec.whatwg.org/multipage/webappapis.html#same-loop-windows
Vector<JS::Handle<HTML::Window>> EventLoop::same_loop_windows() const
Vector<GC::Root<HTML::Window>> EventLoop::same_loop_windows() const
{
Vector<JS::Handle<HTML::Window>> windows;
Vector<GC::Root<HTML::Window>> windows;
for (auto& document : documents_in_this_event_loop()) {
if (document->is_fully_active())
windows.append(JS::make_handle(document->window()));
windows.append(GC::make_root(document->window()));
}
return windows;
}

View file

@ -10,16 +10,16 @@
#include <AK/Noncopyable.h>
#include <AK/WeakPtr.h>
#include <LibCore/Forward.h>
#include <LibGC/Ptr.h>
#include <LibJS/Forward.h>
#include <LibJS/Heap/GCPtr.h>
#include <LibWeb/HTML/EventLoop/TaskQueue.h>
#include <LibWeb/HighResolutionTime/DOMHighResTimeStamp.h>
namespace Web::HTML {
class EventLoop : public JS::Cell {
JS_CELL(EventLoop, JS::Cell);
JS_DECLARE_ALLOCATOR(EventLoop);
GC_CELL(EventLoop, JS::Cell);
GC_DECLARE_ALLOCATOR(EventLoop);
struct PauseHandle {
PauseHandle(EventLoop&, JS::Object const& global, HighResolutionTime::DOMHighResTimeStamp);
@ -28,8 +28,8 @@ class EventLoop : public JS::Cell {
AK_MAKE_NONCOPYABLE(PauseHandle);
AK_MAKE_NONMOVABLE(PauseHandle);
JS::NonnullGCPtr<EventLoop> event_loop;
JS::NonnullGCPtr<JS::Object const> global;
GC::Ref<EventLoop> event_loop;
GC::Ref<JS::Object const> global;
HighResolutionTime::DOMHighResTimeStamp const time_before_pause;
};
@ -53,8 +53,8 @@ public:
TaskQueue& microtask_queue() { return *m_microtask_queue; }
TaskQueue const& microtask_queue() const { return *m_microtask_queue; }
void spin_until(JS::NonnullGCPtr<JS::HeapFunction<bool()>> goal_condition);
void spin_processing_tasks_with_source_until(Task::Source, JS::NonnullGCPtr<JS::HeapFunction<bool()>> goal_condition);
void spin_until(GC::Ref<GC::Function<bool()>> goal_condition);
void spin_processing_tasks_with_source_until(Task::Source, GC::Ref<GC::Function<bool()>> goal_condition);
void process();
void queue_task_to_update_the_rendering();
@ -72,9 +72,9 @@ public:
void register_document(Badge<DOM::Document>, DOM::Document&);
void unregister_document(Badge<DOM::Document>, DOM::Document&);
Vector<JS::Handle<DOM::Document>> documents_in_this_event_loop() const;
Vector<GC::Root<DOM::Document>> documents_in_this_event_loop() const;
Vector<JS::Handle<HTML::Window>> same_loop_windows() const;
Vector<GC::Root<HTML::Window>> same_loop_windows() const;
void push_onto_backup_incumbent_realm_stack(JS::Realm&);
void pop_backup_incumbent_realm_stack();
@ -99,18 +99,18 @@ private:
Type m_type { Type::Window };
JS::GCPtr<TaskQueue> m_task_queue;
JS::GCPtr<TaskQueue> m_microtask_queue;
GC::Ptr<TaskQueue> m_task_queue;
GC::Ptr<TaskQueue> m_microtask_queue;
// https://html.spec.whatwg.org/multipage/webappapis.html#currently-running-task
JS::GCPtr<Task> m_currently_running_task { nullptr };
GC::Ptr<Task> m_currently_running_task { nullptr };
// https://html.spec.whatwg.org/multipage/webappapis.html#last-render-opportunity-time
double m_last_render_opportunity_time { 0 };
// https://html.spec.whatwg.org/multipage/webappapis.html#last-idle-period-start-time
double m_last_idle_period_start_time { 0 };
JS::GCPtr<Platform::Timer> m_system_event_loop_timer;
GC::Ptr<Platform::Timer> m_system_event_loop_timer;
// https://html.spec.whatwg.org/#performing-a-microtask-checkpoint
bool m_performing_a_microtask_checkpoint { false };
@ -123,7 +123,7 @@ private:
// https://html.spec.whatwg.org/multipage/webappapis.html#backup-incumbent-settings-object-stack
// https://whatpr.org/html/9893/webappapis.html#backup-incumbent-realm-stack
Vector<JS::NonnullGCPtr<JS::Realm>> m_backup_incumbent_realm_stack;
Vector<GC::Ref<JS::Realm>> m_backup_incumbent_realm_stack;
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#termination-nesting-level
size_t m_termination_nesting_level { 0 };
@ -134,13 +134,13 @@ private:
bool m_is_running_rendering_task { false };
JS::GCPtr<JS::HeapFunction<void()>> m_rendering_task_function;
GC::Ptr<GC::Function<void()>> m_rendering_task_function;
};
EventLoop& main_thread_event_loop();
TaskID queue_a_task(HTML::Task::Source, JS::GCPtr<EventLoop>, JS::GCPtr<DOM::Document>, JS::NonnullGCPtr<JS::HeapFunction<void()>> steps);
TaskID queue_global_task(HTML::Task::Source, JS::Object&, JS::NonnullGCPtr<JS::HeapFunction<void()>> steps);
void queue_a_microtask(DOM::Document const*, JS::NonnullGCPtr<JS::HeapFunction<void()>> steps);
TaskID queue_a_task(HTML::Task::Source, GC::Ptr<EventLoop>, GC::Ptr<DOM::Document>, GC::Ref<GC::Function<void()>> steps);
TaskID queue_global_task(HTML::Task::Source, JS::Object&, GC::Ref<GC::Function<void()>> steps);
void queue_a_microtask(DOM::Document const*, GC::Ref<GC::Function<void()>> steps);
void perform_a_microtask_checkpoint();
}

View file

@ -10,7 +10,7 @@
namespace Web::HTML {
JS_DEFINE_ALLOCATOR(Task);
GC_DEFINE_ALLOCATOR(Task);
static IDAllocator s_unique_task_source_allocator { static_cast<int>(Task::Source::UniqueTaskSourceStart) };
@ -20,12 +20,12 @@ static IDAllocator s_unique_task_source_allocator { static_cast<int>(Task::Sourc
return next_task_id++;
}
JS::NonnullGCPtr<Task> Task::create(JS::VM& vm, Source source, JS::GCPtr<DOM::Document const> document, JS::NonnullGCPtr<JS::HeapFunction<void()>> steps)
GC::Ref<Task> Task::create(JS::VM& vm, Source source, GC::Ptr<DOM::Document const> document, GC::Ref<GC::Function<void()>> steps)
{
return vm.heap().allocate<Task>(source, document, move(steps));
}
Task::Task(Source source, JS::GCPtr<DOM::Document const> document, JS::NonnullGCPtr<JS::HeapFunction<void()>> steps)
Task::Task(Source source, GC::Ptr<DOM::Document const> document, GC::Ref<GC::Function<void()>> steps)
: m_id(allocate_task_id())
, m_source(source)
, m_steps(steps)

View file

@ -7,8 +7,8 @@
#pragma once
#include <AK/DistinctNumeric.h>
#include <LibGC/CellAllocator.h>
#include <LibJS/Heap/Cell.h>
#include <LibJS/Heap/CellAllocator.h>
#include <LibWeb/Forward.h>
namespace Web::HTML {
@ -18,8 +18,8 @@ struct UniqueTaskSource;
AK_TYPEDEF_DISTINCT_NUMERIC_GENERAL(u64, TaskID, Comparison);
class Task final : public JS::Cell {
JS_CELL(Task, JS::Cell);
JS_DECLARE_ALLOCATOR(Task);
GC_CELL(Task, JS::Cell);
GC_DECLARE_ALLOCATOR(Task);
public:
// https://html.spec.whatwg.org/multipage/webappapis.html#generic-task-sources
@ -74,7 +74,7 @@ public:
UniqueTaskSourceStart
};
static JS::NonnullGCPtr<Task> create(JS::VM&, Source, JS::GCPtr<DOM::Document const>, JS::NonnullGCPtr<JS::HeapFunction<void()>> steps);
static GC::Ref<Task> create(JS::VM&, Source, GC::Ptr<DOM::Document const>, GC::Ref<GC::Function<void()>> steps);
virtual ~Task() override;
@ -87,14 +87,14 @@ public:
bool is_runnable() const;
private:
Task(Source, JS::GCPtr<DOM::Document const>, JS::NonnullGCPtr<JS::HeapFunction<void()>> steps);
Task(Source, GC::Ptr<DOM::Document const>, GC::Ref<GC::Function<void()>> steps);
virtual void visit_edges(Visitor&) override;
TaskID m_id {};
Source m_source { Source::Unspecified };
JS::NonnullGCPtr<JS::HeapFunction<void()>> m_steps;
JS::GCPtr<DOM::Document const> m_document;
GC::Ref<GC::Function<void()>> m_steps;
GC::Ptr<DOM::Document const> m_document;
};
struct UniqueTaskSource {

View file

@ -4,13 +4,13 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Heap/MarkedVector.h>
#include <LibGC/MarkedVector.h>
#include <LibWeb/HTML/EventLoop/EventLoop.h>
#include <LibWeb/HTML/EventLoop/TaskQueue.h>
namespace Web::HTML {
JS_DEFINE_ALLOCATOR(TaskQueue);
GC_DEFINE_ALLOCATOR(TaskQueue);
TaskQueue::TaskQueue(HTML::EventLoop& event_loop)
: m_event_loop(event_loop)
@ -26,13 +26,13 @@ void TaskQueue::visit_edges(Visitor& visitor)
visitor.visit(m_tasks);
}
void TaskQueue::add(JS::NonnullGCPtr<Task> task)
void TaskQueue::add(GC::Ref<Task> task)
{
m_tasks.append(task);
m_event_loop->schedule();
}
JS::GCPtr<Task> TaskQueue::take_first_runnable()
GC::Ptr<Task> TaskQueue::take_first_runnable()
{
if (m_event_loop->execution_paused())
return nullptr;
@ -63,9 +63,9 @@ void TaskQueue::remove_tasks_matching(Function<bool(HTML::Task const&)> filter)
});
}
JS::MarkedVector<JS::NonnullGCPtr<Task>> TaskQueue::take_tasks_matching(Function<bool(HTML::Task const&)> filter)
GC::MarkedVector<GC::Ref<Task>> TaskQueue::take_tasks_matching(Function<bool(HTML::Task const&)> filter)
{
JS::MarkedVector<JS::NonnullGCPtr<Task>> matching_tasks(heap());
GC::MarkedVector<GC::Ref<Task>> matching_tasks(heap());
for (size_t i = 0; i < m_tasks.size();) {
auto& task = m_tasks.at(i);

View file

@ -13,8 +13,8 @@
namespace Web::HTML {
class TaskQueue : public JS::Cell {
JS_CELL(TaskQueue, JS::Cell);
JS_DECLARE_ALLOCATOR(TaskQueue);
GC_CELL(TaskQueue, JS::Cell);
GC_DECLARE_ALLOCATOR(TaskQueue);
public:
explicit TaskQueue(HTML::EventLoop&);
@ -25,11 +25,11 @@ public:
bool has_runnable_tasks() const;
bool has_rendering_tasks() const;
void add(JS::NonnullGCPtr<HTML::Task>);
JS::GCPtr<HTML::Task> take_first_runnable();
void add(GC::Ref<HTML::Task>);
GC::Ptr<HTML::Task> take_first_runnable();
void enqueue(JS::NonnullGCPtr<HTML::Task> task) { add(task); }
JS::GCPtr<HTML::Task> dequeue()
void enqueue(GC::Ref<HTML::Task> task) { add(task); }
GC::Ptr<HTML::Task> dequeue()
{
if (m_tasks.is_empty())
return {};
@ -37,16 +37,16 @@ public:
}
void remove_tasks_matching(Function<bool(HTML::Task const&)>);
JS::MarkedVector<JS::NonnullGCPtr<Task>> take_tasks_matching(Function<bool(HTML::Task const&)>);
GC::MarkedVector<GC::Ref<Task>> take_tasks_matching(Function<bool(HTML::Task const&)>);
Task const* last_added_task() const;
private:
virtual void visit_edges(Visitor&) override;
JS::NonnullGCPtr<HTML::EventLoop> m_event_loop;
GC::Ref<HTML::EventLoop> m_event_loop;
Vector<JS::NonnullGCPtr<HTML::Task>> m_tasks;
Vector<GC::Ref<HTML::Task>> m_tasks;
};
}