Attach FrameProperties to each frame instead of using a shared hashtable

Dispense the shared hashtable and instead attach the frame property list directly to nsIFrame.
This commit is contained in:
win7-7 2019-06-26 01:51:45 +03:00 • committed by Roy Tam
commit 922e819d1c
62 changed files with 738 additions and 945 deletions

View file

@ -178,7 +178,7 @@ LayerActivityTracker::NotifyExpired(LayerActivity* aObject)
f->SchedulePaint();
}
f->RemoveStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY);
f->Properties().Delete(LayerActivityProperty());
f->DeleteProperty(LayerActivityProperty());
} else {
c->DeleteProperty(nsGkAtoms::LayerActivity);
}
@ -190,15 +190,13 @@ GetLayerActivity(nsIFrame* aFrame)
if (!aFrame->HasAnyStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY)) {
return nullptr;
}
FrameProperties properties = aFrame->Properties();
return properties.Get(LayerActivityProperty());
return aFrame->GetProperty(LayerActivityProperty());
}
static LayerActivity*
GetLayerActivityForUpdate(nsIFrame* aFrame)
{
FrameProperties properties = aFrame->Properties();
LayerActivity* layerActivity = properties.Get(LayerActivityProperty());
LayerActivity* layerActivity = aFrame->GetProperty(LayerActivityProperty());
if (layerActivity) {
gLayerActivityTracker->MarkUsed(layerActivity);
} else {
@ -208,7 +206,7 @@ GetLayerActivityForUpdate(nsIFrame* aFrame)
layerActivity = new LayerActivity(aFrame);
gLayerActivityTracker->AddObject(layerActivity);
aFrame->AddStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY);
properties.Set(LayerActivityProperty(), layerActivity);
aFrame->SetProperty(LayerActivityProperty(), layerActivity);
}
return layerActivity;
}
@ -225,8 +223,7 @@ ActiveLayerTracker::TransferActivityToContent(nsIFrame* aFrame, nsIContent* aCon
if (!aFrame->HasAnyStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY)) {
return;
}
FrameProperties properties = aFrame->Properties();
LayerActivity* layerActivity = properties.Remove(LayerActivityProperty());
LayerActivity* layerActivity = aFrame->RemoveProperty(LayerActivityProperty());
aFrame->RemoveStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY);
if (!layerActivity) {
return;
@ -248,7 +245,7 @@ ActiveLayerTracker::TransferActivityToFrame(nsIContent* aContent, nsIFrame* aFra
layerActivity->mContent = nullptr;
layerActivity->mFrame = aFrame;
aFrame->AddStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY);
aFrame->Properties().Set(LayerActivityProperty(), layerActivity);
aFrame->SetProperty(LayerActivityProperty(), layerActivity);
}
static void

View file

