author | Boris Zbarsky <bzbarsky@mit.edu> |
Wed, 08 Mar 2017 00:18:40 -0500 | |
changeset 346444 | afd58f4674d1fdc102e1887b7dbcc13a0c255fc2 |
parent 346443 | 930853cae5a4933387751ac54caccd29b8f4a41e |
child 346445 | 74bd66f2490e43cb9dfc9a8dbc4a0f01a2629126 |
push id | 31467 |
push user | cbook@mozilla.com |
push date | Wed, 08 Mar 2017 13:18:20 +0000 |
treeherder | mozilla-central@becff35a0bed [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | dbaron |
bugs | 1343078 |
milestone | 55.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/layout/base/GeckoRestyleManager.cpp +++ b/layout/base/GeckoRestyleManager.cpp @@ -2481,17 +2481,20 @@ ElementRestyler::RestyleSelf(nsIFrame* a newContext = prevContinuationContext; } else if (pseudoTag == nsCSSAnonBoxes::mozText) { MOZ_ASSERT(aSelf->GetType() == nsGkAtoms::textFrame); newContext = styleSet->ResolveStyleForText(aSelf->GetContent(), parentContext); } else if (pseudoTag == nsCSSAnonBoxes::firstLetterContinuation) { newContext = styleSet->ResolveStyleForFirstLetterContinuation(parentContext); } else if (pseudoTag == nsCSSAnonBoxes::oofPlaceholder) { - newContext = styleSet->ResolveStyleForPlaceholder(parentContext); + // We still need to ResolveStyleForPlaceholder() here, because we may be + // doing a ruletree reconstruct and hence actually changing our style + // context. + newContext = styleSet->ResolveStyleForPlaceholder(); } else { Element* element = ElementForStyleContext(mParentContent, aSelf, pseudoType); if (!MustRestyleSelf(aRestyleHint, element)) { if (CanReparentStyleContext(aRestyleHint)) { LOG_RESTYLE("reparenting style context"); newContext = styleSet->ReparentStyleContext(oldContext, parentContext, element);
--- a/layout/base/crashtests/crashtests.list +++ b/layout/base/crashtests/crashtests.list @@ -105,17 +105,17 @@ load 344057-1.xhtml load 344064-1.html load 344300-1.html load 344300-2.html load 344340-1.xul load 347898-1.html load 348126-1.html load 348688-1.html load 348708-1.xhtml -asserts(2) asserts-if(stylo,0) load 348729-1.html # bug 548836 +asserts(1) asserts-if(stylo,0) load 348729-1.html # bug 548836 load 349095-1.xhtml load 350128-1.xhtml load 350267-1.html load 354133-1.html load 354766-1.xhtml load 354771-1.xul load 355989-1.xhtml load 355993-1.xhtml
--- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -1243,18 +1243,17 @@ nsFrameConstructorState::ConstructBackdr nsFrameState placeholderType; nsAbsoluteItems* frameItems = GetOutOfFlowFrameItems(backdropFrame, true, true, false, &placeholderType); MOZ_ASSERT(placeholderType == PLACEHOLDER_FOR_TOPLAYER); nsIFrame* placeholder = nsCSSFrameConstructor:: CreatePlaceholderFrameFor(mPresShell, aContent, backdropFrame, - frame->StyleContext(), frame, nullptr, - PLACEHOLDER_FOR_TOPLAYER); + frame, nullptr, PLACEHOLDER_FOR_TOPLAYER); nsFrameList temp(placeholder, placeholder); frame->SetInitialChildList(nsIFrame::kBackdropList, temp); frameItems->AddChild(backdropFrame); } void nsFrameConstructorState::AddChild(nsIFrame* aNewFrame, @@ -1286,22 +1285,20 @@ nsFrameConstructorState::AddChild(nsIFra } else { frameItems = &aFrameItems; placeholderType = nsFrameState(0); } if (placeholderType) { NS_ASSERTION(frameItems != &aFrameItems, "Putting frame in-flow _and_ want a placeholder?"); - nsStyleContext* parentContext = aStyleContext->GetParent(); nsIFrame* placeholderFrame = nsCSSFrameConstructor::CreatePlaceholderFrameFor(mPresShell, aContent, aNewFrame, - parentContext, aParentFrame, nullptr, placeholderType); placeholderFrame->AddStateBits(mAdditionalStateBits); // Add the placeholder frame to the flow aFrameItems.AddChild(placeholderFrame); @@ -3029,23 +3026,22 @@ nsCSSFrameConstructor::ConstructPageFram return pageFrame; } /* static */ nsIFrame* nsCSSFrameConstructor::CreatePlaceholderFrameFor(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame* aFrame, - nsStyleContext* aParentStyle, nsContainerFrame* aParentFrame, nsIFrame* aPrevInFlow, nsFrameState aTypeBit) { RefPtr<nsStyleContext> placeholderStyle = aPresShell->StyleSet()-> - ResolveStyleForPlaceholder(aParentStyle); + ResolveStyleForPlaceholder(); // The placeholder frame gets a pseudo style context nsPlaceholderFrame* placeholderFrame = (nsPlaceholderFrame*)NS_NewPlaceholderFrame(aPresShell, placeholderStyle, aTypeBit); placeholderFrame->Init(aContent, aParentFrame, aPrevInFlow); @@ -9124,17 +9120,16 @@ nsCSSFrameConstructor::CreateContinuingF newFrame->Init(content, aParentFrame, aFrame); } else if (nsGkAtoms::placeholderFrame == frameType) { // create a continuing out of flow frame nsIFrame* oofFrame = nsPlaceholderFrame::GetRealFrameForPlaceholder(aFrame); nsIFrame* oofContFrame = CreateContinuingFrame(aPresContext, oofFrame, aParentFrame); newFrame = CreatePlaceholderFrameFor(shell, content, oofContFrame, - styleContext->GetParent(), aParentFrame, aFrame, aFrame->GetStateBits() & PLACEHOLDER_TYPE_MASK); } else if (nsGkAtoms::fieldSetFrame == frameType) { nsContainerFrame* fieldset = NS_NewFieldSetFrame(shell, styleContext); fieldset->Init(content, aParentFrame, aFrame); // Create a continuing area frame
--- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -1308,17 +1308,16 @@ private: nsStyleContext* aStyleContext); // END TABLE SECTION protected: static nsIFrame* CreatePlaceholderFrameFor(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame* aFrame, - nsStyleContext* aParentStyle, nsContainerFrame* aParentFrame, nsIFrame* aPrevInFlow, nsFrameState aTypeBit); static nsIFrame* CreateBackdropFrameFor(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame* aFrame, nsContainerFrame* aParentFrame);
--- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -9288,23 +9288,23 @@ nsFrame::DoGetParentStyleContext(nsIFram // frame would have if we didn't mangle the frame structure. *aProviderFrame = GetCorrectedParent(this); return *aProviderFrame ? (*aProviderFrame)->StyleContext() : nullptr; } // We're an out-of-flow frame. For out-of-flow frames, we must // resolve underneath the placeholder's parent. The placeholder is // reached from the first-in-flow. - nsIFrame* placeholder = fm->GetPlaceholderFrameFor(FirstInFlow()); + nsPlaceholderFrame* placeholder = fm->GetPlaceholderFrameFor(FirstInFlow()); if (!placeholder) { NS_NOTREACHED("no placeholder frame for out-of-flow frame"); *aProviderFrame = GetCorrectedParent(this); return *aProviderFrame ? (*aProviderFrame)->StyleContext() : nullptr; } - return placeholder->GetParentStyleContext(aProviderFrame); + return placeholder->GetParentStyleContextForOutOfFlow(aProviderFrame); } void nsFrame::GetLastLeaf(nsPresContext* aPresContext, nsIFrame **aFrame) { if (!aFrame || !*aFrame) { return; }
--- a/layout/generic/nsPlaceholderFrame.cpp +++ b/layout/generic/nsPlaceholderFrame.cpp @@ -187,17 +187,17 @@ nsPlaceholderFrame::CanContinueTextRun() return false; } // first-letter frames can continue text runs, and placeholders for floated // first-letter frames can too return mOutOfFlowFrame->CanContinueTextRun(); } nsStyleContext* -nsPlaceholderFrame::GetParentStyleContext(nsIFrame** aProviderFrame) const +nsPlaceholderFrame::GetParentStyleContextForOutOfFlow(nsIFrame** aProviderFrame) const { NS_PRECONDITION(GetParent(), "How can we not have a parent here?"); nsIContent* parentContent = mContent ? mContent->GetFlattenedTreeParent() : nullptr; if (parentContent) { nsStyleContext* sc = PresContext()->FrameManager()->GetDisplayContentsStyleFor(parentContent); if (sc) {
--- a/layout/generic/nsPlaceholderFrame.h +++ b/layout/generic/nsPlaceholderFrame.h @@ -132,17 +132,17 @@ public: virtual mozilla::a11y::AccType AccessibleType() override { nsIFrame* realFrame = GetRealFrameForPlaceholder(this); return realFrame ? realFrame->AccessibleType() : nsFrame::AccessibleType(); } #endif - virtual nsStyleContext* GetParentStyleContext(nsIFrame** aProviderFrame) const override; + nsStyleContext* GetParentStyleContextForOutOfFlow(nsIFrame** aProviderFrame) const; bool RenumberFrameAndDescendants(int32_t* aOrdinal, int32_t aDepth, int32_t aIncrement, bool aForCounting) override { return mOutOfFlowFrame-> RenumberFrameAndDescendants(aOrdinal, aDepth, aIncrement, aForCounting);
--- a/layout/style/ServoStyleSet.cpp +++ b/layout/style/ServoStyleSet.cpp @@ -263,30 +263,37 @@ ServoStyleSet::ResolveStyleForFirstLette return GetContext(computedValues.forget(), aParentContext, nsCSSAnonBoxes::firstLetterContinuation, CSSPseudoElementType::AnonBox, nullptr); } already_AddRefed<nsStyleContext> -ServoStyleSet::ResolveStyleForPlaceholder(nsStyleContext* aParentContext) +ServoStyleSet::ResolveStyleForPlaceholder() { - // The parent context can be null if the placeholder's element is a root - // element. - const ServoComputedValues* parent = - aParentContext ? aParentContext->StyleSource().AsServoComputedValues() : nullptr; + RefPtr<nsStyleContext>& cache = + mNonInheritingStyleContexts[ + static_cast<nsCSSAnonBoxes::NonInheritingBase>(nsCSSAnonBoxes::NonInheriting::oofPlaceholder)]; + if (cache) { + RefPtr<nsStyleContext> retval = cache; + return retval.forget(); + } + RefPtr<ServoComputedValues> computedValues = - Servo_ComputedValues_Inherit(mRawSet.get(), parent).Consume(); + Servo_ComputedValues_Inherit(mRawSet.get(), nullptr).Consume(); MOZ_ASSERT(computedValues); - return GetContext(computedValues.forget(), aParentContext, - nsCSSAnonBoxes::oofPlaceholder, - CSSPseudoElementType::AnonBox, - nullptr); + RefPtr<nsStyleContext> retval = + GetContext(computedValues.forget(), nullptr, + nsCSSAnonBoxes::oofPlaceholder, + CSSPseudoElementType::AnonBox, + nullptr); + cache = retval; + return retval.forget(); } already_AddRefed<nsStyleContext> ServoStyleSet::ResolvePseudoElementStyle(Element* aOriginatingElement, CSSPseudoElementType aType, nsStyleContext* aParentContext, Element* aPseudoElement) {
--- a/layout/style/ServoStyleSet.h +++ b/layout/style/ServoStyleSet.h @@ -109,20 +109,20 @@ public: ResolveStyleForFirstLetterContinuation(nsStyleContext* aParentContext); // Get a style context for a placeholder frame (which no rules will match). // // The returned style context will have nsCSSAnonBoxes::oofPlaceholder as // its pseudo. // // (Perhaps nsCSSAnonBoxes::oofPaceholder should go away and we shouldn't even - // create style contexts for placeholders. However, not doing - // any rule matching for them is a first step.) + // create style contexts for placeholders. However, not doing any rule + // matching for them is a first step.) already_AddRefed<nsStyleContext> - ResolveStyleForPlaceholder(nsStyleContext* aParentContext); + ResolveStyleForPlaceholder(); // Get a style context for a pseudo-element. aParentElement must be // non-null. aPseudoID is the CSSPseudoElementType for the // pseudo-element. aPseudoElement must be non-null if the pseudo-element // type is one that allows user action pseudo-classes after it or allows // style attributes; otherwise, it is ignored. already_AddRefed<nsStyleContext> ResolvePseudoElementStyle(dom::Element* aOriginatingElement,
--- a/layout/style/StyleSetHandle.h +++ b/layout/style/StyleSetHandle.h @@ -123,17 +123,17 @@ public: LazyComputeBehavior aMayCompute, TreeMatchContext& aTreeMatchContext); inline already_AddRefed<nsStyleContext> ResolveStyleForText(nsIContent* aTextNode, nsStyleContext* aParentContext); inline already_AddRefed<nsStyleContext> ResolveStyleForFirstLetterContinuation(nsStyleContext* aParentContext); inline already_AddRefed<nsStyleContext> - ResolveStyleForPlaceholder(nsStyleContext* aParentContext); + ResolveStyleForPlaceholder(); inline already_AddRefed<nsStyleContext> ResolvePseudoElementStyle(dom::Element* aParentElement, mozilla::CSSPseudoElementType aType, nsStyleContext* aParentContext, dom::Element* aPseudoElement); inline already_AddRefed<nsStyleContext> ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag, nsStyleContext* aParentContext, uint32_t aFlags = 0);
--- a/layout/style/StyleSetHandleInlines.h +++ b/layout/style/StyleSetHandleInlines.h @@ -97,19 +97,19 @@ StyleSetHandle::Ptr::ResolveStyleFor(dom already_AddRefed<nsStyleContext> StyleSetHandle::Ptr::ResolveStyleForText(nsIContent* aTextNode, nsStyleContext* aParentContext) { FORWARD(ResolveStyleForText, (aTextNode, aParentContext)); } already_AddRefed<nsStyleContext> -StyleSetHandle::Ptr::ResolveStyleForPlaceholder(nsStyleContext* aParentContext) +StyleSetHandle::Ptr::ResolveStyleForPlaceholder() { - FORWARD(ResolveStyleForPlaceholder, (aParentContext)); + FORWARD(ResolveStyleForPlaceholder, ()); } already_AddRefed<nsStyleContext> StyleSetHandle::Ptr::ResolveStyleForFirstLetterContinuation(nsStyleContext* aParentContext) { FORWARD(ResolveStyleForFirstLetterContinuation, (aParentContext)); }
--- a/layout/style/nsCSSAnonBoxList.h +++ b/layout/style/nsCSSAnonBoxList.h @@ -33,17 +33,17 @@ #endif /* CSS_NON_INHERITING_ANON_BOX */ // ::-moz-text, ::-moz-oof-placeholder, and ::-moz-first-letter-continuation are // non-elements which no rule will match. CSS_ANON_BOX(mozText, ":-moz-text") // placeholder frames for out of flows. Note that :-moz-placeholder is used for // the pseudo-element that represents the placeholder text in <input // placeholder="foo">, so we need a different string here. -CSS_ANON_BOX(oofPlaceholder, ":-moz-oof-placeholder") +CSS_NON_INHERITING_ANON_BOX(oofPlaceholder, ":-moz-oof-placeholder") // nsFirstLetterFrames for content outside the ::first-letter. CSS_ANON_BOX(firstLetterContinuation, ":-moz-first-letter-continuation") CSS_ANON_BOX(mozAnonymousBlock, ":-moz-anonymous-block") CSS_ANON_BOX(mozAnonymousPositionedBlock, ":-moz-anonymous-positioned-block") CSS_ANON_BOX(mozMathMLAnonymousBlock, ":-moz-mathml-anonymous-block") CSS_ANON_BOX(mozXULAnonymousBlock, ":-moz-xul-anonymous-block")
--- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -1836,21 +1836,32 @@ already_AddRefed<nsStyleContext> nsStyleSet::ResolveStyleForFirstLetterContinuation(nsStyleContext* aParentContext) { return GetContext(aParentContext, mRuleTree, nullptr, nsCSSAnonBoxes::firstLetterContinuation, CSSPseudoElementType::AnonBox, nullptr, eNoFlags); } already_AddRefed<nsStyleContext> -nsStyleSet::ResolveStyleForPlaceholder(nsStyleContext* aParentContext) +nsStyleSet::ResolveStyleForPlaceholder() { - return GetContext(aParentContext, mRuleTree, nullptr, - nsCSSAnonBoxes::oofPlaceholder, - CSSPseudoElementType::AnonBox, nullptr, eNoFlags); + RefPtr<nsStyleContext>& cache = + mNonInheritingStyleContexts[ + static_cast<nsCSSAnonBoxes::NonInheritingBase>(nsCSSAnonBoxes::NonInheriting::oofPlaceholder)]; + if (cache) { + RefPtr<nsStyleContext> retval = cache; + return retval.forget(); + } + + RefPtr<nsStyleContext> retval = + GetContext(nullptr, mRuleTree, nullptr, + nsCSSAnonBoxes::oofPlaceholder, + CSSPseudoElementType::AnonBox, nullptr, eNoFlags); + cache = retval; + return retval.forget(); } void nsStyleSet::WalkRestrictionRule(CSSPseudoElementType aPseudoType, nsRuleWalker* aRuleWalker) { // This needs to match GetPseudoRestriction in nsRuleNode.cpp. aRuleWalker->SetLevel(SheetType::Agent, false, false);
--- a/layout/style/nsStyleSet.h +++ b/layout/style/nsStyleSet.h @@ -227,17 +227,17 @@ class nsStyleSet final // // The returned style context will have nsCSSAnonBoxes::oofPlaceholder as // its pseudo. // // (Perhaps nsCSSAnonBoxes::oofPlaceholder should go away and we shouldn't // even create style contexts for placeholders. However, not doing any rule // matching for them is a first step.) already_AddRefed<nsStyleContext> - ResolveStyleForPlaceholder(nsStyleContext* aParentContext); + ResolveStyleForPlaceholder(); // Get a style context for a pseudo-element. aParentElement must be // non-null. aPseudoID is the CSSPseudoElementType for the // pseudo-element. aPseudoElement must be non-null if the pseudo-element // type is one that allows user action pseudo-classes after it or allows // style attributes; otherwise, it is ignored. already_AddRefed<nsStyleContext> ResolvePseudoElementStyle(mozilla::dom::Element* aParentElement,
--- a/layout/xul/tree/nsTreeStyleCache.cpp +++ b/layout/xul/tree/nsTreeStyleCache.cpp @@ -78,17 +78,17 @@ nsTreeStyleCache::GetStyleContext(nsICSS } if (!result) { // We missed the cache. Resolve this pseudo-style. // XXXheycam ServoStyleSets do not support XUL tree styles. RefPtr<nsStyleContext> newResult; if (aPresContext->StyleSet()->IsServo()) { NS_ERROR("stylo: ServoStyleSets should not support XUL tree styles yet"); newResult = aPresContext->StyleSet()-> - ResolveStyleForPlaceholder(aContext); + ResolveStyleForPlaceholder(); } else { newResult = aPresContext->StyleSet()->AsGecko()-> ResolveXULTreePseudoStyle(aContent->AsElement(), aPseudoElement, aContext, aComparator); } // Put the style context in our table, transferring the owning reference to the table. if (!mCache) {