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)); } }
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)); } }
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)); } }
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()); } }
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()); } }