зеркало из https://github.com/mozilla/gecko-dev.git
Bug 861449 - Incremental css::Rule destroyer. r=dbaron
Destroying large arrays of css::Rules during page teardown can take multiple milliseconds in incremental CC. To reduce CC pauses, this patch introduces a new class nsIncrementalClearCOMRuleArray that uses the deferred finalizer to incrementally destroy these rule arrays.
This commit is contained in:
Родитель
350215c93f
Коммит
a886770a11
|
@ -10,6 +10,7 @@
|
|||
#define mozilla_CSSStyleSheet_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/IncrementalClearCOMRuleArray.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
|
@ -19,7 +20,6 @@
|
|||
#include "nsIStyleSheet.h"
|
||||
#include "nsIDOMCSSStyleSheet.h"
|
||||
#include "nsICSSLoaderObserver.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsTArrayForwardDeclare.h"
|
||||
#include "nsString.h"
|
||||
#include "mozilla/CORSMode.h"
|
||||
|
@ -84,7 +84,7 @@ private:
|
|||
nsCOMPtr<nsIURI> mOriginalSheetURI; // for GetHref. Can be null.
|
||||
nsCOMPtr<nsIURI> mBaseURI; // for resolving relative URIs
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsCOMArray<css::Rule> mOrderedRules;
|
||||
IncrementalClearCOMRuleArray mOrderedRules;
|
||||
nsAutoPtr<nsXMLNameSpaceMap> mNameSpaceMap;
|
||||
// Linked list of child sheets. This is al fundamentally broken, because
|
||||
// each of the child sheets has a unique parent... We can only hope (and
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
#define mozilla_css_GroupRule_h__
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/IncrementalClearCOMRuleArray.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/css/Rule.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
|
@ -57,7 +57,7 @@ public:
|
|||
int32_t StyleRuleCount() const { return mRules.Count(); }
|
||||
Rule* GetStyleRuleAt(int32_t aIndex) const;
|
||||
|
||||
typedef nsCOMArray<Rule>::nsCOMArrayEnumFunc RuleEnumFunc;
|
||||
typedef IncrementalClearCOMRuleArray::nsCOMArrayEnumFunc RuleEnumFunc;
|
||||
bool EnumerateRulesForwards(RuleEnumFunc aFunc, void * aData) const;
|
||||
|
||||
/*
|
||||
|
@ -80,7 +80,7 @@ public:
|
|||
CloneRuleInto(Rule* aRule, void* aArray)
|
||||
{
|
||||
nsRefPtr<Rule> clone = aRule->Clone();
|
||||
static_cast<nsCOMArray<Rule>*>(aArray)->AppendObject(clone);
|
||||
static_cast<IncrementalClearCOMRuleArray*>(aArray)->AppendObject(clone);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ protected:
|
|||
uint32_t* _retval);
|
||||
nsresult DeleteRule(uint32_t aIndex);
|
||||
|
||||
nsCOMArray<Rule> mRules;
|
||||
IncrementalClearCOMRuleArray mRules;
|
||||
nsRefPtr<GroupRuleRuleList> mRuleCollection; // lazily constructed
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#include "mozilla/IncrementalClearCOMRuleArray.h"
|
||||
|
||||
#include "nsCycleCollector.h"
|
||||
#include "mozilla/DeferredFinalize.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsCCUncollectableMarker.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
typedef nsCOMArray<css::Rule> RuleArray;
|
||||
typedef nsTArray<RuleArray> RuleArrayArray;
|
||||
|
||||
|
||||
// These methods are based on those in DeferredFinalizerImpl.
|
||||
|
||||
static void*
|
||||
AppendRulesArrayPointer(void* aData, void* aObject)
|
||||
{
|
||||
RuleArrayArray* rulesArray = static_cast<RuleArrayArray*>(aData);
|
||||
RuleArray* oldRules = static_cast<RuleArray*>(aObject);
|
||||
|
||||
if (!rulesArray) {
|
||||
rulesArray = new RuleArrayArray();
|
||||
}
|
||||
|
||||
RuleArray* newRules = rulesArray->AppendElement();
|
||||
newRules->SwapElements(*oldRules);
|
||||
|
||||
return rulesArray;
|
||||
}
|
||||
|
||||
// Remove up to |aSliceBudget| css::Rules from the arrays, starting at
|
||||
// the end of the last array.
|
||||
static bool
|
||||
DeferredFinalizeRulesArray(uint32_t aSliceBudget, void* aData)
|
||||
{
|
||||
MOZ_ASSERT(aSliceBudget > 0, "nonsensical/useless call with aSliceBudget == 0");
|
||||
RuleArrayArray* rulesArray = static_cast<RuleArrayArray*>(aData);
|
||||
|
||||
size_t newOuterLen = rulesArray->Length();
|
||||
|
||||
while (aSliceBudget > 0 && newOuterLen > 0) {
|
||||
RuleArray& lastArray = rulesArray->ElementAt(newOuterLen - 1);
|
||||
uint32_t innerLen = lastArray.Length();
|
||||
uint32_t currSlice = std::min(innerLen, aSliceBudget);
|
||||
uint32_t newInnerLen = innerLen - currSlice;
|
||||
lastArray.TruncateLength(newInnerLen);
|
||||
aSliceBudget -= currSlice;
|
||||
if (newInnerLen == 0) {
|
||||
newOuterLen -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
rulesArray->TruncateLength(newOuterLen);
|
||||
|
||||
if (newOuterLen == 0) {
|
||||
delete rulesArray;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
IncrementalClearCOMRuleArray::Clear()
|
||||
{
|
||||
// Destroy the array incrementally if it is long and we
|
||||
// haven't started shutting down.
|
||||
if (Length() > 10 && nsCCUncollectableMarker::sGeneration) {
|
||||
DeferredFinalize(AppendRulesArrayPointer, DeferredFinalizeRulesArray, this);
|
||||
} else {
|
||||
nsCOMArray<css::Rule>::Clear();
|
||||
}
|
||||
MOZ_ASSERT(Length() == 0);
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#ifndef mozilla_IncrementalClearCOMRuleArray_h
|
||||
#define mozilla_IncrementalClearCOMRuleArray_h
|
||||
|
||||
#include "nsCOMArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace css {
|
||||
class Rule;
|
||||
} // namespace css
|
||||
|
||||
class IncrementalClearCOMRuleArray : public nsCOMArray<css::Rule>
|
||||
{
|
||||
public:
|
||||
IncrementalClearCOMRuleArray() {}
|
||||
~IncrementalClearCOMRuleArray() { Clear(); }
|
||||
|
||||
void Clear();
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* !defined(mozilla_IncrementalClearCOMRuleArray_h) */
|
|
@ -84,6 +84,7 @@ EXPORTS.mozilla += [
|
|||
'CSSVariableDeclarations.h',
|
||||
'CSSVariableResolver.h',
|
||||
'CSSVariableValues.h',
|
||||
'IncrementalClearCOMRuleArray.h',
|
||||
'StyleAnimationValue.h',
|
||||
]
|
||||
|
||||
|
@ -125,6 +126,7 @@ UNIFIED_SOURCES += [
|
|||
'FontFace.cpp',
|
||||
'FontFaceSetIterator.cpp',
|
||||
'ImageLoader.cpp',
|
||||
'IncrementalClearCOMRuleArray.cpp',
|
||||
'Loader.cpp',
|
||||
'MediaQueryList.cpp',
|
||||
'nsAnimationManager.cpp',
|
||||
|
|
Загрузка…
Ссылка в новой задаче