Diff
Modified: trunk/Source/WebCore/ChangeLog (292962 => 292963)
--- trunk/Source/WebCore/ChangeLog 2022-04-18 18:46:45 UTC (rev 292962)
+++ trunk/Source/WebCore/ChangeLog 2022-04-18 18:56:46 UTC (rev 292963)
@@ -1,5 +1,47 @@
2022-04-18 Chris Dumez <[email protected]>
+ Optimize nodeHasRole()
+ https://bugs.webkit.org/show_bug.cgi?id=239430
+ <rdar://problem/91857547>
+
+ Reviewed by Darin Adler.
+
+ Optimize nodeHasRole() by calling spaceSplitStringContainsValue() instead of constructing a
+ SpaceSplitString (which is expensive simply for looking for a single value). Also take a
+ StringView in parameter to avoid constructing a String unnecessarily (most call sites pass
+ an ASCIILiteral).
+
+ * accessibility/AXObjectCache.cpp:
+ (WebCore::nodeHasRole):
+ * accessibility/AXObjectCache.h:
+ (WebCore::nodeHasRole):
+ * accessibility/AccessibilityObject.cpp:
+ (WebCore::AccessibilityObject::elementsFromAttribute const):
+ (WebCore::AccessibilityObject::ariaElementsReferencedByAttribute const):
+ * dom/ClassCollection.h:
+ (WebCore::ClassCollection::ClassCollection):
+ * dom/Element.cpp:
+ (WebCore::Element::classAttributeChanged):
+ (WebCore::Element::partAttributeChanged):
+ * dom/SpaceSplitString.cpp:
+ (WebCore::SpaceSplitString::set):
+ (WebCore::SpaceSplitString::spaceSplitStringContainsValue):
+ * dom/SpaceSplitString.h:
+ (WebCore::SpaceSplitString::SpaceSplitString):
+ * html/Autofill.cpp:
+ (WebCore::AutofillData::createFromHTMLFormControlElement):
+ * html/HTMLAnchorElement.cpp:
+ (WebCore::HTMLAnchorElement::parseAttribute):
+ (WebCore::HTMLAnchorElement::sendPings):
+ * inspector/InspectorAuditAccessibilityObject.cpp:
+ (WebCore::InspectorAuditAccessibilityObject::getComputedProperties):
+ * inspector/agents/InspectorDOMAgent.cpp:
+ (WebCore::InspectorDOMAgent::buildObjectForAccessibilityProperties):
+ * page/EventHandler.cpp:
+ (WebCore::findDropZone):
+
+2022-04-18 Chris Dumez <[email protected]>
+
Use AtomString as early as possible when string will eventually get atomized
https://bugs.webkit.org/show_bug.cgi?id=239427
Modified: trunk/Source/WebCore/accessibility/AXObjectCache.cpp (292962 => 292963)
--- trunk/Source/WebCore/accessibility/AXObjectCache.cpp 2022-04-18 18:46:45 UTC (rev 292962)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.cpp 2022-04-18 18:56:46 UTC (rev 292963)
@@ -512,8 +512,7 @@
}
// FIXME: This probably belongs on Node.
-// FIXME: This should take a const char*, but one caller passes nullAtom().
-bool nodeHasRole(Node* node, const String& role)
+bool nodeHasRole(Node* node, StringView role)
{
if (!node || !is<Element>(node))
return false;
@@ -524,7 +523,7 @@
if (roleValue.isEmpty())
return false;
- return SpaceSplitString(roleValue, true).contains(role);
+ return SpaceSplitString::spaceSplitStringContainsValue(roleValue, role, SpaceSplitString::ShouldFoldCase::Yes);
}
static bool isSimpleImage(const RenderObject& renderer)
Modified: trunk/Source/WebCore/accessibility/AXObjectCache.h (292962 => 292963)
--- trunk/Source/WebCore/accessibility/AXObjectCache.h 2022-04-18 18:46:45 UTC (rev 292962)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.h 2022-04-18 18:56:46 UTC (rev 292963)
@@ -550,7 +550,7 @@
#endif
};
-bool nodeHasRole(Node*, const String& role);
+bool nodeHasRole(Node*, StringView role);
// This will let you know if aria-hidden was explicitly set to false.
bool isNodeAriaVisible(Node*);
@@ -574,7 +574,7 @@
inline void AXObjectCache::enableAccessibility() { }
inline void AXObjectCache::disableAccessibility() { }
inline void AXObjectCache::setEnhancedUserInterfaceAccessibility(bool) { }
-inline bool nodeHasRole(Node*, const String&) { return false; }
+inline bool nodeHasRole(Node*, StringView) { return false; }
inline void AXObjectCache::startCachingComputedObjectAttributesUntilTreeMutates() { }
inline void AXObjectCache::stopCachingComputedObjectAttributes() { }
inline bool isNodeAriaVisible(Node*) { return true; }
Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.cpp (292962 => 292963)
--- trunk/Source/WebCore/accessibility/AccessibilityObject.cpp 2022-04-18 18:46:45 UTC (rev 292962)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.cpp 2022-04-18 18:56:46 UTC (rev 292963)
@@ -3754,7 +3754,7 @@
return;
auto& treeScope = node->treeScope();
- auto spaceSplitString = SpaceSplitString(idsString, false);
+ SpaceSplitString spaceSplitString(idsString, SpaceSplitString::ShouldFoldCase::No);
size_t length = spaceSplitString.size();
for (size_t i = 0; i < length; ++i) {
if (auto* element = treeScope.getElementById(spaceSplitString[i]))
@@ -3928,7 +3928,7 @@
for (auto& element : descendantsOfType<Element>(node()->treeScope().rootNode())) {
auto& idList = element.attributeWithoutSynchronization(attribute);
- if (!SpaceSplitString::spaceSplitStringContainsValue(idList, id))
+ if (!SpaceSplitString::spaceSplitStringContainsValue(idList, id, SpaceSplitString::ShouldFoldCase::No))
continue;
if (auto* axObject = cache->getOrCreate(&element))
Modified: trunk/Source/WebCore/dom/ClassCollection.h (292962 => 292963)
--- trunk/Source/WebCore/dom/ClassCollection.h 2022-04-18 18:46:45 UTC (rev 292962)
+++ trunk/Source/WebCore/dom/ClassCollection.h 2022-04-18 18:56:46 UTC (rev 292963)
@@ -53,7 +53,7 @@
inline ClassCollection::ClassCollection(ContainerNode& rootNode, CollectionType type, const AtomString& classNames)
: CachedHTMLCollection(rootNode, type)
- , m_classNames(classNames, rootNode.document().inQuirksMode())
+ , m_classNames(classNames, rootNode.document().inQuirksMode() ? SpaceSplitString::ShouldFoldCase::Yes : SpaceSplitString::ShouldFoldCase::No)
, m_originalClassNames(classNames)
{
}
Modified: trunk/Source/WebCore/dom/Element.cpp (292962 => 292963)
--- trunk/Source/WebCore/dom/Element.cpp 2022-04-18 18:46:45 UTC (rev 292962)
+++ trunk/Source/WebCore/dom/Element.cpp 2022-04-18 18:56:46 UTC (rev 292963)
@@ -1997,7 +1997,7 @@
if (!elementData())
ensureUniqueElementData();
- bool shouldFoldCase = document().inQuirksMode();
+ auto shouldFoldCase = document().inQuirksMode() ? SpaceSplitString::ShouldFoldCase::Yes : SpaceSplitString::ShouldFoldCase::No;
bool newStringHasClasses = isNonEmptyTokenList(newClassString);
auto oldClassNames = elementData()->classNames();
@@ -2017,7 +2017,7 @@
{
bool hasParts = isNonEmptyTokenList(newValue);
if (hasParts || !partNames().isEmpty()) {
- auto newParts = hasParts ? SpaceSplitString(newValue, false) : SpaceSplitString();
+ auto newParts = hasParts ? SpaceSplitString(newValue, SpaceSplitString::ShouldFoldCase::No) : SpaceSplitString();
ensureElementRareData().setPartNames(WTFMove(newParts));
}
Modified: trunk/Source/WebCore/dom/SpaceSplitString.cpp (292962 => 292963)
--- trunk/Source/WebCore/dom/SpaceSplitString.cpp 2022-04-18 18:46:45 UTC (rev 292962)
+++ trunk/Source/WebCore/dom/SpaceSplitString.cpp 2022-04-18 18:56:46 UTC (rev 292963)
@@ -91,13 +91,13 @@
return table;
}
-void SpaceSplitString::set(const AtomString& inputString, bool shouldFoldCase)
+void SpaceSplitString::set(const AtomString& inputString, ShouldFoldCase shouldFoldCase)
{
if (inputString.isNull()) {
clear();
return;
}
- m_data = SpaceSplitStringData::create(shouldFoldCase ? inputString.convertToASCIILowercase() : inputString);
+ m_data = SpaceSplitStringData::create(shouldFoldCase == ShouldFoldCase::Yes ? inputString.convertToASCIILowercase() : inputString);
}
template<typename ReferenceCharacterType>
@@ -135,14 +135,14 @@
return tokenProcessor.referenceStringWasFound();
}
-bool SpaceSplitString::spaceSplitStringContainsValue(StringView spaceSplitString, StringView value)
+bool SpaceSplitString::spaceSplitStringContainsValue(StringView spaceSplitString, StringView value, ShouldFoldCase shouldFoldCase)
{
if (spaceSplitString.isNull())
return false;
if (value.is8Bit())
- return spaceSplitStringContainsValueInternal<LChar>(spaceSplitString, value);
- return spaceSplitStringContainsValueInternal<UChar>(spaceSplitString, value);
+ return spaceSplitStringContainsValueInternal<LChar>(shouldFoldCase == ShouldFoldCase::Yes ? StringView { spaceSplitString.convertToASCIILowercase() } : spaceSplitString, value);
+ return spaceSplitStringContainsValueInternal<UChar>(shouldFoldCase == ShouldFoldCase::Yes ? StringView { spaceSplitString.convertToASCIILowercase() } : spaceSplitString, value);
}
class TokenCounter {
Modified: trunk/Source/WebCore/dom/SpaceSplitString.h (292962 => 292963)
--- trunk/Source/WebCore/dom/SpaceSplitString.h 2022-04-18 18:46:45 UTC (rev 292962)
+++ trunk/Source/WebCore/dom/SpaceSplitString.h 2022-04-18 18:56:46 UTC (rev 292963)
@@ -99,11 +99,13 @@
class SpaceSplitString {
public:
SpaceSplitString() = default;
- SpaceSplitString(const AtomString& string, bool shouldFoldCase) { set(string, shouldFoldCase); }
+ enum class ShouldFoldCase : bool { No, Yes };
+ SpaceSplitString(const AtomString& string, ShouldFoldCase shouldFoldCase) { set(string, shouldFoldCase); }
+
bool operator!=(const SpaceSplitString& other) const { return m_data != other.m_data; }
- void set(const AtomString&, bool shouldFoldCase);
+ void set(const AtomString&, ShouldFoldCase);
void clear() { m_data = nullptr; }
bool contains(const AtomString& string) const { return m_data && m_data->contains(string); }
@@ -117,7 +119,7 @@
return (*m_data)[i];
}
- static bool spaceSplitStringContainsValue(StringView spaceSplitString, StringView value);
+ static bool spaceSplitStringContainsValue(StringView spaceSplitString, StringView value, ShouldFoldCase);
private:
RefPtr<SpaceSplitStringData> m_data;
Modified: trunk/Source/WebCore/html/Autofill.cpp (292962 => 292963)
--- trunk/Source/WebCore/html/Autofill.cpp 2022-04-18 18:46:45 UTC (rev 292962)
+++ trunk/Source/WebCore/html/Autofill.cpp 2022-04-18 18:56:46 UTC (rev 292963)
@@ -162,7 +162,7 @@
return defaultLabel();
// 2. Let tokens be the result of splitting the attribute's value on spaces.
- SpaceSplitString tokens(attributeValue, true);
+ SpaceSplitString tokens(attributeValue, SpaceSplitString::ShouldFoldCase::Yes);
// 3. If tokens is empty, then jump to the step labeled default.
if (tokens.isEmpty())
Modified: trunk/Source/WebCore/html/HTMLAnchorElement.cpp (292962 => 292963)
--- trunk/Source/WebCore/html/HTMLAnchorElement.cpp 2022-04-18 18:46:45 UTC (rev 292962)
+++ trunk/Source/WebCore/html/HTMLAnchorElement.cpp 2022-04-18 18:56:46 UTC (rev 292963)
@@ -259,8 +259,7 @@
static MainThreadNeverDestroyed<const AtomString> noReferrer("noreferrer", AtomString::ConstructFromLiteral);
static MainThreadNeverDestroyed<const AtomString> noOpener("noopener", AtomString::ConstructFromLiteral);
static MainThreadNeverDestroyed<const AtomString> opener("opener", AtomString::ConstructFromLiteral);
- const bool shouldFoldCase = true;
- SpaceSplitString relValue(value, shouldFoldCase);
+ SpaceSplitString relValue(value, SpaceSplitString::ShouldFoldCase::Yes);
if (relValue.contains(noReferrer))
m_linkRelations.add(Relation::NoReferrer);
if (relValue.contains(noOpener))
@@ -370,7 +369,7 @@
if (!hasAttributeWithoutSynchronization(pingAttr) || !document().settings().hyperlinkAuditingEnabled())
return;
- SpaceSplitString pingURLs(attributeWithoutSynchronization(pingAttr), false);
+ SpaceSplitString pingURLs(attributeWithoutSynchronization(pingAttr), SpaceSplitString::ShouldFoldCase::No);
for (unsigned i = 0; i < pingURLs.size(); i++)
PingLoader::sendPing(*document().frame(), document().completeURL(pingURLs[i]), destinationURL);
}
Modified: trunk/Source/WebCore/inspector/InspectorAuditAccessibilityObject.cpp (292962 => 292963)
--- trunk/Source/WebCore/inspector/InspectorAuditAccessibilityObject.cpp 2022-04-18 18:46:45 UTC (rev 292962)
+++ trunk/Source/WebCore/inspector/InspectorAuditAccessibilityObject.cpp 2022-04-18 18:56:46 UTC (rev 292963)
@@ -203,7 +203,7 @@
String ariaRelevantRemovals = "removals"_s;
String ariaRelevantText = "text"_s;
- const auto& values = SpaceSplitString(ariaRelevantAttrValue, true);
+ const auto& values = SpaceSplitString(ariaRelevantAttrValue, SpaceSplitString::ShouldFoldCase::Yes);
if (values.contains("all"_s)) {
liveRegionRelevant.append(ariaRelevantAdditions);
liveRegionRelevant.append(ariaRelevantRemovals);
Modified: trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp (292962 => 292963)
--- trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp 2022-04-18 18:46:45 UTC (rev 292962)
+++ trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp 2022-04-18 18:56:46 UTC (rev 292963)
@@ -2190,7 +2190,7 @@
String ariaRelevantRemovals = Protocol::Helpers::getEnumConstantValue(Protocol::DOM::LiveRegionRelevant::Removals);
String ariaRelevantText = Protocol::Helpers::getEnumConstantValue(Protocol::DOM::LiveRegionRelevant::Text);
liveRegionRelevant = JSON::ArrayOf<String>::create();
- const SpaceSplitString& values = SpaceSplitString(ariaRelevantAttrValue, true);
+ SpaceSplitString values(ariaRelevantAttrValue, SpaceSplitString::ShouldFoldCase::Yes);
// @aria-relevant="all" is exposed as ["additions","removals","text"], in order.
// This order is controlled in WebCore and expected in WebInspectorUI.
if (values.contains("all"_s)) {
Modified: trunk/Source/WebCore/page/EventHandler.cpp (292962 => 292963)
--- trunk/Source/WebCore/page/EventHandler.cpp 2022-04-18 18:46:45 UTC (rev 292962)
+++ trunk/Source/WebCore/page/EventHandler.cpp 2022-04-18 18:56:46 UTC (rev 292963)
@@ -2345,7 +2345,7 @@
{
RefPtr<Element> element = is<Element>(target) ? &downcast<Element>(target) : target.parentElement();
for (; element; element = element->parentElement()) {
- SpaceSplitString keywords(element->attributeWithoutSynchronization(webkitdropzoneAttr), true);
+ SpaceSplitString keywords(element->attributeWithoutSynchronization(webkitdropzoneAttr), SpaceSplitString::ShouldFoldCase::Yes);
bool matched = false;
std::optional<DragOperation> dragOperation;
for (unsigned i = 0, size = keywords.size(); i < size; ++i) {