@ -165,10 +165,10 @@ FrameLayerBuilder::DisplayItemData::AddFrame(nsIFrame* aFrame)
mFrameList.AppendElement(aFrame);
nsTArray<DisplayItemData*>* array =
aFrame->Properties().Get(FrameLayerBuilder::LayerManagerDataProperty());
aFrame->GetProperty(FrameLayerBuilder::LayerManagerDataProperty());
if (!array) {
array = new nsTArray<DisplayItemData*>();
aFrame->Properties().Set(FrameLayerBuilder::LayerManagerDataProperty(), array);
aFrame->SetProperty(FrameLayerBuilder::LayerManagerDataProperty(), array);
}
array->AppendElement(this);
}
@ -181,7 +181,7 @@ FrameLayerBuilder::DisplayItemData::RemoveFrame(nsIFrame* aFrame)
MOZ_RELEASE_ASSERT(result, "Can't remove a frame that wasn't added!");
nsTArray<DisplayItemData*>* array =
aFrame->Properties().Get(FrameLayerBuilder::LayerManagerDataProperty());
aFrame->GetProperty(FrameLayerBuilder::LayerManagerDataProperty());
MOZ_RELEASE_ASSERT(array, "Must be already stored on the frame!");
array->RemoveElement(this);
}
@ -268,7 +268,7 @@ FrameLayerBuilder::DisplayItemData::~DisplayItemData()
continue;
}
nsTArray<DisplayItemData*> *array =
reinterpret_cast<nsTArray<DisplayItemData*>*>(frame->Properties().Get(LayerManagerDataProperty()));
reinterpret_cast<nsTArray<DisplayItemData*>*>(frame->GetProperty(LayerManagerDataProperty()));
array->RemoveElement(this);
}
@ -390,8 +390,7 @@ public:
/* static */ void
FrameLayerBuilder::DestroyDisplayItemDataFor(nsIFrame* aFrame)
{
FrameProperties props = aFrame->Properties();
props.Delete(LayerManagerDataProperty());
aFrame->DeleteProperty(LayerManagerDataProperty());
}
struct AssignedDisplayItem
@ -1823,7 +1822,7 @@ FrameLayerBuilder::DisplayItemData*
FrameLayerBuilder::GetDisplayItemData(nsIFrame* aFrame, uint32_t aKey)
{
const nsTArray<DisplayItemData*>* array =
aFrame->Properties().Get(LayerManagerDataProperty());
aFrame->GetProperty(LayerManagerDataProperty());
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
DisplayItemData* item = AssertDisplayItemData(array->ElementAt(i));
@ -2052,7 +2051,7 @@ FrameLayerBuilder::GetDisplayItemDataForManager(nsDisplayItem* aItem,
LayerManager* aManager)
{
const nsTArray<DisplayItemData*>* array =
aItem->Frame()->Properties().Get(LayerManagerDataProperty());
aItem->Frame()->GetProperty(LayerManagerDataProperty());
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
DisplayItemData* item = AssertDisplayItemData(array->ElementAt(i));
@ -2069,7 +2068,7 @@ bool
FrameLayerBuilder::HasRetainedDataFor(nsIFrame* aFrame, uint32_t aDisplayItemKey)
{
const nsTArray<DisplayItemData*>* array =
aFrame->Properties().Get(LayerManagerDataProperty());
aFrame->GetProperty(LayerManagerDataProperty());
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
if (AssertDisplayItemData(array->ElementAt(i))->mDisplayItemKey == aDisplayItemKey) {
@ -2084,7 +2083,7 @@ void
FrameLayerBuilder::IterateRetainedDataFor(nsIFrame* aFrame, DisplayItemDataCallback aCallback)
{
const nsTArray<DisplayItemData*>* array =
aFrame->Properties().Get(LayerManagerDataProperty());
aFrame->GetProperty(LayerManagerDataProperty());
if (!array) {
return;
}
@ -2151,7 +2150,7 @@ FrameLayerBuilder::ClearCachedGeometry(nsDisplayItem* aItem)
FrameLayerBuilder::GetDebugOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey)
{
const nsTArray<DisplayItemData*>* array =
aFrame->Properties().Get(LayerManagerDataProperty());
aFrame->GetProperty(LayerManagerDataProperty());
if (!array) {
return nullptr;
@ -2171,7 +2170,7 @@ FrameLayerBuilder::GetDebugOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKe
FrameLayerBuilder::GetDebugSingleOldPaintedLayerForFrame(nsIFrame* aFrame)
{
const nsTArray<DisplayItemData*>* array =
aFrame->Properties().Get(LayerManagerDataProperty());
aFrame->GetProperty(LayerManagerDataProperty());
if (!array) {
return nullptr;
@ -5656,7 +5655,7 @@ FrameLayerBuilder::InvalidateAllLayers(LayerManager* aManager)
FrameLayerBuilder::InvalidateAllLayersForFrame(nsIFrame *aFrame)
{
const nsTArray<DisplayItemData*>* array =
aFrame->Properties().Get(LayerManagerDataProperty());
aFrame->GetProperty(LayerManagerDataProperty());
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
AssertDisplayItemData(array->ElementAt(i))->mParent->mInvalidateAllLayers = true;
@ -5673,7 +5672,7 @@ FrameLayerBuilder::GetDedicatedLayer(nsIFrame* aFrame, uint32_t aDisplayItemKey)
// in the secondary manager
const nsTArray<DisplayItemData*>* array =
aFrame->Properties().Get(LayerManagerDataProperty());
aFrame->GetProperty(LayerManagerDataProperty());
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
DisplayItemData *element = AssertDisplayItemData(array->ElementAt(i));
@ -5729,7 +5728,7 @@ FrameLayerBuilder::GetPaintedLayerScaleForFrame(nsIFrame* aFrame)
}
const nsTArray<DisplayItemData*>* array =
f->Properties().Get(LayerManagerDataProperty());
f->GetProperty(LayerManagerDataProperty());
if (!array) {
continue;
}
@ -6165,9 +6164,8 @@ FrameLayerBuilder::GetMostRecentGeometry(nsDisplayItem* aItem)
typedef nsTArray<DisplayItemData*> DataArray;
// Retrieve the array of DisplayItemData associated with our frame.
FrameProperties properties = aItem->Frame()->Properties();
const DataArray* dataArray =
properties.Get(LayerManagerDataProperty());
aItem->Frame()->GetProperty(LayerManagerDataProperty());
if (!dataArray) {
return nullptr;
}

View file

@ -3,15 +3,15 @@
* 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 FRAMEPROPERTYTABLE_H_
#define FRAMEPROPERTYTABLE_H_
#ifndef FRAMEPROPERTIES_H_
#define FRAMEPROPERTIES_H_
#include "mozilla/DebugOnly.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/TypeTraits.h"
#include "mozilla/Unused.h"
#include "nsTArray.h"
#include "nsTHashtable.h"
#include "nsHashKeys.h"
#include "nsThreadUtils.h"
class nsIFrame;
@ -131,7 +131,7 @@ struct FramePropertyTypeHelper<SmallValueHolder<T>>
}
/**
* The FramePropertyTable is optimized for storing 0 or 1 properties on
* The FrameProperties class is optimized for storing 0 or 1 properties on
* a given frame. Storing very large numbers of properties on a single
* frame will not be efficient.
*
@ -141,7 +141,8 @@ struct FramePropertyTypeHelper<SmallValueHolder<T>>
* Of course, the destructor function (if any) must handle such values
* correctly.
*/
class FramePropertyTable {
class FrameProperties
{
public:
template<typename T>
using Descriptor = const FramePropertyDescriptor<T>*;
@ -150,32 +151,31 @@ public:
template<typename T>
using PropertyType = typename detail::FramePropertyTypeHelper<T>::Type;
FramePropertyTable() : mLastFrame(nullptr), mLastEntry(nullptr)
explicit FrameProperties()
{
}
~FramePropertyTable()
~FrameProperties()
{
DeleteAll();
MOZ_ASSERT(mProperties.Length() == 0, "forgot to delete properties");
}
/**
* Set a property value on a frame. This requires one hashtable
* lookup (using the frame as the key) and a linear search through
* the properties of that frame. Any existing value for the property
* Set a property value. This requires a linear search through
* the properties of the frame. Any existing value for the property
* is destroyed.
*/
template<typename T>
void Set(const nsIFrame* aFrame, Descriptor<T> aProperty,
PropertyType<T> aValue)
void Set(Descriptor<T> aProperty, PropertyType<T> aValue,
const nsIFrame* aFrame)
{
void* ptr = ReinterpretHelper<T>::ToPointer(aValue);
SetInternal(aFrame, aProperty, ptr);
SetInternal(aProperty, ptr, aFrame);
}
/**
* @return true if @aProperty is set for @aFrame. This requires one hashtable
* lookup (using the frame as the key) and a linear search through the
* properties of that frame.
* @return true if @aProperty is set. This requires a linear search through the
* properties of the frame.
*
* In most cases, this shouldn't be used outside of assertions, because if
* you're doing a lookup anyway it would be far more efficient to call Get()
@ -190,17 +190,15 @@ public:
* an existing value for the frame property.
*/
template<typename T>
bool Has(const nsIFrame* aFrame, Descriptor<T> aProperty)
bool Has(Descriptor<T> aProperty) const
{
bool foundResult = false;
mozilla::Unused << GetInternal(aFrame, aProperty, &foundResult);
return foundResult;
return mProperties.IndexOf(aProperty, 0, PropertyComparator()) != nsTArray<PropertyValue>::NoIndex;
}
/**
* Get a property value for a frame. This requires one hashtable
* Get a property value. This requires a linear search through
* lookup (using the frame as the key) and a linear search through
* the properties of that frame. If the frame has no such property,
* the properties of the frame. If the frame has no such property,
* returns zero-filled result, which means null for pointers and
* zero for integers and floating point types.
* @param aFoundResult if non-null, receives a value 'true' iff
@ -209,16 +207,15 @@ public:
* 'property value is null'.
*/
template<typename T>
PropertyType<T> Get(const nsIFrame* aFrame, Descriptor<T> aProperty,
bool* aFoundResult = nullptr)
PropertyType<T> Get(Descriptor<T> aProperty,
bool* aFoundResult = nullptr) const
{
void* ptr = GetInternal(aFrame, aProperty, aFoundResult);
void* ptr = GetInternal(aProperty, aFoundResult);
return ReinterpretHelper<T>::FromPointer(ptr);
}
/**
* Remove a property value for a frame. This requires one hashtable
* lookup (using the frame as the key) and a linear search through
* the properties of that frame. The old property value is returned
* Remove a property value. This requires a linear search through
* the properties of the frame. The old property value is returned
* (and not destroyed). If the frame has no such property,
* returns zero-filled result, which means null for pointers and
* zero for integers and floating point types.
@ -228,46 +225,63 @@ public:
* 'property value is null'.
*/
template<typename T>
PropertyType<T> Remove(const nsIFrame* aFrame, Descriptor<T> aProperty,
PropertyType<T> Remove(Descriptor<T> aProperty,
bool* aFoundResult = nullptr)
{
void* ptr = RemoveInternal(aFrame, aProperty, aFoundResult);
void* ptr = RemoveInternal(aProperty, aFoundResult);
return ReinterpretHelper<T>::FromPointer(ptr);
}
/**
* Remove and destroy a property value for a frame. This requires one
* hashtable lookup (using the frame as the key) and a linear search
* through the properties of that frame. If the frame has no such
* Remove and destroy a property value. This requires a linear search
* through the properties of the frame. If the frame has no such
* property, nothing happens.
*/
template<typename T>
void Delete(const nsIFrame* aFrame, Descriptor<T> aProperty)
void Delete(Descriptor<T> aProperty, const nsIFrame* aFrame)
{
DeleteInternal(aFrame, aProperty);
DeleteInternal(aProperty, aFrame);
}
/**
* Remove and destroy all property values for a frame. This requires one
* hashtable lookup (using the frame as the key).
* Remove and destroy all property values for the frame.
*/
void DeleteAllFor(const nsIFrame* aFrame);
/**
* Remove and destroy all property values for all frames.
*/
void DeleteAll();
void DeleteAll(const nsIFrame* aFrame) {
mozilla::DebugOnly<size_t> len = mProperties.Length();
for (auto& prop : mProperties) {
prop.DestroyValueFor(aFrame);
MOZ_ASSERT(mProperties.Length() == len);
}
mProperties.Clear();
}
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
// We currently report only the shallow size of the mProperties array.
// As for the PropertyValue entries: we don't need to measure the mProperty
// field of because it always points to static memory, and we can't measure
// mValue because the type is opaque.
// XXX Can we do better, e.g. with a method on the descriptor?
return mProperties.ShallowSizeOfExcludingThis(aMallocSizeOf);
}
protected:
void SetInternal(const nsIFrame* aFrame, UntypedDescriptor aProperty,
void* aValue);
private:
friend class ::nsIFrame;
void* GetInternal(const nsIFrame* aFrame, UntypedDescriptor aProperty,
bool* aFoundResult);
// Prevent copying of FrameProperties; we should always return/pass around
// references to it, not copies!
FrameProperties(const FrameProperties&) = delete;
FrameProperties& operator=(const FrameProperties&) = delete;
void* RemoveInternal(const nsIFrame* aFrame, UntypedDescriptor aProperty,
bool* aFoundResult);
inline void
SetInternal(UntypedDescriptor aProperty, void* aValue,
const nsIFrame* aFrame);
void DeleteInternal(const nsIFrame* aFrame, UntypedDescriptor aProperty);
inline void*
GetInternal(UntypedDescriptor aProperty, bool* aFoundResult) const;
inline void*
RemoveInternal(UntypedDescriptor aProperty, bool* aFoundResult);
inline void
DeleteInternal(UntypedDescriptor aProperty, const nsIFrame* aFrame);
template<typename T>
struct ReinterpretHelper
@ -305,21 +319,13 @@ protected:
};
/**
* Stores a property descriptor/value pair. It can also be used to
* store an nsTArray of PropertyValues.
* Stores a property descriptor/value pair.
*/
struct PropertyValue {
PropertyValue() : mProperty(nullptr), mValue(nullptr) {}
PropertyValue(UntypedDescriptor aProperty, void* aValue)
: mProperty(aProperty), mValue(aValue) {}
bool IsArray() { return !mProperty && mValue; }
nsTArray<PropertyValue>* ToArray()
{
NS_ASSERTION(IsArray(), "Must be array");
return reinterpret_cast<nsTArray<PropertyValue>*>(&mValue);
}
void DestroyValueFor(const nsIFrame* aFrame) {
if (mProperty->mDestructor) {
mProperty->mDestructor(mValue);
@ -328,20 +334,6 @@ protected:
}
}
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) {
size_t n = 0;
// We don't need to measure mProperty because it always points to static
// memory. As for mValue: if it's a single value we can't measure it,
// because the type is opaque; if it's an array, we measure the array
// storage, but we can't measure the individual values, again because
// their types are opaque.
if (IsArray()) {
nsTArray<PropertyValue>* array = ToArray();
n += array->ShallowSizeOfExcludingThis(aMallocSizeOf);
}
return n;
}
UntypedDescriptor mProperty;
void* mValue;
};
@ -363,80 +355,86 @@ protected:
}
};
/**
* Our hashtable entry. The key is an nsIFrame*, the value is a
* PropertyValue representing one or more property/value pairs.
*/
class Entry : public nsPtrHashKey<const nsIFrame>
{
public:
explicit Entry(KeyTypePointer aKey) : nsPtrHashKey<const nsIFrame>(aKey) {}
Entry(const Entry &toCopy) :
nsPtrHashKey<const nsIFrame>(toCopy), mProp(toCopy.mProp) {}
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) {
return mProp.SizeOfExcludingThis(aMallocSizeOf);
}
PropertyValue mProp;
};
static void DeleteAllForEntry(Entry* aEntry);
// Note that mLastEntry points into mEntries, so we need to be careful about
// not triggering a resize of mEntries, e.g. use RawRemoveEntry() instead of
// RemoveEntry() in some places.
nsTHashtable<Entry> mEntries;
const nsIFrame* mLastFrame;
Entry* mLastEntry;
nsTArray<PropertyValue> mProperties;
};
/**
* This class encapsulates the properties of a frame.
*/
class FrameProperties {
public:
template<typename T> using Descriptor = FramePropertyTable::Descriptor<T>;
template<typename T> using PropertyType = FramePropertyTable::PropertyType<T>;
inline void*
FrameProperties::GetInternal(UntypedDescriptor aProperty,
bool* aFoundResult) const
{
MOZ_ASSERT(aProperty, "Null property?");
FrameProperties(FramePropertyTable* aTable, const nsIFrame* aFrame)
: mTable(aTable), mFrame(aFrame) {}
template<typename T>
void Set(Descriptor<T> aProperty, PropertyType<T> aValue) const
{
mTable->Set(mFrame, aProperty, aValue);
auto index = mProperties.IndexOf(aProperty, 0, PropertyComparator());
if (index == nsTArray<PropertyValue>::NoIndex) {
if (aFoundResult) {
*aFoundResult = false;
}
return nullptr;
}
template<typename T>
bool Has(Descriptor<T> aProperty) const
{
return mTable->Has(mFrame, aProperty);
if (aFoundResult) {
*aFoundResult = true;
}
template<typename T>
PropertyType<T> Get(Descriptor<T> aProperty,
bool* aFoundResult = nullptr) const
{
return mTable->Get(mFrame, aProperty, aFoundResult);
}
template<typename T>
PropertyType<T> Remove(Descriptor<T> aProperty,
bool* aFoundResult = nullptr) const
{
return mTable->Remove(mFrame, aProperty, aFoundResult);
}
template<typename T>
void Delete(Descriptor<T> aProperty)
{
mTable->Delete(mFrame, aProperty);
return mProperties.ElementAt(index).mValue;
}
inline void
FrameProperties::SetInternal(UntypedDescriptor aProperty, void* aValue,
const nsIFrame* aFrame)
{
MOZ_ASSERT(aProperty, "Null property?");
auto index = mProperties.IndexOf(aProperty, 0, PropertyComparator());
if (index != nsTArray<PropertyValue>::NoIndex) {
PropertyValue* pv = &mProperties.ElementAt(index);
pv->DestroyValueFor(aFrame);
pv->mValue = aValue;
return;
}
private:
FramePropertyTable* mTable;
const nsIFrame* mFrame;
};
mProperties.AppendElement(PropertyValue(aProperty, aValue));
}
inline void*
FrameProperties::RemoveInternal(UntypedDescriptor aProperty, bool* aFoundResult)
{
MOZ_ASSERT(aProperty, "Null property?");
auto index = mProperties.IndexOf(aProperty, 0, PropertyComparator());
if (index == nsTArray<PropertyValue>::NoIndex) {
if (aFoundResult) {
*aFoundResult = false;
}
return nullptr;
}
if (aFoundResult) {
*aFoundResult = true;
}
void* result = mProperties.ElementAt(index).mValue;
mProperties.RemoveElementAt(index);
return result;
}
inline void
FrameProperties::DeleteInternal(UntypedDescriptor aProperty,
const nsIFrame* aFrame)
{
MOZ_ASSERT(aProperty, "Null property?");
auto index = mProperties.IndexOf(aProperty, 0, PropertyComparator());
if (index != nsTArray<PropertyValue>::NoIndex) {
mProperties.ElementAt(index).DestroyValueFor(aFrame);
mProperties.RemoveElementAt(index);
}
}
} // namespace mozilla
#endif /* FRAMEPROPERTYTABLE_H_ */
#endif /* FRAMEPROPERTIES_H_ */

View file

@ -1,239 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* 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 "FramePropertyTable.h"
#include "mozilla/MemoryReporting.h"
namespace mozilla {
void
FramePropertyTable::SetInternal(
const nsIFrame* aFrame, UntypedDescriptor aProperty, void* aValue)
{
NS_ASSERTION(aFrame, "Null frame?");
NS_ASSERTION(aProperty, "Null property?");
if (mLastFrame != aFrame || !mLastEntry) {
mLastFrame = aFrame;
mLastEntry = mEntries.PutEntry(aFrame);
}
Entry* entry = mLastEntry;
if (!entry->mProp.IsArray()) {
if (!entry->mProp.mProperty) {
// Empty entry, so we can just store our property in the empty slot
entry->mProp.mProperty = aProperty;
entry->mProp.mValue = aValue;
return;
}
if (entry->mProp.mProperty == aProperty) {
// Just overwrite the current value
entry->mProp.DestroyValueFor(aFrame);
entry->mProp.mValue = aValue;
return;
}
// We need to expand the single current entry to an array
PropertyValue current = entry->mProp;
entry->mProp.mProperty = nullptr;
static_assert(sizeof(nsTArray<PropertyValue>) <= sizeof(void *),
"Property array must fit entirely within entry->mProp.mValue");
new (&entry->mProp.mValue) nsTArray<PropertyValue>(4);
entry->mProp.ToArray()->AppendElement(current);
}
nsTArray<PropertyValue>* array = entry->mProp.ToArray();
nsTArray<PropertyValue>::index_type index =
array->IndexOf(aProperty, 0, PropertyComparator());
if (index != nsTArray<PropertyValue>::NoIndex) {
PropertyValue* pv = &array->ElementAt(index);
pv->DestroyValueFor(aFrame);
pv->mValue = aValue;
return;
}
array->AppendElement(PropertyValue(aProperty, aValue));
}
void*
FramePropertyTable::GetInternal(
const nsIFrame* aFrame, UntypedDescriptor aProperty, bool* aFoundResult)
{
NS_ASSERTION(aFrame, "Null frame?");
NS_ASSERTION(aProperty, "Null property?");
if (aFoundResult) {
*aFoundResult = false;
}
if (mLastFrame != aFrame) {
mLastFrame = aFrame;
mLastEntry = mEntries.GetEntry(mLastFrame);
}
Entry* entry = mLastEntry;
if (!entry)
return nullptr;
if (entry->mProp.mProperty == aProperty) {
if (aFoundResult) {
*aFoundResult = true;
}
return entry->mProp.mValue;
}
if (!entry->mProp.IsArray()) {
// There's just one property and it's not the one we want, bail
return nullptr;
}
nsTArray<PropertyValue>* array = entry->mProp.ToArray();
nsTArray<PropertyValue>::index_type index =
array->IndexOf(aProperty, 0, PropertyComparator());
if (index == nsTArray<PropertyValue>::NoIndex)
return nullptr;
if (aFoundResult) {
*aFoundResult = true;
}
return array->ElementAt(index).mValue;
}
void*
FramePropertyTable::RemoveInternal(
const nsIFrame* aFrame, UntypedDescriptor aProperty, bool* aFoundResult)
{
NS_ASSERTION(aFrame, "Null frame?");
NS_ASSERTION(aProperty, "Null property?");
if (aFoundResult) {
*aFoundResult = false;
}
if (mLastFrame != aFrame) {
mLastFrame = aFrame;
mLastEntry = mEntries.GetEntry(aFrame);
}
Entry* entry = mLastEntry;
if (!entry)
return nullptr;
if (entry->mProp.mProperty == aProperty) {
// There's only one entry and it's the one we want
void* value = entry->mProp.mValue;
// Here it's ok to use RemoveEntry() -- which may resize mEntries --
// because we null mLastEntry at the same time.
mEntries.RemoveEntry(entry);
mLastEntry = nullptr;
if (aFoundResult) {
*aFoundResult = true;
}
return value;
}
if (!entry->mProp.IsArray()) {
// There's just one property and it's not the one we want, bail
return nullptr;
}
nsTArray<PropertyValue>* array = entry->mProp.ToArray();
nsTArray<PropertyValue>::index_type index =
array->IndexOf(aProperty, 0, PropertyComparator());
if (index == nsTArray<PropertyValue>::NoIndex) {
// No such property, bail
return nullptr;
}
if (aFoundResult) {
*aFoundResult = true;
}
void* result = array->ElementAt(index).mValue;
uint32_t last = array->Length() - 1;
array->ElementAt(index) = array->ElementAt(last);
array->RemoveElementAt(last);
if (last == 1) {
PropertyValue pv = array->ElementAt(0);
array->~nsTArray<PropertyValue>();
entry->mProp = pv;
}
return result;
}
void
FramePropertyTable::DeleteInternal(
const nsIFrame* aFrame, UntypedDescriptor aProperty)
{
NS_ASSERTION(aFrame, "Null frame?");
NS_ASSERTION(aProperty, "Null property?");
bool found;
void* v = RemoveInternal(aFrame, aProperty, &found);
if (found) {
PropertyValue pv(aProperty, v);
pv.DestroyValueFor(aFrame);
}
}
/* static */ void
FramePropertyTable::DeleteAllForEntry(Entry* aEntry)
{
if (!aEntry->mProp.IsArray()) {
aEntry->mProp.DestroyValueFor(aEntry->GetKey());
return;
}
nsTArray<PropertyValue>* array = aEntry->mProp.ToArray();
for (uint32_t i = 0; i < array->Length(); ++i) {
array->ElementAt(i).DestroyValueFor(aEntry->GetKey());
}
array->~nsTArray<PropertyValue>();
}
void
FramePropertyTable::DeleteAllFor(const nsIFrame* aFrame)
{
NS_ASSERTION(aFrame, "Null frame?");
Entry* entry = mEntries.GetEntry(aFrame);
if (!entry)
return;
if (mLastFrame == aFrame) {
// Flush cache. We assume DeleteAllForEntry will be called before
// a frame is destroyed.
mLastFrame = nullptr;
mLastEntry = nullptr;
}
DeleteAllForEntry(entry);
// mLastEntry points into mEntries, so we use RawRemoveEntry() which will not
// resize mEntries.
mEntries.RawRemoveEntry(entry);
}
void
FramePropertyTable::DeleteAll()
{
mLastFrame = nullptr;
mLastEntry = nullptr;
for (auto iter = mEntries.Iter(); !iter.Done(); iter.Next()) {
DeleteAllForEntry(iter.Get());
}
mEntries.Clear();
}
size_t
FramePropertyTable::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{
return mEntries.SizeOfExcludingThis(aMallocSizeOf);
}
} // namespace mozilla

View file

@ -112,12 +112,12 @@ public:
// Take a faster path that doesn't require unioning the overflow areas
// of our children.
NS_ASSERTION(frame->Properties().Get(
NS_ASSERTION(frame->GetProperty(
nsIFrame::DebugInitialOverflowPropertyApplied()),
"InitialOverflowProperty must be set first.");
nsOverflowAreas* overflow =
frame->Properties().Get(nsIFrame::InitialOverflowProperty());
frame->GetProperty(nsIFrame::InitialOverflowProperty());
if (overflow) {
// FinishAndStoreOverflow will change the overflow areas passed in,
// so make a copy.

View file

@ -1122,10 +1122,10 @@ GetPrevContinuationWithPossiblySameStyle(nsIFrame* aFrame)
// We're the first continuation, so we can just get the frame
// property directly
prevContinuation =
aFrame->Properties().Get(nsIFrame::IBSplitPrevSibling());
aFrame->GetProperty(nsIFrame::IBSplitPrevSibling());
if (prevContinuation) {
prevContinuation =
prevContinuation->Properties().Get(nsIFrame::IBSplitPrevSibling());
prevContinuation->GetProperty(nsIFrame::IBSplitPrevSibling());
}
}
@ -1313,8 +1313,7 @@ RestyleManager::ReparentStyleContext(nsIFrame* aFrame)
// oldContext)" check will prevent us from redoing work.
if ((aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) &&
!aFrame->GetPrevContinuation()) {
nsIFrame* sib =
aFrame->Properties().Get(nsIFrame::IBSplitSibling());
nsIFrame* sib = aFrame->GetProperty(nsIFrame::IBSplitSibling());
if (sib) {
ReparentStyleContext(sib);
}
@ -3349,7 +3348,6 @@ ElementRestyler::ComputeStyleChangeFor(nsIFrame* aFrame,
// line), we might restyle more than that.
nsPresContext* presContext = aFrame->PresContext();
FramePropertyTable* propTable = presContext->PropertyTable();
TreeMatchContext treeMatchContext(true,
nsRuleWalker::eRelevantLinkUnvisited,
@ -3363,7 +3361,7 @@ ElementRestyler::ComputeStyleChangeFor(nsIFrame* aFrame,
nsTArray<nsIContent*> visibleKidsOfHiddenElement;
nsIFrame* nextIBSibling;
for (nsIFrame* ibSibling = aFrame; ibSibling; ibSibling = nextIBSibling) {
nextIBSibling = RestyleManager::GetNextBlockInInlineSibling(propTable, ibSibling);
nextIBSibling = RestyleManager::GetNextBlockInInlineSibling(ibSibling);
if (nextIBSibling) {
// Don't allow some ib-split siblings to be processed with

View file

@ -385,8 +385,6 @@ RestyleManagerBase::DebugVerifyStyleTree(nsIFrame* aFrame)
#endif // DEBUG
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(ChangeListProperty, bool)
/**
* Sync views on aFrame and all of aFrame's descendants (following placeholders),
* if aChange has nsChangeHint_SyncFrameView.
@ -521,10 +519,9 @@ RecomputePosition(nsIFrame* aFrame)
// normal position, go ahead and add the offsets directly.
// First, we need to ensure that the normal position is stored though.
nsPoint normalPosition = cont->GetNormalPosition();
auto props = cont->Properties();
const auto& prop = nsIFrame::NormalPositionProperty();
if (!props.Get(prop)) {
props.Set(prop, new nsPoint(normalPosition));
if (!cont->GetProperty(nsIFrame::NormalPositionProperty())) {
cont->SetProperty(nsIFrame::NormalPositionProperty(),
new nsPoint(normalPosition));
}
cont->SetPosition(normalPosition +
nsPoint(newOffsets.left, newOffsets.top));
@ -739,8 +736,7 @@ RestyleManagerBase::GetNearestAncestorFrame(nsIContent* aContent)
}
/* static */ nsIFrame*
RestyleManagerBase::GetNextBlockInInlineSibling(FramePropertyTable* aPropTable,
nsIFrame* aFrame)
RestyleManagerBase::GetNextBlockInInlineSibling(nsIFrame* aFrame)
{
NS_ASSERTION(!aFrame->GetPrevContinuation(),
"must start with the first continuation");
@ -750,8 +746,7 @@ RestyleManagerBase::GetNextBlockInInlineSibling(FramePropertyTable* aPropTable,
return nullptr;
}
return static_cast<nsIFrame*>
(aPropTable->Get(aFrame, nsIFrame::IBSplitSibling()));
return aFrame->GetProperty(nsIFrame::IBSplitSibling());
}
static void
@ -1028,10 +1023,10 @@ RestyleManagerBase::GetNextContinuationWithSameStyle(
// We're the last continuation, so we have to hop back to the first
// before getting the frame property
nextContinuation =
aFrame->FirstContinuation()->Properties().Get(nsIFrame::IBSplitSibling());
aFrame->FirstContinuation()->GetProperty(nsIFrame::IBSplitSibling());
if (nextContinuation) {
nextContinuation =
nextContinuation->Properties().Get(nsIFrame::IBSplitSibling());
nextContinuation->GetProperty(nsIFrame::IBSplitSibling());
}
}
@ -1060,14 +1055,52 @@ RestyleManagerBase::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
{
NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
"Someone forgot a script blocker");
if (aChangeList.IsEmpty())
return NS_OK;
// See bug 1378219 comment 9:
// Recursive calls here are a bit worrying, but apparently do happen in the
// wild (although not currently in any of our automated tests). Try to get a
// stack from Nightly/Dev channel to figure out what's going on and whether
// it's OK.
MOZ_DIAGNOSTIC_ASSERT(!mDestroyedFrames, "ProcessRestyledFrames recursion");
if (aChangeList.IsEmpty())
return NS_OK;
// If mDestroyedFrames is null, we want to create a new hashtable here
// and destroy it on exit; but if it is already non-null (because we're in
// a recursive call), we will continue to use the existing table to
// accumulate destroyed frames, and NOT clear mDestroyedFrames on exit.
// We use a MaybeClearDestroyedFrames helper to conditionally reset the
// mDestroyedFrames pointer when this method returns.
typedef decltype(mDestroyedFrames) DestroyedFramesT;
class MOZ_RAII MaybeClearDestroyedFrames
{
private:
DestroyedFramesT& mDestroyedFramesRef; // ref to caller's mDestroyedFrames
const bool mResetOnDestruction;
public:
explicit MaybeClearDestroyedFrames(DestroyedFramesT& aTarget)
: mDestroyedFramesRef(aTarget)
, mResetOnDestruction(!aTarget) // reset only if target starts out null
{
}
~MaybeClearDestroyedFrames()
{
if (mResetOnDestruction) {
mDestroyedFramesRef.reset(nullptr);
}
}
};
MaybeClearDestroyedFrames maybeClear(mDestroyedFrames);
if (!mDestroyedFrames) {
mDestroyedFrames = MakeUnique<nsTHashtable<nsPtrHashKey<const nsIFrame>>>();
}
PROFILER_LABEL("RestyleManager", "ProcessRestyledFrames",
js::ProfileEntry::Category::CSS);
nsPresContext* presContext = PresContext();
FramePropertyTable* propTable = presContext->PropertyTable();
nsCSSFrameConstructor* frameConstructor = presContext->FrameConstructor();
// Handle nsChangeHint_CSSOverflowChange, by either updating the
@ -1135,15 +1168,6 @@ RestyleManagerBase::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
// processing restyles
frameConstructor->BeginUpdate();
// Mark frames so that we skip frames that die along the way, bug 123049.
// A frame can be in the list multiple times with different hints. Further
// optmization is possible if nsStyleChangeList::AppendChange could coalesce
for (const nsStyleChangeData& data : aChangeList) {
if (data.mFrame) {
propTable->Set(data.mFrame, ChangeListProperty(), true);
}
}
bool didUpdateCursor = false;
for (const nsStyleChangeData& data : aChangeList) {
@ -1157,7 +1181,7 @@ RestyleManagerBase::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
"Reflow hint bits set without actually asking for a reflow");
// skip any frame that has been destroyed due to a ripple effect
if (frame && !propTable->Get(frame, ChangeListProperty())) {
if (frame && mDestroyedFrames->Contains(frame)) {
continue;
}
@ -1409,15 +1433,11 @@ RestyleManagerBase::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
frameConstructor->EndUpdate();
// cleanup references and verify the style tree. Note that the latter needs
// to happen once we've processed the whole list, since until then the tree
// is not in fact in a consistent state.
for (const nsStyleChangeData& data : aChangeList) {
if (data.mFrame) {
propTable->Delete(data.mFrame, ChangeListProperty());
}
#ifdef DEBUG
// Verify the style tree. Note that this needs to happen once we've
// processed the whole list, since until then the tree is not in fact in a
// consistent state.
for (const nsStyleChangeData& data : aChangeList) {
// reget frame from content since it may have been regenerated...
if (data.mContent) {
nsIFrame* frame = data.mContent->GetPrimaryFrame();
@ -1429,8 +1449,8 @@ RestyleManagerBase::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
NS_WARNING("Unable to test style tree integrity -- no content node "
"(and not a viewport frame)");
}
#endif
}
#endif
aChangeList.Clear();
return NS_OK;

View file

@ -72,6 +72,11 @@ public:
// WillDestroyFrameTree hasn't been called yet.
void NotifyDestroyingFrame(nsIFrame* aFrame) {
mOverflowChangedTracker.RemoveFrame(aFrame);
// If ProcessRestyledFrames is tracking frames which have been
// destroyed (to avoid re-visiting them), add this one to its set.
if (mDestroyedFrames) {
mDestroyedFrames->PutEntry(aFrame);
}
}
// Note: It's the caller's responsibility to make sure to wrap a
@ -127,6 +132,12 @@ private:
nsPresContext* mPresContext; // weak, can be null after Disconnect().
uint32_t mRestyleGeneration;
uint32_t mHoverGeneration;
// Used to keep track of frames that have been destroyed during
// ProcessRestyledFrames, so we don't try to touch them again even if
// they're referenced again later in the changelist.
mozilla::UniquePtr<nsTHashtable<nsPtrHashKey<const nsIFrame>>> mDestroyedFrames;
// True if we're already waiting for a refresh notification.
bool mObservingRefreshDriver;
@ -146,7 +157,7 @@ protected:
GetNearestAncestorFrame(nsIContent* aContent);
static nsIFrame*
GetNextBlockInInlineSibling(FramePropertyTable* aPropTable, nsIFrame* aFrame);
GetNextBlockInInlineSibling(nsIFrame* aFrame);
/**
* Get the next continuation or similar ib-split sibling (assuming

View file

@ -61,7 +61,7 @@ EXPORTS += [
'DisplayItemScrollClip.h',
'DisplayListClipState.h',
'FrameLayerBuilder.h',
'FramePropertyTable.h',
'FrameProperties.h',
'LayerState.h',
'LayoutLogging.h',
'nsArenaMemoryStats.h',
@ -126,7 +126,6 @@ UNIFIED_SOURCES += [
'DisplayListClipState.cpp',
'DottedCornerFinder.cpp',
'FrameLayerBuilder.cpp',
'FramePropertyTable.cpp',
'GeometryUtils.cpp',
'LayoutLogging.cpp',
'MaskLayerImageCache.cpp',

View file

@ -753,7 +753,6 @@ nsBidiPresUtils::ResolveParagraph(BidiParagraphData* aBpd)
nsIContent* content = nullptr;
int32_t contentTextLength = 0;
FramePropertyTable* propTable = aBpd->mPresContext->PropertyTable();
nsLineBox* currentLine = nullptr;
#ifdef DEBUG
@ -809,7 +808,7 @@ nsBidiPresUtils::ResolveParagraph(BidiParagraphData* aBpd)
}
precedingControl = kBidiLevelNone;
lastEmbedingLevel = embeddingLevel;
propTable->Set(frame, nsIFrame::BidiDataProperty(), bidiData);
frame->SetProperty(nsIFrame::BidiDataProperty(), bidiData);
};
for (; ;) {
@ -1787,7 +1786,7 @@ nsBidiPresUtils::RemoveBidiContinuation(BidiParagraphData *aBpd,
if (frame != NS_BIDI_CONTROL_FRAME) {
// Make the frame and its continuation ancestors fluid,
// so they can be reused or deleted by normal reflow code
frame->Properties().Set(nsIFrame::BidiDataProperty(), bidiData);
frame->SetProperty(nsIFrame::BidiDataProperty(), bidiData);
frame->AddStateBits(NS_FRAME_IS_BIDI);
while (frame) {
nsIFrame* prev = frame->GetPrevContinuation();

View file

@ -492,9 +492,8 @@ static nsContainerFrame* GetIBSplitSibling(nsIFrame* aFrame)
// We only store the "ib-split sibling" annotation with the first
// frame in the continuation chain. Walk back to find that frame now.
return static_cast<nsContainerFrame*>
(aFrame->FirstContinuation()->
Properties().Get(nsIFrame::IBSplitSibling()));
return aFrame->FirstContinuation()->
GetProperty(nsIFrame::IBSplitSibling());
}
static nsContainerFrame* GetIBSplitPrevSibling(nsIFrame* aFrame)
@ -503,9 +502,8 @@ static nsContainerFrame* GetIBSplitPrevSibling(nsIFrame* aFrame)
// We only store the ib-split sibling annotation with the first
// frame in the continuation chain. Walk back to find that frame now.
return static_cast<nsContainerFrame*>
(aFrame->FirstContinuation()->
Properties().Get(nsIFrame::IBSplitPrevSibling()));
return aFrame->FirstContinuation()->
GetProperty(nsIFrame::IBSplitPrevSibling());
}
static nsContainerFrame*
@ -526,7 +524,7 @@ GetLastIBSplitSibling(nsIFrame* aFrame, bool aReturnEmptyTrailingInline)
}
static void
SetFrameIsIBSplit(nsContainerFrame* aFrame, nsIFrame* aIBSplitSibling)
SetFrameIsIBSplit(nsContainerFrame* aFrame, nsContainerFrame* aIBSplitSibling)
{
NS_PRECONDITION(aFrame, "bad args!");
@ -547,9 +545,8 @@ SetFrameIsIBSplit(nsContainerFrame* aFrame, nsIFrame* aIBSplitSibling)
// Store the ib-split sibling (if we were given one) with the
// first frame in the flow.
FramePropertyTable* props = aFrame->PresContext()->PropertyTable();
props->Set(aFrame, nsIFrame::IBSplitSibling(), aIBSplitSibling);
props->Set(aIBSplitSibling, nsIFrame::IBSplitPrevSibling(), aFrame);
aFrame->SetProperty(nsIFrame::IBSplitSibling(), aIBSplitSibling);
aIBSplitSibling->SetProperty(nsIFrame::IBSplitPrevSibling(), aFrame);
}
}
@ -6075,11 +6072,11 @@ AddGenConPseudoToFrame(nsIFrame* aOwnerFrame, nsIContent* aContent)
NS_ASSERTION(nsLayoutUtils::IsFirstContinuationOrIBSplitSibling(aOwnerFrame),
"property should only be set on first continuation/ib-sibling");
FrameProperties props = aOwnerFrame->Properties();
nsIFrame::ContentArray* value = props.Get(nsIFrame::GenConProperty());
nsIFrame::ContentArray* value =
aOwnerFrame->GetProperty(nsIFrame::GenConProperty());
if (!value) {
value = new nsIFrame::ContentArray;
props.Set(nsIFrame::GenConProperty(), value);
aOwnerFrame->SetProperty(nsIFrame::GenConProperty(), value);
}
value->AppendElement(aContent);
}

View file

@ -293,13 +293,13 @@ protected:
if (!prevCont &&
(aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT)) {
nsIFrame* block =
aFrame->Properties().Get(nsIFrame::IBSplitPrevSibling());
aFrame->GetProperty(nsIFrame::IBSplitPrevSibling());
if (block) {
// The {ib} properties are only stored on first continuations
NS_ASSERTION(!block->GetPrevContinuation(),
"Incorrect value for IBSplitPrevSibling");
prevCont =
block->Properties().Get(nsIFrame::IBSplitPrevSibling());
block->GetProperty(nsIFrame::IBSplitPrevSibling());
NS_ASSERTION(prevCont, "How did that happen?");
}
}
@ -313,9 +313,9 @@ protected:
(aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT)) {
// The {ib} properties are only stored on first continuations
aFrame = aFrame->FirstContinuation();
nsIFrame* block = aFrame->Properties().Get(nsIFrame::IBSplitSibling());
nsIFrame* block = aFrame->GetProperty(nsIFrame::IBSplitSibling());
if (block) {
nextCont = block->Properties().Get(nsIFrame::IBSplitSibling());
nextCont = block->GetProperty(nsIFrame::IBSplitSibling());
NS_ASSERTION(nextCont, "How did that happen?");
}
}
@ -842,7 +842,7 @@ static nsRect
GetOutlineInnerRect(nsIFrame* aFrame)
{
nsRect* savedOutlineInnerRect =
aFrame->Properties().Get(nsIFrame::OutlineInnerRectProperty());
aFrame->GetProperty(nsIFrame::OutlineInnerRectProperty());
if (savedOutlineInnerRect)
return *savedOutlineInnerRect;
NS_NOTREACHED("we should have saved a frame property");

View file

@ -666,7 +666,7 @@ nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(Layer* aLayer,
// EffectCompositor needs to know that we refused to run this animation
// asynchronously so that it will not throttle the main thread
// animation.
aFrame->Properties().Set(nsIFrame::RefusedAsyncAnimationProperty(), true);
aFrame->SetProperty(nsIFrame::RefusedAsyncAnimationProperty(), true);
// We need to schedule another refresh driver run so that EffectCompositor
// gets a chance to unthrottle the animation.
@ -902,15 +902,13 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
const DisplayItemClip* oldClip = mClipState.GetClipForContainingBlockDescendants();
const DisplayItemScrollClip* sc = mClipState.GetCurrentInnermostScrollClip();
OutOfFlowDisplayData* data = new OutOfFlowDisplayData(oldClip, sc, dirty);
aFrame->Properties().Set(nsDisplayListBuilder::OutOfFlowDisplayDataProperty(), data);
aFrame->SetProperty(nsDisplayListBuilder::OutOfFlowDisplayDataProperty(), data);
MarkFrameForDisplay(aFrame, aDirtyFrame);
}
static void UnmarkFrameForDisplay(nsIFrame* aFrame) {
nsPresContext* presContext = aFrame->PresContext();
presContext->PropertyTable()->
Delete(aFrame, nsDisplayListBuilder::OutOfFlowDisplayDataProperty());
aFrame->DeleteProperty(nsDisplayListBuilder::OutOfFlowDisplayDataProperty());
for (nsIFrame* f = aFrame; f;
f = nsLayoutUtils::GetParentOrPlaceholderFor(f)) {

View file

@ -1003,7 +1003,7 @@ public:
static OutOfFlowDisplayData* GetOutOfFlowData(nsIFrame* aFrame)
{
return aFrame->Properties().Get(OutOfFlowDisplayDataProperty());
return aFrame->GetProperty(OutOfFlowDisplayDataProperty());
}
nsPresContext* CurrentPresContext() {

View file

@ -1533,11 +1533,12 @@ public:
bool aFlushOnHoverChange) = 0;
virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
nsArenaMemoryStats *aArenaObjectsSize,
size_t *aPresShellSize,
size_t *aStyleSetsSize,
size_t *aTextRunsSize,
size_t *aPresContextSize) = 0;
nsArenaMemoryStats* aArenaObjectsSize,
size_t* aPresShellSize,
size_t* aStyleSetsSize,
size_t* aTextRunsSize,
size_t* aPresContextSize,
size_t* aFramePropertiesSize) = 0;
/**
* Methods that retrieve the cached font inflation preferences.

View file

@ -2057,13 +2057,13 @@ NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(ScrollbarThumbLayerized, bool)
/* static */ void
nsLayoutUtils::SetScrollbarThumbLayerization(nsIFrame* aThumbFrame, bool aLayerize)
{
aThumbFrame->Properties().Set(ScrollbarThumbLayerized(), aLayerize);
aThumbFrame->SetProperty(ScrollbarThumbLayerized(), aLayerize);
}
bool
nsLayoutUtils::IsScrollbarThumbLayerized(nsIFrame* aThumbFrame)
{
return aThumbFrame->Properties().Get(ScrollbarThumbLayerized());
return aThumbFrame->GetProperty(ScrollbarThumbLayerized());
}
// static
@ -4427,7 +4427,7 @@ nsLayoutUtils::GetNextContinuationOrIBSplitSibling(nsIFrame *aFrame)
// frame in the continuation chain. Walk back to find that frame now.
aFrame = aFrame->FirstContinuation();
return aFrame->Properties().Get(nsIFrame::IBSplitSibling());
return aFrame->GetProperty(nsIFrame::IBSplitSibling());
}
return nullptr;
@ -4440,7 +4440,7 @@ nsLayoutUtils::FirstContinuationOrIBSplitSibling(nsIFrame *aFrame)
if (result->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) {
while (true) {
nsIFrame* f =
result->Properties().Get(nsIFrame::IBSplitPrevSibling());
result->GetProperty(nsIFrame::IBSplitPrevSibling());
if (!f)
break;
result = f;
@ -4456,10 +4456,10 @@ nsLayoutUtils::LastContinuationOrIBSplitSibling(nsIFrame *aFrame)
nsIFrame *result = aFrame->FirstContinuation();
if (result->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) {
while (true) {
nsIFrame* f =
result->Properties().Get(nsIFrame::IBSplitSibling());
if (!f)
nsIFrame* f = result->GetProperty(nsIFrame::IBSplitSibling());
if (!f) {
break;
}
result = f;
}
}
@ -4476,7 +4476,7 @@ nsLayoutUtils::IsFirstContinuationOrIBSplitSibling(nsIFrame *aFrame)
return false;
}
if ((aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) &&
aFrame->Properties().Get(nsIFrame::IBSplitPrevSibling())) {
aFrame->GetProperty(nsIFrame::IBSplitPrevSibling())) {
return false;
}

View file

@ -2741,8 +2741,7 @@ nsPresContext::GetPrimaryFrameFor(nsIContent* aContent)
size_t
nsPresContext::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
{
return mPropertyTable.SizeOfExcludingThis(aMallocSizeOf) +
mLangGroupFontPrefs.SizeOfExcludingThis(aMallocSizeOf);
return mLangGroupFontPrefs.SizeOfExcludingThis(aMallocSizeOf);
// Measurement of other members may be added later if DMD finds it is
// worthwhile.

View file

@ -22,7 +22,6 @@
#include "nsITimer.h"
#include "nsCRT.h"
#include "nsIWidgetListener.h"
#include "FramePropertyTable.h"
#include "nsGkAtoms.h"
#include "nsCycleCollectionParticipant.h"
#include "nsChangeHint.h"
@ -140,7 +139,6 @@ class nsRootPresContext;
class nsPresContext : public nsIObserver,
public mozilla::SupportsWeakPtr<nsPresContext> {
public:
typedef mozilla::FramePropertyTable FramePropertyTable;
typedef mozilla::LangGroupFontPrefs LangGroupFontPrefs;
typedef mozilla::ScrollbarStyles ScrollbarStyles;
typedef mozilla::StaticPresData StaticPresData;
@ -867,9 +865,6 @@ public:
nsIPrintSettings* GetPrintSettings() { return mPrintSettings; }
/* Accessor for table of frame properties */
FramePropertyTable* PropertyTable() { return &mPropertyTable; }
/* Helper function that ensures that this prescontext is shown in its
docshell if it's the most recent prescontext for the docshell. Returns
whether the prescontext is now being shown.
@ -1064,11 +1059,6 @@ public:
*/
nsIFrame* GetPrimaryFrameFor(nsIContent* aContent);
void NotifyDestroyingFrame(nsIFrame* aFrame)
{
PropertyTable()->DeleteAllFor(aFrame);
}
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
@ -1294,7 +1284,6 @@ protected:
nsCOMPtr<nsIPrintSettings> mPrintSettings;
nsCOMPtr<nsITimer> mPrefChangedTimer;
FramePropertyTable mPropertyTable;
nsInvalidateRequestList mInvalidateRequestsSinceLastPaint;
nsInvalidateRequestList mUndeliveredInvalidateRequestsBeforeLastPaint;

View file

@ -1306,19 +1306,6 @@ PresShell::Destroy()
// Destroy the frame manager. This will destroy the frame hierarchy
mFrameConstructor->WillDestroyFrameTree();
// Destroy all frame properties (whose destruction was suppressed
// while destroying the frame tree, but which might contain more
// frames within the properties.
if (mPresContext) {
// Clear out the prescontext's property table -- since our frame tree is
// now dead, we shouldn't be looking up any more properties in that table.
// We want to do this before we call DetachShell() on the prescontext, so
// property destructors can usefully call GetPresShell() on the
// prescontext.
mPresContext->PropertyTable()->DeleteAll();
}
NS_WARNING_ASSERTION(!mWeakFrames,
"Weak frames alive after destroying FrameManager");
while (mWeakFrames) {
@ -2047,7 +2034,7 @@ PresShell::NotifyDestroyingFrame(nsIFrame* aFrame)
}
// Remove frame properties
mPresContext->NotifyDestroyingFrame(aFrame);
aFrame->DeleteAllProperties();
if (aFrame == mCurrentEventFrame) {
mCurrentEventContent = aFrame->GetContent();
@ -2076,8 +2063,7 @@ PresShell::NotifyDestroyingFrame(nsIFrame* aFrame)
// frame from FrameLayerBuilder::DisplayItemData::mFrameList -- otherwise
// the DisplayItemData destructor will use the destroyed frame when it
// tries to remove it from the (array) value of this property.
mPresContext->PropertyTable()->
Delete(aFrame, FrameLayerBuilder::LayerManagerDataProperty());
aFrame->DeleteProperty( FrameLayerBuilder::LayerManagerDataProperty());
}
}
@ -10929,11 +10915,12 @@ PresShell::GetRootPresShell()
void
PresShell::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
nsArenaMemoryStats *aArenaObjectsSize,
size_t *aPresShellSize,
size_t *aStyleSetsSize,
size_t *aTextRunsSize,
size_t *aPresContextSize)
nsArenaMemoryStats* aArenaObjectsSize,
size_t* aPresShellSize,
size_t* aStyleSetsSize,
size_t* aTextRunsSize,
size_t* aPresContextSize,
size_t* aFramePropertiesSize)
{
mFrameArena.AddSizeOfExcludingThis(aMallocSizeOf, aArenaObjectsSize);
*aPresShellSize += aMallocSizeOf(this);
@ -10953,6 +10940,12 @@ PresShell::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
*aTextRunsSize += SizeOfTextRuns(aMallocSizeOf);
*aPresContextSize += mPresContext->SizeOfIncludingThis(aMallocSizeOf);
nsIFrame* rootFrame = mFrameConstructor->GetRootFrame();
if (rootFrame) {
*aFramePropertiesSize +=
rootFrame->SizeOfFramePropertiesForTree(aMallocSizeOf);
}
}
size_t

View file

@ -384,11 +384,12 @@ public:
virtual void LoadComplete() override;
void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
nsArenaMemoryStats *aArenaObjectsSize,
size_t *aPresShellSize,
size_t *aStyleSetsSize,
size_t *aTextRunsSize,
size_t *aPresContextSize) override;
nsArenaMemoryStats* aArenaObjectsSize,
size_t* aPresShellSize,
size_t* aStyleSetsSize,
size_t* aTextRunsSize,
size_t* aPresContextSize,
size_t* aFramePropertiesSize) override;
size_t SizeOfTextRuns(mozilla::MallocSizeOf aMallocSizeOf) const;
virtual void AddInvalidateHiddenPresShellObserver(nsRefreshDriver *aDriver) override;