void HTMLFormattingElementList::ensureNoahsArkCondition(HTMLStackItem* newItem) { WillBeHeapVector<RawPtrWillBeMember<HTMLStackItem> > candidates; tryToEnsureNoahsArkConditionQuickly(newItem, candidates); if (candidates.isEmpty()) return; // We pre-allocate and re-use this second vector to save one malloc per // attribute that we verify. WillBeHeapVector<RawPtrWillBeMember<HTMLStackItem> > remainingCandidates; remainingCandidates.reserveInitialCapacity(candidates.size()); const Vector<Attribute>& attributes = newItem->attributes(); for (size_t i = 0; i < attributes.size(); ++i) { const Attribute& attribute = attributes[i]; for (size_t j = 0; j < candidates.size(); ++j) { HTMLStackItem* candidate = candidates[j]; // These properties should already have been checked by tryToEnsureNoahsArkConditionQuickly. ASSERT(newItem->attributes().size() == candidate->attributes().size()); ASSERT(newItem->localName() == candidate->localName() && newItem->namespaceURI() == candidate->namespaceURI()); Attribute* candidateAttribute = candidate->getAttributeItem(attribute.name()); if (candidateAttribute && candidateAttribute->value() == attribute.value()) remainingCandidates.append(candidate); } if (remainingCandidates.size() < kNoahsArkCapacity) return; candidates.swap(remainingCandidates); remainingCandidates.shrink(0); } // Inductively, we shouldn't spin this loop very many times. It's possible, // however, that we wil spin the loop more than once because of how the // formatting element list gets permuted. for (size_t i = kNoahsArkCapacity - 1; i < candidates.size(); ++i) remove(candidates[i]->element()); }