mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-05-12 01:46:46 +02:00
LibJS: Check live blocks before pruning executable caches
Executable caches can retain weak pointers to shapes and prototypes across collections. With incremental sweeping, a previous sweep may have already freed the block behind one of those pointers by the time pruning runs for weak containers. Use the live HeapBlock registry before reading cached cells. This matches the other weak containers updated for incremental sweeping.
This commit is contained in:
committed by
Andreas Kling
parent
4dfed815cc
commit
37117b1cb4
Notes:
github-actions[bot]
2026-05-10 08:59:26 +00:00
Author: https://github.com/awesomekling Commit: https://github.com/LadybirdBrowser/ladybird/commit/37117b1cb44 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/7663 Reviewed-by: https://github.com/ADKaster
@@ -5,6 +5,8 @@
|
||||
*/
|
||||
|
||||
#include <AK/BinarySearch.h>
|
||||
#include <LibGC/Heap.h>
|
||||
#include <LibGC/HeapBlock.h>
|
||||
#include <LibJS/Bytecode/BasicBlock.h>
|
||||
#include <LibJS/Bytecode/Executable.h>
|
||||
#include <LibJS/Bytecode/FormatOperand.h>
|
||||
@@ -339,11 +341,16 @@ StaticPropertyLookupCache::StaticPropertyLookupCache()
|
||||
static_property_lookup_caches().append(this);
|
||||
}
|
||||
|
||||
static bool cell_is_dead(Cell const* cell)
|
||||
{
|
||||
auto* block = GC::HeapBlock::from_cell(cell);
|
||||
if (!GC::Heap::the().is_live_heap_block(block))
|
||||
return true;
|
||||
return cell->state() != Cell::State::Live || !cell->is_marked();
|
||||
}
|
||||
|
||||
static void clear_cache_entry_if_dead(PropertyLookupCache::Entry& entry)
|
||||
{
|
||||
auto cell_is_dead = [](Cell const* cell) {
|
||||
return cell->state() != Cell::State::Live || !cell->is_marked();
|
||||
};
|
||||
if (entry.from_shape && cell_is_dead(entry.from_shape))
|
||||
entry.from_shape = nullptr;
|
||||
if (entry.shape && cell_is_dead(entry.shape))
|
||||
@@ -373,7 +380,8 @@ void Executable::remove_dead_cells(Badge<GC::Heap>)
|
||||
clear_cache_entry_if_dead(entry);
|
||||
}
|
||||
for (auto& cache : object_shape_caches) {
|
||||
if (cache.shape && (cache.shape->state() != Cell::State::Live || !cache.shape->is_marked()))
|
||||
auto* shape = cache.shape.ptr();
|
||||
if (shape && cell_is_dead(shape))
|
||||
cache.shape = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user