diff --git a/Userland/Libraries/LibJS/Forward.h b/Userland/Libraries/LibJS/Forward.h index 769ad374b6d..1ef0423fb06 100644 --- a/Userland/Libraries/LibJS/Forward.h +++ b/Userland/Libraries/LibJS/Forward.h @@ -141,6 +141,7 @@ class Symbol; class Token; class VM; class Value; +class WeakContainer; enum class DeclarationKind; struct AlreadyResolved; struct JobCallback; diff --git a/Userland/Libraries/LibJS/Heap/Heap.cpp b/Userland/Libraries/LibJS/Heap/Heap.cpp index 5d557159550..8b807ff606d 100644 --- a/Userland/Libraries/LibJS/Heap/Heap.cpp +++ b/Userland/Libraries/LibJS/Heap/Heap.cpp @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include namespace JS { @@ -190,7 +190,7 @@ void Heap::sweep_dead_cells(bool print_report, const Core::ElapsedTimer& measure size_t collected_cell_bytes = 0; size_t live_cell_bytes = 0; - auto should_store_sweeped_cells = !m_weak_sets.is_empty(); + auto should_store_sweeped_cells = !m_weak_containers.is_empty(); for_each_block([&](auto& block) { bool block_has_live_cells = false; bool block_was_full = block.is_full(); @@ -226,8 +226,8 @@ void Heap::sweep_dead_cells(bool print_report, const Core::ElapsedTimer& measure allocator_for_size(block->cell_size()).block_did_become_usable({}, *block); } - for (auto* weak_set : m_weak_sets) - weak_set->remove_sweeped_cells({}, sweeped_cells); + for (auto* weak_container : m_weak_containers) + weak_container->remove_sweeped_cells({}, sweeped_cells); if constexpr (HEAP_DEBUG) { for_each_block([&](auto& block) { @@ -280,16 +280,16 @@ void Heap::did_destroy_marked_value_list(Badge, MarkedValueList m_marked_value_lists.remove(&list); } -void Heap::did_create_weak_set(Badge, WeakSet& set) +void Heap::did_create_weak_container(Badge, WeakContainer& set) { - VERIFY(!m_weak_sets.contains(&set)); - m_weak_sets.set(&set); + VERIFY(!m_weak_containers.contains(&set)); + m_weak_containers.set(&set); } -void Heap::did_destroy_weak_set(Badge, WeakSet& set) +void Heap::did_destroy_weak_container(Badge, WeakContainer& set) { - VERIFY(m_weak_sets.contains(&set)); - m_weak_sets.remove(&set); + VERIFY(m_weak_containers.contains(&set)); + m_weak_containers.remove(&set); } void Heap::defer_gc(Badge) diff --git a/Userland/Libraries/LibJS/Heap/Heap.h b/Userland/Libraries/LibJS/Heap/Heap.h index 624efa9d5df..57cf1a40ccc 100644 --- a/Userland/Libraries/LibJS/Heap/Heap.h +++ b/Userland/Libraries/LibJS/Heap/Heap.h @@ -70,8 +70,8 @@ public: void did_create_marked_value_list(Badge, MarkedValueList&); void did_destroy_marked_value_list(Badge, MarkedValueList&); - void did_create_weak_set(Badge, WeakSet&); - void did_destroy_weak_set(Badge, WeakSet&); + void did_create_weak_container(Badge, WeakContainer&); + void did_destroy_weak_container(Badge, WeakContainer&); void defer_gc(Badge); void undefer_gc(Badge); @@ -109,7 +109,7 @@ private: HashTable m_marked_value_lists; - HashTable m_weak_sets; + HashTable m_weak_containers; BlockAllocator m_block_allocator; diff --git a/Userland/Libraries/LibJS/Runtime/WeakContainer.h b/Userland/Libraries/LibJS/Runtime/WeakContainer.h new file mode 100644 index 00000000000..04cf3a83acb --- /dev/null +++ b/Userland/Libraries/LibJS/Runtime/WeakContainer.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021, Idan Horowitz + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace JS { + +class WeakContainer { +public: + explicit WeakContainer(Heap& heap) + : m_heap(heap) + { + m_heap.did_create_weak_container({}, *this); + } + virtual ~WeakContainer() + { + m_heap.did_destroy_weak_container({}, *this); + } + + virtual void remove_sweeped_cells(Badge, Vector&) = 0; + +private: + Heap& m_heap; +}; + +} diff --git a/Userland/Libraries/LibJS/Runtime/WeakSet.cpp b/Userland/Libraries/LibJS/Runtime/WeakSet.cpp index ff64c0858d7..5e028752706 100644 --- a/Userland/Libraries/LibJS/Runtime/WeakSet.cpp +++ b/Userland/Libraries/LibJS/Runtime/WeakSet.cpp @@ -15,13 +15,12 @@ WeakSet* WeakSet::create(GlobalObject& global_object) WeakSet::WeakSet(Object& prototype) : Object(prototype) + , WeakContainer(heap()) { - heap().did_create_weak_set({}, *this); } WeakSet::~WeakSet() { - heap().did_destroy_weak_set({}, *this); } void WeakSet::remove_sweeped_cells(Badge, Vector& cells) diff --git a/Userland/Libraries/LibJS/Runtime/WeakSet.h b/Userland/Libraries/LibJS/Runtime/WeakSet.h index 0062d4eef4f..8e0719ca6b2 100644 --- a/Userland/Libraries/LibJS/Runtime/WeakSet.h +++ b/Userland/Libraries/LibJS/Runtime/WeakSet.h @@ -9,10 +9,13 @@ #include #include #include +#include namespace JS { -class WeakSet : public Object { +class WeakSet final + : public Object + , public WeakContainer { JS_OBJECT(WeakSet, Object); public: @@ -24,7 +27,7 @@ public: HashTable const& values() const { return m_values; }; HashTable& values() { return m_values; }; - void remove_sweeped_cells(Badge, Vector&); + virtual void remove_sweeped_cells(Badge, Vector&) override; private: HashTable m_values; // This stores Cell pointers instead of Object pointers to aide with sweeping