void StyledElement::rebuildPresentationAttributeStyle() { PresentationAttributeCacheKey cacheKey; makePresentationAttributeCacheKey(cacheKey); unsigned cacheHash = computePresentationAttributeCacheHash(cacheKey); PresentationAttributeCache::iterator cacheIterator; if (cacheHash) { cacheIterator = presentationAttributeCache().add(cacheHash, nullptr).iterator; if (cacheIterator->value && cacheIterator->value->key != cacheKey) cacheHash = 0; } else cacheIterator = presentationAttributeCache().end(); RefPtr<StyleProperties> style; if (cacheHash && cacheIterator->value) { style = cacheIterator->value->value; presentationAttributeCacheCleaner().didHitPresentationAttributeCache(); } else { style = MutableStyleProperties::create(isSVGElement() ? SVGAttributeMode : CSSQuirksMode); for (const Attribute& attribute : attributesIterator()) collectStyleForPresentationAttribute(attribute.name(), attribute.value(), static_cast<MutableStyleProperties&>(*style)); } // ShareableElementData doesn't store presentation attribute style, so make sure we have a UniqueElementData. UniqueElementData& elementData = ensureUniqueElementData(); elementData.setPresentationAttributeStyleIsDirty(false); elementData.m_presentationAttributeStyle = style->isEmpty() ? 0 : style; if (!cacheHash || cacheIterator->value) return; std::unique_ptr<PresentationAttributeCacheEntry> newEntry = std::make_unique<PresentationAttributeCacheEntry>(); newEntry->key = cacheKey; newEntry->value = style.release(); static const int presentationAttributeCacheMaximumSize = 4096; if (presentationAttributeCache().size() > presentationAttributeCacheMaximumSize) { // Start building from scratch if the cache ever gets big. presentationAttributeCache().clear(); presentationAttributeCache().set(cacheHash, WTF::move(newEntry)); } else cacheIterator->value = WTF::move(newEntry); }
DCHECK(key.attributesAndValues.size()); unsigned attributeHash = StringHasher::hashMemory( key.attributesAndValues.data(), key.attributesAndValues.size() * sizeof(key.attributesAndValues[0])); return WTF::hashInts(key.tagName->existingHash(), attributeHash); } StylePropertySet* computePresentationAttributeStyle(Element& element) { DEFINE_STATIC_LOCAL(PresentationAttributeCacheCleaner, cacheCleaner, ()); DCHECK(element.isStyledElement()); PresentationAttributeCacheKey cacheKey; makePresentationAttributeCacheKey(element, cacheKey); unsigned cacheHash = computePresentationAttributeCacheHash(cacheKey); PresentationAttributeCache::ValueType* cacheValue; if (cacheHash) { cacheValue = presentationAttributeCache().add(cacheHash, nullptr).storedValue; if (cacheValue->value && cacheValue->value->key != cacheKey) cacheHash = 0; } else { cacheValue = nullptr; } StylePropertySet* style = nullptr; if (cacheHash && cacheValue->value) { style = cacheValue->value->value; cacheCleaner.didHitPresentationAttributeCache();