Bug 1429126 - Rejigger cached anonymous box styles to use a union. r=emilio

MozReview-Commit-ID: I2b3wILKwNp
This commit is contained in:
Bobby Holley 2018-01-08 16:44:55 -08:00
Родитель c10cdf7282
Коммит 788dd2de1d
5 изменённых файлов: 159 добавлений и 41 удалений

Просмотреть файл

@ -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',