mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-01 13:57:32 +00:00
Bug 77999 - Part 2: Add RuleProcessorCache. r=dbaron
This commit is contained in:
parent
ea9aba1e83
commit
7c894d7982
@ -30,6 +30,7 @@
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsImageFrame.h"
|
||||
#include "nsLayoutStylesheetCache.h"
|
||||
#include "mozilla/RuleProcessorCache.h"
|
||||
#include "nsPrincipal.h"
|
||||
#include "nsRange.h"
|
||||
#include "nsRegion.h"
|
||||
@ -376,6 +377,7 @@ nsLayoutStatics::Shutdown()
|
||||
nsAttrValue::Shutdown();
|
||||
nsContentUtils::Shutdown();
|
||||
nsLayoutStylesheetCache::Shutdown();
|
||||
RuleProcessorCache::Shutdown();
|
||||
|
||||
ShutdownJSEnvironment();
|
||||
nsGlobalWindow::ShutDown();
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "mozilla/dom/CSSStyleSheetBinding.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "mozilla/RuleProcessorCache.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
@ -1075,6 +1076,7 @@ CSSStyleSheet::CSSStyleSheet(CORSMode aCORSMode, ReferrerPolicy aReferrerPolicy)
|
||||
mOwningNode(nullptr),
|
||||
mDisabled(false),
|
||||
mDirty(false),
|
||||
mInRuleProcessorCache(false),
|
||||
mScopeElement(nullptr),
|
||||
mRuleProcessors(nullptr)
|
||||
{
|
||||
@ -1093,6 +1095,7 @@ CSSStyleSheet::CSSStyleSheet(const CSSStyleSheet& aCopy,
|
||||
mOwningNode(aOwningNodeToUse),
|
||||
mDisabled(aCopy.mDisabled),
|
||||
mDirty(aCopy.mDirty),
|
||||
mInRuleProcessorCache(false),
|
||||
mScopeElement(nullptr),
|
||||
mInner(aCopy.mInner),
|
||||
mRuleProcessors(nullptr)
|
||||
@ -1135,6 +1138,9 @@ CSSStyleSheet::~CSSStyleSheet()
|
||||
NS_ASSERTION(mRuleProcessors->Length() == 0, "destructing sheet with rule processor reference");
|
||||
delete mRuleProcessors; // weak refs, should be empty here anyway
|
||||
}
|
||||
if (mInRuleProcessorCache) {
|
||||
RuleProcessorCache::RemoveSheet(this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -1703,10 +1709,18 @@ CSSStyleSheet::List(FILE* out, int32_t aIndent) const
|
||||
void
|
||||
CSSStyleSheet::ClearRuleCascades()
|
||||
{
|
||||
bool removedSheetFromRuleProcessorCache = false;
|
||||
if (mRuleProcessors) {
|
||||
nsCSSRuleProcessor **iter = mRuleProcessors->Elements(),
|
||||
**end = iter + mRuleProcessors->Length();
|
||||
for(; iter != end; ++iter) {
|
||||
if (!removedSheetFromRuleProcessorCache && (*iter)->IsShared()) {
|
||||
// Since the sheet has been modified, we need to remove all
|
||||
// RuleProcessorCache entries that contain this sheet, as the
|
||||
// list of @-moz-document rules might have changed.
|
||||
RuleProcessorCache::RemoveSheet(this);
|
||||
removedSheetFromRuleProcessorCache = true;
|
||||
}
|
||||
(*iter)->ClearRuleCascades();
|
||||
}
|
||||
}
|
||||
|
@ -239,6 +239,8 @@ public:
|
||||
|
||||
nsresult ParseSheet(const nsAString& aInput);
|
||||
|
||||
void SetInRuleProcessorCache() { mInRuleProcessorCache = true; }
|
||||
|
||||
// nsIDOMStyleSheet interface
|
||||
NS_DECL_NSIDOMSTYLESHEET
|
||||
|
||||
@ -357,6 +359,7 @@ protected:
|
||||
nsINode* mOwningNode; // weak ref
|
||||
bool mDisabled;
|
||||
bool mDirty; // has been modified
|
||||
bool mInRuleProcessorCache;
|
||||
nsRefPtr<dom::Element> mScopeElement;
|
||||
|
||||
CSSStyleSheetInner* mInner;
|
||||
|
284
layout/style/RuleProcessorCache.cpp
Normal file
284
layout/style/RuleProcessorCache.cpp
Normal file
@ -0,0 +1,284 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* cache of re-usable nsCSSRuleProcessors for given sets of style sheets
|
||||
*/
|
||||
|
||||
#include "RuleProcessorCache.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "nsCSSRuleProcessor.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
NS_IMPL_ISUPPORTS(RuleProcessorCache, nsIMemoryReporter)
|
||||
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF(RuleProcessorCacheMallocSizeOf)
|
||||
|
||||
NS_IMETHODIMP
|
||||
RuleProcessorCache::CollectReports(nsIHandleReportCallback* aHandleReport,
|
||||
nsISupports* aData, bool aAnonymize)
|
||||
{
|
||||
return MOZ_COLLECT_REPORT(
|
||||
"explicit/layout/rule-processor-cache", KIND_HEAP, UNITS_BYTES,
|
||||
SizeOfIncludingThis(RuleProcessorCacheMallocSizeOf),
|
||||
"Memory used for cached rule processors.");
|
||||
}
|
||||
|
||||
RuleProcessorCache::~RuleProcessorCache()
|
||||
{
|
||||
UnregisterWeakMemoryReporter(this);
|
||||
|
||||
for (Entry& e : mEntries) {
|
||||
for (DocumentEntry& de : e.mDocumentEntries) {
|
||||
if (de.mRuleProcessor->GetExpirationState()->IsTracked()) {
|
||||
mExpirationTracker.RemoveObject(de.mRuleProcessor);
|
||||
}
|
||||
de.mRuleProcessor->SetInRuleProcessorCache(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RuleProcessorCache::InitMemoryReporter()
|
||||
{
|
||||
RegisterWeakMemoryReporter(this);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
RuleProcessorCache::EnsureGlobal()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (gShutdown) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!gRuleProcessorCache) {
|
||||
gRuleProcessorCache = new RuleProcessorCache;
|
||||
gRuleProcessorCache->InitMemoryReporter();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
RuleProcessorCache::RemoveSheet(CSSStyleSheet* aSheet)
|
||||
{
|
||||
if (!EnsureGlobal()) {
|
||||
return;
|
||||
}
|
||||
gRuleProcessorCache->DoRemoveSheet(aSheet);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* static */ bool
|
||||
RuleProcessorCache::HasRuleProcessor(nsCSSRuleProcessor* aRuleProcessor)
|
||||
{
|
||||
if (!EnsureGlobal()) {
|
||||
return false;
|
||||
}
|
||||
return gRuleProcessorCache->DoHasRuleProcessor(aRuleProcessor);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* static */ void
|
||||
RuleProcessorCache::RemoveRuleProcessor(nsCSSRuleProcessor* aRuleProcessor)
|
||||
{
|
||||
if (!EnsureGlobal()) {
|
||||
return;
|
||||
}
|
||||
gRuleProcessorCache->DoRemoveRuleProcessor(aRuleProcessor);
|
||||
}
|
||||
|
||||
/* static */ nsCSSRuleProcessor*
|
||||
RuleProcessorCache::GetRuleProcessor(const nsTArray<CSSStyleSheet*>& aSheets,
|
||||
nsPresContext* aPresContext)
|
||||
{
|
||||
if (!EnsureGlobal()) {
|
||||
return nullptr;
|
||||
}
|
||||
return gRuleProcessorCache->DoGetRuleProcessor(aSheets, aPresContext);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
RuleProcessorCache::PutRuleProcessor(
|
||||
const nsTArray<CSSStyleSheet*>& aSheets,
|
||||
nsTArray<css::DocumentRule*>&& aDocumentRulesInSheets,
|
||||
const nsDocumentRuleResultCacheKey& aCacheKey,
|
||||
nsCSSRuleProcessor* aRuleProcessor)
|
||||
{
|
||||
if (!EnsureGlobal()) {
|
||||
return;
|
||||
}
|
||||
gRuleProcessorCache->DoPutRuleProcessor(aSheets, Move(aDocumentRulesInSheets),
|
||||
aCacheKey, aRuleProcessor);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
RuleProcessorCache::StartTracking(nsCSSRuleProcessor* aRuleProcessor)
|
||||
{
|
||||
if (!EnsureGlobal()) {
|
||||
return;
|
||||
}
|
||||
return gRuleProcessorCache->DoStartTracking(aRuleProcessor);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
RuleProcessorCache::StopTracking(nsCSSRuleProcessor* aRuleProcessor)
|
||||
{
|
||||
if (!EnsureGlobal()) {
|
||||
return;
|
||||
}
|
||||
return gRuleProcessorCache->DoStopTracking(aRuleProcessor);
|
||||
}
|
||||
|
||||
void
|
||||
RuleProcessorCache::DoRemoveSheet(CSSStyleSheet* aSheet)
|
||||
{
|
||||
Entry* last = std::remove_if(mEntries.begin(), mEntries.end(),
|
||||
HasSheet_ThenRemoveRuleProcessors(this, aSheet));
|
||||
mEntries.TruncateLength(last - mEntries.begin());
|
||||
}
|
||||
|
||||
nsCSSRuleProcessor*
|
||||
RuleProcessorCache::DoGetRuleProcessor(const nsTArray<CSSStyleSheet*>& aSheets,
|
||||
nsPresContext* aPresContext)
|
||||
{
|
||||
for (Entry& e : mEntries) {
|
||||
if (e.mSheets == aSheets) {
|
||||
for (DocumentEntry& de : e.mDocumentEntries) {
|
||||
if (de.mCacheKey.Matches(aPresContext, e.mDocumentRulesInSheets)) {
|
||||
return de.mRuleProcessor;
|
||||
}
|
||||
}
|
||||
// Entry::mSheets is unique; if we matched aSheets but didn't
|
||||
// find a matching DocumentEntry, we won't find one later in
|
||||
// mEntries.
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
RuleProcessorCache::DoPutRuleProcessor(
|
||||
const nsTArray<CSSStyleSheet*>& aSheets,
|
||||
nsTArray<css::DocumentRule*>&& aDocumentRulesInSheets,
|
||||
const nsDocumentRuleResultCacheKey& aCacheKey,
|
||||
nsCSSRuleProcessor* aRuleProcessor)
|
||||
{
|
||||
MOZ_ASSERT(!aRuleProcessor->IsInRuleProcessorCache());
|
||||
|
||||
Entry* entry = nullptr;
|
||||
for (Entry& e : mEntries) {
|
||||
if (e.mSheets == aSheets) {
|
||||
entry = &e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!entry) {
|
||||
entry = mEntries.AppendElement();
|
||||
entry->mSheets = aSheets;
|
||||
entry->mDocumentRulesInSheets = aDocumentRulesInSheets;
|
||||
for (CSSStyleSheet* sheet : aSheets) {
|
||||
sheet->SetInRuleProcessorCache();
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(entry->mDocumentRulesInSheets == aDocumentRulesInSheets,
|
||||
"DocumentRule array shouldn't have changed");
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
for (DocumentEntry& de : entry->mDocumentEntries) {
|
||||
MOZ_ASSERT(de.mCacheKey != aCacheKey,
|
||||
"should not have duplicate document cache keys");
|
||||
}
|
||||
#endif
|
||||
|
||||
DocumentEntry* documentEntry = entry->mDocumentEntries.AppendElement();
|
||||
documentEntry->mCacheKey = aCacheKey;
|
||||
documentEntry->mRuleProcessor = aRuleProcessor;
|
||||
aRuleProcessor->SetInRuleProcessorCache(true);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bool
|
||||
RuleProcessorCache::DoHasRuleProcessor(nsCSSRuleProcessor* aRuleProcessor)
|
||||
{
|
||||
for (Entry& e : mEntries) {
|
||||
for (DocumentEntry& de : e.mDocumentEntries) {
|
||||
if (de.mRuleProcessor == aRuleProcessor) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
RuleProcessorCache::DoRemoveRuleProcessor(nsCSSRuleProcessor* aRuleProcessor)
|
||||
{
|
||||
MOZ_ASSERT(aRuleProcessor->IsInRuleProcessorCache());
|
||||
|
||||
aRuleProcessor->SetInRuleProcessorCache(false);
|
||||
mExpirationTracker.RemoveObjectIfTracked(aRuleProcessor);
|
||||
for (Entry& e : mEntries) {
|
||||
for (size_t i = 0; i < e.mDocumentEntries.Length(); i++) {
|
||||
if (e.mDocumentEntries[i].mRuleProcessor == aRuleProcessor) {
|
||||
e.mDocumentEntries.RemoveElementAt(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT_UNREACHABLE("should have found rule processor");
|
||||
}
|
||||
|
||||
void
|
||||
RuleProcessorCache::DoStartTracking(nsCSSRuleProcessor* aRuleProcessor)
|
||||
{
|
||||
mExpirationTracker.AddObject(aRuleProcessor);
|
||||
}
|
||||
|
||||
void
|
||||
RuleProcessorCache::DoStopTracking(nsCSSRuleProcessor* aRuleProcessor)
|
||||
{
|
||||
mExpirationTracker.RemoveObjectIfTracked(aRuleProcessor);
|
||||
}
|
||||
|
||||
size_t
|
||||
RuleProcessorCache::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
|
||||
{
|
||||
size_t n = aMallocSizeOf(this);
|
||||
|
||||
int count = 0;
|
||||
n += mEntries.SizeOfExcludingThis(aMallocSizeOf);
|
||||
for (Entry& e : mEntries) {
|
||||
n += e.mDocumentEntries.SizeOfExcludingThis(aMallocSizeOf);
|
||||
for (DocumentEntry& de : e.mDocumentEntries) {
|
||||
count++;
|
||||
n += de.mRuleProcessor->SizeOfIncludingThis(aMallocSizeOf);
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
RuleProcessorCache::ExpirationTracker::RemoveObjectIfTracked(
|
||||
nsCSSRuleProcessor* aRuleProcessor)
|
||||
{
|
||||
if (aRuleProcessor->GetExpirationState()->IsTracked()) {
|
||||
RemoveObject(aRuleProcessor);
|
||||
}
|
||||
}
|
||||
|
||||
bool RuleProcessorCache::gShutdown = false;
|
||||
mozilla::StaticRefPtr<RuleProcessorCache> RuleProcessorCache::gRuleProcessorCache;
|
149
layout/style/RuleProcessorCache.h
Normal file
149
layout/style/RuleProcessorCache.h
Normal file
@ -0,0 +1,149 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* cache of re-usable nsCSSRuleProcessors for given sets of style sheets
|
||||
*/
|
||||
|
||||
#ifndef mozilla_RuleProcessorCache_h
|
||||
#define mozilla_RuleProcessorCache_h
|
||||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsCSSRuleProcessor.h"
|
||||
#include "nsExpirationTracker.h"
|
||||
#include "nsIMediaList.h"
|
||||
#include "nsIMemoryReporter.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
class nsCSSRuleProcessor;
|
||||
namespace mozilla {
|
||||
class CSSStyleSheet;
|
||||
namespace css {
|
||||
class DocumentRule;
|
||||
}
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/**
|
||||
* The RuleProcessorCache is a singleton object that caches
|
||||
* nsCSSRuleProcessors keyed off a list of style sheets and the result of
|
||||
* evaluating all @-moz-documents in the style sheets. nsStyleSet gets and
|
||||
* puts nsCSSRuleProcessors from/to the RuleProcessorCache.
|
||||
*
|
||||
* State bits on CSSStyleSheet and nsCSSRuleProcessor track whether they are in
|
||||
* the RuleProcessorCache. This lets us remove them from the RuleProcessorCache
|
||||
* when they're going away.
|
||||
*/
|
||||
class RuleProcessorCache final : public nsIMemoryReporter
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMEMORYREPORTER
|
||||
|
||||
public:
|
||||
static nsCSSRuleProcessor* GetRuleProcessor(
|
||||
const nsTArray<CSSStyleSheet*>& aSheets,
|
||||
nsPresContext* aPresContext);
|
||||
static void PutRuleProcessor(
|
||||
const nsTArray<CSSStyleSheet*>& aSheets,
|
||||
nsTArray<css::DocumentRule*>&& aDocumentRulesInSheets,
|
||||
const nsDocumentRuleResultCacheKey& aCacheKey,
|
||||
nsCSSRuleProcessor* aRuleProcessor);
|
||||
static void StartTracking(nsCSSRuleProcessor* aRuleProcessor);
|
||||
static void StopTracking(nsCSSRuleProcessor* aRuleProcessor);
|
||||
|
||||
#ifdef DEBUG
|
||||
static bool HasRuleProcessor(nsCSSRuleProcessor* aRuleProcessor);
|
||||
#endif
|
||||
static void RemoveRuleProcessor(nsCSSRuleProcessor* aRuleProcessor);
|
||||
static void RemoveSheet(CSSStyleSheet* aSheet);
|
||||
|
||||
static void Shutdown() { gShutdown = true; gRuleProcessorCache = nullptr; }
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
|
||||
|
||||
private:
|
||||
class ExpirationTracker : public nsExpirationTracker<nsCSSRuleProcessor,3>
|
||||
{
|
||||
public:
|
||||
ExpirationTracker(RuleProcessorCache* aCache)
|
||||
: nsExpirationTracker<nsCSSRuleProcessor,3>(10000)
|
||||
, mCache(aCache) {}
|
||||
|
||||
void RemoveObjectIfTracked(nsCSSRuleProcessor* aRuleProcessor);
|
||||
|
||||
virtual void NotifyExpired(nsCSSRuleProcessor* aRuleProcessor) override {
|
||||
mCache->RemoveRuleProcessor(aRuleProcessor);
|
||||
}
|
||||
|
||||
private:
|
||||
RuleProcessorCache* mCache;
|
||||
};
|
||||
|
||||
RuleProcessorCache() : mExpirationTracker(this) {}
|
||||
~RuleProcessorCache();
|
||||
|
||||
void InitMemoryReporter();
|
||||
|
||||
static bool EnsureGlobal();
|
||||
static StaticRefPtr<RuleProcessorCache> gRuleProcessorCache;
|
||||
static bool gShutdown;
|
||||
|
||||
void DoRemoveSheet(CSSStyleSheet* aSheet);
|
||||
nsCSSRuleProcessor* DoGetRuleProcessor(
|
||||
const nsTArray<CSSStyleSheet*>& aSheets,
|
||||
nsPresContext* aPresContext);
|
||||
void DoPutRuleProcessor(const nsTArray<CSSStyleSheet*>& aSheets,
|
||||
nsTArray<css::DocumentRule*>&& aDocumentRulesInSheets,
|
||||
const nsDocumentRuleResultCacheKey& aCacheKey,
|
||||
nsCSSRuleProcessor* aRuleProcessor);
|
||||
#ifdef DEBUG
|
||||
bool DoHasRuleProcessor(nsCSSRuleProcessor* aRuleProcessor);
|
||||
#endif
|
||||
void DoRemoveRuleProcessor(nsCSSRuleProcessor* aRuleProcessor);
|
||||
void DoStartTracking(nsCSSRuleProcessor* aRuleProcessor);
|
||||
void DoStopTracking(nsCSSRuleProcessor* aRuleProcessor);
|
||||
|
||||
struct DocumentEntry {
|
||||
nsDocumentRuleResultCacheKey mCacheKey;
|
||||
nsRefPtr<nsCSSRuleProcessor> mRuleProcessor;
|
||||
};
|
||||
|
||||
struct Entry {
|
||||
nsTArray<CSSStyleSheet*> mSheets;
|
||||
nsTArray<css::DocumentRule*> mDocumentRulesInSheets;
|
||||
nsTArray<DocumentEntry> mDocumentEntries;
|
||||
};
|
||||
|
||||
// Function object to test whether an Entry object has a given sheet
|
||||
// in its mSheets array. If it does, removes all of its rule processors
|
||||
// before returning true.
|
||||
struct HasSheet_ThenRemoveRuleProcessors {
|
||||
HasSheet_ThenRemoveRuleProcessors(RuleProcessorCache* aCache,
|
||||
CSSStyleSheet* aSheet)
|
||||
: mCache(aCache), mSheet(aSheet) {}
|
||||
bool operator()(Entry& aEntry) {
|
||||
if (aEntry.mSheets.Contains(mSheet)) {
|
||||
for (DocumentEntry& de : aEntry.mDocumentEntries) {
|
||||
de.mRuleProcessor->SetInRuleProcessorCache(false);
|
||||
mCache->mExpirationTracker.RemoveObjectIfTracked(de.mRuleProcessor);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
RuleProcessorCache* mCache;
|
||||
CSSStyleSheet* mSheet;
|
||||
};
|
||||
|
||||
ExpirationTracker mExpirationTracker;
|
||||
nsTArray<Entry> mEntries;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_RuleProcessorCache_h
|
@ -86,6 +86,7 @@ EXPORTS.mozilla += [
|
||||
'CSSVariableValues.h',
|
||||
'IncrementalClearCOMRuleArray.h',
|
||||
'RuleNodeCacheConditions.h',
|
||||
'RuleProcessorCache.h',
|
||||
'StyleAnimationValue.h',
|
||||
]
|
||||
|
||||
@ -165,6 +166,7 @@ UNIFIED_SOURCES += [
|
||||
'nsStyleUtil.cpp',
|
||||
'nsTransitionManager.cpp',
|
||||
'RuleNodeCacheConditions.cpp',
|
||||
'RuleProcessorCache.cpp',
|
||||
'StyleAnimationValue.cpp',
|
||||
'StyleRule.cpp',
|
||||
'SVGAttrAnimationRuleProcessor.cpp',
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/TypedEnumBits.h"
|
||||
#include "RuleProcessorCache.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
@ -1005,7 +1006,8 @@ nsCSSRuleProcessor::nsCSSRuleProcessor(const sheet_array_type& aSheets,
|
||||
uint8_t aSheetType,
|
||||
Element* aScopeElement,
|
||||
nsCSSRuleProcessor*
|
||||
aPreviousCSSRuleProcessor)
|
||||
aPreviousCSSRuleProcessor,
|
||||
bool aIsShared)
|
||||
: mSheets(aSheets)
|
||||
, mRuleCascades(nullptr)
|
||||
, mPreviousCacheKey(aPreviousCSSRuleProcessor
|
||||
@ -1014,6 +1016,8 @@ nsCSSRuleProcessor::nsCSSRuleProcessor(const sheet_array_type& aSheets,
|
||||
, mLastPresContext(nullptr)
|
||||
, mScopeElement(aScopeElement)
|
||||
, mSheetType(aSheetType)
|
||||
, mIsShared(aIsShared)
|
||||
, mInRuleProcessorCache(false)
|
||||
{
|
||||
NS_ASSERTION(!!mScopeElement == (aSheetType == nsStyleSet::eScopedDocSheet),
|
||||
"aScopeElement must be specified iff aSheetType is "
|
||||
@ -1025,6 +1029,10 @@ nsCSSRuleProcessor::nsCSSRuleProcessor(const sheet_array_type& aSheets,
|
||||
|
||||
nsCSSRuleProcessor::~nsCSSRuleProcessor()
|
||||
{
|
||||
if (mInRuleProcessorCache) {
|
||||
RuleProcessorCache::RemoveRuleProcessor(this);
|
||||
}
|
||||
MOZ_ASSERT(!mExpirationState.IsTracked());
|
||||
ClearSheets();
|
||||
ClearRuleCascades();
|
||||
}
|
||||
@ -2990,6 +2998,13 @@ nsCSSRuleProcessor::ClearRuleCascades()
|
||||
mPreviousCacheKey = CloneMQCacheKey();
|
||||
}
|
||||
|
||||
// No need to remove the rule processor from the RuleProcessorCache here,
|
||||
// since CSSStyleSheet::ClearRuleCascades will have called
|
||||
// RuleProcessorCache::RemoveSheet() passing itself, which will catch
|
||||
// this rule processor (and any others for different @-moz-document
|
||||
// cache key results).
|
||||
MOZ_ASSERT(!RuleProcessorCache::HasRuleProcessor(this));
|
||||
|
||||
// We rely on our caller (perhaps indirectly) to do something that
|
||||
// will rebuild style data and the user font set (either
|
||||
// nsIPresShell::ReconstructStyleData or
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "nsIStyleRuleProcessor.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsExpirationTracker.h"
|
||||
#include "nsRuleWalker.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
@ -59,7 +60,8 @@ public:
|
||||
nsCSSRuleProcessor(const sheet_array_type& aSheets,
|
||||
uint8_t aSheetType,
|
||||
mozilla::dom::Element* aScopeElement,
|
||||
nsCSSRuleProcessor* aPreviousCSSRuleProcessor);
|
||||
nsCSSRuleProcessor* aPreviousCSSRuleProcessor,
|
||||
bool aIsShared = false);
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(nsCSSRuleProcessor)
|
||||
@ -161,6 +163,16 @@ public:
|
||||
*/
|
||||
mozilla::dom::Element* GetScopeElement() const { return mScopeElement; }
|
||||
|
||||
bool IsShared() const { return mIsShared; }
|
||||
|
||||
nsExpirationState* GetExpirationState() { return &mExpirationState; }
|
||||
void SetInRuleProcessorCache(bool aVal) {
|
||||
MOZ_ASSERT(mIsShared);
|
||||
printf("%p SetInRuleProcessorCache %d\n", this, aVal);
|
||||
mInRuleProcessorCache = aVal;
|
||||
}
|
||||
bool IsInRuleProcessorCache() const { return mInRuleProcessorCache; }
|
||||
|
||||
#ifdef XP_WIN
|
||||
// Cached theme identifier for the moz-windows-theme media query.
|
||||
static uint8_t GetWindowsThemeIdentifier();
|
||||
@ -214,9 +226,14 @@ private:
|
||||
// Only used if mSheetType == nsStyleSet::eScopedDocSheet.
|
||||
nsRefPtr<mozilla::dom::Element> mScopeElement;
|
||||
|
||||
nsExpirationState mExpirationState;
|
||||
|
||||
// type of stylesheet using this processor
|
||||
uint8_t mSheetType; // == nsStyleSet::sheetType
|
||||
|
||||
const bool mIsShared;
|
||||
bool mInRuleProcessorCache;
|
||||
|
||||
#ifdef XP_WIN
|
||||
static uint8_t sWinThemeId;
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user