mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-19 15:43:20 +00:00
78 lines
1.9 KiB
C++
78 lines
1.9 KiB
C++
![]() |
/*
|
||
|
* Copyright (c) 2025, Andreas Kling <andreas@ladybird.org>
|
||
|
*
|
||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||
|
*/
|
||
|
|
||
|
#include <LibGC/Cell.h>
|
||
|
#include <LibGC/WeakBlock.h>
|
||
|
#include <sys/mman.h>
|
||
|
|
||
|
#if defined(AK_OS_WINDOWS)
|
||
|
# include <AK/Windows.h>
|
||
|
# include <memoryapi.h>
|
||
|
#endif
|
||
|
|
||
|
namespace GC {
|
||
|
|
||
|
WeakImpl WeakImpl::the_null_weak_impl;
|
||
|
|
||
|
WeakBlock* WeakBlock::create()
|
||
|
{
|
||
|
#if !defined(AK_OS_WINDOWS)
|
||
|
auto* block = (HeapBlock*)mmap(nullptr, WeakBlock::BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||
|
VERIFY(block != MAP_FAILED);
|
||
|
#else
|
||
|
auto* block = (HeapBlock*)VirtualAlloc(NULL, WeakBlock::BLOCK_SIZE, MEM_COMMIT, PAGE_READWRITE);
|
||
|
VERIFY(block);
|
||
|
#endif
|
||
|
return new (block) WeakBlock;
|
||
|
}
|
||
|
|
||
|
WeakBlock::WeakBlock()
|
||
|
{
|
||
|
for (size_t i = 0; i < IMPL_COUNT; ++i) {
|
||
|
m_impls[i].set_ptr({}, i + 1 < IMPL_COUNT ? &m_impls[i + 1] : nullptr);
|
||
|
m_impls[i].set_state(WeakImpl::State::Freelist);
|
||
|
}
|
||
|
m_freelist = &m_impls[0];
|
||
|
}
|
||
|
|
||
|
WeakBlock::~WeakBlock() = default;
|
||
|
|
||
|
WeakImpl* WeakBlock::allocate(Cell* cell)
|
||
|
{
|
||
|
auto* impl = m_freelist;
|
||
|
if (!impl)
|
||
|
return nullptr;
|
||
|
VERIFY(impl->ref_count() == 0);
|
||
|
m_freelist = impl->ptr() ? static_cast<WeakImpl*>(impl->ptr()) : nullptr;
|
||
|
impl->set_ptr({}, cell);
|
||
|
impl->set_state(WeakImpl::State::Allocated);
|
||
|
return impl;
|
||
|
}
|
||
|
|
||
|
void WeakBlock::deallocate(WeakImpl* impl)
|
||
|
{
|
||
|
VERIFY(impl->ref_count() == 0);
|
||
|
impl->set_ptr({}, m_freelist);
|
||
|
impl->set_state(WeakImpl::State::Freelist);
|
||
|
m_freelist = impl;
|
||
|
}
|
||
|
|
||
|
void WeakBlock::sweep()
|
||
|
{
|
||
|
for (size_t i = 0; i < IMPL_COUNT; ++i) {
|
||
|
auto& impl = m_impls[i];
|
||
|
if (impl.state() == WeakImpl::State::Freelist)
|
||
|
continue;
|
||
|
auto* cell = static_cast<Cell*>(impl.ptr());
|
||
|
if (!cell || !cell->is_marked())
|
||
|
impl.set_ptr({}, nullptr);
|
||
|
if (impl.ref_count() == 0)
|
||
|
deallocate(&impl);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|