author | Andreea Pavel <apavel@mozilla.com> |
Tue, 16 Jan 2018 14:26:41 +0200 | |
changeset 453715 | da9adac5500fca2ee893ebe1c363ffd24cceb969 |
parent 453714 | 1565e46c84799fbf3c8a1b609d649446a205796a |
child 453716 | 3b7efb332de3425cae2606ada7f923fb3f3670d2 |
push id | 1648 |
push user | mtabara@mozilla.com |
push date | Thu, 01 Mar 2018 12:45:47 +0000 |
treeherder | mozilla-release@cbb9688c2eeb [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 1428491 |
milestone | 59.0a1 |
backs out | 308e79e6c98f0f38c3c7c1652fd6ceae35a12955 dbfd798e491b86e55ec11b8d5cccc260e885f619 |
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/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -4019,19 +4019,20 @@ nsDocument::CreateShell(nsPresContext* a if (node->IsElement()) { MOZ_ASSERT(!node->AsElement()->HasServoData()); } } #endif } RefPtr<PresShell> shell = new PresShell; + shell->Init(this, aContext, aViewManager, aStyleSet); + // Note: we don't hold a ref to the shell (it holds a ref to us) mPresShell = shell; - shell->Init(this, aContext, aViewManager, aStyleSet); // Make sure to never paint if we belong to an invisible DocShell. nsCOMPtr<nsIDocShell> docShell(mDocumentContainer); if (docShell && docShell->IsInvisible()) shell->SetNeverPainting(true); MOZ_LOG(gDocumentLeakPRLog, LogLevel::Debug, ("DOCUMENT %p with PressShell %p and DocShell %p", this, shell.get(), docShell.get()));
--- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -954,17 +954,17 @@ PresShell::Init(nsIDocument* aDocument, // Bind the context to the presentation shell. mPresContext = aPresContext; mPresContext->AttachShell(this, aStyleSet->BackendType()); // Now we can initialize the style set. Make sure to set the member before // calling Init, since various subroutines need to find the style set off // the PresContext during initialization. mStyleSet = aStyleSet; - mStyleSet->Init(aPresContext); + mStyleSet->Init(aPresContext, mDocument->BindingManager()); // Notify our prescontext that it now has a compatibility mode. Note that // this MUST happen after we set up our style set but before we create any // frames. mPresContext->CompatibilityModeChanged(); // Add the preference style sheet. UpdatePreferenceStyles();
--- a/layout/style/ServoStyleSet.cpp +++ b/layout/style/ServoStyleSet.cpp @@ -76,32 +76,32 @@ private: // Sets up for one or more calls to Servo_TraverseSubtree. class MOZ_RAII AutoPrepareTraversal { public: explicit AutoPrepareTraversal(ServoStyleSet* aSet) // For markers for animations, we have already set the markers in // ServoRestyleManager::PostRestyleEventForAnimations so that we don't need // to care about animation restyles here. - : mTimelineMarker(aSet->mDocument->GetDocShell(), false) + : mTimelineMarker(aSet->mPresContext->GetDocShell(), false) , mSetInServoTraversal(aSet) { MOZ_ASSERT(!aSet->StylistNeedsUpdate()); } private: AutoRestyleTimelineMarker mTimelineMarker; AutoSetInServoTraversal mSetInServoTraversal; }; } // namespace mozilla ServoStyleSet::ServoStyleSet(Kind aKind) : mKind(aKind) - , mDocument(nullptr) + , mPresContext(nullptr) , mAuthorStyleDisabled(false) , mStylistState(StylistState::NotDirty) , mUserFontSetUpdateGeneration(0) , mUserFontCacheUpdateGeneration(0) , mNeedsRestyleAfterEnsureUniqueInner(false) { } @@ -115,60 +115,45 @@ ServoStyleSet::~ServoStyleSet() } UniquePtr<ServoStyleSet> ServoStyleSet::CreateXBLServoStyleSet( nsPresContext* aPresContext, const nsTArray<RefPtr<ServoStyleSheet>>& aNewSheets) { auto set = MakeUnique<ServoStyleSet>(Kind::ForXBL); - set->Init(aPresContext); + set->Init(aPresContext, nullptr); // The XBL style sheets aren't document level sheets, but we need to // decide a particular SheetType to add them to style set. This type // doesn't affect the place where we pull those rules from // stylist::push_applicable_declarations_as_xbl_only_stylist(). set->ReplaceSheets(SheetType::Doc, aNewSheets); // Update stylist immediately. set->UpdateStylist(); - // XBL resources are shared for a given URL, even across documents, so we - // can't safely keep this reference. - set->mDocument = nullptr; + // The PresContext of the bound document could be destroyed anytime later, + // which shouldn't be used for XBL styleset, so we clear it here to avoid + // dangling pointer. + set->mPresContext = nullptr; return set; } -nsPresContext* -ServoStyleSet::GetPresContext() +void +ServoStyleSet::Init(nsPresContext* aPresContext, nsBindingManager* aBindingManager) { - if (!mDocument) { - return nullptr; - } - - auto* shell = mDocument->GetShell(); - if (!shell) { - return nullptr; - } - - return shell->GetPresContext(); -} - -void -ServoStyleSet::Init(nsPresContext* aPresContext) -{ - mDocument = aPresContext->Document(); - MOZ_ASSERT(GetPresContext() == aPresContext); - + mPresContext = aPresContext; mLastPresContextUsesXBLStyleSet = aPresContext; mRawSet.reset(Servo_StyleSet_Init(aPresContext)); + mBindingManager = aBindingManager; - aPresContext->DeviceContext()->InitFontCache(); + mPresContext->DeviceContext()->InitFontCache(); // Now that we have an mRawSet, go ahead and notify about whatever stylesheets // we have so far. for (auto& sheetArray : mSheets) { for (auto& sheet : sheetArray) { // There's no guarantee this will create a list on the servo side whose // ordering matches the list that would have been created had all those // sheets been appended/prepended/etc after we had mRawSet. That's okay @@ -189,25 +174,29 @@ ServoStyleSet::Init(nsPresContext* aPres void ServoStyleSet::Shutdown() { // Make sure we drop our cached style contexts before the presshell arena // starts going away. ClearNonInheritingStyleContexts(); mRawSet = nullptr; mStyleRuleMap = nullptr; + + // Also drop the reference to the pres context to avoid notifications from our + // stylesheets to dereference a null restyle manager, see bug 1422634. + // + // We should really fix bug 154199... + mPresContext = nullptr; } void ServoStyleSet::InvalidateStyleForCSSRuleChanges() { MOZ_ASSERT(StylistNeedsUpdate()); - if (nsPresContext* pc = GetPresContext()) { - pc->RestyleManager()->AsServo()->PostRestyleEventForCSSRuleChanges(); - } + mPresContext->RestyleManager()->AsServo()->PostRestyleEventForCSSRuleChanges(); } bool ServoStyleSet::SetPresContext(nsPresContext* aPresContext) { MOZ_ASSERT(IsForXBL(), "Only XBL styleset can set PresContext!"); mLastPresContextUsesXBLStyleSet = aPresContext; @@ -224,22 +213,20 @@ ServoStyleSet::SetPresContext(nsPresCont } nsRestyleHint ServoStyleSet::MediumFeaturesChanged(bool aViewportChanged) { bool viewportUnitsUsed = false; bool rulesChanged = MediumFeaturesChangedRules(&viewportUnitsUsed); - if (nsPresContext* pc = GetPresContext()) { - if (mDocument->BindingManager()->MediumFeaturesChanged(pc)) { - // TODO(emilio): We could technically just restyle the bound elements. - SetStylistXBLStyleSheetsDirty(); - rulesChanged = true; - } + if (mBindingManager && + mBindingManager->MediumFeaturesChanged(mPresContext)) { + SetStylistXBLStyleSheetsDirty(); + rulesChanged = true; } if (rulesChanged) { return eRestyle_Subtree; } if (viewportUnitsUsed && aViewportChanged) { return eRestyle_ForceDescendants; @@ -304,17 +291,17 @@ ServoStyleSet::AddSizeOfIncludingThis(ns } // Measurement of the following members may be added later if DMD finds it is // worthwhile: // - mSheets // - mNonInheritingStyleContexts // // The following members are not measured: - // - mDocument, because it a non-owning pointer + // - mPresContext, because it a non-owning pointer } bool ServoStyleSet::GetAuthorStyleDisabled() const { return mAuthorStyleDisabled; } @@ -354,52 +341,48 @@ ServoStyleSet::ResolveStyleFor(Element* } return ResolveServoStyle(aElement); } const ServoElementSnapshotTable& ServoStyleSet::Snapshots() { - MOZ_ASSERT(GetPresContext(), "Styling a document without a shell?"); - return GetPresContext()->RestyleManager()->AsServo()->Snapshots(); + return mPresContext->RestyleManager()->AsServo()->Snapshots(); } void ServoStyleSet::ResolveMappedAttrDeclarationBlocks() { - if (nsHTMLStyleSheet* sheet = mDocument->GetAttributeStyleSheet()) { + if (nsHTMLStyleSheet* sheet = mPresContext->Document()->GetAttributeStyleSheet()) { sheet->CalculateMappedServoDeclarations(); } - mDocument->ResolveScheduledSVGPresAttrs(); + mPresContext->Document()->ResolveScheduledSVGPresAttrs(); } void ServoStyleSet::PreTraverseSync() { // Get the Document's root element to ensure that the cache is valid before // calling into the (potentially-parallel) Servo traversal, where a cache hit // is necessary to avoid a data race when updating the cache. - mozilla::Unused << mDocument->GetRootElement(); + mozilla::Unused << mPresContext->Document()->GetRootElement(); ResolveMappedAttrDeclarationBlocks(); nsMediaFeatures::InitSystemMetrics(); LookAndFeel::NativeInit(); - nsPresContext* presContext = GetPresContext(); - MOZ_ASSERT(presContext, - "For now, we don't call into here without a pres context"); - if (gfxUserFontSet* userFontSet = mDocument->GetUserFontSet()) { + if (gfxUserFontSet* userFontSet = mPresContext->Document()->GetUserFontSet()) { // Ensure that the @font-face data is not stale uint64_t generation = userFontSet->GetGeneration(); if (generation != mUserFontSetUpdateGeneration) { - presContext->DeviceContext()->UpdateFontCacheUserFonts(userFontSet); + mPresContext->DeviceContext()->UpdateFontCacheUserFonts(userFontSet); mUserFontSetUpdateGeneration = generation; } // Ensure that the FontFaceSet's cached document principal is up to date. FontFaceSet* fontFaceSet = static_cast<FontFaceSet::UserFontSet*>(userFontSet)->GetFontFaceSet(); fontFaceSet->UpdateStandardFontLoadPrincipal(); bool principalChanged = fontFaceSet->HasStandardFontLoadPrincipalChanged(); @@ -412,39 +395,39 @@ ServoStyleSet::PreTraverseSync() } if (cacheGeneration != mUserFontCacheUpdateGeneration || principalChanged) { gfxUserFontSet::UserFontCache::UpdateAllowedFontSets(userFontSet); mUserFontCacheUpdateGeneration = cacheGeneration; } } UpdateStylistIfNeeded(); - presContext->CacheAllLangs(); + mPresContext->CacheAllLangs(); } void ServoStyleSet::PreTraverse(ServoTraversalFlags aFlags, Element* aRoot) { PreTraverseSync(); // Process animation stuff that we should avoid doing during the parallel // traversal. nsSMILAnimationController* smilController = - mDocument->HasAnimationController() - ? mDocument->GetAnimationController() + mPresContext->Document()->HasAnimationController() + ? mPresContext->Document()->GetAnimationController() : nullptr; - MOZ_ASSERT(GetPresContext()); if (aRoot) { - GetPresContext()->EffectCompositor()->PreTraverseInSubtree(aFlags, aRoot); + mPresContext->EffectCompositor() + ->PreTraverseInSubtree(aFlags, aRoot); if (smilController) { smilController->PreTraverseInSubtree(aRoot); } } else { - GetPresContext()->EffectCompositor()->PreTraverse(aFlags); + mPresContext->EffectCompositor()->PreTraverse(aFlags); if (smilController) { smilController->PreTraverse(); } } } static inline already_AddRefed<ServoStyleContext> ResolveStyleForTextOrFirstLetterContinuation( @@ -826,18 +809,18 @@ ServoStyleSet::StyleSheetAt(SheetType aT { MOZ_ASSERT(IsCSSSheetType(aType)); return mSheets[aType][aIndex]; } void ServoStyleSet::AppendAllXBLStyleSheets(nsTArray<StyleSheet*>& aArray) const { - if (mDocument) { - mDocument->BindingManager()->AppendAllSheets(aArray); + if (mBindingManager) { + mBindingManager->AppendAllSheets(aArray); } } nsresult ServoStyleSet::RemoveDocStyleSheet(ServoStyleSheet* aSheet) { return RemoveStyleSheet(SheetType::Doc, aSheet); } @@ -933,61 +916,60 @@ ServoStyleSet::ProbePseudoElementStyle(E } return computedValues.forget(); } bool ServoStyleSet::StyleDocument(ServoTraversalFlags aFlags) { - MOZ_ASSERT(GetPresContext(), "Styling a document without a shell?"); - - if (!mDocument->GetServoRestyleRoot()) { + nsIDocument* doc = mPresContext->Document(); + if (!doc->GetServoRestyleRoot()) { return false; } PreTraverse(aFlags); AutoPrepareTraversal guard(this); const SnapshotTable& snapshots = Snapshots(); // Restyle the document from the root element and each of the document level // NAC subtree roots. bool postTraversalRequired = false; - Element* rootElement = mDocument->GetRootElement(); + Element* rootElement = doc->GetRootElement(); MOZ_ASSERT_IF(rootElement, rootElement->HasServoData()); if (ShouldTraverseInParallel()) { aFlags |= ServoTraversalFlags::ParallelTraversal; } // Do the first traversal. - DocumentStyleRootIterator iter(mDocument->GetServoRestyleRoot()); + DocumentStyleRootIterator iter(doc->GetServoRestyleRoot()); while (Element* root = iter.GetNextStyleRoot()) { MOZ_ASSERT(MayTraverseFrom(root)); Element* parent = root->GetFlattenedTreeParentElementForStyle(); MOZ_ASSERT_IF(parent, !parent->HasAnyOfFlags(Element::kAllServoDescendantBits)); postTraversalRequired |= Servo_TraverseSubtree(root, mRawSet.get(), &snapshots, aFlags); postTraversalRequired |= root->HasAnyOfFlags(Element::kAllServoDescendantBits | NODE_NEEDS_FRAME); if (parent) { - MOZ_ASSERT(root == mDocument->GetServoRestyleRoot()); + MOZ_ASSERT(root == doc->GetServoRestyleRoot()); if (parent->HasDirtyDescendantsForServo()) { // If any style invalidation was triggered in our siblings, then we may // need to post-traverse them, even if the root wasn't restyled after // all. - uint32_t existingBits = mDocument->GetServoRestyleRootDirtyBits(); + uint32_t existingBits = doc->GetServoRestyleRootDirtyBits(); // We need to propagate the existing bits to the parent. parent->SetFlags(existingBits); - mDocument->SetServoRestyleRoot( + doc->SetServoRestyleRoot( parent, existingBits | ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO); postTraversalRequired = true; } } } // If there are still animation restyles needed, trigger a second traversal to @@ -997,33 +979,32 @@ ServoStyleSet::StyleDocument(ServoTraver // PreTraverse on the EffectCompositor might alter the style root. But we // don't need to worry about NAC, since document-level NAC shouldn't have // animations. // // We don't need to do this for SMIL since SMIL only updates its animation // values once at the begin of a tick. As a result, even if the previous // traversal caused, for example, the font-size to change, the SMIL style // won't be updated until the next tick anyway. - if (GetPresContext()->EffectCompositor()->PreTraverse(aFlags)) { - nsINode* styleRoot = mDocument->GetServoRestyleRoot(); + if (mPresContext->EffectCompositor()->PreTraverse(aFlags)) { + nsINode* styleRoot = doc->GetServoRestyleRoot(); Element* root = styleRoot->IsElement() ? styleRoot->AsElement() : rootElement; postTraversalRequired |= Servo_TraverseSubtree(root, mRawSet.get(), &snapshots, aFlags); postTraversalRequired |= root->HasAnyOfFlags(Element::kAllServoDescendantBits | NODE_NEEDS_FRAME); } return postTraversalRequired; } void ServoStyleSet::StyleNewSubtree(Element* aRoot) { - MOZ_ASSERT(GetPresContext()); MOZ_ASSERT(!aRoot->HasServoData()); PreTraverseSync(); AutoPrepareTraversal guard(this); // Do the traversal. The snapshots will not be used. const SnapshotTable& snapshots = Snapshots(); auto flags = ServoTraversalFlags::Empty; if (ShouldTraverseInParallel()) { @@ -1033,17 +1014,17 @@ ServoStyleSet::StyleNewSubtree(Element* DebugOnly<bool> postTraversalRequired = Servo_TraverseSubtree(aRoot, mRawSet.get(), &snapshots, flags); MOZ_ASSERT(!postTraversalRequired); // Annoyingly, the newly-styled content may have animations that need // starting, which requires traversing them again. Mark the elements // that need animation processing, then do a forgetful traversal to // update the styles and clear the animation bits. - if (GetPresContext()->EffectCompositor()->PreTraverseInSubtree(flags, aRoot)) { + if (mPresContext->EffectCompositor()->PreTraverseInSubtree(flags, aRoot)) { postTraversalRequired = Servo_TraverseSubtree(aRoot, mRawSet.get(), &snapshots, ServoTraversalFlags::AnimationOnly | ServoTraversalFlags::Forgetful | ServoTraversalFlags::ClearAnimationOnlyDirtyDescendants); MOZ_ASSERT(!postTraversalRequired); } } @@ -1064,34 +1045,33 @@ ServoStyleSet::MarkOriginsDirty(OriginFl void ServoStyleSet::SetStylistStyleSheetsDirty() { mStylistState |= StylistState::StyleSheetsDirty; // We need to invalidate cached style in getComputedStyle for undisplayed // elements, since we don't know if any of the style sheet change that we // do would affect undisplayed elements. - if (nsPresContext* presContext = GetPresContext()) { - // XBL sheets don't have a pres context, but invalidating the restyle - // generation in that case is handled by SetXBLStyleSheetsDirty in the - // "master" stylist. - presContext->RestyleManager()->AsServo()->IncrementUndisplayedRestyleGeneration(); + if (mPresContext) { + // XBL sheets don't have a pres context, but invalidating the restyle generation + // in that case is handled by SetXBLStyleSheetsDirty in the "master" stylist. + mPresContext->RestyleManager()->AsServo()->IncrementUndisplayedRestyleGeneration(); } } void ServoStyleSet::SetStylistXBLStyleSheetsDirty() { mStylistState |= StylistState::XBLStyleSheetsDirty; // We need to invalidate cached style in getComputedStyle for undisplayed // elements, since we don't know if any of the style sheet change that we // do would affect undisplayed elements. - MOZ_ASSERT(GetPresContext()); - GetPresContext()->RestyleManager()->AsServo()->IncrementUndisplayedRestyleGeneration(); + MOZ_ASSERT(mPresContext); + mPresContext->RestyleManager()->AsServo()->IncrementUndisplayedRestyleGeneration(); } void ServoStyleSet::RuleAdded(ServoStyleSheet& aSheet, css::Rule& aRule) { if (mStyleRuleMap) { mStyleRuleMap->RuleAdded(aSheet, aRule); } @@ -1117,17 +1097,17 @@ ServoStyleSet::RuleChanged(ServoStyleShe // FIXME(emilio): Could be more granular based on aRule. MarkOriginsDirty(aSheet.GetOrigin()); } #ifdef DEBUG void ServoStyleSet::AssertTreeIsClean() { - DocumentStyleRootIterator iter(mDocument); + DocumentStyleRootIterator iter(mPresContext->Document()); while (Element* root = iter.GetNextStyleRoot()) { Servo_AssertTreeIsClean(root); } } #endif bool ServoStyleSet::GetKeyframesForName(nsAtom* aName, @@ -1290,19 +1270,17 @@ ServoStyleSet::ClearNonInheritingStyleCo } } already_AddRefed<ServoStyleContext> ServoStyleSet::ResolveStyleLazilyInternal(Element* aElement, CSSPseudoElementType aPseudoType, StyleRuleInclusion aRuleInclusion) { - MOZ_ASSERT(GetPresContext(), - "For now, no style resolution without a pres context"); - GetPresContext()->EffectCompositor()->PreTraverse(aElement, aPseudoType); + mPresContext->EffectCompositor()->PreTraverse(aElement, aPseudoType); MOZ_ASSERT(!StylistNeedsUpdate()); AutoSetInServoTraversal guard(this); /** * NB: This is needed because we process animations and transitions on the * pseudo-elements themselves, not on the parent's EagerPseudoStyles. * @@ -1330,27 +1308,27 @@ ServoStyleSet::ResolveStyleLazilyInterna RefPtr<ServoStyleContext> computedValues = Servo_ResolveStyleLazily(elementForStyleResolution, pseudoTypeForStyleResolution, aRuleInclusion, &Snapshots(), mRawSet.get(), /* aIgnoreExistingStyles = */ false).Consume(); - if (GetPresContext()->EffectCompositor()->PreTraverse(aElement, aPseudoType)) { + if (mPresContext->EffectCompositor()->PreTraverse(aElement, aPseudoType)) { computedValues = Servo_ResolveStyleLazily(elementForStyleResolution, pseudoTypeForStyleResolution, aRuleInclusion, &Snapshots(), mRawSet.get(), /* aIgnoreExistingStyles = */ false).Consume(); } - MOZ_DIAGNOSTIC_ASSERT(computedValues->PresContext() == GetPresContext() || + MOZ_DIAGNOSTIC_ASSERT(computedValues->PresContext() == mPresContext || aElement->OwnerDoc()->GetBFCacheEntry()); return computedValues.forget(); } bool ServoStyleSet::AppendFontFaceRules(nsTArray<nsFontFaceRuleContainer>& aArray) { @@ -1389,24 +1367,25 @@ void ServoStyleSet::UpdateStylist() { MOZ_ASSERT(StylistNeedsUpdate()); if (mStylistState & StylistState::StyleSheetsDirty) { // There's no need to compute invalidations and such for an XBL styleset, // since they are loaded and unloaded synchronously, and they don't have to // deal with dynamic content changes. - Element* root = IsMaster() ? mDocument->GetRootElement() : nullptr; + Element* root = + IsMaster() ? mPresContext->Document()->GetDocumentElement() : nullptr; + Servo_StyleSet_FlushStyleSheets(mRawSet.get(), root); } if (MOZ_UNLIKELY(mStylistState & StylistState::XBLStyleSheetsDirty)) { MOZ_ASSERT(IsMaster(), "Only master styleset can mark XBL stylesets dirty!"); - MOZ_ASSERT(GetPresContext(), "How did they get dirty?"); - mDocument->BindingManager()->UpdateBoundContentBindingsForServo(GetPresContext()); + mBindingManager->UpdateBoundContentBindingsForServo(mPresContext); } mStylistState = StylistState::NotDirty; } void ServoStyleSet::MaybeGCRuleTree() { @@ -1433,18 +1412,17 @@ ServoStyleSet::MayTraverseFrom(const Ele } return !Servo_Element_IsDisplayNone(parent->AsElement()); } bool ServoStyleSet::ShouldTraverseInParallel() const { - MOZ_ASSERT(mDocument->GetShell(), "Styling a document without a shell?"); - return mDocument->GetShell()->IsActive(); + return mPresContext->PresShell()->IsActive(); } void ServoStyleSet::PrependSheetOfType(SheetType aType, ServoStyleSheet* aSheet) { aSheet->AddStyleSet(this); mSheets[aType].InsertElementAt(0, aSheet);
--- a/layout/style/ServoStyleSet.h +++ b/layout/style/ServoStyleSet.h @@ -127,17 +127,17 @@ public: explicit ServoStyleSet(Kind aKind); ~ServoStyleSet(); static UniquePtr<ServoStyleSet> CreateXBLServoStyleSet(nsPresContext* aPresContext, const nsTArray<RefPtr<ServoStyleSheet>>& aNewSheets); - void Init(nsPresContext* aPresContext); + void Init(nsPresContext* aPresContext, nsBindingManager* aBindingManager); void BeginShutdown() {} void Shutdown(); // Called when a rules in a stylesheet in this set, or a child sheet of that, // are mutated from CSSOM. void RuleAdded(ServoStyleSheet&, css::Rule&); void RuleRemoved(ServoStyleSheet&, css::Rule&); void RuleChanged(ServoStyleSheet& aSheet, css::Rule* aRule); @@ -595,37 +595,23 @@ private: ServoStyleSheet* aSheet, ServoStyleSheet* aBeforeSheet); void RemoveSheetOfType(SheetType aType, ServoStyleSheet* aSheet); const Kind mKind; - // The owner document of this style set. Null if this is an XBL style set. - // - // TODO(emilio): This should become a DocumentOrShadowRoot, and be owned by it - // directly instead of the shell, eventually. - nsIDocument* mDocument; - - const nsPresContext* GetPresContext() const { - return const_cast<ServoStyleSet*>(this)->GetPresContext(); - } - - /** - * Return the associated pres context if we're the master style set and we - * have an associated pres shell. - */ - nsPresContext* GetPresContext(); + // Nullptr if this is an XBL style set, or if we've been already detached from + // our shell. + nsPresContext* MOZ_NON_OWNING_REF mPresContext = nullptr; // Because XBL style set could be used by multiple PresContext, we need to // store the last PresContext pointer which uses this XBL styleset for // computing medium rule changes. - // - // FIXME(emilio): This is a hack, and is broken. See bug 1406875. void* MOZ_NON_OWNING_REF mLastPresContextUsesXBLStyleSet = nullptr; UniquePtr<RawServoStyleSet> mRawSet; EnumeratedArray<SheetType, SheetType::Count, nsTArray<RefPtr<ServoStyleSheet>>> mSheets; bool mAuthorStyleDisabled; StylistState mStylistState; uint64_t mUserFontSetUpdateGeneration; @@ -644,16 +630,19 @@ private: // These are similar to Servo's SequentialTasks, except that they are // posted by C++ code running on style worker threads. nsTArray<PostTraversalTask> mPostTraversalTasks; // Map from raw Servo style rule to Gecko's wrapper object. // Constructed lazily when requested by devtools. UniquePtr<ServoStyleRuleMap> mStyleRuleMap; + // This can be null if we are used to hold XBL style sheets. + RefPtr<nsBindingManager> mBindingManager; + static ServoStyleSet* sInServoTraversal; }; class UACacheReporter final : public nsIMemoryReporter { NS_DECL_ISUPPORTS NS_DECL_NSIMEMORYREPORTER
--- a/layout/style/StyleSetHandle.h +++ b/layout/style/StyleSetHandle.h @@ -110,17 +110,17 @@ public: // These inline methods are defined in StyleSetHandleInlines.h. inline void Delete(); // Style set interface. These inline methods are defined in // StyleSetHandleInlines.h and just forward to the underlying // nsStyleSet or ServoStyleSet. See corresponding comments in // nsStyleSet.h for descriptions of these methods. - inline void Init(nsPresContext* aPresContext); + inline void Init(nsPresContext* aPresContext, nsBindingManager* aBindingManager); inline void BeginShutdown(); inline void Shutdown(); inline bool GetAuthorStyleDisabled() const; inline nsresult SetAuthorStyleDisabled(bool aStyleDisabled); inline void BeginUpdate(); inline nsresult EndUpdate(); inline already_AddRefed<nsStyleContext> ResolveStyleFor(dom::Element* aElement,
--- a/layout/style/StyleSetHandleInlines.h +++ b/layout/style/StyleSetHandleInlines.h @@ -39,19 +39,20 @@ StyleSetHandle::Ptr::Delete() delete AsGecko(); } else { delete AsServo(); } } } void -StyleSetHandle::Ptr::Init(nsPresContext* aPresContext) +StyleSetHandle::Ptr::Init(nsPresContext* aPresContext, + nsBindingManager* aBindingManager) { - FORWARD(Init, (aPresContext)); + FORWARD(Init, (aPresContext, aBindingManager)); } void StyleSetHandle::Ptr::BeginShutdown() { FORWARD(BeginShutdown, ()); }
--- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -269,25 +269,25 @@ nsStyleSet::AddSizeOfIncludingThis(nsWin n += mScopedDocSheetRuleProcessors[i]->SizeOfIncludingThis(mallocSizeOf); } n += mScopedDocSheetRuleProcessors.ShallowSizeOfExcludingThis(mallocSizeOf); aSizes.mLayoutGeckoStyleSets += n; } void -nsStyleSet::Init(nsPresContext* aPresContext) +nsStyleSet::Init(nsPresContext* aPresContext, nsBindingManager* aBindingManager) { mFirstLineRule = new nsEmptyStyleRule; mFirstLetterRule = new nsEmptyStyleRule; mPlaceholderRule = new nsEmptyStyleRule; mDisableTextZoomStyleRule = new nsDisableTextZoomStyleRule; - mBindingManager = aPresContext->Document()->BindingManager(); mRuleTree = nsRuleNode::CreateRootNode(aPresContext); + mBindingManager = aBindingManager; // Make an explicit GatherRuleProcessors call for the levels that // don't have style sheets. The other levels will have their calls // triggered by DirtyRuleProcessors. GatherRuleProcessors(SheetType::PresHint); GatherRuleProcessors(SheetType::StyleAttr); GatherRuleProcessors(SheetType::Animation); GatherRuleProcessors(SheetType::Transition); @@ -2697,16 +2697,19 @@ nsStyleSet::EnsureUniqueInnerOnCSSSheets for (SheetType type : gCSSSheetTypes) { for (StyleSheet* sheet : mSheets[type]) { queue.AppendElement(sheet); } } if (mBindingManager) { AutoTArray<StyleSheet*, 32> sheets; + // XXXheycam stylo: AppendAllSheets will need to be able to return either + // CSSStyleSheets or ServoStyleSheets, on request (and then here requesting + // CSSStyleSheets). mBindingManager->AppendAllSheets(sheets); for (StyleSheet* sheet : sheets) { MOZ_ASSERT(sheet->IsGecko(), "stylo: AppendAllSheets shouldn't give us " "ServoStyleSheets yet"); queue.AppendElement(sheet->AsGecko()); } }
--- a/layout/style/nsStyleSet.h +++ b/layout/style/nsStyleSet.h @@ -105,17 +105,17 @@ public: class nsStyleSet final { public: nsStyleSet(); ~nsStyleSet(); void AddSizeOfIncludingThis(nsWindowSizes& aSizes) const; - void Init(nsPresContext* aPresContext); + void Init(nsPresContext* aPresContext, nsBindingManager* aBindingManager); nsRuleNode* GetRuleTree() { return mRuleTree; } // get a style context for a non-pseudo frame. already_AddRefed<mozilla::GeckoStyleContext> ResolveStyleFor(mozilla::dom::Element* aElement, mozilla::GeckoStyleContext* aParentContext);