Ejemplo n.º 1
0
void WeakBlock::visit(HeapRootVisitor& heapRootVisitor)
{
    // If a block is completely empty, a visit won't have any effect.
    if (isEmpty())
        return;

    // If this WeakBlock doesn't belong to a MarkedBlock, we won't even be here.
    ASSERT(m_markedBlock);

    // We only visit after marking.
    ASSERT(m_markedBlock->isMarkedOrRetired());

    SlotVisitor& visitor = heapRootVisitor.visitor();

    for (size_t i = 0; i < weakImplCount(); ++i) {
        WeakImpl* weakImpl = &weakImpls()[i];
        if (weakImpl->state() != WeakImpl::Live)
            continue;

        WeakHandleOwner* weakHandleOwner = weakImpl->weakHandleOwner();
        if (!weakHandleOwner)
            continue;

        const JSValue& jsValue = weakImpl->jsValue();
        if (m_markedBlock->isMarkedOrNewlyAllocated(jsValue.asCell()))
            continue;

        if (!weakHandleOwner->isReachableFromOpaqueRoots(Handle<Unknown>::wrapSlot(&const_cast<JSValue&>(jsValue)), weakImpl->context(), visitor))
            continue;

        heapRootVisitor.visit(&const_cast<JSValue&>(jsValue));
    }
}
Ejemplo n.º 2
0
void SmallStrings::visitChildren(HeapRootVisitor& heapRootMarker)
{
    /*
       Our hypothesis is that small strings are very common. So, we cache them
       to avoid GC churn. However, in cases where this hypothesis turns out to
       be false -- including the degenerate case where all JavaScript execution
       has terminated -- we don't want to waste memory.

       To test our hypothesis, we check if any small string has been marked. If
       so, it's probably reasonable to mark the rest. If not, we clear the cache.
     */

    bool isAnyStringMarked = isMarked(m_emptyString);
    for (unsigned i = 0; i < singleCharacterStringCount && !isAnyStringMarked; ++i)
        isAnyStringMarked = isMarked(m_singleCharacterStrings[i]);
    
    if (!isAnyStringMarked) {
        clear();
        return;
    }
    
    if (m_emptyString)
        heapRootMarker.mark(&m_emptyString);
    for (unsigned i = 0; i < singleCharacterStringCount; ++i) {
        if (m_singleCharacterStrings[i])
            heapRootMarker.mark(&m_singleCharacterStrings[i]);
    }
}
Ejemplo n.º 3
0
void WeakBlock::specializedVisit(ContainerType& container, HeapRootVisitor& heapRootVisitor)
{
    SlotVisitor& visitor = heapRootVisitor.visitor();
    
    HeapVersion markingVersion = visitor.markingVersion();

    for (size_t i = 0; i < weakImplCount(); ++i) {
        WeakImpl* weakImpl = &weakImpls()[i];
        if (weakImpl->state() != WeakImpl::Live)
            continue;

        WeakHandleOwner* weakHandleOwner = weakImpl->weakHandleOwner();
        if (!weakHandleOwner)
            continue;

        const JSValue& jsValue = weakImpl->jsValue();
        if (container.isMarkedConcurrently(markingVersion, jsValue.asCell()))
            continue;
        
        if (!weakHandleOwner->isReachableFromOpaqueRoots(Handle<Unknown>::wrapSlot(&const_cast<JSValue&>(jsValue)), weakImpl->context(), visitor))
            continue;

        heapRootVisitor.visit(&const_cast<JSValue&>(jsValue));
    }
}
Ejemplo n.º 4
0
void WeakBlock::visitLiveWeakImpls(HeapRootVisitor& heapRootVisitor)
{
    // If a block is completely empty, a visit won't have any effect.
    if (!m_sweepResult.isNull() && m_sweepResult.blockIsFree)
        return;

    SlotVisitor& visitor = heapRootVisitor.visitor();

    for (size_t i = 0; i < weakImplCount(); ++i) {
        WeakImpl* weakImpl = &weakImpls()[i];
        if (weakImpl->state() != WeakImpl::Live)
            continue;

        const JSValue& jsValue = weakImpl->jsValue();
        if (Heap::isMarked(jsValue.asCell()))
            continue;

        WeakHandleOwner* weakHandleOwner = weakImpl->weakHandleOwner();
        if (!weakHandleOwner)
            continue;

        if (!weakHandleOwner->isReachableFromOpaqueRoots(Handle<Unknown>::wrapSlot(&const_cast<JSValue&>(jsValue)), weakImpl->context(), visitor))
            continue;

        heapRootVisitor.visit(&const_cast<JSValue&>(jsValue));
    }
}
Ejemplo n.º 5
0
void Heap::visitException(HeapRootVisitor& visitor)
{
    GCPHASE(MarkingException);
    if (!m_vm->exception() && !m_vm->lastException())
        return;

    visitor.visit(m_vm->addressOfException());
    visitor.visit(m_vm->addressOfLastException());

    if (Options::logGC() == GCLogging::Verbose)
        dataLog("Exceptions:\n", m_slotVisitor);

    m_slotVisitor.donateAndDrain();
}
Ejemplo n.º 6
0
void MarkedArgumentBuffer::markLists(HeapRootVisitor& heapRootVisitor, ListSet& markSet)
{
    ListSet::iterator end = markSet.end();
    for (ListSet::iterator it = markSet.begin(); it != end; ++it) {
        MarkedArgumentBuffer* list = *it;
        for (int i = 0; i < list->m_size; ++i)
            heapRootVisitor.visit(reinterpret_cast<JSValue*>(&list->slotFor(i)));
    }
}
Ejemplo n.º 7
0
void HandleSet::visitStrongHandles(HeapRootVisitor& heapRootVisitor)
{
    Node* end = m_strongList.end();
    for (Node* node = m_strongList.begin(); node != end; node = node->next()) {
#if ENABLE(GC_VALIDATION)
        RELEASE_ASSERT(isLiveNode(node));
#endif
        heapRootVisitor.visit(node->slot());
    }
}
Ejemplo n.º 8
0
void Heap::visitProtectedObjects(HeapRootVisitor& heapRootVisitor)
{
    GCPHASE(VisitProtectedObjects);

    for (auto& pair : m_protectedValues)
        heapRootVisitor.visit(&pair.key);

    if (Options::logGC() == GCLogging::Verbose)
        dataLog("Protected Objects:\n", m_slotVisitor);

    m_slotVisitor.donateAndDrain();
}
Ejemplo n.º 9
0
void HandleHeap::markWeakHandles(HeapRootVisitor& heapRootVisitor)
{
    SlotVisitor& visitor = heapRootVisitor.visitor();

    Node* end = m_weakList.end();
    for (Node* node = m_weakList.begin(); node != end; node = node->next()) {
        ASSERT(isValidWeakNode(node));
        JSCell* cell = node->slot()->asCell();
        if (Heap::isMarked(cell))
            continue;

        WeakHandleOwner* weakOwner = node->weakOwner();
        if (!weakOwner)
            continue;

        if (!weakOwner->isReachableFromOpaqueRoots(Handle<Unknown>::wrapSlot(node->slot()), node->weakOwnerContext(), visitor))
            continue;

        heapRootVisitor.mark(node->slot());
    }
}
Ejemplo n.º 10
0
void HandleHeap::visitWeakHandles(HeapRootVisitor& heapRootVisitor)
{
    SlotVisitor& visitor = heapRootVisitor.visitor();

    Node* end = m_weakList.end();
    for (Node* node = m_weakList.begin(); node != end; node = node->next()) {
#if ENABLE(GC_VALIDATION)
        if (!isValidWeakNode(node))
            CRASH();
#endif
        JSCell* cell = node->slot()->asCell();
        if (Heap::isMarked(cell))
            continue;

        WeakHandleOwner* weakOwner = node->weakOwner();
        if (!weakOwner)
            continue;

        if (!weakOwner->isReachableFromOpaqueRoots(Handle<Unknown>::wrapSlot(node->slot()), node->weakOwnerContext(), visitor))
            continue;

        heapRootVisitor.visit(node->slot());
    }
}
Ejemplo n.º 11
0
void Heap::markTempSortVectors(HeapRootVisitor& heapRootVisitor)
{
    typedef Vector<Vector<ValueStringPair>* > VectorOfValueStringVectors;

    VectorOfValueStringVectors::iterator end = m_tempSortingVectors.end();
    for (VectorOfValueStringVectors::iterator it = m_tempSortingVectors.begin(); it != end; ++it) {
        Vector<ValueStringPair>* tempSortingVector = *it;

        Vector<ValueStringPair>::iterator vectorEnd = tempSortingVector->end();
        for (Vector<ValueStringPair>::iterator vectorIt = tempSortingVector->begin(); vectorIt != vectorEnd; ++vectorIt) {
            if (vectorIt->first)
                heapRootVisitor.visit(&vectorIt->first);
        }
    }
}
Ejemplo n.º 12
0
void Heap::markProtectedObjects(HeapRootVisitor& heapRootVisitor)
{
    ProtectCountSet::iterator end = m_protectedValues.end();
    for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
        heapRootVisitor.visit(&it->first);
}
Ejemplo n.º 13
0
void HandleHeap::markStrongHandles(HeapRootVisitor& heapRootMarker)
{
    Node* end = m_strongList.end();
    for (Node* node = m_strongList.begin(); node != end; node = node->next())
        heapRootMarker.mark(node->slot());
}