зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1429126 - Rejigger cached anonymous box styles to use a union. r=emilio
MozReview-Commit-ID: I2b3wILKwNp
This commit is contained in:
Родитель
c10cdf7282
Коммит
788dd2de1d
|
@ -0,0 +1,71 @@
|
|||
/* -*- 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 "nsIMemoryReporter.h"
|
||||
#include "mozilla/CachedAnonBoxStyles.h"
|
||||
#include "mozilla/ServoStyleContext.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
void
|
||||
CachedAnonBoxStyles::Insert(ServoStyleContext* aStyle)
|
||||
{
|
||||
MOZ_ASSERT(aStyle);
|
||||
MOZ_ASSERT(aStyle->IsInheritingAnonBox());
|
||||
|
||||
if (IsEmpty()) {
|
||||
RefPtr<ServoStyleContext> s = aStyle;
|
||||
mBits = reinterpret_cast<uintptr_t>(s.forget().take());
|
||||
MOZ_ASSERT(!IsEmpty() && !IsIndirect());
|
||||
} else if (IsIndirect()) {
|
||||
AsIndirect()->AppendElement(aStyle);
|
||||
} else {
|
||||
IndirectCache* cache = new IndirectCache();
|
||||
cache->AppendElement(dont_AddRef(AsDirect()));
|
||||
cache->AppendElement(aStyle);
|
||||
mBits = reinterpret_cast<uintptr_t>(cache) | 1;
|
||||
MOZ_ASSERT(IsIndirect());
|
||||
}
|
||||
}
|
||||
|
||||
ServoStyleContext*
|
||||
CachedAnonBoxStyles::Lookup(nsAtom* aAnonBox) const
|
||||
{
|
||||
MOZ_ASSERT(nsCSSAnonBoxes::IsInheritingAnonBox(aAnonBox));
|
||||
if (IsIndirect()) {
|
||||
for (auto& style : *AsIndirect()) {
|
||||
if (style->GetPseudo() == aAnonBox) {
|
||||
return style;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ServoStyleContext* direct = AsDirect();
|
||||
return direct && direct->GetPseudo() == aAnonBox ? direct : nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
CachedAnonBoxStyles::AddSizeOfIncludingThis(nsWindowSizes& aSizes, size_t* aCVsSize) const
|
||||
{
|
||||
if (IsIndirect()) {
|
||||
for (auto& style : *AsIndirect()) {
|
||||
if (!aSizes.mState.HaveSeenPtr(style)) {
|
||||
style->AddSizeOfIncludingThis(aSizes, aCVsSize);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ServoStyleContext* direct = AsDirect();
|
||||
if (direct && !aSizes.mState.HaveSeenPtr(direct)) {
|
||||
direct->AddSizeOfIncludingThis(aSizes, aCVsSize);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,67 @@
|
|||
/* -*- 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_CachedAnonBoxStyles_h
|
||||
#define mozilla_CachedAnonBoxStyles_h
|
||||
|
||||
#include "nsAtom.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
class nsWindowSizes;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class ServoStyleContext;
|
||||
|
||||
// Cache of anonymous box styles that inherit from a given style.
|
||||
//
|
||||
// To minimize memory footprint, the cache is word-sized with a tagged pointer
|
||||
// If there is only one entry, it's stored inline. If there are more, they're
|
||||
// stored in an out-of-line buffer. See bug 1429126 comment 0 and comment 1 for
|
||||
// the measurements and rationale that influenced the design.
|
||||
class CachedAnonBoxStyles
|
||||
{
|
||||
public:
|
||||
void Insert(ServoStyleContext* aStyle);
|
||||
ServoStyleContext* Lookup(nsAtom* aAnonBox) const;
|
||||
|
||||
CachedAnonBoxStyles() : mBits(0) {}
|
||||
~CachedAnonBoxStyles()
|
||||
{
|
||||
if (IsIndirect()) {
|
||||
delete AsIndirect();
|
||||
} else if (!IsEmpty()) {
|
||||
RefPtr<ServoStyleContext> ref = dont_AddRef(AsDirect());
|
||||
}
|
||||
}
|
||||
|
||||
void AddSizeOfIncludingThis(nsWindowSizes& aSizes, size_t* aCVsSize) const;
|
||||
|
||||
private:
|
||||
// See bug 1429126 comment 1 for the choice of four here.
|
||||
typedef AutoTArray<RefPtr<ServoStyleContext>, 4> IndirectCache;
|
||||
|
||||
bool IsEmpty() const { return !mBits; }
|
||||
bool IsIndirect() const { return (mBits & 1); }
|
||||
|
||||
ServoStyleContext* AsDirect() const
|
||||
{
|
||||
MOZ_ASSERT(!IsIndirect());
|
||||
return reinterpret_cast<ServoStyleContext*>(mBits);
|
||||
}
|
||||
|
||||
IndirectCache* AsIndirect() const
|
||||
{
|
||||
MOZ_ASSERT(IsIndirect());
|
||||
return reinterpret_cast<IndirectCache*>(mBits & ~1);
|
||||
}
|
||||
|
||||
uintptr_t mBits;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_CachedAnonBoxStyles_h
|
|
@ -33,26 +33,6 @@ ServoStyleContext::ServoStyleContext(
|
|||
// producing the ServoComputedData.
|
||||
}
|
||||
|
||||
ServoStyleContext*
|
||||
ServoStyleContext::GetCachedInheritingAnonBoxStyle(nsAtom* aAnonBox) const
|
||||
{
|
||||
MOZ_ASSERT(nsCSSAnonBoxes::IsInheritingAnonBox(aAnonBox));
|
||||
|
||||
// See the reasoning in SetCachedInheritingAnonBoxStyle to understand why we
|
||||
// can't use the cache in this case.
|
||||
if (IsInheritingAnonBox()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto* current = mNextInheritingAnonBoxStyle.get();
|
||||
|
||||
while (current && current->GetPseudo() != aAnonBox) {
|
||||
current = current->mNextInheritingAnonBoxStyle.get();
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
ServoStyleContext*
|
||||
ServoStyleContext::GetCachedLazyPseudoStyle(CSSPseudoElementType aPseudo) const
|
||||
{
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include "nsWindowSizes.h"
|
||||
#include <algorithm>
|
||||
|
||||
#include "mozilla/CachedAnonBoxStyles.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
|
@ -45,26 +47,29 @@ public:
|
|||
!nsCSSPseudoElements::IsEagerlyCascadedInServo(GetPseudoType());
|
||||
}
|
||||
|
||||
ServoStyleContext* GetCachedInheritingAnonBoxStyle(nsAtom* aAnonBox) const;
|
||||
ServoStyleContext* GetCachedInheritingAnonBoxStyle(nsAtom* aAnonBox) const
|
||||
{
|
||||
MOZ_ASSERT(nsCSSAnonBoxes::IsInheritingAnonBox(aAnonBox));
|
||||
|
||||
// This restriction is no longer necessary. We remove it in the next patch.
|
||||
if (IsInheritingAnonBox()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return mInheritingAnonBoxStyles.Lookup(aAnonBox);
|
||||
}
|
||||
|
||||
void SetCachedInheritedAnonBoxStyle(nsAtom* aAnonBox,
|
||||
ServoStyleContext* aStyle)
|
||||
{
|
||||
MOZ_ASSERT(!GetCachedInheritingAnonBoxStyle(aAnonBox));
|
||||
MOZ_ASSERT(!aStyle->mNextInheritingAnonBoxStyle);
|
||||
|
||||
// NOTE(emilio): Since we use it to cache inheriting anon boxes in a linked
|
||||
// list, we can't use that cache if the style we're inheriting from is an
|
||||
// inheriting anon box itself, since otherwise our parent would mistakenly
|
||||
// think that the style we're caching inherits from it.
|
||||
//
|
||||
// See the documentation of mNextInheritingAnonBoxStyle.
|
||||
// This restriction is no longer necessary. We remove it in the next patch.
|
||||
if (IsInheritingAnonBox()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mNextInheritingAnonBoxStyle.swap(aStyle->mNextInheritingAnonBoxStyle);
|
||||
mNextInheritingAnonBoxStyle = aStyle;
|
||||
mInheritingAnonBoxStyles.Insert(aStyle);
|
||||
}
|
||||
|
||||
ServoStyleContext* GetCachedLazyPseudoStyle(CSSPseudoElementType aPseudo) const;
|
||||
|
@ -111,11 +116,7 @@ public:
|
|||
// clearly identify in DMD's output the memory measured here.
|
||||
*aCVsSize += ServoComputedValuesMallocEnclosingSizeOf(this);
|
||||
mSource.AddSizeOfExcludingThis(aSizes);
|
||||
|
||||
if (mNextInheritingAnonBoxStyle &&
|
||||
!aSizes.mState.HaveSeenPtr(mNextInheritingAnonBoxStyle)) {
|
||||
mNextInheritingAnonBoxStyle->AddSizeOfIncludingThis(aSizes, aCVsSize);
|
||||
}
|
||||
mInheritingAnonBoxStyles.AddSizeOfIncludingThis(aSizes, aCVsSize);
|
||||
|
||||
if (mNextLazyPseudoStyle &&
|
||||
!aSizes.mState.HaveSeenPtr(mNextLazyPseudoStyle)) {
|
||||
|
@ -127,12 +128,9 @@ private:
|
|||
nsPresContext* mPresContext;
|
||||
ServoComputedData mSource;
|
||||
|
||||
// A linked-list cache of inheriting anon boxes inheriting from this style _if
|
||||
// the style isn't an inheriting anon-box_.
|
||||
//
|
||||
// Otherwise it represents the next entry in the cache of the parent style
|
||||
// context.
|
||||
RefPtr<ServoStyleContext> mNextInheritingAnonBoxStyle;
|
||||
// A cache of inheriting anon boxes inheriting from this style _if the style
|
||||
// isn't an inheriting anon-box_.
|
||||
CachedAnonBoxStyles mInheritingAnonBoxStyles;
|
||||
|
||||
// A linked-list cache of lazy pseudo styles inheriting from this style _if
|
||||
// the style isn't a lazy pseudo style itself_.
|
||||
|
|
|
@ -81,6 +81,7 @@ EXPORTS += [
|
|||
EXPORTS.mozilla += [
|
||||
'AnimationCollection.h',
|
||||
'BindingStyleRule.h',
|
||||
'CachedAnonBoxStyles.h',
|
||||
'CSSEnabledState.h',
|
||||
'CSSStyleSheet.h',
|
||||
'CSSVariableDeclarations.h',
|
||||
|
@ -179,6 +180,7 @@ EXPORTS.mozilla.css += [
|
|||
UNIFIED_SOURCES += [
|
||||
'AnimationCollection.cpp',
|
||||
'BindingStyleRule.cpp',
|
||||
'CachedAnonBoxStyles.cpp',
|
||||
'CounterStyleManager.cpp',
|
||||
'CSS.cpp',
|
||||
'CSSFontFeatureValuesRule.cpp',
|
||||
|
|
Загрузка…
Ссылка в новой задаче