mirror of
https://github.com/darlinghq/darling-JavaScriptCore.git
synced 2024-11-23 04:09:40 +00:00
147 lines
4.4 KiB
C++
147 lines
4.4 KiB
C++
/*
|
|
* Copyright (C) 2012-2019 Apple Inc. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "CellContainer.h"
|
|
#include "WeakImpl.h"
|
|
#include <wtf/DoublyLinkedList.h>
|
|
#include <wtf/StdLibExtras.h>
|
|
|
|
namespace JSC {
|
|
|
|
class Heap;
|
|
class SlotVisitor;
|
|
|
|
DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(WeakBlock);
|
|
|
|
class WeakBlock : public DoublyLinkedListNode<WeakBlock> {
|
|
public:
|
|
friend class WTF::DoublyLinkedListNode<WeakBlock>;
|
|
static constexpr size_t blockSize = 256; // 1/16 of MarkedBlock size
|
|
|
|
struct FreeCell {
|
|
FreeCell* next;
|
|
};
|
|
|
|
struct SweepResult {
|
|
bool isNull() const;
|
|
|
|
bool blockIsFree { true };
|
|
bool blockIsLogicallyEmpty { true };
|
|
FreeCell* freeList { nullptr };
|
|
};
|
|
|
|
static WeakBlock* create(Heap&, CellContainer);
|
|
static void destroy(Heap&, WeakBlock*);
|
|
|
|
static WeakImpl* asWeakImpl(FreeCell*);
|
|
|
|
bool isEmpty();
|
|
bool isLogicallyEmptyButNotFree() const;
|
|
|
|
void sweep();
|
|
SweepResult takeSweepResult();
|
|
|
|
void visit(SlotVisitor&);
|
|
|
|
void reap();
|
|
|
|
void lastChanceToFinalize();
|
|
void disconnectContainer() { m_container = CellContainer(); }
|
|
|
|
private:
|
|
static FreeCell* asFreeCell(WeakImpl*);
|
|
|
|
template<typename ContainerType>
|
|
void specializedVisit(ContainerType&, SlotVisitor&);
|
|
|
|
explicit WeakBlock(CellContainer);
|
|
void finalize(WeakImpl*);
|
|
WeakImpl* weakImpls();
|
|
size_t weakImplCount();
|
|
void addToFreeList(FreeCell**, WeakImpl*);
|
|
|
|
CellContainer m_container;
|
|
WeakBlock* m_prev;
|
|
WeakBlock* m_next;
|
|
SweepResult m_sweepResult;
|
|
};
|
|
|
|
inline bool WeakBlock::SweepResult::isNull() const
|
|
{
|
|
return blockIsFree && !freeList; // This state is impossible, so we can use it to mean null.
|
|
}
|
|
|
|
inline WeakImpl* WeakBlock::asWeakImpl(FreeCell* freeCell)
|
|
{
|
|
return reinterpret_cast_ptr<WeakImpl*>(freeCell);
|
|
}
|
|
|
|
inline WeakBlock::SweepResult WeakBlock::takeSweepResult()
|
|
{
|
|
SweepResult tmp;
|
|
std::swap(tmp, m_sweepResult);
|
|
ASSERT(m_sweepResult.isNull());
|
|
return tmp;
|
|
}
|
|
|
|
inline WeakBlock::FreeCell* WeakBlock::asFreeCell(WeakImpl* weakImpl)
|
|
{
|
|
return reinterpret_cast_ptr<FreeCell*>(weakImpl);
|
|
}
|
|
|
|
inline WeakImpl* WeakBlock::weakImpls()
|
|
{
|
|
return reinterpret_cast_ptr<WeakImpl*>(this) + ((sizeof(WeakBlock) + sizeof(WeakImpl) - 1) / sizeof(WeakImpl));
|
|
}
|
|
|
|
inline size_t WeakBlock::weakImplCount()
|
|
{
|
|
return (blockSize / sizeof(WeakImpl)) - ((sizeof(WeakBlock) + sizeof(WeakImpl) - 1) / sizeof(WeakImpl));
|
|
}
|
|
|
|
inline void WeakBlock::addToFreeList(FreeCell** freeList, WeakImpl* weakImpl)
|
|
{
|
|
ASSERT(weakImpl->state() == WeakImpl::Deallocated);
|
|
FreeCell* freeCell = asFreeCell(weakImpl);
|
|
ASSERT(!*freeList || ((char*)*freeList > (char*)this && (char*)*freeList < (char*)this + blockSize));
|
|
ASSERT((char*)freeCell > (char*)this && (char*)freeCell < (char*)this + blockSize);
|
|
freeCell->next = *freeList;
|
|
*freeList = freeCell;
|
|
}
|
|
|
|
inline bool WeakBlock::isEmpty()
|
|
{
|
|
return !m_sweepResult.isNull() && m_sweepResult.blockIsFree;
|
|
}
|
|
|
|
inline bool WeakBlock::isLogicallyEmptyButNotFree() const
|
|
{
|
|
return !m_sweepResult.isNull() && !m_sweepResult.blockIsFree && m_sweepResult.blockIsLogicallyEmpty;
|
|
}
|
|
|
|
} // namespace JSC
|