diff --git a/mozilla/content/base/public/nsIDocument.h b/mozilla/content/base/public/nsIDocument.h index a671217a583..74ac4b104b6 100644 --- a/mozilla/content/base/public/nsIDocument.h +++ b/mozilla/content/base/public/nsIDocument.h @@ -53,7 +53,6 @@ #include "nsILoadGroup.h" #include "nsReadableUtils.h" #include "nsCRT.h" -#include // for FILE definition class nsIAtom; class nsIContent; diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp index d783714c8a9..4957c8352ed 100644 --- a/mozilla/content/base/src/nsDocument.cpp +++ b/mozilla/content/base/src/nsDocument.cpp @@ -1519,7 +1519,9 @@ nsDocument::SetStyleSheetApplicableState(nsIStyleSheet* aSheet, } } else { // We still need to notify the style set of the state change, because - // this will invalidate some of the rule processor data. + // this will invalidate some of the rule processor data. We do this + // here instead of in the pres shell because we _don't_ want to do this + // for document style sheets. PRInt32 count = mPresShells.Count(); PRInt32 indx; @@ -1647,14 +1649,6 @@ nsDocument::RemoveObserver(nsIDocumentObserver* aObserver) void nsDocument::BeginUpdate(nsUpdateType aUpdateType) { - if (aUpdateType & UPDATE_STYLE) { - PRInt32 shellCount = mPresShells.Count(); - for (PRInt32 j = 0; j < shellCount; ++j) { - NS_STATIC_CAST(nsIPresShell*, mPresShells.ElementAt(j))->StyleSet()-> - BeginUpdate(); - } - } - PRInt32 i; for (i = mObservers.Count() - 1; i >= 0; --i) { nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i]; @@ -1665,14 +1659,6 @@ nsDocument::BeginUpdate(nsUpdateType aUpdateType) void nsDocument::EndUpdate(nsUpdateType aUpdateType) { - if (aUpdateType & UPDATE_STYLE) { - PRInt32 shellCount = mPresShells.Count(); - for (PRInt32 j = 0; j < shellCount; ++j) { - NS_STATIC_CAST(nsIPresShell*, mPresShells.ElementAt(j))->StyleSet()-> - EndUpdate(); - } - } - PRInt32 i; for (i = mObservers.Count() - 1; i >= 0; --i) { nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i]; diff --git a/mozilla/content/base/src/nsDocumentViewer.cpp b/mozilla/content/base/src/nsDocumentViewer.cpp index 3e01343df94..ec28baeaf64 100644 --- a/mozilla/content/base/src/nsDocumentViewer.cpp +++ b/mozilla/content/base/src/nsDocumentViewer.cpp @@ -639,8 +639,8 @@ nsresult DocumentViewerImpl::InitPresentationStuff(PRBool aDoInitialReflow) { // Create the style set... - nsStyleSet *styleSet; - nsresult rv = CreateStyleSet(mDocument, &styleSet); + nsAutoPtr styleSet; + nsresult rv = CreateStyleSet(mDocument, getter_Transfers(styleSet)); NS_ENSURE_SUCCESS(rv, rv); // Now make the shell for the document @@ -649,6 +649,9 @@ DocumentViewerImpl::InitPresentationStuff(PRBool aDoInitialReflow) NS_ENSURE_SUCCESS(rv, rv); + // The pres shell owns the style set now. + styleSet.forget(); + if (aDoInitialReflow) { // Since InitialReflow() will create frames for *all* items // that are currently in the document tree, we need to flush @@ -1191,8 +1194,8 @@ DocumentViewerImpl::SetDOMDocument(nsIDOMDocument *aDocument) if (mPresContext) { // 3) Create a new style set for the document - nsStyleSet *styleSet; - rv = CreateStyleSet(mDocument, &styleSet); + nsAutoPtr styleSet; + rv = CreateStyleSet(mDocument, getter_Transfers(styleSet)); if (NS_FAILED(rv)) return rv; @@ -1200,6 +1203,9 @@ DocumentViewerImpl::SetDOMDocument(nsIDOMDocument *aDocument) getter_AddRefs(mPresShell)); NS_ENSURE_SUCCESS(rv, rv); + // The pres shell owns the style set now. + styleSet.forget(); + mPresShell->BeginObservingDocument(); // 4) Register the focus listener on the new document @@ -1594,7 +1600,7 @@ DocumentViewerImpl::CreateStyleSet(nsIDocument* aDocument, NS_WARNING("unable to load UA style sheet"); } - nsStyleSet *styleSet = new nsStyleSet(); + nsAutoPtr styleSet(new nsStyleSet()); if (!styleSet) { return NS_ERROR_OUT_OF_MEMORY; } @@ -1663,6 +1669,7 @@ DocumentViewerImpl::CreateStyleSet(nsIDocument* aDocument, styleSet->EndUpdate(); *aStyleSet = styleSet; + styleSet.forget(); return NS_OK; } diff --git a/mozilla/content/base/src/nsPrintEngine.cpp b/mozilla/content/base/src/nsPrintEngine.cpp index 151e4cc9e08..a4c8dc21387 100644 --- a/mozilla/content/base/src/nsPrintEngine.cpp +++ b/mozilla/content/base/src/nsPrintEngine.cpp @@ -2608,7 +2608,8 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO, PRBool aDoCalcShrink) // init it with the DC (aPO->mPresContext)->Init(mPrt->mPrintDocDC); - rv = mDocViewerPrint->CreateStyleSet(aPO->mDocument, &aPO->mStyleSet); + rv = mDocViewerPrint->CreateStyleSet(aPO->mDocument, + getter_Transfers(aPO->mStyleSet)); NS_ENSURE_SUCCESS(rv, rv); aPO->mViewManager = do_CreateInstance(kViewManagerCID, &rv); diff --git a/mozilla/content/base/src/nsPrintObject.h b/mozilla/content/base/src/nsPrintObject.h index 06cd9638010..d0b732607ed 100644 --- a/mozilla/content/base/src/nsPrintObject.h +++ b/mozilla/content/base/src/nsPrintObject.h @@ -81,7 +81,7 @@ public: PrintObjectType mFrameType; nsCOMPtr mPresContext; - nsStyleSet *mStyleSet; + nsAutoPtr mStyleSet; nsCOMPtr mPresShell; nsCOMPtr mViewManager; nsCOMPtr mWindow; diff --git a/mozilla/content/base/src/nsRuleNode.cpp b/mozilla/content/base/src/nsRuleNode.cpp index 54972c6ad12..ccb28d4acfd 100644 --- a/mozilla/content/base/src/nsRuleNode.cpp +++ b/mozilla/content/base/src/nsRuleNode.cpp @@ -4358,6 +4358,9 @@ PRBool nsRuleNode::Sweep() { // If we're not marked, then we have to delete ourself. + // However, we never allow the root node to GC itself, because nsStyleSet + // wants to hold onto the root node and not worry about re-creating a + // rule walker if the root node is deleted. if (!(mDependentBits & NS_RULE_NODE_GC_MARK) && !IsRoot()) { Destroy(); return PR_TRUE; diff --git a/mozilla/content/base/src/nsStyleSet.cpp b/mozilla/content/base/src/nsStyleSet.cpp index 460ac7e944e..f2d7978bdc5 100644 --- a/mozilla/content/base/src/nsStyleSet.cpp +++ b/mozilla/content/base/src/nsStyleSet.cpp @@ -55,7 +55,7 @@ nsStyleSet::nsStyleSet() : mRuleTree(nsnull), mRuleWalker(nsnull), mDestroyedCount(0), - mBatching(PR_FALSE), + mBatching(0), mInShutdown(PR_FALSE), mDirty(0) { @@ -70,8 +70,10 @@ nsStyleSet::Init(nsIPresContext *aPresContext) NS_ENSURE_TRUE(gQuirkURI, NS_ERROR_OUT_OF_MEMORY); } - if (!BuildDefaultStyleData(aPresContext)) - return NS_ERROR_FAILURE; + if (!BuildDefaultStyleData(aPresContext)) { + mDefaultStyleData.Destroy(0, aPresContext); + return NS_ERROR_OUT_OF_MEMORY; + } mRuleTree = nsRuleNode::CreateRootNode(aPresContext); if (!mRuleTree) { @@ -195,10 +197,8 @@ nsStyleSet::ReplaceSheets(sheetType aType, const nsCOMArray &aNewSheets) { mSheets[aType].Clear(); - for (PRInt32 i = 0; i < aNewSheets.Count(); ++i) { - if (!mSheets[aType].AppendObject(aNewSheets.ObjectAt(i))) - return NS_ERROR_OUT_OF_MEMORY; - } + if (!mSheets[aType].AppendObjects(aNewSheets)) + return NS_ERROR_OUT_OF_MEMORY; if (!mBatching) return GatherRuleProcessors(aType); @@ -212,7 +212,7 @@ nsStyleSet::ReplaceSheets(sheetType aType, nsresult nsStyleSet::AddDocStyleSheet(nsIStyleSheet* aSheet, nsIDocument* aDocument) { - NS_PRECONDITION((nsnull != aSheet) && (nsnull != aDocument), "null arg"); + NS_PRECONDITION(aSheet && aDocument, "null arg"); CHECK_APPLICABLE; nsCOMArray& docSheets = mSheets[eDocSheet]; @@ -248,21 +248,26 @@ nsStyleSet::AddDocStyleSheet(nsIStyleSheet* aSheet, nsIDocument* aDocument) void nsStyleSet::BeginUpdate() { - mBatching = 1; + ++mBatching; } nsresult nsStyleSet::EndUpdate() { + NS_ASSERTION(mBatching > 0, "Unbalanced EndUpdate"); + if (--mBatching) { + // We're not completely done yet. + return NS_OK; + } + for (int i = 0; i < eSheetTypeCount; ++i) { - if (mDirty & 1 << i) { + if (mDirty & (1 << i)) { nsresult rv = GatherRuleProcessors(i); NS_ENSURE_SUCCESS(rv, rv); } } mDirty = 0; - mBatching = 0; return NS_OK; } @@ -721,7 +726,7 @@ nsStyleSet::NotifyStyleContextDestroyed(nsIPresContext* aPresContext, #endif mRuleTree->Sweep(); - NS_ASSERTION(deleted, "Root not must not be gc'd"); + NS_ASSERTION(!deleted, "Root node must not be gc'd"); } } diff --git a/mozilla/content/base/src/nsStyleSet.h b/mozilla/content/base/src/nsStyleSet.h index 31cd29049f5..2de04e13a5c 100644 --- a/mozilla/content/base/src/nsStyleSet.h +++ b/mozilla/content/base/src/nsStyleSet.h @@ -49,6 +49,10 @@ class nsIURI; +// The style set object is created by the document viewer and ownership is +// then handed off to the PresShell. Only the PresShell should delete a +// style set. + class nsStyleSet { public: @@ -156,12 +160,13 @@ class nsStyleSet // Free global data at module shutdown static void FreeGlobals() { NS_IF_RELEASE(gQuirkURI); } - // APIs to manipulate the style sheet lists + // APIs to manipulate the style sheet lists. + // All sheet types are ordered most-significant-first. enum sheetType { eAgentSheet, eUserSheet, eDocSheet, - eOverrideSheet, // override sheets are ordered most significant first + eOverrideSheet, eSheetTypeCount }; @@ -237,9 +242,10 @@ class nsStyleSet PRInt32 mDestroyedCount; // used to batch style context GC nsVoidArray mRoots; // style contexts with no parent - unsigned mBatching : 1; + PRUint16 mBatching; + unsigned mInShutdown : 1; - unsigned mDirty : 6; // one dirty bit is used per sheet type + unsigned mDirty : 7; // one dirty bit is used per sheet type }; #endif diff --git a/mozilla/layout/base/nsDocumentViewer.cpp b/mozilla/layout/base/nsDocumentViewer.cpp index 3e01343df94..ec28baeaf64 100644 --- a/mozilla/layout/base/nsDocumentViewer.cpp +++ b/mozilla/layout/base/nsDocumentViewer.cpp @@ -639,8 +639,8 @@ nsresult DocumentViewerImpl::InitPresentationStuff(PRBool aDoInitialReflow) { // Create the style set... - nsStyleSet *styleSet; - nsresult rv = CreateStyleSet(mDocument, &styleSet); + nsAutoPtr styleSet; + nsresult rv = CreateStyleSet(mDocument, getter_Transfers(styleSet)); NS_ENSURE_SUCCESS(rv, rv); // Now make the shell for the document @@ -649,6 +649,9 @@ DocumentViewerImpl::InitPresentationStuff(PRBool aDoInitialReflow) NS_ENSURE_SUCCESS(rv, rv); + // The pres shell owns the style set now. + styleSet.forget(); + if (aDoInitialReflow) { // Since InitialReflow() will create frames for *all* items // that are currently in the document tree, we need to flush @@ -1191,8 +1194,8 @@ DocumentViewerImpl::SetDOMDocument(nsIDOMDocument *aDocument) if (mPresContext) { // 3) Create a new style set for the document - nsStyleSet *styleSet; - rv = CreateStyleSet(mDocument, &styleSet); + nsAutoPtr styleSet; + rv = CreateStyleSet(mDocument, getter_Transfers(styleSet)); if (NS_FAILED(rv)) return rv; @@ -1200,6 +1203,9 @@ DocumentViewerImpl::SetDOMDocument(nsIDOMDocument *aDocument) getter_AddRefs(mPresShell)); NS_ENSURE_SUCCESS(rv, rv); + // The pres shell owns the style set now. + styleSet.forget(); + mPresShell->BeginObservingDocument(); // 4) Register the focus listener on the new document @@ -1594,7 +1600,7 @@ DocumentViewerImpl::CreateStyleSet(nsIDocument* aDocument, NS_WARNING("unable to load UA style sheet"); } - nsStyleSet *styleSet = new nsStyleSet(); + nsAutoPtr styleSet(new nsStyleSet()); if (!styleSet) { return NS_ERROR_OUT_OF_MEMORY; } @@ -1663,6 +1669,7 @@ DocumentViewerImpl::CreateStyleSet(nsIDocument* aDocument, styleSet->EndUpdate(); *aStyleSet = styleSet; + styleSet.forget(); return NS_OK; } diff --git a/mozilla/layout/base/nsIPresShell.h b/mozilla/layout/base/nsIPresShell.h index b24f2e82b5c..db839805d79 100644 --- a/mozilla/layout/base/nsIPresShell.h +++ b/mozilla/layout/base/nsIPresShell.h @@ -649,7 +649,7 @@ protected: // we must share ownership. nsIDocument* mDocument; // [STRONG] nsIPresContext* mPresContext; // [STRONG] - nsStyleSet* mStyleSet; // [STRONG] + nsStyleSet* mStyleSet; // [OWNS] nsIStyleFrameConstruction* mFrameConstructor; // [STRONG] nsIViewManager* mViewManager; // [WEAK] docViewer owns it so I don't have to nsIFrameManager* mFrameManager; // [STRONG] diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index 3b981265bd6..9ccc808178e 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -1644,9 +1644,7 @@ PresShell::Init(nsIDocument* aDocument, // before creating any frames. SetPreferenceStyleRules(PR_FALSE); - result = nsComponentManager::CreateInstance(kFrameSelectionCID, nsnull, - NS_GET_IID(nsIFrameSelection), - getter_AddRefs(mSelection)); + mSelection = do_CreateInstance(kFrameSelectionCID, &result); if (NS_FAILED(result)) return result; @@ -3541,6 +3539,9 @@ PresShell::BeginUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType) #ifdef DEBUG mUpdateCount++; #endif + if (aUpdateType & UPDATE_STYLE) + mStyleSet->BeginUpdate(); + return NS_OK; } @@ -3552,6 +3553,9 @@ PresShell::EndUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType) --mUpdateCount; #endif + if (aUpdateType & UPDATE_STYLE) + mStyleSet->EndUpdate(); + if (mStylesHaveChanged && (aUpdateType & UPDATE_STYLE)) return ReconstructStyleData(); @@ -7097,7 +7101,7 @@ PresShell::VerifyIncrementalReflow() // Create a new presentation shell to view the document. Use the // exact same style information that this document has. - nsStyleSet *newSet; + nsAutoPtr newSet; rv = CloneStyleSet(mStyleSet, &newSet); NS_ASSERTION(NS_SUCCEEDED(rv), "failed to clone style set"); rv = mDocument->CreateShell(cx, vm, newSet, &sh); diff --git a/mozilla/layout/base/public/nsIPresShell.h b/mozilla/layout/base/public/nsIPresShell.h index b24f2e82b5c..db839805d79 100644 --- a/mozilla/layout/base/public/nsIPresShell.h +++ b/mozilla/layout/base/public/nsIPresShell.h @@ -649,7 +649,7 @@ protected: // we must share ownership. nsIDocument* mDocument; // [STRONG] nsIPresContext* mPresContext; // [STRONG] - nsStyleSet* mStyleSet; // [STRONG] + nsStyleSet* mStyleSet; // [OWNS] nsIStyleFrameConstruction* mFrameConstructor; // [STRONG] nsIViewManager* mViewManager; // [WEAK] docViewer owns it so I don't have to nsIFrameManager* mFrameManager; // [STRONG] diff --git a/mozilla/layout/base/public/nsIStyleFrameConstruction.h b/mozilla/layout/base/public/nsIStyleFrameConstruction.h index 0d56b2cbff4..86579c19f51 100644 --- a/mozilla/layout/base/public/nsIStyleFrameConstruction.h +++ b/mozilla/layout/base/public/nsIStyleFrameConstruction.h @@ -57,7 +57,7 @@ class nsILayoutHistoryState; /** a simple struct (that may someday be expanded) * that contains data supplied by the caller to help - * the style set find a frame for a content node + * the frame constructor find a frame for a content node */ struct nsFindFrameHint { diff --git a/mozilla/layout/html/base/src/nsPresShell.cpp b/mozilla/layout/html/base/src/nsPresShell.cpp index 3b981265bd6..9ccc808178e 100644 --- a/mozilla/layout/html/base/src/nsPresShell.cpp +++ b/mozilla/layout/html/base/src/nsPresShell.cpp @@ -1644,9 +1644,7 @@ PresShell::Init(nsIDocument* aDocument, // before creating any frames. SetPreferenceStyleRules(PR_FALSE); - result = nsComponentManager::CreateInstance(kFrameSelectionCID, nsnull, - NS_GET_IID(nsIFrameSelection), - getter_AddRefs(mSelection)); + mSelection = do_CreateInstance(kFrameSelectionCID, &result); if (NS_FAILED(result)) return result; @@ -3541,6 +3539,9 @@ PresShell::BeginUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType) #ifdef DEBUG mUpdateCount++; #endif + if (aUpdateType & UPDATE_STYLE) + mStyleSet->BeginUpdate(); + return NS_OK; } @@ -3552,6 +3553,9 @@ PresShell::EndUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType) --mUpdateCount; #endif + if (aUpdateType & UPDATE_STYLE) + mStyleSet->EndUpdate(); + if (mStylesHaveChanged && (aUpdateType & UPDATE_STYLE)) return ReconstructStyleData(); @@ -7097,7 +7101,7 @@ PresShell::VerifyIncrementalReflow() // Create a new presentation shell to view the document. Use the // exact same style information that this document has. - nsStyleSet *newSet; + nsAutoPtr newSet; rv = CloneStyleSet(mStyleSet, &newSet); NS_ASSERTION(NS_SUCCEEDED(rv), "failed to clone style set"); rv = mDocument->CreateShell(cx, vm, newSet, &sh); diff --git a/mozilla/layout/printing/nsPrintEngine.cpp b/mozilla/layout/printing/nsPrintEngine.cpp index 151e4cc9e08..a4c8dc21387 100644 --- a/mozilla/layout/printing/nsPrintEngine.cpp +++ b/mozilla/layout/printing/nsPrintEngine.cpp @@ -2608,7 +2608,8 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO, PRBool aDoCalcShrink) // init it with the DC (aPO->mPresContext)->Init(mPrt->mPrintDocDC); - rv = mDocViewerPrint->CreateStyleSet(aPO->mDocument, &aPO->mStyleSet); + rv = mDocViewerPrint->CreateStyleSet(aPO->mDocument, + getter_Transfers(aPO->mStyleSet)); NS_ENSURE_SUCCESS(rv, rv); aPO->mViewManager = do_CreateInstance(kViewManagerCID, &rv); diff --git a/mozilla/layout/printing/nsPrintObject.h b/mozilla/layout/printing/nsPrintObject.h index 06cd9638010..d0b732607ed 100644 --- a/mozilla/layout/printing/nsPrintObject.h +++ b/mozilla/layout/printing/nsPrintObject.h @@ -81,7 +81,7 @@ public: PrintObjectType mFrameType; nsCOMPtr mPresContext; - nsStyleSet *mStyleSet; + nsAutoPtr mStyleSet; nsCOMPtr mPresShell; nsCOMPtr mViewManager; nsCOMPtr mWindow; diff --git a/mozilla/layout/style/nsRuleNode.cpp b/mozilla/layout/style/nsRuleNode.cpp index 54972c6ad12..ccb28d4acfd 100644 --- a/mozilla/layout/style/nsRuleNode.cpp +++ b/mozilla/layout/style/nsRuleNode.cpp @@ -4358,6 +4358,9 @@ PRBool nsRuleNode::Sweep() { // If we're not marked, then we have to delete ourself. + // However, we never allow the root node to GC itself, because nsStyleSet + // wants to hold onto the root node and not worry about re-creating a + // rule walker if the root node is deleted. if (!(mDependentBits & NS_RULE_NODE_GC_MARK) && !IsRoot()) { Destroy(); return PR_TRUE; diff --git a/mozilla/layout/style/nsStyleSet.cpp b/mozilla/layout/style/nsStyleSet.cpp index 460ac7e944e..f2d7978bdc5 100644 --- a/mozilla/layout/style/nsStyleSet.cpp +++ b/mozilla/layout/style/nsStyleSet.cpp @@ -55,7 +55,7 @@ nsStyleSet::nsStyleSet() : mRuleTree(nsnull), mRuleWalker(nsnull), mDestroyedCount(0), - mBatching(PR_FALSE), + mBatching(0), mInShutdown(PR_FALSE), mDirty(0) { @@ -70,8 +70,10 @@ nsStyleSet::Init(nsIPresContext *aPresContext) NS_ENSURE_TRUE(gQuirkURI, NS_ERROR_OUT_OF_MEMORY); } - if (!BuildDefaultStyleData(aPresContext)) - return NS_ERROR_FAILURE; + if (!BuildDefaultStyleData(aPresContext)) { + mDefaultStyleData.Destroy(0, aPresContext); + return NS_ERROR_OUT_OF_MEMORY; + } mRuleTree = nsRuleNode::CreateRootNode(aPresContext); if (!mRuleTree) { @@ -195,10 +197,8 @@ nsStyleSet::ReplaceSheets(sheetType aType, const nsCOMArray &aNewSheets) { mSheets[aType].Clear(); - for (PRInt32 i = 0; i < aNewSheets.Count(); ++i) { - if (!mSheets[aType].AppendObject(aNewSheets.ObjectAt(i))) - return NS_ERROR_OUT_OF_MEMORY; - } + if (!mSheets[aType].AppendObjects(aNewSheets)) + return NS_ERROR_OUT_OF_MEMORY; if (!mBatching) return GatherRuleProcessors(aType); @@ -212,7 +212,7 @@ nsStyleSet::ReplaceSheets(sheetType aType, nsresult nsStyleSet::AddDocStyleSheet(nsIStyleSheet* aSheet, nsIDocument* aDocument) { - NS_PRECONDITION((nsnull != aSheet) && (nsnull != aDocument), "null arg"); + NS_PRECONDITION(aSheet && aDocument, "null arg"); CHECK_APPLICABLE; nsCOMArray& docSheets = mSheets[eDocSheet]; @@ -248,21 +248,26 @@ nsStyleSet::AddDocStyleSheet(nsIStyleSheet* aSheet, nsIDocument* aDocument) void nsStyleSet::BeginUpdate() { - mBatching = 1; + ++mBatching; } nsresult nsStyleSet::EndUpdate() { + NS_ASSERTION(mBatching > 0, "Unbalanced EndUpdate"); + if (--mBatching) { + // We're not completely done yet. + return NS_OK; + } + for (int i = 0; i < eSheetTypeCount; ++i) { - if (mDirty & 1 << i) { + if (mDirty & (1 << i)) { nsresult rv = GatherRuleProcessors(i); NS_ENSURE_SUCCESS(rv, rv); } } mDirty = 0; - mBatching = 0; return NS_OK; } @@ -721,7 +726,7 @@ nsStyleSet::NotifyStyleContextDestroyed(nsIPresContext* aPresContext, #endif mRuleTree->Sweep(); - NS_ASSERTION(deleted, "Root not must not be gc'd"); + NS_ASSERTION(!deleted, "Root node must not be gc'd"); } } diff --git a/mozilla/layout/style/nsStyleSet.h b/mozilla/layout/style/nsStyleSet.h index 31cd29049f5..2de04e13a5c 100644 --- a/mozilla/layout/style/nsStyleSet.h +++ b/mozilla/layout/style/nsStyleSet.h @@ -49,6 +49,10 @@ class nsIURI; +// The style set object is created by the document viewer and ownership is +// then handed off to the PresShell. Only the PresShell should delete a +// style set. + class nsStyleSet { public: @@ -156,12 +160,13 @@ class nsStyleSet // Free global data at module shutdown static void FreeGlobals() { NS_IF_RELEASE(gQuirkURI); } - // APIs to manipulate the style sheet lists + // APIs to manipulate the style sheet lists. + // All sheet types are ordered most-significant-first. enum sheetType { eAgentSheet, eUserSheet, eDocSheet, - eOverrideSheet, // override sheets are ordered most significant first + eOverrideSheet, eSheetTypeCount }; @@ -237,9 +242,10 @@ class nsStyleSet PRInt32 mDestroyedCount; // used to batch style context GC nsVoidArray mRoots; // style contexts with no parent - unsigned mBatching : 1; + PRUint16 mBatching; + unsigned mInShutdown : 1; - unsigned mDirty : 6; // one dirty bit is used per sheet type + unsigned mDirty : 7; // one dirty bit is used per sheet type }; #endif