Bug 1335863 - Inline common case parent access. r=emilio

This commit is contained in:
Bobby Holley 2017-02-01 12:37:00 -08:00
Родитель bd672b2ad1
Коммит c35f772b59
3 изменённых файлов: 56 добавлений и 29 удалений

Просмотреть файл

@ -34,39 +34,52 @@ inline mozilla::dom::ShadowRoot* nsIContent::GetShadowRoot() const
}
template<nsIContent::FlattenedParentType Type>
static inline nsINode*
GetFlattenedTreeParentNode(const nsINode* aNode)
static inline bool FlattenedTreeParentIsParent(const nsINode* aNode)
{
nsINode* parent = aNode->GetParentNode();
// Try to short-circuit past the complicated and not-exactly-fast logic for
// computing the flattened parent.
//
// There are four cases where we need might something other than parentNode:
// (1) The node is an explicit child of an XBL-bound element, re-bound
// to an XBL insertion point.
// (2) The node is a top-level element in a shadow tree, whose flattened
// parent is the host element (as opposed to the actual parent which
// WARNING! This logic is replicated in Servo to avoid out of line calls.
// If you change the cases here, you need to change them in Servo as well!
// Check if the node is an explicit child of an XBL-bound element, re-bound to
// an XBL insertion point, or is a top-level element in a shadow tree, whose
// flattened parent is the host element (as opposed to the actual parent which
// is the shadow root).
// (3) The node is an explicit child of an element with a shadow root,
if (aNode->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR | NODE_IS_IN_SHADOW_TREE)) {
return false;
}
// Check if we want the flattened parent for style, and the node is the root
// of a native anonymous content subtree parented to the document's root element.
if (Type == nsIContent::eForStyle && aNode->HasFlag(NODE_IS_NATIVE_ANONYMOUS_ROOT) &&
aNode->OwnerDoc()->GetRootElement() == aNode->GetParentNode())
{
return false;
}
// Check if the node is an explicit child of an element with a shadow root,
// re-bound to an insertion point.
// (4) We want the flattened parent for style, and the node is the root
// of a native anonymous content subtree parented to the document's
// root element.
bool needSlowCall = aNode->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR) ||
aNode->IsInShadowTree() ||
(parent &&
parent->IsContent() &&
parent->AsContent()->GetShadowRoot()) ||
(Type == nsIContent::eForStyle &&
aNode->IsContent() &&
aNode->AsContent()->IsRootOfNativeAnonymousSubtree() &&
aNode->OwnerDoc()->GetRootElement() == parent);
if (MOZ_UNLIKELY(needSlowCall)) {
nsIContent* parent = aNode->GetParent();
if (parent && parent->GetShadowRoot()) {
return false;
}
// Common case.
return true;
}
template<nsIContent::FlattenedParentType Type>
static inline nsINode*
GetFlattenedTreeParentNode(const nsINode* aNode)
{
if (MOZ_LIKELY(FlattenedTreeParentIsParent<Type>(aNode))) {
return aNode->GetParentNode();
}
MOZ_ASSERT(aNode->IsContent());
return aNode->AsContent()->GetFlattenedTreeParentNodeInternal(Type);
}
return parent;
}
inline nsINode*
nsINode::GetFlattenedTreeParentNode() const

Просмотреть файл

@ -73,10 +73,24 @@ Gecko_IsInDocument(RawGeckoNodeBorrowed aNode)
return aNode->IsInComposedDoc();
}
#ifdef DEBUG
bool
Gecko_FlattenedTreeParentIsParent(RawGeckoNodeBorrowed aNode)
{
// Servo calls this in debug builds to verify the result of its own
// flattened_tree_parent_is_parent() function.
return FlattenedTreeParentIsParent<nsIContent::eForStyle>(aNode);
}
#endif
RawGeckoNodeBorrowedOrNull
Gecko_GetParentNode(RawGeckoNodeBorrowed aNode)
{
return aNode->GetFlattenedTreeParentNodeForStyle();
MOZ_ASSERT(!FlattenedTreeParentIsParent<nsIContent::eForStyle>(aNode),
"Should have taken the inline path");
MOZ_ASSERT(aNode->IsContent(), "Slow path only applies to content");
const nsIContent* c = aNode->AsContent();
return c->GetFlattenedTreeParentNodeInternal(nsIContent::eForStyle);
}
RawGeckoNodeBorrowedOrNull

Просмотреть файл

@ -89,12 +89,12 @@ NS_DECL_HOLDER_FFI_REFCOUNTING(nsIURI, URI)
uint32_t Gecko_ChildrenCount(RawGeckoNodeBorrowed node);
bool Gecko_NodeIsElement(RawGeckoNodeBorrowed node);
bool Gecko_IsInDocument(RawGeckoNodeBorrowed node);
bool Gecko_FlattenedTreeParentIsParent(RawGeckoNodeBorrowed node);
RawGeckoNodeBorrowedOrNull Gecko_GetParentNode(RawGeckoNodeBorrowed node);
RawGeckoNodeBorrowedOrNull Gecko_GetFirstChild(RawGeckoNodeBorrowed node);
RawGeckoNodeBorrowedOrNull Gecko_GetLastChild(RawGeckoNodeBorrowed node);
RawGeckoNodeBorrowedOrNull Gecko_GetPrevSibling(RawGeckoNodeBorrowed node);
RawGeckoNodeBorrowedOrNull Gecko_GetNextSibling(RawGeckoNodeBorrowed node);
RawGeckoElementBorrowedOrNull Gecko_GetParentElement(RawGeckoElementBorrowed element);
RawGeckoElementBorrowedOrNull Gecko_GetFirstChildElement(RawGeckoElementBorrowed element);
RawGeckoElementBorrowedOrNull Gecko_GetLastChildElement(RawGeckoElementBorrowed element);
RawGeckoElementBorrowedOrNull Gecko_GetPrevSiblingElement(RawGeckoElementBorrowed element);