void WeakBlock::reap() { // If a block is completely empty, a reaping 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 reap after marking. ASSERT(m_markedBlock->isMarkedOrRetired()); for (size_t i = 0; i < weakImplCount(); ++i) { WeakImpl* weakImpl = &weakImpls()[i]; if (weakImpl->state() > WeakImpl::Dead) continue; if (m_markedBlock->isMarkedOrNewlyAllocated(weakImpl->jsValue().asCell())) { ASSERT(weakImpl->state() == WeakImpl::Live); continue; } weakImpl->setState(WeakImpl::Dead); } }
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 WeakBlock::lastChanceToFinalize() { for (size_t i = 0; i < weakImplCount(); ++i) { WeakImpl* weakImpl = &weakImpls()[i]; if (weakImpl->state() >= WeakImpl::Finalized) continue; weakImpl->setState(WeakImpl::Dead); finalize(weakImpl); } }
void WeakBlock::sweep() { if (!m_sweepResult.isNull()) return; SweepResult sweepResult; for (size_t i = 0; i < weakImplCount(); ++i) { WeakImpl* weakImpl = &weakImpls()[i]; if (weakImpl->state() == WeakImpl::Dead) finalize(weakImpl); if (weakImpl->state() == WeakImpl::Deallocated) addToFreeList(&sweepResult.freeList, weakImpl); else sweepResult.blockIsFree = false; } m_sweepResult = sweepResult; ASSERT(!m_sweepResult.isNull()); }
void WeakBlock::sweep() { // If a block is completely empty, a sweep won't have any effect. if (isEmpty()) return; SweepResult sweepResult; for (size_t i = 0; i < weakImplCount(); ++i) { WeakImpl* weakImpl = &weakImpls()[i]; if (weakImpl->state() == WeakImpl::Dead) finalize(weakImpl); if (weakImpl->state() == WeakImpl::Deallocated) addToFreeList(&sweepResult.freeList, weakImpl); else { sweepResult.blockIsFree = false; if (weakImpl->state() == WeakImpl::Live) sweepResult.blockIsLogicallyEmpty = false; } } m_sweepResult = sweepResult; ASSERT(!m_sweepResult.isNull()); }
void WeakBlock::reap() { // If a block is completely empty, a reaping won't have any effect. if (isEmpty()) return; // If this WeakBlock doesn't belong to a CellContainer, we won't even be here. ASSERT(m_container); HeapVersion markingVersion = m_container.heap()->objectSpace().markingVersion(); for (size_t i = 0; i < weakImplCount(); ++i) { WeakImpl* weakImpl = &weakImpls()[i]; if (weakImpl->state() > WeakImpl::Dead) continue; if (m_container.isMarked(markingVersion, weakImpl->jsValue().asCell())) { ASSERT(weakImpl->state() == WeakImpl::Live); continue; } weakImpl->setState(WeakImpl::Dead); } }
void WeakBlock::visitDeadWeakImpls(HeapRootVisitor&) { // If a block is completely empty, a visit won't have any effect. if (!m_sweepResult.isNull() && m_sweepResult.blockIsFree) return; for (size_t i = 0; i < weakImplCount(); ++i) { WeakImpl* weakImpl = &weakImpls()[i]; if (weakImpl->state() > WeakImpl::Dead) continue; if (Heap::isMarked(weakImpl->jsValue().asCell())) continue; weakImpl->setState(WeakImpl::Dead); } }