Commit 99659043 authored by Mason Freed's avatar Mason Freed Committed by Commit Bot

Optimize bit access for hot code path in IsHTMLElement()

The [1] CL combined the ElementNamespaceType bits, to save
space. However, as seen in [2], this caused a performance
regression, likely due to a slower IsHTMLElement(). This CL
attempts to get back that performance through two optimizations:
 - ALWAYS_INLINE the accessors for both GetElementNamespaceType()
   and the IsXyzElement() accessors.
 - Move kHTML to a value of 0, in the hope that this operation
   is faster when the kConstant is zero:
      GetElementNamespaceType() == kConstant

[1] https://chromium.googlesource.com/chromium/src/+/956931765e5969c44ad9a4641ff1c99977c8498f
[2] https://crbug.com/1036543

Bug: 1036543
Change-Id: I4976829ab0b7c9d875d4d4e6b516333b44e7dddb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2029311
Commit-Queue: Kent Tamura <tkent@chromium.org>
Auto-Submit: Mason Freed <masonfreed@chromium.org>
Reviewed-by: default avatarKent Tamura <tkent@chromium.org>
Cr-Commit-Position: refs/heads/master@{#737181}
parent 9b575aed
...@@ -278,13 +278,13 @@ class CORE_EXPORT Node : public EventTarget { ...@@ -278,13 +278,13 @@ class CORE_EXPORT Node : public EventTarget {
return GetDOMNodeType() == DOMNodeType::kDocumentFragment; return GetDOMNodeType() == DOMNodeType::kDocumentFragment;
} }
bool IsHTMLElement() const { ALWAYS_INLINE bool IsHTMLElement() const {
return GetElementNamespaceType() == ElementNamespaceType::kHTML; return GetElementNamespaceType() == ElementNamespaceType::kHTML;
} }
bool IsMathMLElement() const { ALWAYS_INLINE bool IsMathMLElement() const {
return GetElementNamespaceType() == ElementNamespaceType::kMathML; return GetElementNamespaceType() == ElementNamespaceType::kMathML;
} }
bool IsSVGElement() const { ALWAYS_INLINE bool IsSVGElement() const {
return GetElementNamespaceType() == ElementNamespaceType::kSVG; return GetElementNamespaceType() == ElementNamespaceType::kSVG;
} }
...@@ -989,35 +989,42 @@ class CORE_EXPORT Node : public EventTarget { ...@@ -989,35 +989,42 @@ class CORE_EXPORT Node : public EventTarget {
} }
enum class ElementNamespaceType : uint32_t { enum class ElementNamespaceType : uint32_t {
kOther = 0, kHTML = 0,
kHTML = 1 << kElementNamespaceTypeShift, kMathML = 1 << kElementNamespaceTypeShift,
kMathML = 2 << kElementNamespaceTypeShift, kSVG = 2 << kElementNamespaceTypeShift,
kSVG = 3 << kElementNamespaceTypeShift, kOther = 3 << kElementNamespaceTypeShift,
}; };
ElementNamespaceType GetElementNamespaceType() const { ALWAYS_INLINE ElementNamespaceType GetElementNamespaceType() const {
return static_cast<ElementNamespaceType>(node_flags_ & return static_cast<ElementNamespaceType>(node_flags_ &
kElementNamespaceTypeMask); kElementNamespaceTypeMask);
} }
protected: protected:
enum ConstructionType { enum ConstructionType {
kCreateOther = kCreateOther = kDefaultNodeFlags |
kDefaultNodeFlags | static_cast<NodeFlags>(DOMNodeType::kOther), static_cast<NodeFlags>(DOMNodeType::kOther) |
kCreateText = static_cast<NodeFlags>(ElementNamespaceType::kOther),
kDefaultNodeFlags | static_cast<NodeFlags>(DOMNodeType::kText), kCreateText = kDefaultNodeFlags |
kCreateContainer = kDefaultNodeFlags | kIsContainerFlag, static_cast<NodeFlags>(DOMNodeType::kText) |
static_cast<NodeFlags>(ElementNamespaceType::kOther),
kCreateContainer = kDefaultNodeFlags | kIsContainerFlag |
static_cast<NodeFlags>(ElementNamespaceType::kOther),
kCreateElement = kCreateElement =
kCreateContainer | static_cast<NodeFlags>(DOMNodeType::kElement), kCreateContainer | static_cast<NodeFlags>(DOMNodeType::kElement),
kCreateDocumentFragment = kCreateDocumentFragment =
kCreateContainer | kCreateContainer |
static_cast<NodeFlags>(DOMNodeType::kDocumentFragment), static_cast<NodeFlags>(DOMNodeType::kDocumentFragment),
kCreateShadowRoot = kCreateDocumentFragment | kIsInShadowTreeFlag, kCreateShadowRoot = kCreateDocumentFragment | kIsInShadowTreeFlag,
kCreateHTMLElement = kCreateHTMLElement = kDefaultNodeFlags | kIsContainerFlag |
kCreateElement | static_cast<NodeFlags>(ElementNamespaceType::kHTML), static_cast<NodeFlags>(DOMNodeType::kElement) |
static_cast<NodeFlags>(ElementNamespaceType::kHTML),
kCreateMathMLElement = kCreateMathMLElement =
kCreateElement | static_cast<NodeFlags>(ElementNamespaceType::kMathML), kDefaultNodeFlags | kIsContainerFlag |
kCreateSVGElement = static_cast<NodeFlags>(DOMNodeType::kElement) |
kCreateElement | static_cast<NodeFlags>(ElementNamespaceType::kSVG), static_cast<NodeFlags>(ElementNamespaceType::kMathML),
kCreateSVGElement = kDefaultNodeFlags | kIsContainerFlag |
static_cast<NodeFlags>(DOMNodeType::kElement) |
static_cast<NodeFlags>(ElementNamespaceType::kSVG),
kCreateDocument = kCreateContainer | kIsConnectedFlag, kCreateDocument = kCreateContainer | kIsConnectedFlag,
kCreateV0InsertionPoint = kCreateHTMLElement | kIsV0InsertionPointFlag, kCreateV0InsertionPoint = kCreateHTMLElement | kIsV0InsertionPointFlag,
kCreateEditingText = kCreateText | kHasNameOrIsEditingTextFlag, kCreateEditingText = kCreateText | kHasNameOrIsEditingTextFlag,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment