From 00812e30dfa70f9b1a752cf0d09de00f6d401c85 Mon Sep 17 00:00:00 2001 From: win7-7 Date: Wed, 26 Jun 2019 01:51:45 +0300 Subject: 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. --- dom/base/nsDocument.cpp | 3 +- dom/base/nsWindowMemoryReporter.cpp | 9 + dom/base/nsWindowMemoryReporter.h | 1 + layout/base/ActiveLayerTracker.cpp | 15 +- layout/base/FrameLayerBuilder.cpp | 32 ++- layout/base/FrameProperties.h | 440 ++++++++++++++++++++++++++++++ layout/base/FramePropertyTable.cpp | 239 ----------------- layout/base/FramePropertyTable.h | 442 ------------------------------- layout/base/OverflowChangedTracker.h | 4 +- layout/base/RestyleManager.cpp | 10 +- layout/base/RestyleManagerBase.cpp | 88 +++--- layout/base/RestyleManagerBase.h | 13 +- layout/base/moz.build | 3 +- layout/base/nsBidiPresUtils.cpp | 5 +- layout/base/nsCSSFrameConstructor.cpp | 23 +- layout/base/nsCSSRendering.cpp | 10 +- layout/base/nsDisplayList.cpp | 8 +- layout/base/nsDisplayList.h | 2 +- layout/base/nsIPresShell.h | 11 +- layout/base/nsLayoutUtils.cpp | 16 +- layout/base/nsPresContext.cpp | 3 +- layout/base/nsPresContext.h | 11 - layout/base/nsPresShell.cpp | 35 +-- layout/base/nsPresShell.h | 11 +- layout/forms/nsTextControlFrame.cpp | 14 +- layout/forms/nsTextControlFrame.h | 2 +- layout/generic/ReflowInput.cpp | 36 +-- layout/generic/RubyUtils.cpp | 6 +- layout/generic/StickyScrollContainer.cpp | 26 +- layout/generic/nsBlockFrame.cpp | 58 ++-- layout/generic/nsBlockFrame.h | 4 +- layout/generic/nsBulletFrame.cpp | 6 +- layout/generic/nsCanvasFrame.cpp | 4 +- layout/generic/nsCanvasFrame.h | 2 +- layout/generic/nsContainerFrame.cpp | 70 +++-- layout/generic/nsContainerFrame.h | 10 +- layout/generic/nsFlexContainerFrame.cpp | 22 +- layout/generic/nsFloatManager.cpp | 9 +- layout/generic/nsFontInflationData.cpp | 12 +- layout/generic/nsFrame.cpp | 177 +++++++------ layout/generic/nsGridContainerFrame.cpp | 80 +++--- layout/generic/nsGridContainerFrame.h | 12 +- layout/generic/nsIFrame.h | 75 +++++- layout/generic/nsLineLayout.cpp | 4 +- layout/generic/nsPlaceholderFrame.cpp | 2 +- layout/generic/nsTextFrame.cpp | 59 ++--- layout/mathml/nsMathMLContainerFrame.cpp | 7 +- layout/mathml/nsMathMLmtableFrame.cpp | 14 +- layout/svg/SVGTextFrame.cpp | 10 +- layout/svg/nsSVGEffects.cpp | 47 ++-- layout/svg/nsSVGEffects.h | 2 +- layout/svg/nsSVGFilterFrame.cpp | 4 +- layout/svg/nsSVGGradientFrame.cpp | 4 +- layout/svg/nsSVGIntegrationUtils.cpp | 5 +- layout/svg/nsSVGPatternFrame.cpp | 4 +- layout/svg/nsSVGUtils.cpp | 5 +- layout/tables/nsTableFrame.cpp | 31 ++- layout/tables/nsTableFrame.h | 3 +- layout/tables/nsTableRowFrame.cpp | 10 +- layout/tables/nsTableRowGroupFrame.cpp | 6 +- layout/tables/nsTableWrapperFrame.cpp | 4 +- layout/xul/nsBox.cpp | 7 +- layout/xul/nsMenuFrame.cpp | 6 +- 63 files changed, 1043 insertions(+), 1250 deletions(-) create mode 100644 layout/base/FrameProperties.h delete mode 100644 layout/base/FramePropertyTable.cpp delete mode 100644 layout/base/FramePropertyTable.h diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index a6ed419df..d8abc174f 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -11943,7 +11943,8 @@ nsIDocument::DocAddSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const &aWindowSizes->mLayoutPresShellSize, &aWindowSizes->mLayoutStyleSetsSize, &aWindowSizes->mLayoutTextRunsSize, - &aWindowSizes->mLayoutPresContextSize); + &aWindowSizes->mLayoutPresContextSize, + &aWindowSizes->mLayoutFramePropertiesSize); } aWindowSizes->mPropertyTablesSize += diff --git a/dom/base/nsWindowMemoryReporter.cpp b/dom/base/nsWindowMemoryReporter.cpp index acec4acfb..8f4bf6b11 100644 --- a/dom/base/nsWindowMemoryReporter.cpp +++ b/dom/base/nsWindowMemoryReporter.cpp @@ -400,6 +400,12 @@ CollectWindowReports(nsGlobalWindow *aWindow, aWindowTotalSizes->mLayoutPresContextSize += windowSizes.mLayoutPresContextSize; + REPORT_SIZE("/layout/frame-properties", windowSizes.mLayoutFramePropertiesSize, + "Memory used for frame properties attached to frames " + "within a window."); + aWindowTotalSizes->mLayoutFramePropertiesSize += + windowSizes.mLayoutFramePropertiesSize; + // There are many different kinds of frames, but it is very likely // that only a few matter. Implement a cutoff so we don't bloat // about:memory with many uninteresting entries. @@ -563,6 +569,9 @@ nsWindowMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport, REPORT("window-objects/layout/pres-contexts", windowTotalSizes.mLayoutPresContextSize, "This is the sum of all windows' 'layout/pres-contexts' numbers."); + REPORT("window-objects/layout/frame-properties", windowTotalSizes.mLayoutFramePropertiesSize, + "This is the sum of all windows' 'layout/frame-properties' numbers."); + size_t frameTotal = 0; #define FRAME_ID(classname) \ frameTotal += windowTotalSizes.mArenaStats.FRAME_ID_STAT_FIELD(classname); diff --git a/dom/base/nsWindowMemoryReporter.h b/dom/base/nsWindowMemoryReporter.h index b9e986959..5d40dc9f5 100644 --- a/dom/base/nsWindowMemoryReporter.h +++ b/dom/base/nsWindowMemoryReporter.h @@ -33,6 +33,7 @@ class nsWindowSizes { macro(Style, mLayoutStyleSetsSize) \ macro(Other, mLayoutTextRunsSize) \ macro(Other, mLayoutPresContextSize) \ + macro(Other, mLayoutFramePropertiesSize) \ macro(Other, mPropertyTablesSize) \ public: diff --git a/layout/base/ActiveLayerTracker.cpp b/layout/base/ActiveLayerTracker.cpp index 4f60f82d7..ecee4897a 100644 --- a/layout/base/ActiveLayerTracker.cpp +++ b/layout/base/ActiveLayerTracker.cpp @@ -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 diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index 9aaa28fb5..e87d9dc09 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -165,10 +165,10 @@ FrameLayerBuilder::DisplayItemData::AddFrame(nsIFrame* aFrame) mFrameList.AppendElement(aFrame); nsTArray* array = - aFrame->Properties().Get(FrameLayerBuilder::LayerManagerDataProperty()); + aFrame->GetProperty(FrameLayerBuilder::LayerManagerDataProperty()); if (!array) { array = new nsTArray(); - 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* 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 *array = - reinterpret_cast*>(frame->Properties().Get(LayerManagerDataProperty())); + reinterpret_cast*>(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* 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* 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* 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* 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* 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* 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* 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* 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* array = - f->Properties().Get(LayerManagerDataProperty()); + f->GetProperty(LayerManagerDataProperty()); if (!array) { continue; } @@ -6165,9 +6164,8 @@ FrameLayerBuilder::GetMostRecentGeometry(nsDisplayItem* aItem) typedef nsTArray 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; } diff --git a/layout/base/FrameProperties.h b/layout/base/FrameProperties.h new file mode 100644 index 000000000..bba3ee06b --- /dev/null +++ b/layout/base/FrameProperties.h @@ -0,0 +1,440 @@ +/* -*- 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/. */ + +#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 "nsThreadUtils.h" + +class nsIFrame; + +namespace mozilla { + +struct FramePropertyDescriptorUntyped +{ + /** + * mDestructor will be called if it's non-null. + */ + typedef void UntypedDestructor(void* aPropertyValue); + UntypedDestructor* mDestructor; + /** + * mDestructorWithFrame will be called if it's non-null and mDestructor + * is null. WARNING: The frame passed to mDestructorWithFrame may + * be a dangling frame pointer, if this is being called during + * presshell teardown. Do not use it except to compare against + * other frame pointers. No frame will have been allocated with + * the same address yet. + */ + typedef void UntypedDestructorWithFrame(const nsIFrame* aFrame, + void* aPropertyValue); + UntypedDestructorWithFrame* mDestructorWithFrame; + /** + * mDestructor and mDestructorWithFrame may both be null, in which case + * no value destruction is a no-op. + */ + +protected: + /** + * At most one destructor should be passed in. In general, you should + * just use the static function FramePropertyDescriptor::New* below + * instead of using this constructor directly. + */ + constexpr FramePropertyDescriptorUntyped( + UntypedDestructor* aDtor, UntypedDestructorWithFrame* aDtorWithFrame) + : mDestructor(aDtor) + , mDestructorWithFrame(aDtorWithFrame) + {} +}; + +/** + * A pointer to a FramePropertyDescriptor serves as a unique property ID. + * The FramePropertyDescriptor stores metadata about the property. + * Currently the only metadata is a destructor function. The destructor + * function is called on property values when they are overwritten or + * deleted. + * + * To use this class, declare a global (i.e., file, class or function-scope + * static member) FramePropertyDescriptor and pass its address as + * aProperty in the FramePropertyTable methods. + */ +template +struct FramePropertyDescriptor : public FramePropertyDescriptorUntyped +{ + typedef void Destructor(T* aPropertyValue); + typedef void DestructorWithFrame(const nsIFrame* aaFrame, + T* aPropertyValue); + + template + static constexpr const FramePropertyDescriptor NewWithDestructor() + { + return { Destruct, nullptr }; + } + + template + static constexpr + const FramePropertyDescriptor NewWithDestructorWithFrame() + { + return { nullptr, DestructWithFrame }; + } + + static constexpr const FramePropertyDescriptor NewWithoutDestructor() + { + return { nullptr, nullptr }; + } + +private: + constexpr FramePropertyDescriptor( + UntypedDestructor* aDtor, UntypedDestructorWithFrame* aDtorWithFrame) + : FramePropertyDescriptorUntyped(aDtor, aDtorWithFrame) + {} + + template + static void Destruct(void* aPropertyValue) + { + Dtor(static_cast(aPropertyValue)); + } + + template + static void DestructWithFrame(const nsIFrame* aFrame, void* aPropertyValue) + { + Dtor(aFrame, static_cast(aPropertyValue)); + } +}; + +// SmallValueHolder is a placeholder intended to be used as template +// argument of FramePropertyDescriptor for types which can fit into the +// size of a pointer directly. This class should never be defined, so +// that we won't use it for unexpected purpose by mistake. +template +class SmallValueHolder; + +namespace detail { + +template +struct FramePropertyTypeHelper +{ + typedef T* Type; +}; +template +struct FramePropertyTypeHelper> +{ + typedef T Type; +}; + +} + +/** + * 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. + * + * Property values are passed as void* but do not actually have to be + * valid pointers. You can use NS_INT32_TO_PTR/NS_PTR_TO_INT32 to + * store int32_t values. Null/zero values can be stored and retrieved. + * Of course, the destructor function (if any) must handle such values + * correctly. + */ +class FrameProperties +{ +public: + template + using Descriptor = const FramePropertyDescriptor*; + using UntypedDescriptor = const FramePropertyDescriptorUntyped*; + + template + using PropertyType = typename detail::FramePropertyTypeHelper::Type; + + explicit FrameProperties() + { + } + + ~FrameProperties() + { + MOZ_ASSERT(mProperties.Length() == 0, "forgot to delete properties"); + } + + /** + * Set a property value. This requires a linear search through + * the properties of the frame. Any existing value for the property + * is destroyed. + */ + template + void Set(Descriptor aProperty, PropertyType aValue, + const nsIFrame* aFrame) + { + void* ptr = ReinterpretHelper::ToPointer(aValue); + SetInternal(aProperty, ptr, aFrame); + } + + /** + * @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() + * or Remove() and check the aFoundResult outparam to find out whether the + * property is set. Legitimate non-assertion uses include: + * + * - Checking if a frame property is set in cases where that's all we want + * to know (i.e., we don't intend to read the actual value or remove the + * property). + * + * - Calling Has() before Set() in cases where we don't want to overwrite + * an existing value for the frame property. + */ + template + bool Has(Descriptor aProperty) const + { + return mProperties.IndexOf(aProperty, 0, PropertyComparator()) != nsTArray::NoIndex; + } + + /** + * 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 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 + * the frame has a value for the property. This lets callers + * disambiguate a null result, which can mean 'no such property' or + * 'property value is null'. + */ + template + PropertyType Get(Descriptor aProperty, + bool* aFoundResult = nullptr) const + { + void* ptr = GetInternal(aProperty, aFoundResult); + return ReinterpretHelper::FromPointer(ptr); + } + /** + * 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. + * @param aFoundResult if non-null, receives a value 'true' iff + * the frame had a value for the property. This lets callers + * disambiguate a null result, which can mean 'no such property' or + * 'property value is null'. + */ + template + PropertyType Remove(Descriptor aProperty, + bool* aFoundResult = nullptr) + { + void* ptr = RemoveInternal(aProperty, aFoundResult); + return ReinterpretHelper::FromPointer(ptr); + } + /** + * 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 + void Delete(Descriptor aProperty, const nsIFrame* aFrame) + { + DeleteInternal(aProperty, aFrame); + } + /** + * Remove and destroy all property values for the frame. + */ + void DeleteAll(const nsIFrame* aFrame) { + mozilla::DebugOnly len = mProperties.Length(); + for (auto& prop : mProperties) { + prop.DestroyValueFor(aFrame); + MOZ_ASSERT(mProperties.Length() == len); + } + mProperties.Clear(); + } + + 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); + } + +private: + friend class ::nsIFrame; + + // Prevent copying of FrameProperties; we should always return/pass around + // references to it, not copies! + FrameProperties(const FrameProperties&) = delete; + FrameProperties& operator=(const FrameProperties&) = delete; + + inline void + SetInternal(UntypedDescriptor aProperty, void* aValue, + const nsIFrame* aFrame); + + inline void* + GetInternal(UntypedDescriptor aProperty, bool* aFoundResult) const; + + inline void* + RemoveInternal(UntypedDescriptor aProperty, bool* aFoundResult); + + inline void + DeleteInternal(UntypedDescriptor aProperty, const nsIFrame* aFrame); + + template + struct ReinterpretHelper + { + static_assert(sizeof(PropertyType) <= sizeof(void*), + "size of the value must never be larger than a pointer"); + + static void* ToPointer(PropertyType aValue) + { + void* ptr = nullptr; + memcpy(&ptr, &aValue, sizeof(aValue)); + return ptr; + } + + static PropertyType FromPointer(void* aPtr) + { + PropertyType value; + memcpy(&value, &aPtr, sizeof(value)); + return value; + } + }; + + template + struct ReinterpretHelper + { + static void* ToPointer(T* aValue) + { + return static_cast(aValue); + } + + static T* FromPointer(void* aPtr) + { + return static_cast(aPtr); + } + }; + + /** + * Stores a property descriptor/value pair. + */ + struct PropertyValue { + PropertyValue() : mProperty(nullptr), mValue(nullptr) {} + PropertyValue(UntypedDescriptor aProperty, void* aValue) + : mProperty(aProperty), mValue(aValue) {} + + void DestroyValueFor(const nsIFrame* aFrame) { + if (mProperty->mDestructor) { + mProperty->mDestructor(mValue); + } else if (mProperty->mDestructorWithFrame) { + mProperty->mDestructorWithFrame(aFrame, mValue); + } + } + + UntypedDescriptor mProperty; + void* mValue; + }; + + /** + * Used with an array of PropertyValues to allow lookups that compare + * only on the FramePropertyDescriptor. + */ + class PropertyComparator { + public: + bool Equals(const PropertyValue& a, const PropertyValue& b) const { + return a.mProperty == b.mProperty; + } + bool Equals(UntypedDescriptor a, const PropertyValue& b) const { + return a == b.mProperty; + } + bool Equals(const PropertyValue& a, UntypedDescriptor b) const { + return a.mProperty == b; + } + }; + + nsTArray mProperties; +}; + +/** + * This class encapsulates the properties of a frame. + */ +inline void* +FrameProperties::GetInternal(UntypedDescriptor aProperty, + bool* aFoundResult) const +{ + MOZ_ASSERT(aProperty, "Null property?"); + + auto index = mProperties.IndexOf(aProperty, 0, PropertyComparator()); + if (index == nsTArray::NoIndex) { + if (aFoundResult) { + *aFoundResult = false; + } + return nullptr; + } + + if (aFoundResult) { + *aFoundResult = true; + } + +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::NoIndex) { + PropertyValue* pv = &mProperties.ElementAt(index); + pv->DestroyValueFor(aFrame); + pv->mValue = aValue; + return; + } + + 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::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::NoIndex) { + mProperties.ElementAt(index).DestroyValueFor(aFrame); + mProperties.RemoveElementAt(index); + } +} + +} // namespace mozilla + +#endif /* FRAMEPROPERTIES_H_ */ diff --git a/layout/base/FramePropertyTable.cpp b/layout/base/FramePropertyTable.cpp deleted file mode 100644 index 0fd9b1c37..000000000 --- a/layout/base/FramePropertyTable.cpp +++ /dev/null @@ -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) <= sizeof(void *), - "Property array must fit entirely within entry->mProp.mValue"); - new (&entry->mProp.mValue) nsTArray(4); - entry->mProp.ToArray()->AppendElement(current); - } - - nsTArray* array = entry->mProp.ToArray(); - nsTArray::index_type index = - array->IndexOf(aProperty, 0, PropertyComparator()); - if (index != nsTArray::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* array = entry->mProp.ToArray(); - nsTArray::index_type index = - array->IndexOf(aProperty, 0, PropertyComparator()); - if (index == nsTArray::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* array = entry->mProp.ToArray(); - nsTArray::index_type index = - array->IndexOf(aProperty, 0, PropertyComparator()); - if (index == nsTArray::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(); - 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* array = aEntry->mProp.ToArray(); - for (uint32_t i = 0; i < array->Length(); ++i) { - array->ElementAt(i).DestroyValueFor(aEntry->GetKey()); - } - array->~nsTArray(); -} - -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 diff --git a/layout/base/FramePropertyTable.h b/layout/base/FramePropertyTable.h deleted file mode 100644 index e9847efbf..000000000 --- a/layout/base/FramePropertyTable.h +++ /dev/null @@ -1,442 +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/. */ - -#ifndef FRAMEPROPERTYTABLE_H_ -#define FRAMEPROPERTYTABLE_H_ - -#include "mozilla/MemoryReporting.h" -#include "mozilla/TypeTraits.h" -#include "mozilla/Unused.h" -#include "nsTArray.h" -#include "nsTHashtable.h" -#include "nsHashKeys.h" - -class nsIFrame; - -namespace mozilla { - -struct FramePropertyDescriptorUntyped -{ - /** - * mDestructor will be called if it's non-null. - */ - typedef void UntypedDestructor(void* aPropertyValue); - UntypedDestructor* mDestructor; - /** - * mDestructorWithFrame will be called if it's non-null and mDestructor - * is null. WARNING: The frame passed to mDestructorWithFrame may - * be a dangling frame pointer, if this is being called during - * presshell teardown. Do not use it except to compare against - * other frame pointers. No frame will have been allocated with - * the same address yet. - */ - typedef void UntypedDestructorWithFrame(const nsIFrame* aFrame, - void* aPropertyValue); - UntypedDestructorWithFrame* mDestructorWithFrame; - /** - * mDestructor and mDestructorWithFrame may both be null, in which case - * no value destruction is a no-op. - */ - -protected: - /** - * At most one destructor should be passed in. In general, you should - * just use the static function FramePropertyDescriptor::New* below - * instead of using this constructor directly. - */ - constexpr FramePropertyDescriptorUntyped( - UntypedDestructor* aDtor, UntypedDestructorWithFrame* aDtorWithFrame) - : mDestructor(aDtor) - , mDestructorWithFrame(aDtorWithFrame) - {} -}; - -/** - * A pointer to a FramePropertyDescriptor serves as a unique property ID. - * The FramePropertyDescriptor stores metadata about the property. - * Currently the only metadata is a destructor function. The destructor - * function is called on property values when they are overwritten or - * deleted. - * - * To use this class, declare a global (i.e., file, class or function-scope - * static member) FramePropertyDescriptor and pass its address as - * aProperty in the FramePropertyTable methods. - */ -template -struct FramePropertyDescriptor : public FramePropertyDescriptorUntyped -{ - typedef void Destructor(T* aPropertyValue); - typedef void DestructorWithFrame(const nsIFrame* aaFrame, - T* aPropertyValue); - - template - static constexpr const FramePropertyDescriptor NewWithDestructor() - { - return { Destruct, nullptr }; - } - - template - static constexpr - const FramePropertyDescriptor NewWithDestructorWithFrame() - { - return { nullptr, DestructWithFrame }; - } - - static constexpr const FramePropertyDescriptor NewWithoutDestructor() - { - return { nullptr, nullptr }; - } - -private: - constexpr FramePropertyDescriptor( - UntypedDestructor* aDtor, UntypedDestructorWithFrame* aDtorWithFrame) - : FramePropertyDescriptorUntyped(aDtor, aDtorWithFrame) - {} - - template - static void Destruct(void* aPropertyValue) - { - Dtor(static_cast(aPropertyValue)); - } - - template - static void DestructWithFrame(const nsIFrame* aFrame, void* aPropertyValue) - { - Dtor(aFrame, static_cast(aPropertyValue)); - } -}; - -// SmallValueHolder is a placeholder intended to be used as template -// argument of FramePropertyDescriptor for types which can fit into the -// size of a pointer directly. This class should never be defined, so -// that we won't use it for unexpected purpose by mistake. -template -class SmallValueHolder; - -namespace detail { - -template -struct FramePropertyTypeHelper -{ - typedef T* Type; -}; -template -struct FramePropertyTypeHelper> -{ - typedef T Type; -}; - -} - -/** - * The FramePropertyTable 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. - * - * Property values are passed as void* but do not actually have to be - * valid pointers. You can use NS_INT32_TO_PTR/NS_PTR_TO_INT32 to - * store int32_t values. Null/zero values can be stored and retrieved. - * Of course, the destructor function (if any) must handle such values - * correctly. - */ -class FramePropertyTable { -public: - template - using Descriptor = const FramePropertyDescriptor*; - using UntypedDescriptor = const FramePropertyDescriptorUntyped*; - - template - using PropertyType = typename detail::FramePropertyTypeHelper::Type; - - FramePropertyTable() : mLastFrame(nullptr), mLastEntry(nullptr) - { - } - ~FramePropertyTable() - { - DeleteAll(); - } - - /** - * 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 - * is destroyed. - */ - template - void Set(const nsIFrame* aFrame, Descriptor aProperty, - PropertyType aValue) - { - void* ptr = ReinterpretHelper::ToPointer(aValue); - SetInternal(aFrame, aProperty, ptr); - } - - /** - * @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. - * - * 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() - * or Remove() and check the aFoundResult outparam to find out whether the - * property is set. Legitimate non-assertion uses include: - * - * - Checking if a frame property is set in cases where that's all we want - * to know (i.e., we don't intend to read the actual value or remove the - * property). - * - * - Calling Has() before Set() in cases where we don't want to overwrite - * an existing value for the frame property. - */ - template - bool Has(const nsIFrame* aFrame, Descriptor aProperty) - { - bool foundResult = false; - mozilla::Unused << GetInternal(aFrame, aProperty, &foundResult); - return foundResult; - } - - /** - * Get 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 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 - * the frame has a value for the property. This lets callers - * disambiguate a null result, which can mean 'no such property' or - * 'property value is null'. - */ - template - PropertyType Get(const nsIFrame* aFrame, Descriptor aProperty, - bool* aFoundResult = nullptr) - { - void* ptr = GetInternal(aFrame, aProperty, aFoundResult); - return ReinterpretHelper::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 - * (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. - * @param aFoundResult if non-null, receives a value 'true' iff - * the frame had a value for the property. This lets callers - * disambiguate a null result, which can mean 'no such property' or - * 'property value is null'. - */ - template - PropertyType Remove(const nsIFrame* aFrame, Descriptor aProperty, - bool* aFoundResult = nullptr) - { - void* ptr = RemoveInternal(aFrame, aProperty, aFoundResult); - return ReinterpretHelper::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 - * property, nothing happens. - */ - template - void Delete(const nsIFrame* aFrame, Descriptor aProperty) - { - DeleteInternal(aFrame, aProperty); - } - /** - * Remove and destroy all property values for a frame. This requires one - * hashtable lookup (using the frame as the key). - */ - void DeleteAllFor(const nsIFrame* aFrame); - /** - * Remove and destroy all property values for all frames. - */ - void DeleteAll(); - - size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; - -protected: - void SetInternal(const nsIFrame* aFrame, UntypedDescriptor aProperty, - void* aValue); - - void* GetInternal(const nsIFrame* aFrame, UntypedDescriptor aProperty, - bool* aFoundResult); - - void* RemoveInternal(const nsIFrame* aFrame, UntypedDescriptor aProperty, - bool* aFoundResult); - - void DeleteInternal(const nsIFrame* aFrame, UntypedDescriptor aProperty); - - template - struct ReinterpretHelper - { - static_assert(sizeof(PropertyType) <= sizeof(void*), - "size of the value must never be larger than a pointer"); - - static void* ToPointer(PropertyType aValue) - { - void* ptr = nullptr; - memcpy(&ptr, &aValue, sizeof(aValue)); - return ptr; - } - - static PropertyType FromPointer(void* aPtr) - { - PropertyType value; - memcpy(&value, &aPtr, sizeof(value)); - return value; - } - }; - - template - struct ReinterpretHelper - { - static void* ToPointer(T* aValue) - { - return static_cast(aValue); - } - - static T* FromPointer(void* aPtr) - { - return static_cast(aPtr); - } - }; - - /** - * Stores a property descriptor/value pair. It can also be used to - * store an nsTArray of PropertyValues. - */ - struct PropertyValue { - PropertyValue() : mProperty(nullptr), mValue(nullptr) {} - PropertyValue(UntypedDescriptor aProperty, void* aValue) - : mProperty(aProperty), mValue(aValue) {} - - bool IsArray() { return !mProperty && mValue; } - nsTArray* ToArray() - { - NS_ASSERTION(IsArray(), "Must be array"); - return reinterpret_cast*>(&mValue); - } - - void DestroyValueFor(const nsIFrame* aFrame) { - if (mProperty->mDestructor) { - mProperty->mDestructor(mValue); - } else if (mProperty->mDestructorWithFrame) { - mProperty->mDestructorWithFrame(aFrame, mValue); - } - } - - 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* array = ToArray(); - n += array->ShallowSizeOfExcludingThis(aMallocSizeOf); - } - return n; - } - - UntypedDescriptor mProperty; - void* mValue; - }; - - /** - * Used with an array of PropertyValues to allow lookups that compare - * only on the FramePropertyDescriptor. - */ - class PropertyComparator { - public: - bool Equals(const PropertyValue& a, const PropertyValue& b) const { - return a.mProperty == b.mProperty; - } - bool Equals(UntypedDescriptor a, const PropertyValue& b) const { - return a == b.mProperty; - } - bool Equals(const PropertyValue& a, UntypedDescriptor b) const { - return a.mProperty == b; - } - }; - - /** - * Our hashtable entry. The key is an nsIFrame*, the value is a - * PropertyValue representing one or more property/value pairs. - */ - class Entry : public nsPtrHashKey - { - public: - explicit Entry(KeyTypePointer aKey) : nsPtrHashKey(aKey) {} - Entry(const Entry &toCopy) : - nsPtrHashKey(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 mEntries; - const nsIFrame* mLastFrame; - Entry* mLastEntry; -}; - -/** - * This class encapsulates the properties of a frame. - */ -class FrameProperties { -public: - template using Descriptor = FramePropertyTable::Descriptor; - template using PropertyType = FramePropertyTable::PropertyType; - - FrameProperties(FramePropertyTable* aTable, const nsIFrame* aFrame) - : mTable(aTable), mFrame(aFrame) {} - - template - void Set(Descriptor aProperty, PropertyType aValue) const - { - mTable->Set(mFrame, aProperty, aValue); - } - - template - bool Has(Descriptor aProperty) const - { - return mTable->Has(mFrame, aProperty); - } - - template - PropertyType Get(Descriptor aProperty, - bool* aFoundResult = nullptr) const - { - return mTable->Get(mFrame, aProperty, aFoundResult); - } - template - PropertyType Remove(Descriptor aProperty, - bool* aFoundResult = nullptr) const - { - return mTable->Remove(mFrame, aProperty, aFoundResult); - } - template - void Delete(Descriptor aProperty) - { - mTable->Delete(mFrame, aProperty); - } - -private: - FramePropertyTable* mTable; - const nsIFrame* mFrame; -}; - -} // namespace mozilla - -#endif /* FRAMEPROPERTYTABLE_H_ */ diff --git a/layout/base/OverflowChangedTracker.h b/layout/base/OverflowChangedTracker.h index a18d64b46..40145c65c 100644 --- a/layout/base/OverflowChangedTracker.h +++ b/layout/base/OverflowChangedTracker.h @@ -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. diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index de8f10224..124b5535e 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -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 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 diff --git a/layout/base/RestyleManagerBase.cpp b/layout/base/RestyleManagerBase.cpp index d96d9dbbb..6770f9464 100644 --- a/layout/base/RestyleManagerBase.cpp +++ b/layout/base/RestyleManagerBase.cpp @@ -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 - (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>>(); +} 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; diff --git a/layout/base/RestyleManagerBase.h b/layout/base/RestyleManagerBase.h index f81f5e73f..d92c3d1f7 100644 --- a/layout/base/RestyleManagerBase.h +++ b/layout/base/RestyleManagerBase.h @@ -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>> 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 diff --git a/layout/base/moz.build b/layout/base/moz.build index d3e417f16..4308a6e4d 100644 --- a/layout/base/moz.build +++ b/layout/base/moz.build @@ -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', diff --git a/layout/base/nsBidiPresUtils.cpp b/layout/base/nsBidiPresUtils.cpp index b3c20aabb..887563504 100644 --- a/layout/base/nsBidiPresUtils.cpp +++ b/layout/base/nsBidiPresUtils.cpp @@ -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(); diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 07a5b80e7..ec676ca92 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -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 - (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 - (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); } diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index ff9edf742..119c6c8a2 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -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"); diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index a55ec1e39..e35e027e3 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -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)) { diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index fcdc9e4fc..c81d34fac 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -1003,7 +1003,7 @@ public: static OutOfFlowDisplayData* GetOutOfFlowData(nsIFrame* aFrame) { - return aFrame->Properties().Get(OutOfFlowDisplayDataProperty()); + return aFrame->GetProperty(OutOfFlowDisplayDataProperty()); } nsPresContext* CurrentPresContext() { diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index 4016cc0a9..865f5534c 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -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. diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 07befdc81..06690b208 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -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; } diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index 3106ff386..befb5deb2 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -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. diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h index d8f876291..a2b9bb533 100644 --- a/layout/base/nsPresContext.h +++ b/layout/base/nsPresContext.h @@ -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 { 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 mPrintSettings; nsCOMPtr mPrefChangedTimer; - FramePropertyTable mPropertyTable; nsInvalidateRequestList mInvalidateRequestsSinceLastPaint; nsInvalidateRequestList mUndeliveredInvalidateRequestsBeforeLastPaint; diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index d4fbebbf2..dacc6603b 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -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 diff --git a/layout/base/nsPresShell.h b/layout/base/nsPresShell.h index 1a8dd3fef..10548880a 100644 --- a/layout/base/nsPresShell.h +++ b/layout/base/nsPresShell.h @@ -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; diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp index a7f7d40a8..f8fdf3420 100644 --- a/layout/forms/nsTextControlFrame.cpp +++ b/layout/forms/nsTextControlFrame.cpp @@ -124,10 +124,10 @@ nsTextControlFrame::DestroyFrom(nsIFrame* aDestructRoot) { mScrollEvent.Revoke(); - EditorInitializer* initializer = Properties().Get(TextControlInitializer()); + EditorInitializer* initializer = GetProperty(TextControlInitializer()); if (initializer) { initializer->Revoke(); - Properties().Delete(TextControlInitializer()); + DeleteProperty(TextControlInitializer()); } // Unbind the text editor state object from the frame. The editor will live @@ -410,12 +410,12 @@ nsTextControlFrame::CreateAnonymousContent(nsTArray& aElements) if (initEagerly) { NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(), "Someone forgot a script blocker?"); - EditorInitializer* initializer = Properties().Get(TextControlInitializer()); + EditorInitializer* initializer = GetProperty(TextControlInitializer()); if (initializer) { initializer->Revoke(); } initializer = new EditorInitializer(this); - Properties().Set(TextControlInitializer(),initializer); + SetProperty(TextControlInitializer(),initializer); nsContentUtils::AddScriptRunner(initializer); } @@ -1262,7 +1262,7 @@ nsTextControlFrame::SetInitialChildList(ChildListID aListID, NS_ASSERTION(txtCtrl, "Content not a text control element"); txtCtrl->InitializeKeyboardEventListeners(); - nsPoint* contentScrollPos = Properties().Get(ContentScrollPos()); + nsPoint* contentScrollPos = GetProperty(ContentScrollPos()); if (contentScrollPos) { // If we have a scroll pos stored to be passed to our anonymous // div, do it here! @@ -1271,7 +1271,7 @@ nsTextControlFrame::SetInitialChildList(ChildListID aListID, nsPresState fakePresState; fakePresState.SetScrollState(*contentScrollPos); statefulFrame->RestoreState(&fakePresState); - Properties().Remove(ContentScrollPos()); + RemoveProperty(ContentScrollPos()); delete contentScrollPos; } } @@ -1421,7 +1421,7 @@ nsTextControlFrame::RestoreState(nsPresState* aState) // Most likely, we don't have our anonymous content constructed yet, which // would cause us to end up here. In this case, we'll just store the scroll // pos ourselves, and forward it to the scroll frame later when it's created. - Properties().Set(ContentScrollPos(), new nsPoint(aState->GetScrollPosition())); + SetProperty(ContentScrollPos(), new nsPoint(aState->GetScrollPosition())); return NS_OK; } diff --git a/layout/forms/nsTextControlFrame.h b/layout/forms/nsTextControlFrame.h index 9d4d0b77c..7fa39c5fb 100644 --- a/layout/forms/nsTextControlFrame.h +++ b/layout/forms/nsTextControlFrame.h @@ -327,7 +327,7 @@ private: nsresult GetRootNodeAndInitializeEditor(nsIDOMElement **aRootElement); void FinishedInitializer() { - Properties().Delete(TextControlInitializer()); + DeleteProperty(TextControlInitializer()); } private: diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp index bbff77ad4..78eca8c6c 100644 --- a/layout/generic/ReflowInput.cpp +++ b/layout/generic/ReflowInput.cpp @@ -999,13 +999,13 @@ ReflowInput::ComputeRelativeOffsets(WritingMode aWM, // Convert the offsets to physical coordinates and store them on the frame aComputedOffsets = offsets.GetPhysicalMargin(aWM); - FrameProperties props = aFrame->Properties(); - nsMargin* physicalOffsets = props.Get(nsIFrame::ComputedOffsetProperty()); + nsMargin* physicalOffsets = + aFrame->GetProperty(nsIFrame::ComputedOffsetProperty()); if (physicalOffsets) { *physicalOffsets = aComputedOffsets; } else { - props.Set(nsIFrame::ComputedOffsetProperty(), - new nsMargin(aComputedOffsets)); + aFrame->SetProperty(nsIFrame::ComputedOffsetProperty(), + new nsMargin(aComputedOffsets)); } } @@ -1015,21 +1015,22 @@ ReflowInput::ApplyRelativePositioning(nsIFrame* aFrame, nsPoint* aPosition) { if (!aFrame->IsRelativelyPositioned()) { - NS_ASSERTION(!aFrame->Properties().Get(nsIFrame::NormalPositionProperty()), + NS_ASSERTION(!aFrame->GetProperty(nsIFrame::NormalPositionProperty()), "We assume that changing the 'position' property causes " "frame reconstruction. If that ever changes, this code " "should call " - "props.Delete(nsIFrame::NormalPositionProperty())"); + "aFrame->DeleteProperty(nsIFrame::NormalPositionProperty())"); return; } // Store the normal position - FrameProperties props = aFrame->Properties(); - nsPoint* normalPosition = props.Get(nsIFrame::NormalPositionProperty()); + nsPoint* normalPosition = + aFrame->GetProperty(nsIFrame::NormalPositionProperty()); if (normalPosition) { *normalPosition = *aPosition; } else { - props.Set(nsIFrame::NormalPositionProperty(), new nsPoint(*aPosition)); + aFrame->SetProperty(nsIFrame::NormalPositionProperty(), + new nsPoint(*aPosition)); } const nsStyleDisplay* display = aFrame->StyleDisplay(); @@ -2452,20 +2453,20 @@ ReflowInput::InitConstraints(nsPresContext* aPresContext, } static void -UpdateProp(FrameProperties& aProps, +UpdateProp(nsIFrame* aFrame, const FramePropertyDescriptor* aProperty, bool aNeeded, nsMargin& aNewValue) { if (aNeeded) { - nsMargin* propValue = aProps.Get(aProperty); + nsMargin* propValue = aFrame->GetProperty(aProperty); if (propValue) { *propValue = aNewValue; } else { - aProps.Set(aProperty, new nsMargin(aNewValue)); + aFrame->SetProperty(aProperty, new nsMargin(aNewValue)); } } else { - aProps.Delete(aProperty); + aFrame->DeleteProperty(aProperty); } } @@ -2482,8 +2483,7 @@ SizeComputationInput::InitOffsets(WritingMode aWM, // Since we are in reflow, we don't need to store these properties anymore // unless they are dependent on width, in which case we store the new value. nsPresContext *presContext = mFrame->PresContext(); - FrameProperties props(presContext->PropertyTable(), mFrame); - props.Delete(nsIFrame::UsedBorderProperty()); + mFrame->DeleteProperty(nsIFrame::UsedBorderProperty()); // Compute margins from the specified margin style information. These // become the default computed values, and may be adjusted below @@ -2494,7 +2494,7 @@ SizeComputationInput::InitOffsets(WritingMode aWM, // ... but if we did that, we'd need to fix nsFrame::GetUsedMargin // to use it even when the margins are all zero (since sometimes // they get treated as auto) - ::UpdateProp(props, nsIFrame::UsedMarginProperty(), needMarginProp, + ::UpdateProp(mFrame, nsIFrame::UsedMarginProperty(), needMarginProp, ComputedPhysicalMargin()); @@ -2530,7 +2530,7 @@ SizeComputationInput::InitOffsets(WritingMode aWM, auto ApplyBaselinePadding = [this, &needPaddingProp] (LogicalAxis aAxis, Prop aProp) { bool found; - nscoord val = mFrame->Properties().Get(aProp, &found); + nscoord val = mFrame->GetProperty(aProp, &found); if (found) { NS_ASSERTION(val != nscoord(0), "zero in this property is useless"); WritingMode wm = GetWritingMode(); @@ -2603,7 +2603,7 @@ SizeComputationInput::InitOffsets(WritingMode aWM, ComputedPhysicalBorderPadding().SizeTo(0,0,0,0); } } - ::UpdateProp(props, nsIFrame::UsedPaddingProperty(), needPaddingProp, + ::UpdateProp(mFrame, nsIFrame::UsedPaddingProperty(), needPaddingProp, ComputedPhysicalPadding()); } diff --git a/layout/generic/RubyUtils.cpp b/layout/generic/RubyUtils.cpp index f340663bc..05dd25413 100644 --- a/layout/generic/RubyUtils.cpp +++ b/layout/generic/RubyUtils.cpp @@ -19,21 +19,21 @@ NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(ReservedISize, nscoord) RubyUtils::SetReservedISize(nsIFrame* aFrame, nscoord aISize) { MOZ_ASSERT(IsExpandableRubyBox(aFrame)); - aFrame->Properties().Set(ReservedISize(), aISize); + aFrame->SetProperty(ReservedISize(), aISize); } /* static */ void RubyUtils::ClearReservedISize(nsIFrame* aFrame) { MOZ_ASSERT(IsExpandableRubyBox(aFrame)); - aFrame->Properties().Remove(ReservedISize()); + aFrame->RemoveProperty(ReservedISize()); } /* static */ nscoord RubyUtils::GetReservedISize(nsIFrame* aFrame) { MOZ_ASSERT(IsExpandableRubyBox(aFrame)); - return aFrame->Properties().Get(ReservedISize()); + return aFrame->GetProperty(ReservedISize()); } AutoRubyTextContainerArray::AutoRubyTextContainerArray( diff --git a/layout/generic/StickyScrollContainer.cpp b/layout/generic/StickyScrollContainer.cpp index d61a7e042..ca68992c3 100644 --- a/layout/generic/StickyScrollContainer.cpp +++ b/layout/generic/StickyScrollContainer.cpp @@ -45,12 +45,12 @@ StickyScrollContainer::GetStickyScrollContainerForFrame(nsIFrame* aFrame) // return nullptr; } - FrameProperties props = static_cast(do_QueryFrame(scrollFrame))-> - Properties(); - StickyScrollContainer* s = props.Get(StickyScrollContainerProperty()); + auto frame = static_cast(do_QueryFrame(scrollFrame)); + StickyScrollContainer* s = + frame->GetProperty(StickyScrollContainerProperty()); if (!s) { s = new StickyScrollContainer(scrollFrame); - props.Set(StickyScrollContainerProperty(), s); + frame->SetProperty(StickyScrollContainerProperty(), s); } return s; } @@ -69,9 +69,9 @@ StickyScrollContainer::NotifyReparentedFrameAcrossScrollFrameBoundary(nsIFrame* // we aren't going to handle that. return; } - FrameProperties props = static_cast(do_QueryFrame(oldScrollFrame))-> - Properties(); - StickyScrollContainer* oldSSC = props.Get(StickyScrollContainerProperty()); + StickyScrollContainer* oldSSC = + static_cast(do_QueryFrame(oldScrollFrame))-> + GetProperty(StickyScrollContainerProperty()); if (!oldSSC) { // aOldParent had no sticky descendants, so aFrame doesn't have any sticky // descendants, and we're done here. @@ -95,8 +95,7 @@ StickyScrollContainer::NotifyReparentedFrameAcrossScrollFrameBoundary(nsIFrame* StickyScrollContainer* StickyScrollContainer::GetStickyScrollContainerForScrollFrame(nsIFrame* aFrame) { - FrameProperties props = aFrame->Properties(); - return props.Get(StickyScrollContainerProperty()); + return aFrame->GetProperty(StickyScrollContainerProperty()); } static nscoord @@ -141,13 +140,12 @@ StickyScrollContainer::ComputeStickyOffsets(nsIFrame* aFrame) scrollContainerSize.height); // Store the offset - FrameProperties props = aFrame->Properties(); - nsMargin* offsets = props.Get(nsIFrame::ComputedOffsetProperty()); + nsMargin* offsets = aFrame->GetProperty(nsIFrame::ComputedOffsetProperty()); if (offsets) { *offsets = computedOffsets; } else { - props.Set(nsIFrame::ComputedOffsetProperty(), - new nsMargin(computedOffsets)); + aFrame->SetProperty(nsIFrame::ComputedOffsetProperty(), + new nsMargin(computedOffsets)); } } @@ -162,7 +160,7 @@ StickyScrollContainer::ComputeStickyLimits(nsIFrame* aFrame, nsRect* aStick, aContain->SetRect(nscoord_MIN/2, nscoord_MIN/2, nscoord_MAX, nscoord_MAX); const nsMargin* computedOffsets = - aFrame->Properties().Get(nsIFrame::ComputedOffsetProperty()); + aFrame->GetProperty(nsIFrame::ComputedOffsetProperty()); if (!computedOffsets) { // We haven't reflowed the scroll frame yet, so offsets haven't been // computed. Bail. diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 851e3406c..a37bfc06b 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -326,10 +326,8 @@ nsBlockFrame::DestroyFrom(nsIFrame* aDestructRoot) nsLineBox::DeleteLineList(presContext, mLines, aDestructRoot, &mFrames); - FramePropertyTable* props = presContext->PropertyTable(); - if (HasPushedFloats()) { - SafelyDestroyFrameListProp(aDestructRoot, shell, props, + SafelyDestroyFrameListProp(aDestructRoot, shell, PushedFloatProperty()); RemoveStateBits(NS_BLOCK_HAS_PUSHED_FLOATS); } @@ -343,13 +341,13 @@ nsBlockFrame::DestroyFrom(nsIFrame* aDestructRoot) } if (GetStateBits() & NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS) { - SafelyDestroyFrameListProp(aDestructRoot, shell, props, + SafelyDestroyFrameListProp(aDestructRoot, shell, OverflowOutOfFlowsProperty()); RemoveStateBits(NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS); } if (HasOutsideBullet()) { - SafelyDestroyFrameListProp(aDestructRoot, shell, props, + SafelyDestroyFrameListProp(aDestructRoot, shell, OutsideBulletProperty()); RemoveStateBits(NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET); } @@ -1669,7 +1667,7 @@ nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput, // our computed size due to overflowing their containing block. (E.g. this // ensures we fill the last row when a multi-row grid item is fragmented). bool found; - nscoord bSize = Properties().Get(FragStretchBSizeProperty(), &found); + nscoord bSize = GetProperty(FragStretchBSizeProperty(), &found); if (found) { finalSize.BSize(wm) = std::max(bSize, finalSize.BSize(wm)); } @@ -1679,7 +1677,7 @@ nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput, if (MOZ_UNLIKELY(aReflowInput.mFlags.mBClampMarginBoxMinSize) && NS_FRAME_IS_COMPLETE(aState.mReflowStatus)) { bool found; - nscoord cbSize = Properties().Get(BClampMarginBoxMinSizeProperty(), &found); + nscoord cbSize = GetProperty(BClampMarginBoxMinSizeProperty(), &found); if (found) { auto marginBoxBSize = finalSize.BSize(wm) + aReflowInput.ComputedLogicalMargin().BStartEnd(wm); @@ -1697,11 +1695,10 @@ nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput, finalSize.BSize(wm) = std::max(0, finalSize.BSize(wm)); *aBEndEdgeOfChildren = blockEndEdgeOfChildren; - FrameProperties properties = Properties(); if (blockEndEdgeOfChildren != finalSize.BSize(wm) - borderPadding.BEnd(wm)) { - properties.Set(BlockEndEdgeOfChildrenProperty(), blockEndEdgeOfChildren); + SetProperty(BlockEndEdgeOfChildrenProperty(), blockEndEdgeOfChildren); } else { - properties.Delete(BlockEndEdgeOfChildrenProperty()); + DeleteProperty(BlockEndEdgeOfChildrenProperty()); } aMetrics.SetSize(wm, finalSize); @@ -1834,7 +1831,7 @@ nsBlockFrame::ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) { bool found; nscoord blockEndEdgeOfChildren = - Properties().Get(BlockEndEdgeOfChildrenProperty(), &found); + GetProperty(BlockEndEdgeOfChildrenProperty(), &found); if (found) { ConsiderBlockEndEdgeOfChildren(GetWritingMode(), blockEndEdgeOfChildren, aOverflowAreas); @@ -4985,7 +4982,7 @@ nsBlockFrame::GetOverflowLines() const if (!HasOverflowLines()) { return nullptr; } - FrameLines* prop = Properties().Get(OverflowLinesProperty()); + FrameLines* prop = GetProperty(OverflowLinesProperty()); NS_ASSERTION(prop && !prop->mLines.empty() && prop->mLines.front()->GetChildCount() == 0 ? prop->mFrames.IsEmpty() : prop->mLines.front()->mFirstChild == prop->mFrames.FirstChild(), @@ -4999,7 +4996,7 @@ nsBlockFrame::RemoveOverflowLines() if (!HasOverflowLines()) { return nullptr; } - FrameLines* prop = Properties().Remove(OverflowLinesProperty()); + FrameLines* prop = RemoveProperty(OverflowLinesProperty()); NS_ASSERTION(prop && !prop->mLines.empty() && prop->mLines.front()->GetChildCount() == 0 ? prop->mFrames.IsEmpty() : prop->mLines.front()->mFirstChild == prop->mFrames.FirstChild(), @@ -5012,7 +5009,7 @@ void nsBlockFrame::DestroyOverflowLines() { NS_ASSERTION(HasOverflowLines(), "huh?"); - FrameLines* prop = Properties().Remove(OverflowLinesProperty()); + FrameLines* prop = RemoveProperty(OverflowLinesProperty()); NS_ASSERTION(prop && prop->mLines.empty(), "value should always be stored but empty when destroying"); RemoveStateBits(NS_BLOCK_HAS_OVERFLOW_LINES); @@ -5032,10 +5029,9 @@ nsBlockFrame::SetOverflowLines(FrameLines* aOverflowLines) NS_ASSERTION(!(GetStateBits() & NS_BLOCK_HAS_OVERFLOW_LINES), "Overwriting existing overflow lines"); - FrameProperties props = Properties(); // Verify that we won't overwrite an existing overflow list - NS_ASSERTION(!props.Get(OverflowLinesProperty()), "existing overflow list"); - props.Set(OverflowLinesProperty(), aOverflowLines); + NS_ASSERTION(!GetProperty(OverflowLinesProperty()), "existing overflow list"); + SetProperty(OverflowLinesProperty(), aOverflowLines); AddStateBits(NS_BLOCK_HAS_OVERFLOW_LINES); } @@ -5088,7 +5084,7 @@ nsBlockFrame::GetInsideBullet() const return nullptr; } NS_ASSERTION(!HasOutsideBullet(), "invalid bullet state"); - nsBulletFrame* frame = Properties().Get(InsideBulletProperty()); + nsBulletFrame* frame = GetProperty(InsideBulletProperty()); NS_ASSERTION(frame && frame->GetType() == nsGkAtoms::bulletFrame, "bogus inside bullet frame"); return frame; @@ -5109,8 +5105,7 @@ nsBlockFrame::GetOutsideBulletList() const return nullptr; } NS_ASSERTION(!HasInsideBullet(), "invalid bullet state"); - nsFrameList* list = - Properties().Get(OutsideBulletProperty()); + nsFrameList* list = GetProperty(OutsideBulletProperty()); NS_ASSERTION(list && list->GetLength() == 1 && list->FirstChild()->GetType() == nsGkAtoms::bulletFrame, "bogus outside bullet list"); @@ -5123,8 +5118,7 @@ nsBlockFrame::GetPushedFloats() const if (!HasPushedFloats()) { return nullptr; } - nsFrameList* result = - Properties().Get(PushedFloatProperty()); + nsFrameList* result = GetProperty(PushedFloatProperty()); NS_ASSERTION(result, "value should always be non-empty when state set"); return result; } @@ -5137,7 +5131,7 @@ nsBlockFrame::EnsurePushedFloats() return result; result = new (PresContext()->PresShell()) nsFrameList; - Properties().Set(PushedFloatProperty(), result); + SetProperty(PushedFloatProperty(), result); AddStateBits(NS_BLOCK_HAS_PUSHED_FLOATS); return result; @@ -5149,7 +5143,7 @@ nsBlockFrame::RemovePushedFloats() if (!HasPushedFloats()) { return nullptr; } - nsFrameList *result = Properties().Remove(PushedFloatProperty()); + nsFrameList *result = RemoveProperty(PushedFloatProperty()); RemoveStateBits(NS_BLOCK_HAS_PUSHED_FLOATS); NS_ASSERTION(result, "value should always be non-empty when state set"); return result; @@ -5619,7 +5613,7 @@ nsBlockInFlowLineIterator::nsBlockInFlowLineIterator(nsBlockFrame* aFrame, if (mLine != line_end) { *aFoundValidLine = true; if (mLine != cursor) { - aFrame->Properties().Set(nsBlockFrame::LineCursorProperty(), mLine); + aFrame->SetProperty(nsBlockFrame::LineCursorProperty(), mLine); } return; } @@ -6769,7 +6763,7 @@ void nsBlockFrame::ClearLineCursor() return; } - Properties().Delete(LineCursorProperty()); + DeleteProperty(LineCursorProperty()); RemoveStateBits(NS_BLOCK_HAS_LINE_CURSOR); } @@ -6780,7 +6774,7 @@ void nsBlockFrame::SetupLineCursor() return; } - Properties().Set(LineCursorProperty(), mLines.front()); + SetProperty(LineCursorProperty(), mLines.front()); AddStateBits(NS_BLOCK_HAS_LINE_CURSOR); } @@ -6790,9 +6784,7 @@ nsLineBox* nsBlockFrame::GetFirstLineContaining(nscoord y) return nullptr; } - FrameProperties props = Properties(); - - nsLineBox* property = props.Get(LineCursorProperty()); + nsLineBox* property = GetProperty(LineCursorProperty()); LineIterator cursor = mLines.begin(property); nsRect cursorArea = cursor->GetVisualOverflowArea(); @@ -6808,7 +6800,7 @@ nsLineBox* nsBlockFrame::GetFirstLineContaining(nscoord y) } if (cursor.get() != property) { - props.Set(LineCursorProperty(), cursor.get()); + SetProperty(LineCursorProperty(), cursor.get()); } return cursor.get(); @@ -7021,11 +7013,11 @@ nsBlockFrame::CreateBulletFrameForListItem(bool aCreateBulletList, if (aListStylePositionInside) { nsFrameList bulletList(bullet, bullet); AddFrames(bulletList, nullptr); - Properties().Set(InsideBulletProperty(), bullet); + SetProperty(InsideBulletProperty(), bullet); AddStateBits(NS_BLOCK_FRAME_HAS_INSIDE_BULLET); } else { nsFrameList* bulletList = new (shell) nsFrameList(bullet, bullet); - Properties().Set(OutsideBulletProperty(), bulletList); + SetProperty(OutsideBulletProperty(), bulletList); AddStateBits(NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET); } } diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h index bb41a6e99..f515cc26f 100644 --- a/layout/generic/nsBlockFrame.h +++ b/layout/generic/nsBlockFrame.h @@ -215,7 +215,7 @@ public: ~AutoLineCursorSetup() { if (mOrigCursor) { - mFrame->Properties().Set(LineCursorProperty(), mOrigCursor); + mFrame->SetProperty(LineCursorProperty(), mOrigCursor); } else { mFrame->ClearLineCursor(); } @@ -416,7 +416,7 @@ protected: NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(LineCursorProperty, nsLineBox) bool HasLineCursor() { return GetStateBits() & NS_BLOCK_HAS_LINE_CURSOR; } nsLineBox* GetLineCursor() { - return HasLineCursor() ? Properties().Get(LineCursorProperty()) : nullptr; + return HasLineCursor() ? GetProperty(LineCursorProperty()) : nullptr; } nsLineBox* NewLineBox(nsIFrame* aFrame, bool aIsBlock) { diff --git a/layout/generic/nsBulletFrame.cpp b/layout/generic/nsBulletFrame.cpp index aa8794321..f6595e8f6 100644 --- a/layout/generic/nsBulletFrame.cpp +++ b/layout/generic/nsBulletFrame.cpp @@ -903,7 +903,7 @@ nsBulletFrame::GetFontSizeInflation() const if (!HasFontSizeInflation()) { return 1.0f; } - return Properties().Get(FontSizeInflationProperty()); + return GetProperty(FontSizeInflationProperty()); } void @@ -912,13 +912,13 @@ nsBulletFrame::SetFontSizeInflation(float aInflation) if (aInflation == 1.0f) { if (HasFontSizeInflation()) { RemoveStateBits(BULLET_FRAME_HAS_FONT_INFLATION); - Properties().Delete(FontSizeInflationProperty()); + DeleteProperty(FontSizeInflationProperty()); } return; } AddStateBits(BULLET_FRAME_HAS_FONT_INFLATION); - Properties().Set(FontSizeInflationProperty(), aInflation); + SetProperty(FontSizeInflationProperty(), aInflation); } already_AddRefed diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp index 70a2117cf..1a8812fb7 100644 --- a/layout/generic/nsCanvasFrame.cpp +++ b/layout/generic/nsCanvasFrame.cpp @@ -300,7 +300,7 @@ nsDisplayCanvasBackgroundImage::Paint(nsDisplayListBuilder* aBuilder, // above. destRect.Round(); RefPtr dt = - Frame()->Properties().Get(nsIFrame::CachedBackgroundImageDT()); + Frame()->GetProperty(nsIFrame::CachedBackgroundImageDT()); DrawTarget* destDT = dest->GetDrawTarget(); if (dt) { BlitSurface(destDT, destRect, dt); @@ -317,7 +317,7 @@ nsDisplayCanvasBackgroundImage::Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext context(ctx); PaintInternal(aBuilder, &context, bgClipRect, &bgClipRect); BlitSurface(dest->GetDrawTarget(), destRect, dt); - frame->Properties().Set(nsIFrame::CachedBackgroundImageDT(), + frame->SetProperty(nsIFrame::CachedBackgroundImageDT(), dt.forget().take()); return; } diff --git a/layout/generic/nsCanvasFrame.h b/layout/generic/nsCanvasFrame.h index 236ffb9c7..8bd9dbf79 100644 --- a/layout/generic/nsCanvasFrame.h +++ b/layout/generic/nsCanvasFrame.h @@ -201,7 +201,7 @@ public: virtual void NotifyRenderingChanged() override { - mFrame->Properties().Delete(nsIFrame::CachedBackgroundImageDT()); + mFrame->DeleteProperty(nsIFrame::CachedBackgroundImageDT()); } virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) override diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp index 813d19dfe..2933ac4cf 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -78,7 +78,7 @@ nsContainerFrame::SetInitialChildList(ChildListID aListID, "Only top layer frames should have backdrop"); MOZ_ASSERT(GetStateBits() & NS_FRAME_OUT_OF_FLOW, "Top layer frames should be out-of-flow"); - MOZ_ASSERT(!Properties().Get(BackdropProperty()), + MOZ_ASSERT(!GetProperty(BackdropProperty()), "We shouldn't have setup backdrop frame list before"); #ifdef DEBUG { @@ -93,7 +93,7 @@ nsContainerFrame::SetInitialChildList(ChildListID aListID, #endif nsFrameList* list = new (PresContext()->PresShell()) nsFrameList(aChildList); - Properties().Set(BackdropProperty(), list); + SetProperty(BackdropProperty(), list); } else { MOZ_ASSERT_UNREACHABLE("Unexpected child list"); } @@ -189,18 +189,17 @@ nsContainerFrame::DestroyAbsoluteFrames(nsIFrame* aDestructRoot) void nsContainerFrame::SafelyDestroyFrameListProp(nsIFrame* aDestructRoot, nsIPresShell* aPresShell, - FramePropertyTable* aPropTable, FrameListPropertyDescriptor aProp) { // Note that the last frame can be removed through another route and thus // delete the property -- that's why we fetch the property again before // removing each frame rather than fetching it once and iterating the list. - while (nsFrameList* frameList = aPropTable->Get(this, aProp)) { + while (nsFrameList* frameList = GetProperty(aProp)) { nsIFrame* frame = frameList->RemoveFirstChild(); if (MOZ_LIKELY(frame)) { frame->DestroyFrom(aDestructRoot); } else { - aPropTable->Remove(this, aProp); + RemoveProperty(aProp); frameList->Delete(aPresShell); return; } @@ -223,22 +222,21 @@ nsContainerFrame::DestroyFrom(nsIFrame* aDestructRoot) // Destroy frames on the auxiliary frame lists and delete the lists. nsPresContext* pc = PresContext(); nsIPresShell* shell = pc->PresShell(); - FramePropertyTable* props = pc->PropertyTable(); - SafelyDestroyFrameListProp(aDestructRoot, shell, props, OverflowProperty()); + SafelyDestroyFrameListProp(aDestructRoot, shell, OverflowProperty()); MOZ_ASSERT(IsFrameOfType(nsIFrame::eCanContainOverflowContainers) || - !(props->Get(this, nsContainerFrame::OverflowContainersProperty()) || - props->Get(this, nsContainerFrame::ExcessOverflowContainersProperty())), + !(GetProperty(nsContainerFrame::OverflowContainersProperty()) || + GetProperty(nsContainerFrame::ExcessOverflowContainersProperty())), "this type of frame should't have overflow containers"); - SafelyDestroyFrameListProp(aDestructRoot, shell, props, + SafelyDestroyFrameListProp(aDestructRoot, shell, OverflowContainersProperty()); - SafelyDestroyFrameListProp(aDestructRoot, shell, props, + SafelyDestroyFrameListProp(aDestructRoot, shell, ExcessOverflowContainersProperty()); - MOZ_ASSERT(!props->Get(this, BackdropProperty()) || + MOZ_ASSERT(!GetProperty(BackdropProperty()) || StyleDisplay()->mTopLayer != NS_STYLE_TOP_LAYER_NONE, "only top layer frame may have backdrop"); - SafelyDestroyFrameListProp(aDestructRoot, shell, props, BackdropProperty()); + SafelyDestroyFrameListProp(aDestructRoot, shell, BackdropProperty()); nsSplittableFrame::DestroyFrom(aDestructRoot); } @@ -278,12 +276,11 @@ nsContainerFrame::GetChildList(ChildListID aListID) const static void AppendIfNonempty(const nsIFrame* aFrame, - FramePropertyTable* aPropTable, nsContainerFrame::FrameListPropertyDescriptor aProperty, nsTArray* aLists, nsIFrame::ChildListID aListID) { - if (nsFrameList* list = aPropTable->Get(aFrame, aProperty)) { + if (nsFrameList* list = aFrame->GetProperty(aProperty)) { list->AppendIfNonempty(aLists, aListID); } } @@ -292,20 +289,19 @@ void nsContainerFrame::GetChildLists(nsTArray* aLists) const { mFrames.AppendIfNonempty(aLists, kPrincipalList); - FramePropertyTable* propTable = PresContext()->PropertyTable(); - ::AppendIfNonempty(this, propTable, OverflowProperty(), + ::AppendIfNonempty(this, OverflowProperty(), aLists, kOverflowList); if (IsFrameOfType(nsIFrame::eCanContainOverflowContainers)) { - ::AppendIfNonempty(this, propTable, OverflowContainersProperty(), + ::AppendIfNonempty(this, OverflowContainersProperty(), aLists, kOverflowContainersList); - ::AppendIfNonempty(this, propTable, ExcessOverflowContainersProperty(), + ::AppendIfNonempty(this, ExcessOverflowContainersProperty(), aLists, kExcessOverflowContainersList); } // Bypass BackdropProperty hashtable lookup for any in-flow frames // since frames in the top layer (only which can have backdrop) are // definitely out-of-flow. if (GetStateBits() & NS_FRAME_OUT_OF_FLOW) { - ::AppendIfNonempty(this, propTable, BackdropProperty(), + ::AppendIfNonempty(this, BackdropProperty(), aLists, kBackdropList); } nsSplittableFrame::GetChildLists(aLists); @@ -1335,15 +1331,15 @@ nsContainerFrame::DisplayOverflowContainers(nsDisplayListBuilder* aBuilder, } static bool -TryRemoveFrame(nsIFrame* aFrame, FramePropertyTable* aPropTable, +TryRemoveFrame(nsIFrame* aFrame, nsContainerFrame::FrameListPropertyDescriptor aProp, nsIFrame* aChildToRemove) { - nsFrameList* list = aPropTable->Get(aFrame, aProp); + nsFrameList* list = aFrame->GetProperty(aProp); if (list && list->StartRemoveFrame(aChildToRemove)) { // aChildToRemove *may* have been removed from this list. if (list->IsEmpty()) { - aPropTable->Remove(aFrame, aProp); + aFrame->RemoveProperty(aProp); list->Delete(aFrame->PresContext()->PresShell()); } return true; @@ -1356,13 +1352,12 @@ nsContainerFrame::MaybeStealOverflowContainerFrame(nsIFrame* aChild) { bool removed = false; if (MOZ_UNLIKELY(aChild->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) { - FramePropertyTable* propTable = PresContext()->PropertyTable(); // Try removing from the overflow container list. - removed = ::TryRemoveFrame(this, propTable, OverflowContainersProperty(), + removed = ::TryRemoveFrame(this, OverflowContainersProperty(), aChild); if (!removed) { // It might be in the excess overflow container list. - removed = ::TryRemoveFrame(this, propTable, + removed = ::TryRemoveFrame(this, ExcessOverflowContainersProperty(), aChild); } @@ -1377,10 +1372,9 @@ nsContainerFrame::StealFrame(nsIFrame* aChild) if (!mFrames.ContainsFrame(aChild)) { nsFrameList* list = GetOverflowFrames(); if (!list || !list->ContainsFrame(aChild)) { - FramePropertyTable* propTable = PresContext()->PropertyTable(); - list = propTable->Get(this, OverflowContainersProperty()); + list = GetProperty(OverflowContainersProperty()); if (!list || !list->ContainsFrame(aChild)) { - list = propTable->Get(this, ExcessOverflowContainersProperty()); + list = GetProperty(ExcessOverflowContainersProperty()); MOZ_ASSERT(list && list->ContainsFrame(aChild), "aChild isn't our child" " or on a frame list not supported by StealFrame"); } @@ -1536,20 +1530,20 @@ nsContainerFrame::SetOverflowFrames(const nsFrameList& aOverflowFrames) nsPresContext* pc = PresContext(); nsFrameList* newList = new (pc->PresShell()) nsFrameList(aOverflowFrames); - pc->PropertyTable()->Set(this, OverflowProperty(), newList); + SetProperty(OverflowProperty(), newList); } nsFrameList* nsContainerFrame::GetPropTableFrames( FrameListPropertyDescriptor aProperty) const { - return PresContext()->PropertyTable()->Get(this, aProperty); + return GetProperty(aProperty); } nsFrameList* nsContainerFrame::RemovePropTableFrames(FrameListPropertyDescriptor aProperty) { - return PresContext()->PropertyTable()->Remove(this, aProperty); + return RemoveProperty(aProperty); } void @@ -1563,7 +1557,7 @@ nsContainerFrame::SetPropTableFrames(nsFrameList* aFrameList, IsFrameOfType(nsIFrame::eCanContainOverflowContainers), "this type of frame can't have overflow containers"); MOZ_ASSERT(!GetPropTableFrames(aProperty)); - PresContext()->PropertyTable()->Set(this, aProperty, aFrameList); + SetProperty(aProperty, aFrameList); } /** @@ -2253,13 +2247,11 @@ nsOverflowContinuationTracker::EndFinish(nsIFrame* aChild) return; } // Forget mOverflowContList if it was deleted. - nsPresContext* pc = aChild->PresContext(); - FramePropertyTable* propTable = pc->PropertyTable(); - nsFrameList* eoc = propTable->Get( - mParent, nsContainerFrame::ExcessOverflowContainersProperty()); + nsFrameList* eoc = mParent->GetProperty + (nsContainerFrame::ExcessOverflowContainersProperty()); if (eoc != mOverflowContList) { - nsFrameList* oc = static_cast(propTable->Get(mParent, - nsContainerFrame::OverflowContainersProperty())); + nsFrameList* oc = static_cast(mParent->GetProperty + (nsContainerFrame::OverflowContainersProperty())); if (oc != mOverflowContList) { // mOverflowContList was deleted mPrevOverflowCont = nullptr; diff --git a/layout/generic/nsContainerFrame.h b/layout/generic/nsContainerFrame.h index a9f6d52df..ddf993d91 100644 --- a/layout/generic/nsContainerFrame.h +++ b/layout/generic/nsContainerFrame.h @@ -24,9 +24,6 @@ #define NS_FRAME_NO_DELETE_NEXT_IN_FLOW_CHILD 0x0010 class nsOverflowContinuationTracker; -namespace mozilla { -class FramePropertyTable; -} // namespace mozilla // Some macros for container classes to do sanity checking on // width/height/x/y values computed during reflow. @@ -548,7 +545,7 @@ public: // Use this to suppress the CRAZY_SIZE assertions. NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(DebugReflowingWithInfiniteISize, bool) bool IsCrazySizeAssertSuppressed() const { - return Properties().Get(DebugReflowingWithInfiniteISize()); + return GetProperty(DebugReflowingWithInfiniteISize()); } #endif @@ -716,7 +713,6 @@ protected: */ void SafelyDestroyFrameListProp(nsIFrame* aDestructRoot, nsIPresShell* aPresShell, - mozilla::FramePropertyTable* aPropTable, FrameListPropertyDescriptor aProp); // ========================================================================== @@ -898,7 +894,7 @@ inline nsFrameList* nsContainerFrame::GetOverflowFrames() const { - nsFrameList* list = Properties().Get(OverflowProperty()); + nsFrameList* list = GetProperty(OverflowProperty()); NS_ASSERTION(!list || !list->IsEmpty(), "Unexpected empty overflow list"); return list; } @@ -907,7 +903,7 @@ inline nsFrameList* nsContainerFrame::StealOverflowFrames() { - nsFrameList* list = Properties().Remove(OverflowProperty()); + nsFrameList* list = RemoveProperty(OverflowProperty()); NS_ASSERTION(!list || !list->IsEmpty(), "Unexpected empty overflow list"); return list; } diff --git a/layout/generic/nsFlexContainerFrame.cpp b/layout/generic/nsFlexContainerFrame.cpp index 3818d3cb7..94bce1e7a 100644 --- a/layout/generic/nsFlexContainerFrame.cpp +++ b/layout/generic/nsFlexContainerFrame.cpp @@ -1816,8 +1816,8 @@ nsFlexContainerFrame::MeasureAscentAndHeightForFlexItem( nsPresContext* aPresContext, ReflowInput& aChildReflowInput) { - const FrameProperties props = aItem.Frame()->Properties(); - if (const auto* cachedResult = props.Get(CachedFlexMeasuringReflow())) { + if (const auto* cachedResult = + aItem.Frame()->GetProperty(CachedFlexMeasuringReflow())) { if (cachedResult->IsValidFor(aChildReflowInput)) { return *cachedResult; } @@ -1847,7 +1847,7 @@ nsFlexContainerFrame::MeasureAscentAndHeightForFlexItem( auto result = new CachedMeasuringReflowResult(aChildReflowInput, childDesiredSize); - props.Set(CachedFlexMeasuringReflow(), result); + aItem.Frame()->SetProperty(CachedFlexMeasuringReflow(), result); return *result; } @@ -1855,7 +1855,7 @@ nsFlexContainerFrame::MeasureAscentAndHeightForFlexItem( nsFlexContainerFrame::MarkIntrinsicISizesDirty() { for (nsIFrame* childFrame : mFrames) { - childFrame->Properties().Delete(CachedFlexMeasuringReflow()); + childFrame->DeleteProperty(CachedFlexMeasuringReflow()); } nsContainerFrame::MarkIntrinsicISizesDirty(); } @@ -4236,25 +4236,26 @@ class MOZ_RAII AutoFlexItemMainSizeOverride final public: explicit AutoFlexItemMainSizeOverride(FlexItem& aItem MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mItemProps(aItem.Frame()->Properties()) + : mItemFrame(aItem.Frame()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; - MOZ_ASSERT(!mItemProps.Has(nsIFrame::FlexItemMainSizeOverride()), + MOZ_ASSERT(!mItemFrame->HasProperty(nsIFrame::FlexItemMainSizeOverride()), "FlexItemMainSizeOverride prop shouldn't be set already; " "it should only be set temporarily (& not recursively)"); NS_ASSERTION(aItem.HasIntrinsicRatio(), "This should only be needed for items with an aspect ratio"); - mItemProps.Set(nsIFrame::FlexItemMainSizeOverride(), aItem.GetMainSize()); + mItemFrame->SetProperty(nsIFrame::FlexItemMainSizeOverride(), + aItem.GetMainSize()); } ~AutoFlexItemMainSizeOverride() { - mItemProps.Remove(nsIFrame::FlexItemMainSizeOverride()); + mItemFrame->RemoveProperty(nsIFrame::FlexItemMainSizeOverride()); } private: - const FrameProperties mItemProps; + nsIFrame* mItemFrame; MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; @@ -4668,8 +4669,7 @@ nsFlexContainerFrame::MoveFlexItemToFinalPosition( // If item is relpos, look up its offsets (cached from prev reflow) LogicalMargin logicalOffsets(outerWM); if (NS_STYLE_POSITION_RELATIVE == aItem.Frame()->StyleDisplay()->mPosition) { - FrameProperties props = aItem.Frame()->Properties(); - nsMargin* cachedOffsets = props.Get(nsIFrame::ComputedOffsetProperty()); + nsMargin* cachedOffsets = aItem.Frame()->GetProperty(nsIFrame::ComputedOffsetProperty()); MOZ_ASSERT(cachedOffsets, "relpos previously-reflowed frame should've cached its offsets"); logicalOffsets = LogicalMargin(outerWM, *cachedOffsets); diff --git a/layout/generic/nsFloatManager.cpp b/layout/generic/nsFloatManager.cpp index 2c0ff1f38..4e7e7ff91 100644 --- a/layout/generic/nsFloatManager.cpp +++ b/layout/generic/nsFloatManager.cpp @@ -331,7 +331,7 @@ nsFloatManager::GetRegionFor(WritingMode aWM, nsIFrame* aFloat, const nsSize& aContainerSize) { LogicalRect region = aFloat->GetLogicalRect(aWM, aContainerSize); - void* storedRegion = aFloat->Properties().Get(FloatRegionProperty()); + void* storedRegion = aFloat->GetProperty(FloatRegionProperty()); if (storedRegion) { nsMargin margin = *static_cast(storedRegion); region.Inflate(aWM, LogicalMargin(aWM, margin)); @@ -346,15 +346,14 @@ nsFloatManager::StoreRegionFor(WritingMode aWM, nsIFrame* aFloat, { nsRect region = aRegion.GetPhysicalRect(aWM, aContainerSize); nsRect rect = aFloat->GetRect(); - FrameProperties props = aFloat->Properties(); if (region.IsEqualEdges(rect)) { - props.Delete(FloatRegionProperty()); + aFloat->DeleteProperty(FloatRegionProperty()); } else { - nsMargin* storedMargin = props.Get(FloatRegionProperty()); + nsMargin* storedMargin = aFloat->GetProperty(FloatRegionProperty()); if (!storedMargin) { storedMargin = new nsMargin(); - props.Set(FloatRegionProperty(), storedMargin); + aFloat->SetProperty(FloatRegionProperty(), storedMargin); } *storedMargin = region - rect; } diff --git a/layout/generic/nsFontInflationData.cpp b/layout/generic/nsFontInflationData.cpp index 9e9a51999..831658c9e 100644 --- a/layout/generic/nsFontInflationData.cpp +++ b/layout/generic/nsFontInflationData.cpp @@ -6,7 +6,7 @@ /* Per-block-formatting-context manager of font size inflation for pan and zoom UI. */ #include "nsFontInflationData.h" -#include "FramePropertyTable.h" +#include "FrameProperties.h" #include "nsTextControlFrame.h" #include "nsListControlFrame.h" #include "nsComboboxControlFrame.h" @@ -27,7 +27,7 @@ nsFontInflationData::FindFontInflationDataFor(const nsIFrame *aFrame) NS_ASSERTION(bfc->GetStateBits() & NS_FRAME_FONT_INFLATION_FLOW_ROOT, "should have found a flow root"); - return bfc->Properties().Get(FontInflationDataProperty()); + return bfc->GetProperty(FontInflationDataProperty()); } /* static */ bool @@ -36,8 +36,7 @@ nsFontInflationData::UpdateFontInflationDataISizeFor(const ReflowInput& aReflowI nsIFrame *bfc = aReflowInput.mFrame; NS_ASSERTION(bfc->GetStateBits() & NS_FRAME_FONT_INFLATION_FLOW_ROOT, "should have been given a flow root"); - FrameProperties bfcProps(bfc->Properties()); - nsFontInflationData *data = bfcProps.Get(FontInflationDataProperty()); + nsFontInflationData *data = bfc->GetProperty(FontInflationDataProperty()); bool oldInflationEnabled; nscoord oldNCAISize; if (data) { @@ -45,7 +44,7 @@ nsFontInflationData::UpdateFontInflationDataISizeFor(const ReflowInput& aReflowI oldInflationEnabled = data->mInflationEnabled; } else { data = new nsFontInflationData(bfc); - bfcProps.Set(FontInflationDataProperty(), data); + bfc->SetProperty(FontInflationDataProperty(), data); oldNCAISize = -1; oldInflationEnabled = true; /* not relevant */ } @@ -65,8 +64,7 @@ nsFontInflationData::MarkFontInflationDataTextDirty(nsIFrame *aBFCFrame) NS_ASSERTION(aBFCFrame->GetStateBits() & NS_FRAME_FONT_INFLATION_FLOW_ROOT, "should have been given a flow root"); - FrameProperties bfcProps(aBFCFrame->Properties()); - nsFontInflationData *data = bfcProps.Get(FontInflationDataProperty()); + nsFontInflationData *data = aBFCFrame->GetProperty(FontInflationDataProperty()); if (data) { data->MarkTextDirty(); } diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index fa5b24d40..bd96f213b 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -168,13 +168,12 @@ NS_DECLARE_FRAME_PROPERTY_DELETABLE(BoxMetricsProperty, nsBoxLayoutMetrics) static void InitBoxMetrics(nsIFrame* aFrame, bool aClear) { - FrameProperties props = aFrame->Properties(); if (aClear) { - props.Delete(BoxMetricsProperty()); + aFrame->DeleteProperty(BoxMetricsProperty()); } nsBoxLayoutMetrics* metrics = new nsBoxLayoutMetrics(); - props.Set(BoxMetricsProperty(), metrics); + aFrame->SetProperty(BoxMetricsProperty(), metrics); static_cast(aFrame)->nsFrame::MarkIntrinsicISizesDirty(); metrics->mBlockAscent = 0; @@ -254,7 +253,7 @@ nsIFrame::HasAbsolutelyPositionedChildren() const { nsAbsoluteContainingBlock* nsIFrame::GetAbsoluteContainingBlock() const { NS_ASSERTION(IsAbsoluteContainer(), "The frame is not marked as an abspos container correctly"); - nsAbsoluteContainingBlock* absCB = Properties().Get(AbsoluteContainingBlockProperty()); + nsAbsoluteContainingBlock* absCB = GetProperty(AbsoluteContainingBlockProperty()); NS_ASSERTION(absCB, "The frame is marked as an abspos container but doesn't have the property"); return absCB; } @@ -263,25 +262,25 @@ void nsIFrame::MarkAsAbsoluteContainingBlock() { MOZ_ASSERT(GetStateBits() & NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN); - NS_ASSERTION(!Properties().Get(AbsoluteContainingBlockProperty()), + NS_ASSERTION(!GetProperty(AbsoluteContainingBlockProperty()), "Already has an abs-pos containing block property?"); NS_ASSERTION(!HasAnyStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN), "Already has NS_FRAME_HAS_ABSPOS_CHILDREN state bit?"); AddStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN); - Properties().Set(AbsoluteContainingBlockProperty(), new nsAbsoluteContainingBlock(GetAbsoluteListID())); + SetProperty(AbsoluteContainingBlockProperty(), new nsAbsoluteContainingBlock(GetAbsoluteListID())); } void nsIFrame::MarkAsNotAbsoluteContainingBlock() { NS_ASSERTION(!HasAbsolutelyPositionedChildren(), "Think of the children!"); - NS_ASSERTION(Properties().Get(AbsoluteContainingBlockProperty()), + NS_ASSERTION(GetProperty(AbsoluteContainingBlockProperty()), "Should have an abs-pos containing block property"); NS_ASSERTION(HasAnyStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN), "Should have NS_FRAME_HAS_ABSPOS_CHILDREN state bit"); MOZ_ASSERT(HasAnyStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN)); RemoveStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN); - Properties().Delete(AbsoluteContainingBlockProperty()); + DeleteProperty(AbsoluteContainingBlockProperty()); } bool @@ -652,32 +651,30 @@ nsFrame::DestroyFrom(nsIFrame* aDestructRoot) } // If we have any IB split siblings, clear their references to us. - // (Note: This has to happen before we call shell->NotifyDestroyingFrame, - // because that clears our Properties() table.) + // (Note: This has to happen before we clear our Properties() table.) if (mState & NS_FRAME_PART_OF_IBSPLIT) { // Delete previous sibling's reference to me. - nsIFrame* prevSib = Properties().Get(nsIFrame::IBSplitPrevSibling()); + nsIFrame* prevSib = GetProperty(nsIFrame::IBSplitPrevSibling()); if (prevSib) { NS_WARNING_ASSERTION( - this == prevSib->Properties().Get(nsIFrame::IBSplitSibling()), + this == prevSib->GetProperty(nsIFrame::IBSplitSibling()), "IB sibling chain is inconsistent"); - prevSib->Properties().Delete(nsIFrame::IBSplitSibling()); + prevSib->DeleteProperty(nsIFrame::IBSplitSibling()); } // Delete next sibling's reference to me. - nsIFrame* nextSib = Properties().Get(nsIFrame::IBSplitSibling()); + nsIFrame* nextSib = GetProperty(nsIFrame::IBSplitSibling()); if (nextSib) { NS_WARNING_ASSERTION( - this == nextSib->Properties().Get(nsIFrame::IBSplitPrevSibling()), + this == nextSib->GetProperty(nsIFrame::IBSplitPrevSibling()), "IB sibling chain is inconsistent"); - nextSib->Properties().Delete(nsIFrame::IBSplitPrevSibling()); + nextSib->DeleteProperty(nsIFrame::IBSplitPrevSibling()); } } bool isPrimaryFrame = (mContent && mContent->GetPrimaryFrame() == this); if (isPrimaryFrame) { - // This needs to happen before shell->NotifyDestroyingFrame because - // that clears our Properties() table. + // This needs to happen before we clear our Properties() table. ActiveLayerTracker::TransferActivityToContent(this, mContent); // Unfortunately, we need to do this for all frames being reframed @@ -712,9 +709,8 @@ nsFrame::DestroyFrom(nsIFrame* aDestructRoot) } } - // Disable visibility tracking. Note that we have to do this before calling - // NotifyDestroyingFrame(), which will clear frame properties and make us lose - // track of whether we were previously visible or not. + // Disable visibility tracking. Note that we have to do this before we clear + // frame properties and lose track of whether we were previously visible. // XXX(seth): It'd be ideal to assert that we're already marked nonvisible // here, but it's unfortunately tricky to guarantee in the face of things like // frame reconstruction induced by style changes. @@ -742,6 +738,10 @@ nsFrame::DestroyFrom(nsIFrame* aDestructRoot) mContent->SetPrimaryFrame(nullptr); } + // Delete all properties attached to the frame, to ensure any property + // destructors that need the frame pointer are handled properly. + DeleteAllProperties(); + // Must retrieve the object ID before calling destructors, so the // vtable is still valid. // @@ -860,22 +860,21 @@ nsFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) // calls GetUsed(Margin|Border|Padding)() before the next reflow, we // can give an accurate answer. // We don't want to set the property if one already exists. - FrameProperties props = Properties(); nsMargin oldValue(0, 0, 0, 0); nsMargin newValue(0, 0, 0, 0); const nsStyleMargin* oldMargin = aOldStyleContext->PeekStyleMargin(); if (oldMargin && oldMargin->GetMargin(oldValue)) { if ((!StyleMargin()->GetMargin(newValue) || oldValue != newValue) && - !props.Get(UsedMarginProperty())) { - props.Set(UsedMarginProperty(), new nsMargin(oldValue)); + !GetProperty(UsedMarginProperty())) { + SetProperty(UsedMarginProperty(), new nsMargin(oldValue)); } } const nsStylePadding* oldPadding = aOldStyleContext->PeekStylePadding(); if (oldPadding && oldPadding->GetPadding(oldValue)) { if ((!StylePadding()->GetPadding(newValue) || oldValue != newValue) && - !props.Get(UsedPaddingProperty())) { - props.Set(UsedPaddingProperty(), new nsMargin(oldValue)); + !GetProperty(UsedPaddingProperty())) { + SetProperty(UsedPaddingProperty(), new nsMargin(oldValue)); } } @@ -884,8 +883,8 @@ nsFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) oldValue = oldBorder->GetComputedBorder(); newValue = StyleBorder()->GetComputedBorder(); if (oldValue != newValue && - !props.Get(UsedBorderProperty())) { - props.Set(UsedBorderProperty(), new nsMargin(oldValue)); + !GetProperty(UsedBorderProperty())) { + SetProperty(UsedBorderProperty(), new nsMargin(oldValue)); } } } @@ -961,7 +960,7 @@ nsIFrame::GetUsedMargin() const IsSVGText()) return margin; - nsMargin *m = Properties().Get(UsedMarginProperty()); + nsMargin *m = GetProperty(UsedMarginProperty()); if (m) { margin = *m; } else { @@ -1000,7 +999,7 @@ nsIFrame::GetUsedBorder() const return border; } - nsMargin *b = Properties().Get(UsedBorderProperty()); + nsMargin *b = GetProperty(UsedBorderProperty()); if (b) { border = *b; } else { @@ -1037,7 +1036,7 @@ nsIFrame::GetUsedPadding() const } } - nsMargin *p = Properties().Get(UsedPaddingProperty()); + nsMargin *p = GetProperty(UsedPaddingProperty()); if (p) { padding = *p; } else { @@ -1478,8 +1477,7 @@ nsIFrame::GetVisibility() const } bool isSet = false; - FrameProperties props = Properties(); - uint32_t visibleCount = props.Get(VisibilityStateProperty(), &isSet); + uint32_t visibleCount = GetProperty(VisibilityStateProperty(), &isSet); MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value " "if NS_FRAME_VISIBILITY_IS_TRACKED is set"); @@ -1552,15 +1550,14 @@ nsIFrame::EnableVisibilityTracking() return; // Nothing to do. } - FrameProperties props = Properties(); - MOZ_ASSERT(!props.Has(VisibilityStateProperty()), + MOZ_ASSERT(!HasProperty(VisibilityStateProperty()), "Shouldn't have a VisibilityStateProperty value " "if NS_FRAME_VISIBILITY_IS_TRACKED is not set"); // Add the state bit so we know to track visibility for this frame, and // initialize the frame property. AddStateBits(NS_FRAME_VISIBILITY_IS_TRACKED); - props.Set(VisibilityStateProperty(), 0); + SetProperty(VisibilityStateProperty(), 0); nsIPresShell* presShell = PresContext()->PresShell(); if (!presShell) { @@ -1582,8 +1579,7 @@ nsIFrame::DisableVisibilityTracking() } bool isSet = false; - FrameProperties props = Properties(); - uint32_t visibleCount = props.Remove(VisibilityStateProperty(), &isSet); + uint32_t visibleCount = RemoveProperty(VisibilityStateProperty(), &isSet); MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value " "if NS_FRAME_VISIBILITY_IS_TRACKED is set"); @@ -1605,8 +1601,7 @@ nsIFrame::DecApproximateVisibleCount(Maybe aNonvisibleAction MOZ_ASSERT(GetStateBits() & NS_FRAME_VISIBILITY_IS_TRACKED); bool isSet = false; - FrameProperties props = Properties(); - uint32_t visibleCount = props.Get(VisibilityStateProperty(), &isSet); + uint32_t visibleCount = GetProperty(VisibilityStateProperty(), &isSet); MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value " "if NS_FRAME_VISIBILITY_IS_TRACKED is set"); @@ -1614,7 +1609,7 @@ nsIFrame::DecApproximateVisibleCount(Maybe aNonvisibleAction "decrementing its visible count?"); visibleCount--; - props.Set(VisibilityStateProperty(), visibleCount); + SetProperty(VisibilityStateProperty(), visibleCount); if (visibleCount > 0) { return; } @@ -1629,14 +1624,13 @@ nsIFrame::IncApproximateVisibleCount() MOZ_ASSERT(GetStateBits() & NS_FRAME_VISIBILITY_IS_TRACKED); bool isSet = false; - FrameProperties props = Properties(); - uint32_t visibleCount = props.Get(VisibilityStateProperty(), &isSet); + uint32_t visibleCount = GetProperty(VisibilityStateProperty(), &isSet); MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value " "if NS_FRAME_VISIBILITY_IS_TRACKED is set"); visibleCount++; - props.Set(VisibilityStateProperty(), visibleCount); + SetProperty(VisibilityStateProperty(), visibleCount); if (visibleCount > 1) { return; } @@ -4943,10 +4937,9 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte // If FlexItemMainSizeOverride frame-property is set, then that means the // flex container is imposing a main-size on this flex item for it to use // as its size in the container's main axis. - FrameProperties props = Properties(); bool didImposeMainSize; nscoord imposedMainSize = - props.Get(nsIFrame::FlexItemMainSizeOverride(), &didImposeMainSize); + GetProperty(nsIFrame::FlexItemMainSizeOverride(), &didImposeMainSize); if (didImposeMainSize) { imposedMainSizeStyleCoord.emplace(imposedMainSize, nsStyleCoord::CoordConstructor); @@ -5686,7 +5679,7 @@ nsIFrame::GetView() const return nullptr; // Check for a property on the frame - nsView* value = Properties().Get(ViewProperty()); + nsView* value = GetProperty(ViewProperty()); NS_ASSERTION(value, "frame state bit was set but frame has no view"); return value; } @@ -5709,7 +5702,7 @@ nsIFrame::SetView(nsView* aView) #endif // Set a property on the frame - Properties().Set(ViewProperty(), aView); + SetProperty(ViewProperty(), aView); // Set the frame state bit that says the frame has a view AddStateBits(NS_FRAME_HAS_VIEW); @@ -6098,7 +6091,7 @@ static void InvalidateFrameInternal(nsIFrame *aFrame, bool aHasDisplayItem = tru SchedulePaintInternal(aFrame); } if (aFrame->HasAnyStateBits(NS_FRAME_HAS_INVALID_RECT)) { - aFrame->Properties().Delete(nsIFrame::InvalidationRect()); + aFrame->DeleteProperty(nsIFrame::InvalidationRect()); aFrame->RemoveStateBits(NS_FRAME_HAS_INVALID_RECT); } } @@ -6173,13 +6166,13 @@ nsIFrame::InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey) return; } - nsRect* rect = Properties().Get(InvalidationRect()); + nsRect* rect = GetProperty(InvalidationRect()); if (!rect) { if (alreadyInvalid) { return; } rect = new nsRect(); - Properties().Set(InvalidationRect(), rect); + SetProperty(InvalidationRect(), rect); AddStateBits(NS_FRAME_HAS_INVALID_RECT); } @@ -6280,7 +6273,7 @@ nsIFrame::IsInvalid(nsRect& aRect) } if (HasAnyStateBits(NS_FRAME_HAS_INVALID_RECT)) { - nsRect* rect = Properties().Get(InvalidationRect()); + nsRect* rect = GetProperty(InvalidationRect()); NS_ASSERTION(rect, "Must have an invalid rect if NS_FRAME_HAS_INVALID_RECT is set!"); aRect = *rect; } else { @@ -6368,8 +6361,8 @@ ComputeEffectsRect(nsIFrame* aFrame, const nsRect& aOverflowRect, // TODO: We could also take account of clipPath and mask to reduce the // visual overflow, but that's not essential. if (aFrame->StyleEffects()->HasFilters()) { - aFrame->Properties(). - Set(nsIFrame::PreEffectsBBoxProperty(), new nsRect(r)); + aFrame->SetProperty + (nsIFrame::PreEffectsBBoxProperty(), new nsRect(r)); r = nsSVGUtils::GetPostFilterVisualOverflowRect(aFrame, aOverflowRect); } return r; @@ -6407,8 +6400,8 @@ ComputeEffectsRect(nsIFrame* aFrame, const nsRect& aOverflowRect, // the frame dies. if (nsSVGIntegrationUtils::UsingEffectsForFrame(aFrame)) { - aFrame->Properties(). - Set(nsIFrame::PreEffectsBBoxProperty(), new nsRect(r)); + aFrame->SetProperty + (nsIFrame::PreEffectsBBoxProperty(), new nsRect(r)); r = nsSVGIntegrationUtils::ComputePostEffectsVisualOverflowRect(aFrame, r); } @@ -6422,7 +6415,7 @@ nsIFrame::MovePositionBy(const nsPoint& aTranslation) const nsMargin* computedOffsets = nullptr; if (IsRelativelyPositioned()) { - computedOffsets = Properties().Get(nsIFrame::ComputedOffsetProperty()); + computedOffsets = GetProperty(nsIFrame::ComputedOffsetProperty()); } ReflowInput::ApplyRelativePositioning(this, computedOffsets ? *computedOffsets : nsMargin(), @@ -6435,7 +6428,7 @@ nsIFrame::GetNormalRect() const { // It might be faster to first check // StyleDisplay()->IsRelativelyPositionedStyle(). - nsPoint* normalPosition = Properties().Get(NormalPositionProperty()); + nsPoint* normalPosition = GetProperty(NormalPositionProperty()); if (normalPosition) { return nsRect(*normalPosition, GetSize()); } @@ -6447,7 +6440,7 @@ nsIFrame::GetNormalPosition() const { // It might be faster to first check // StyleDisplay()->IsRelativelyPositionedStyle(). - nsPoint* normalPosition = Properties().Get(NormalPositionProperty()); + nsPoint* normalPosition = GetProperty(NormalPositionProperty()); if (normalPosition) { return *normalPosition; } @@ -6506,7 +6499,7 @@ nsIFrame::GetOverflowAreasRelativeToSelf() const { if (IsTransformed()) { nsOverflowAreas* preTransformOverflows = - Properties().Get(PreTransformOverflowAreasProperty()); + GetProperty(PreTransformOverflowAreasProperty()); if (preTransformOverflows) { return nsOverflowAreas(preTransformOverflows->VisualOverflow(), preTransformOverflows->ScrollableOverflow()); @@ -6533,7 +6526,7 @@ nsIFrame::GetScrollableOverflowRectRelativeToSelf() const { if (IsTransformed()) { nsOverflowAreas* preTransformOverflows = - Properties().Get(PreTransformOverflowAreasProperty()); + GetProperty(PreTransformOverflowAreasProperty()); if (preTransformOverflows) return preTransformOverflows->ScrollableOverflow(); } @@ -6545,7 +6538,7 @@ nsIFrame::GetVisualOverflowRectRelativeToSelf() const { if (IsTransformed()) { nsOverflowAreas* preTransformOverflows = - Properties().Get(PreTransformOverflowAreasProperty()); + GetProperty(PreTransformOverflowAreasProperty()); if (preTransformOverflows) return preTransformOverflows->VisualOverflow(); } @@ -6555,7 +6548,7 @@ nsIFrame::GetVisualOverflowRectRelativeToSelf() const nsRect nsIFrame::GetPreEffectsVisualOverflowRect() const { - nsRect* r = Properties().Get(nsIFrame::PreEffectsBBoxProperty()); + nsRect* r = GetProperty(nsIFrame::PreEffectsBBoxProperty()); return r ? *r : GetVisualOverflowRectRelativeToSelf(); } @@ -6758,11 +6751,11 @@ nsIFrame::ListGeneric(nsACString& aTo, const char* aPrefix, uint32_t aFlags) con aTo += nsPrintfCString(" next-%s=%p", fluid?"in-flow":"continuation", static_cast(GetNextContinuation())); } - void* IBsibling = Properties().Get(IBSplitSibling()); + void* IBsibling = GetProperty(IBSplitSibling()); if (IBsibling) { aTo += nsPrintfCString(" IBSplitSibling=%p", IBsibling); } - void* IBprevsibling = Properties().Get(IBSplitPrevSibling()); + void* IBprevsibling = GetProperty(IBSplitPrevSibling()); if (IBprevsibling) { aTo += nsPrintfCString(" IBSplitPrevSibling=%p", IBprevsibling); } @@ -7164,8 +7157,7 @@ nsFrame::GetPointFromOffset(int32_t inOffset, nsPoint* outPoint) // If the embedding level isn't set, just use the CSS direction // property. bool hasBidiData; - FrameBidiData bidiData = - Properties().Get(BidiDataProperty(), &hasBidiData); + FrameBidiData bidiData = GetProperty(BidiDataProperty(), &hasBidiData); bool isRTL = hasBidiData ? IS_LEVEL_RTL(bidiData.embeddingLevel) : StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL; @@ -8315,7 +8307,7 @@ nsIFrame::ClearOverflowRects() return false; } if (mOverflow.mType == NS_FRAME_OVERFLOW_LARGE) { - Properties().Delete(OverflowAreasProperty()); + DeleteProperty(OverflowAreasProperty()); } mOverflow.mType = NS_FRAME_OVERFLOW_NONE; return true; @@ -8328,8 +8320,7 @@ nsIFrame::ClearOverflowRects() nsOverflowAreas* nsIFrame::GetOverflowAreasProperty() { - FrameProperties props = Properties(); - nsOverflowAreas* overflow = props.Get(OverflowAreasProperty()); + nsOverflowAreas* overflow = GetProperty(OverflowAreasProperty()); if (overflow) { return overflow; // the property already exists @@ -8338,7 +8329,7 @@ nsIFrame::GetOverflowAreasProperty() // The property isn't set yet, so allocate a new rect, set the property, // and return the newly allocated rect overflow = new nsOverflowAreas; - props.Set(OverflowAreasProperty(), overflow); + SetProperty(OverflowAreasProperty(), overflow); return overflow; } @@ -8349,7 +8340,7 @@ bool nsIFrame::SetOverflowAreas(const nsOverflowAreas& aOverflowAreas) { if (mOverflow.mType == NS_FRAME_OVERFLOW_LARGE) { - nsOverflowAreas* overflow = Properties().Get(OverflowAreasProperty()); + nsOverflowAreas* overflow = GetProperty(OverflowAreasProperty()); bool changed = *overflow != aOverflowAreas; *overflow = aOverflowAreas; @@ -8593,7 +8584,7 @@ ComputeAndIncludeOutlineArea(nsIFrame* aFrame, nsOverflowAreas& aOverflowAreas, } // Keep this code in sync with GetOutlineInnerRect in nsCSSRendering.cpp. - aFrame->Properties().Set(nsIFrame::OutlineInnerRectProperty(), + aFrame->SetProperty(nsIFrame::OutlineInnerRectProperty(), new nsRect(innerRect)); const nscoord offset = outline->mOutlineOffset; nsRect outerRect(innerRect); @@ -8635,22 +8626,22 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas, if (!aOverflowAreas.VisualOverflow().IsEqualEdges(bounds) || !aOverflowAreas.ScrollableOverflow().IsEqualEdges(bounds)) { nsOverflowAreas* initial = - Properties().Get(nsIFrame::InitialOverflowProperty()); + GetProperty(nsIFrame::InitialOverflowProperty()); if (!initial) { - Properties().Set(nsIFrame::InitialOverflowProperty(), + SetProperty(nsIFrame::InitialOverflowProperty(), new nsOverflowAreas(aOverflowAreas)); } else if (initial != &aOverflowAreas) { *initial = aOverflowAreas; } } else { - Properties().Delete(nsIFrame::InitialOverflowProperty()); + DeleteProperty(nsIFrame::InitialOverflowProperty()); } #ifdef DEBUG - Properties().Set(nsIFrame::DebugInitialOverflowPropertyApplied(), true); + SetProperty(nsIFrame::DebugInitialOverflowPropertyApplied(), true); #endif } else { #ifdef DEBUG - Properties().Delete(nsIFrame::DebugInitialOverflowPropertyApplied()); + DeleteProperty(nsIFrame::DebugInitialOverflowPropertyApplied()); #endif } @@ -8745,8 +8736,8 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas, } if (hasTransform) { - Properties().Set(nsIFrame::PreTransformOverflowAreasProperty(), - new nsOverflowAreas(aOverflowAreas)); + SetProperty(nsIFrame::PreTransformOverflowAreasProperty(), + new nsOverflowAreas(aOverflowAreas)); if (Combines3DTransformWithAncestors()) { /* If we're a preserve-3d leaf frame, then our pre-transform overflow should be correct. Our @@ -8771,7 +8762,7 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas, } } } else { - Properties().Delete(nsIFrame::PreTransformOverflowAreasProperty()); + DeleteProperty(nsIFrame::PreTransformOverflowAreasProperty()); } /* Revert the size change in case some caller is depending on this. */ @@ -8803,7 +8794,7 @@ nsIFrame::RecomputePerspectiveChildrenOverflow(const nsIFrame* aStartFrame) } if (child->HasPerspective()) { nsOverflowAreas* overflow = - child->Properties().Get(nsIFrame::InitialOverflowProperty()); + child->GetProperty(nsIFrame::InitialOverflowProperty()); nsRect bounds(nsPoint(0, 0), child->GetSize()); if (overflow) { nsOverflowAreas overflowCopy = *overflow; @@ -8915,7 +8906,7 @@ GetIBSplitSiblingForAnonymousBlock(const nsIFrame* aFrame) * property. */ nsIFrame *ibSplitSibling = - aFrame->Properties().Get(nsIFrame::IBSplitPrevSibling()); + aFrame->GetProperty(nsIFrame::IBSplitPrevSibling()); NS_ASSERTION(ibSplitSibling, "Broken frame tree?"); return ibSplitSibling; } @@ -9825,7 +9816,7 @@ nsFrame::BoxReflow(nsBoxLayoutState& aState, nsBoxLayoutMetrics* nsFrame::BoxMetrics() const { - nsBoxLayoutMetrics* metrics = Properties().Get(BoxMetricsProperty()); + nsBoxLayoutMetrics* metrics = GetProperty(BoxMetricsProperty()); NS_ASSERTION(metrics, "A box layout method was called but InitBoxMetrics was never called"); return metrics; } @@ -10069,6 +10060,24 @@ nsFrame::HasCSSTransitions() return collection && collection->mAnimations.Length() > 0; } +size_t +nsIFrame::SizeOfFramePropertiesForTree(MallocSizeOf aMallocSizeOf) const +{ + size_t result = 0; + + result += mProperties.SizeOfExcludingThis(aMallocSizeOf); + + FrameChildListIterator iter(this); + while (!iter.IsDone()) { + for (const nsIFrame* f : iter.CurrentList()) { + result += f->SizeOfFramePropertiesForTree(aMallocSizeOf); + } + iter.Next(); + } + + return result; +} + // Box layout debugging #ifdef DEBUG_REFLOW int32_t gIndent2 = 0; diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index fbd61f783..3a2d5ad1d 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -2000,7 +2000,7 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::GridReflowInput ++fragment; firstInFlow = pif; } - mSharedGridData = firstInFlow->Properties().Get(SharedGridData::Prop()); + mSharedGridData = firstInFlow->GetProperty(SharedGridData::Prop()); MOZ_ASSERT(mSharedGridData, "first-in-flow must have SharedGridData"); // Find the start row for this fragment and undo breaks after that row @@ -2809,7 +2809,7 @@ nsGridContainerFrame::GridItemCB(nsIFrame* aChild) { MOZ_ASSERT((aChild->GetStateBits() & NS_FRAME_OUT_OF_FLOW) && aChild->IsAbsolutelyPositioned()); - nsRect* cb = aChild->Properties().Get(GridItemContainingBlockRect()); + nsRect* cb = aChild->GetProperty(GridItemContainingBlockRect()); MOZ_ASSERT(cb, "this method must only be called on grid items, and the grid " "container should've reflowed this item by now and set up cb"); return *cb; @@ -2836,7 +2836,7 @@ nsGridContainerFrame::AddImplicitNamedAreas( // Lazily create the ImplicitNamedAreas. if (!areas) { areas = new ImplicitNamedAreas; - Properties().Set(ImplicitNamedAreasProperty(), areas); + SetProperty(ImplicitNamedAreasProperty(), areas); } mozilla::css::GridNamedArea area; @@ -2868,7 +2868,7 @@ nsGridContainerFrame::InitImplicitNamedAreas(const nsStylePosition* aStyle) AddImplicitNamedAreas(aStyle->mGridTemplateColumns.mLineNameLists); AddImplicitNamedAreas(aStyle->mGridTemplateRows.mLineNameLists); if (areas && areas->Count() == 0) { - Properties().Delete(ImplicitNamedAreasProperty()); + DeleteProperty(ImplicitNamedAreasProperty()); } } @@ -3711,7 +3711,7 @@ MeasuringReflow(nsIFrame* aChild, } #ifdef DEBUG // This will suppress various CRAZY_SIZE warnings for this reflow. - parent->Properties().Set( + parent->SetProperty( nsContainerFrame::DebugReflowingWithInfiniteISize(), true); #endif auto wm = aChild->GetWritingMode(); @@ -3724,10 +3724,10 @@ MeasuringReflow(nsIFrame* aChild, } if (aBMinSizeClamp != NS_MAXSIZE) { riFlags |= ReflowInput::B_CLAMP_MARGIN_BOX_MIN_SIZE; - aChild->Properties().Set(nsIFrame::BClampMarginBoxMinSizeProperty(), + aChild->SetProperty(nsIFrame::BClampMarginBoxMinSizeProperty(), aBMinSizeClamp); } else { - aChild->Properties().Delete(nsIFrame::BClampMarginBoxMinSizeProperty()); + aChild->DeleteProperty(nsIFrame::BClampMarginBoxMinSizeProperty()); } ReflowInput childRI(pc, *rs, aChild, aAvailableSize, &aCBSize, riFlags); ReflowOutput childSize(childRI); @@ -3738,7 +3738,7 @@ MeasuringReflow(nsIFrame* aChild, parent->FinishReflowChild(aChild, pc, childSize, &childRI, wm, LogicalPoint(wm), nsSize(), flags); #ifdef DEBUG - parent->Properties().Delete(nsContainerFrame::DebugReflowingWithInfiniteISize()); + parent->DeleteProperty(nsContainerFrame::DebugReflowingWithInfiniteISize()); #endif return childSize.BSize(wm); } @@ -5253,9 +5253,9 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame* aChild, baselineAdjust = -baselineAdjust; } if (baselineAdjust != nscoord(0)) { - aChild->Properties().Set(aProp, baselineAdjust); + aChild->SetProperty(aProp, baselineAdjust); } else { - aChild->Properties().Delete(aProp); + aChild->DeleteProperty(aProp); } }; SetProp(eLogicalAxisBlock, isOrthogonal ? IBaselinePadProperty() : @@ -5292,10 +5292,10 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame* aChild, auto childBAxis = GetOrthogonalAxis(childIAxis); if (aGridItemInfo->mState[childBAxis] & ItemState::eClampMarginBoxMinSize) { flags |= ReflowInput::B_CLAMP_MARGIN_BOX_MIN_SIZE; - aChild->Properties().Set(BClampMarginBoxMinSizeProperty(), - childCBSize.BSize(childWM)); + aChild->SetProperty(BClampMarginBoxMinSizeProperty(), + childCBSize.BSize(childWM)); } else { - aChild->Properties().Delete(BClampMarginBoxMinSizeProperty()); + aChild->DeleteProperty(BClampMarginBoxMinSizeProperty()); } if ((aGridItemInfo->mState[childIAxis] & ItemState::eApplyAutoMinSize)) { flags |= ReflowInput::I_APPLY_AUTO_MIN_SIZE; @@ -5313,11 +5313,11 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame* aChild, // A table-wrapper needs to propagate the CB size we give it to its // inner table frame later. @see nsTableWrapperFrame::InitChildReflowInput. if (childType == nsGkAtoms::tableWrapperFrame) { - const auto& props = aChild->Properties(); - LogicalSize* cb = props.Get(nsTableWrapperFrame::GridItemCBSizeProperty()); + LogicalSize* cb = + aChild->GetProperty(nsTableWrapperFrame::GridItemCBSizeProperty()); if (!cb) { cb = new LogicalSize(childWM); - props.Set(nsTableWrapperFrame::GridItemCBSizeProperty(), cb); + aChild->SetProperty(nsTableWrapperFrame::GridItemCBSizeProperty(), cb); } *cb = percentBasis; } @@ -5337,9 +5337,9 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame* aChild, } } if (stretch) { - aChild->Properties().Set(FragStretchBSizeProperty(), *aStretchBSize); + aChild->SetProperty(FragStretchBSizeProperty(), *aStretchBSize); } else { - aChild->Properties().Delete(FragStretchBSizeProperty()); + aChild->DeleteProperty(FragStretchBSizeProperty()); } } @@ -5951,10 +5951,10 @@ nsGridContainerFrame::ReflowChildren(GridReflowInput& aState, LogicalRect itemCB = aState.ContainingBlockForAbsPos(area, gridOrigin, gridCB); // nsAbsoluteContainingBlock::Reflow uses physical coordinates. - nsRect* cb = child->Properties().Get(GridItemContainingBlockRect()); + nsRect* cb = child->GetProperty(GridItemContainingBlockRect()); if (!cb) { cb = new nsRect; - child->Properties().Set(GridItemContainingBlockRect(), cb); + child->SetProperty(GridItemContainingBlockRect(), cb); } *cb = itemCB.GetPhysicalRect(wm, gridCBPhysicalSize); } @@ -6044,7 +6044,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext, f = next; } if (overflowContainers->IsEmpty()) { - Properties().Delete(OverflowContainersProperty()); + DeleteProperty(OverflowContainersProperty()); } MergeSortedExcessOverflowContainers(moveToEOC); } @@ -6355,7 +6355,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext, Move(colTrackStates), Move(colRemovedRepeatTracks), gridReflowInput.mColFunctions.mRepeatAutoStart); - Properties().Set(GridColTrackInfo(), colInfo); + SetProperty(GridColTrackInfo(), colInfo); uint32_t rowTrackCount = gridReflowInput.mRows.mSizes.Length(); nsTArray rowTrackPositions(rowTrackCount); @@ -6390,7 +6390,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext, Move(rowTrackStates), Move(rowRemovedRepeatTracks), gridReflowInput.mRowFunctions.mRepeatAutoStart); - Properties().Set(GridRowTrackInfo(), rowInfo); + SetProperty(GridRowTrackInfo(), rowInfo); if (prevInFlow) { // This frame is fragmenting rows from a previous frame, so patch up @@ -6399,7 +6399,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext, // FIXME: This can be streamlined and/or removed when bug 1151204 lands. ComputedGridTrackInfo* priorRowInfo = - prevInFlow->Properties().Get(GridRowTrackInfo()); + prevInFlow->GetProperty(GridRowTrackInfo()); // Adjust track positions based on the first track in this fragment. if (priorRowInfo->mPositions.Length() > @@ -6421,7 +6421,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext, Move(priorRowInfo->mStates), Move(priorRowInfo->mRemovedRepeatTracks), priorRowInfo->mRepeatFirstTrack); - prevInFlow->Properties().Set(GridRowTrackInfo(), revisedPriorRowInfo); + prevInFlow->SetProperty(GridRowTrackInfo(), revisedPriorRowInfo); } // Generate the line info properties. We need to provide the number of @@ -6448,7 +6448,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext, Move(columnLineNames), gridColTemplate.mRepeatAutoLineNameListBefore, gridColTemplate.mRepeatAutoLineNameListAfter); - Properties().Set(GridColumnLineInfo(), columnLineInfo); + SetProperty(GridColumnLineInfo(), columnLineInfo); // Generate row lines next. capacity = gridReflowInput.mRows.mSizes.Length(); @@ -6469,25 +6469,25 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext, Move(rowLineNames), gridRowTemplate.mRepeatAutoLineNameListBefore, gridRowTemplate.mRepeatAutoLineNameListAfter); - Properties().Set(GridRowLineInfo(), rowLineInfo); + SetProperty(GridRowLineInfo(), rowLineInfo); // Generate area info for explicit areas. Implicit areas are handled // elsewhere. if (gridReflowInput.mGridStyle->mGridTemplateAreas) { nsTArray* areas = new nsTArray( gridReflowInput.mGridStyle->mGridTemplateAreas->mNamedAreas); - Properties().Set(ExplicitNamedAreasProperty(), areas); + SetProperty(ExplicitNamedAreasProperty(), areas); } else { - Properties().Delete(ExplicitNamedAreasProperty()); + DeleteProperty(ExplicitNamedAreasProperty()); } } if (!prevInFlow) { - SharedGridData* sharedGridData = Properties().Get(SharedGridData::Prop()); + SharedGridData* sharedGridData = GetProperty(SharedGridData::Prop()); if (!NS_FRAME_IS_FULLY_COMPLETE(aStatus)) { if (!sharedGridData) { sharedGridData = new SharedGridData; - Properties().Set(SharedGridData::Prop(), sharedGridData); + SetProperty(SharedGridData::Prop(), sharedGridData); } sharedGridData->mCols.mSizes.Clear(); sharedGridData->mCols.mSizes.SwapElements(gridReflowInput.mCols.mSizes); @@ -6522,7 +6522,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext, sharedGridData->mGenerateComputedGridInfo = HasAnyStateBits(NS_STATE_GRID_GENERATE_COMPUTED_VALUES); } else if (sharedGridData && !GetNextInFlow()) { - Properties().Delete(SharedGridData::Prop()); + DeleteProperty(SharedGridData::Prop()); } } @@ -7142,10 +7142,10 @@ nsGridContainerFrame::GetGridFrameWithComputedInfo(nsIFrame* aFrame) nsGridContainerFrame* gridFrame = GetGridContainerFrame(aFrame); if (gridFrame) { // if any of our properties are missing, generate them - bool reflowNeeded = (!gridFrame->Properties().Has(GridColTrackInfo()) || - !gridFrame->Properties().Has(GridRowTrackInfo()) || - !gridFrame->Properties().Has(GridColumnLineInfo()) || - !gridFrame->Properties().Has(GridRowLineInfo())); + bool reflowNeeded = (!gridFrame->HasProperty(GridColTrackInfo()) || + !gridFrame->HasProperty(GridRowTrackInfo()) || + !gridFrame->HasProperty(GridColumnLineInfo()) || + !gridFrame->HasProperty(GridRowLineInfo())); if (reflowNeeded) { // Trigger a reflow that generates additional grid property data. @@ -7161,13 +7161,13 @@ nsGridContainerFrame::GetGridFrameWithComputedInfo(nsIFrame* aFrame) // Assert the grid properties are present MOZ_ASSERT(!gridFrame || - gridFrame->Properties().Has(GridColTrackInfo())); + gridFrame->HasProperty(GridColTrackInfo())); MOZ_ASSERT(!gridFrame || - gridFrame->Properties().Has(GridRowTrackInfo())); + gridFrame->HasProperty(GridRowTrackInfo())); MOZ_ASSERT(!gridFrame || - gridFrame->Properties().Has(GridColumnLineInfo())); + gridFrame->HasProperty(GridColumnLineInfo())); MOZ_ASSERT(!gridFrame || - gridFrame->Properties().Has(GridRowLineInfo())); + gridFrame->HasProperty(GridRowLineInfo())); } } diff --git a/layout/generic/nsGridContainerFrame.h b/layout/generic/nsGridContainerFrame.h index e610dfa0b..960558421 100644 --- a/layout/generic/nsGridContainerFrame.h +++ b/layout/generic/nsGridContainerFrame.h @@ -164,7 +164,7 @@ public: NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridColTrackInfo, ComputedGridTrackInfo) const ComputedGridTrackInfo* GetComputedTemplateColumns() { - const ComputedGridTrackInfo* info = Properties().Get(GridColTrackInfo()); + const ComputedGridTrackInfo* info = GetProperty(GridColTrackInfo()); MOZ_ASSERT(info, "Property generation wasn't requested."); return info; } @@ -172,7 +172,7 @@ public: NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridRowTrackInfo, ComputedGridTrackInfo) const ComputedGridTrackInfo* GetComputedTemplateRows() { - const ComputedGridTrackInfo* info = Properties().Get(GridRowTrackInfo()); + const ComputedGridTrackInfo* info = GetProperty(GridRowTrackInfo()); MOZ_ASSERT(info, "Property generation wasn't requested."); return info; } @@ -180,7 +180,7 @@ public: NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridColumnLineInfo, ComputedGridLineInfo) const ComputedGridLineInfo* GetComputedTemplateColumnLines() { - const ComputedGridLineInfo* info = Properties().Get(GridColumnLineInfo()); + const ComputedGridLineInfo* info = GetProperty(GridColumnLineInfo()); MOZ_ASSERT(info, "Property generation wasn't requested."); return info; } @@ -188,7 +188,7 @@ public: NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridRowLineInfo, ComputedGridLineInfo) const ComputedGridLineInfo* GetComputedTemplateRowLines() { - const ComputedGridLineInfo* info = Properties().Get(GridRowLineInfo()); + const ComputedGridLineInfo* info = GetProperty(GridRowLineInfo()); MOZ_ASSERT(info, "Property generation wasn't requested."); return info; } @@ -199,14 +199,14 @@ public: NS_DECLARE_FRAME_PROPERTY_DELETABLE(ImplicitNamedAreasProperty, ImplicitNamedAreas) ImplicitNamedAreas* GetImplicitNamedAreas() const { - return Properties().Get(ImplicitNamedAreasProperty()); + return GetProperty(ImplicitNamedAreasProperty()); } typedef nsTArray ExplicitNamedAreas; NS_DECLARE_FRAME_PROPERTY_DELETABLE(ExplicitNamedAreasProperty, ExplicitNamedAreas) ExplicitNamedAreas* GetExplicitNamedAreas() const { - return Properties().Get(ExplicitNamedAreasProperty()); + return GetProperty(ExplicitNamedAreasProperty()); } /** diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 2acafa882..37a4e3749 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -24,7 +24,7 @@ #include #include "CaretAssociationHint.h" -#include "FramePropertyTable.h" +#include "FrameProperties.h" #include "mozilla/layout/FrameChildList.h" #include "mozilla/Maybe.h" #include "mozilla/WritingModes.h" @@ -1005,8 +1005,8 @@ public: #define NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(prop, type) \ NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(prop, mozilla::SmallValueHolder) - NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(IBSplitSibling, nsIFrame) - NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(IBSplitPrevSibling, nsIFrame) + NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(IBSplitSibling, nsContainerFrame) + NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(IBSplitPrevSibling, nsContainerFrame) NS_DECLARE_FRAME_PROPERTY_DELETABLE(NormalPositionProperty, nsPoint) NS_DECLARE_FRAME_PROPERTY_DELETABLE(ComputedOffsetProperty, nsMargin) @@ -1059,7 +1059,7 @@ public: mozilla::FrameBidiData GetBidiData() { - return Properties().Get(BidiDataProperty()); + return GetProperty(BidiDataProperty()); } nsBidiLevel GetBaseLevel() @@ -1073,7 +1073,7 @@ public: } nsTArray* GetGenConPseudos() { - return Properties().Get(GenConProperty()); + return GetProperty(GenConProperty()); } /** @@ -1534,7 +1534,7 @@ public: bool RefusedAsyncAnimation() const { - return Properties().Get(RefusedAsyncAnimationProperty()); + return GetProperty(RefusedAsyncAnimationProperty()); } /** @@ -3061,9 +3061,53 @@ public: return mContent == aParentContent; } - FrameProperties Properties() const { - return FrameProperties(PresContext()->PropertyTable(), this); - } +/** + * Support for reading and writing properties on the frame. + * These call through to the frame's FrameProperties object, if it + * exists, but avoid creating it if no property is ever set. + */ +template +FrameProperties::PropertyType +GetProperty(FrameProperties::Descriptor aProperty, + bool* aFoundResult = nullptr) const +{ + return mProperties.Get(aProperty, aFoundResult); +} + +template +bool HasProperty(FrameProperties::Descriptor aProperty) const +{ + return mProperties.Has(aProperty); +} + +template +void SetProperty(FrameProperties::Descriptor aProperty, + FrameProperties::PropertyType aValue) +{ + mProperties.Set(aProperty, aValue, this); +} + +template +FrameProperties::PropertyType +RemoveProperty(FrameProperties::Descriptor aProperty, + bool* aFoundResult = nullptr) +{ + return mProperties.Remove(aProperty, aFoundResult); +} + +template +void DeleteProperty(FrameProperties::Descriptor aProperty) +{ + mProperties.Delete(aProperty, this); +} + +void DeleteAllProperties() +{ + mProperties.DeleteAll(this); +} + +// Reports size of the FrameProperties for this frame and its descendants +size_t SizeOfFramePropertiesForTree(mozilla::MallocSizeOf aMallocSizeOf) const; /** * Return true if and only if this frame obeys visibility:hidden. @@ -3423,7 +3467,7 @@ public: */ bool FrameIsNonFirstInIBSplit() const { return (GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) && - FirstContinuation()->Properties().Get(nsIFrame::IBSplitPrevSibling()); + FirstContinuation()->GetProperty(nsIFrame::IBSplitPrevSibling()); } /** @@ -3432,7 +3476,7 @@ public: */ bool FrameIsNonLastInIBSplit() const { return (GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) && - FirstContinuation()->Properties().Get(nsIFrame::IBSplitSibling()); + FirstContinuation()->GetProperty(nsIFrame::IBSplitSibling()); } /** @@ -3514,11 +3558,11 @@ private: DestroyPaintedPresShellList) nsTArray* PaintedPresShellList() { - nsTArray* list = Properties().Get(PaintedPresShellsProperty()); + nsTArray* list = GetProperty(PaintedPresShellsProperty()); if (!list) { list = new nsTArray(); - Properties().Set(PaintedPresShellsProperty(), list); + SetProperty(PaintedPresShellsProperty(), list); } return list; @@ -3535,6 +3579,11 @@ protected: nsFrameState mState; + /** + * List of properties attached to the frame. + */ + FrameProperties mProperties; + // When there is an overflow area only slightly larger than mRect, // we store a set of four 1-byte deltas from the edges of mRect // rather than allocating a whole separate rectangle property. diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index 138d0b871..6a15a9cfa 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -819,11 +819,11 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, #endif if (mCurrentSpan == mRootSpan) { - pfd->mFrame->Properties().Remove(nsIFrame::LineBaselineOffset()); + pfd->mFrame->RemoveProperty(nsIFrame::LineBaselineOffset()); } else { #ifdef DEBUG bool hasLineOffset; - pfd->mFrame->Properties().Get(nsIFrame::LineBaselineOffset(), &hasLineOffset); + pfd->mFrame->GetProperty(nsIFrame::LineBaselineOffset(), &hasLineOffset); NS_ASSERTION(!hasLineOffset, "LineBaselineOffset was set but was not expected"); #endif } diff --git a/layout/generic/nsPlaceholderFrame.cpp b/layout/generic/nsPlaceholderFrame.cpp index 2b6799f48..bd380a2d9 100644 --- a/layout/generic/nsPlaceholderFrame.cpp +++ b/layout/generic/nsPlaceholderFrame.cpp @@ -128,7 +128,7 @@ nsPlaceholderFrame::Reflow(nsPresContext* aPresContext, nsIFrame* ancestor = this; while ((ancestor = ancestor->GetParent())) { if (ancestor->GetPrevContinuation() || - ancestor->Properties().Get(IBSplitPrevSibling())) { + ancestor->GetProperty(IBSplitPrevSibling())) { isInContinuationOrIBSplit = true; break; } diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 3288d3f2e..0641c7439 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -2838,9 +2838,9 @@ nsTextFrame::EnsureTextRun(TextRunType aWhichTextRun, return gfxSkipCharsIterator(gfxPlatform:: GetPlatform()->EmptySkipChars(), 0); } - TabWidthStore* tabWidths = Properties().Get(TabWidthProperty()); + TabWidthStore* tabWidths = GetProperty(TabWidthProperty()); if (tabWidths && tabWidths->mValidForContentOffset != GetContentOffset()) { - Properties().Delete(TabWidthProperty()); + DeleteProperty(TabWidthProperty()); } } @@ -3478,7 +3478,7 @@ PropertyProvider::CalcTabWidths(Range aRange) return; } if (!mReflowing) { - mTabWidths = mFrame->Properties().Get(TabWidthProperty()); + mTabWidths = mFrame->GetProperty(TabWidthProperty()); #ifdef DEBUG // If we're not reflowing, we should have already computed the // tab widths; check that they're available as far as the last @@ -3524,7 +3524,7 @@ PropertyProvider::CalcTabWidths(Range aRange) } else { if (!mTabWidths) { mTabWidths = new TabWidthStore(mFrame->GetContentOffset()); - mFrame->Properties().Set(TabWidthProperty(), mTabWidths); + mFrame->SetProperty(TabWidthProperty(), mTabWidths); } double nextTab = AdvanceToNextTab(mOffsetFromBlockOriginForTabs, mFrame, mTextRun, &tabWidth); @@ -3543,7 +3543,7 @@ PropertyProvider::CalcTabWidths(Range aRange) if (!mTabWidths) { // Delete any stale property that may be left on the frame - mFrame->Properties().Delete(TabWidthProperty()); + mFrame->DeleteProperty(TabWidthProperty()); mTabWidthsAnalyzedLimit = std::max(mTabWidthsAnalyzedLimit, aRange.end - startOffset); } @@ -4249,7 +4249,7 @@ nsTextFrame::ClearFrameOffsetCache() // just destroys the frames in order, which means that the primary frame is already // dead if we're a continuing text frame, in which case, all of its properties are // gone, and we don't need to worry about deleting this property here. - primaryFrame->Properties().Delete(OffsetToFrameProperty()); + primaryFrame->DeleteProperty(OffsetToFrameProperty()); } RemoveStateBits(TEXT_IN_OFFSET_CACHE); } @@ -4358,7 +4358,7 @@ nsContinuingTextFrame::Init(nsIContent* aContent, if (aPrevInFlow->GetStateBits() & NS_FRAME_IS_BIDI) { FrameBidiData bidiData = aPrevInFlow->GetBidiData(); bidiData.precedingControl = kBidiLevelNone; - Properties().Set(BidiDataProperty(), bidiData); + SetProperty(BidiDataProperty(), bidiData); if (nextContinuation) { SetNextContinuation(nextContinuation); @@ -4622,7 +4622,7 @@ nsTextFrame::InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemK gfxTextRun* nsTextFrame::GetUninflatedTextRun() { - return Properties().Get(UninflatedTextRunProperty()); + return GetProperty(UninflatedTextRunProperty()); } void @@ -4648,7 +4648,7 @@ nsTextFrame::SetTextRun(gfxTextRun* aTextRun, TextRunType aWhichTextRun, // Setting the property will not automatically increment the textrun's // reference count, so we need to do it here. aTextRun->AddRef(); - Properties().Set(UninflatedTextRunProperty(), aTextRun); + SetProperty(UninflatedTextRunProperty(), aTextRun); return; } // fall through to setting mTextRun @@ -4668,10 +4668,9 @@ nsTextFrame::RemoveTextRun(gfxTextRun* aTextRun) mTextRun = nullptr; return true; } - FrameProperties props = Properties(); if ((GetStateBits() & TEXT_HAS_FONT_INFLATION) && - props.Get(UninflatedTextRunProperty()) == aTextRun) { - props.Delete(UninflatedTextRunProperty()); + GetProperty(UninflatedTextRunProperty()) == aTextRun) { + DeleteProperty(UninflatedTextRunProperty()); return true; } return false; @@ -4689,7 +4688,7 @@ nsTextFrame::ClearTextRun(nsTextFrame* aStartContinuation, DebugOnly checkmTextrun = textRun == mTextRun; UnhookTextRunFromFrames(textRun, aStartContinuation); MOZ_ASSERT(checkmTextrun ? !mTextRun - : !Properties().Get(UninflatedTextRunProperty())); + : !GetProperty(UninflatedTextRunProperty())); } void @@ -4699,7 +4698,7 @@ nsTextFrame::DisconnectTextRuns() "Textrun mentions this frame in its user data so we can't just disconnect"); mTextRun = nullptr; if ((GetStateBits() & TEXT_HAS_FONT_INFLATION)) { - Properties().Delete(UninflatedTextRunProperty()); + DeleteProperty(UninflatedTextRunProperty()); } } @@ -4929,7 +4928,7 @@ NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(TextCombineScaleFactorProperty, float) static float GetTextCombineScaleFactor(nsTextFrame* aFrame) { - float factor = aFrame->Properties().Get(TextCombineScaleFactorProperty()); + float factor = aFrame->GetProperty(TextCombineScaleFactorProperty()); return factor ? factor : 1.0f; } @@ -5105,7 +5104,7 @@ static nscoord LazyGetLineBaselineOffset(nsIFrame* aChildFrame, nsBlockFrame* aBlockFrame) { bool offsetFound; - nscoord offset = aChildFrame->Properties().Get( + nscoord offset = aChildFrame->GetProperty( nsIFrame::LineBaselineOffset(), &offsetFound); if (!offsetFound) { @@ -5118,11 +5117,11 @@ LazyGetLineBaselineOffset(nsIFrame* aChildFrame, nsBlockFrame* aBlockFrame) for (nsIFrame* lineFrame = line->mFirstChild; n > 0; lineFrame = lineFrame->GetNextSibling(), --n) { offset = lineBaseline - lineFrame->GetNormalPosition().y; - lineFrame->Properties().Set(nsIFrame::LineBaselineOffset(), offset); + lineFrame->SetProperty(nsIFrame::LineBaselineOffset(), offset); } } } - return aChildFrame->Properties().Get( + return aChildFrame->GetProperty( nsIFrame::LineBaselineOffset(), &offsetFound); } else { return offset; @@ -5367,7 +5366,7 @@ nsTextFrame::UpdateTextEmphasis(WritingMode aWM, PropertyProvider& aProvider) { const nsStyleText* styleText = StyleText(); if (!styleText->HasTextEmphasis()) { - Properties().Delete(EmphasisMarkProperty()); + DeleteProperty(EmphasisMarkProperty()); return nsRect(); } @@ -5419,7 +5418,7 @@ nsTextFrame::UpdateTextEmphasis(WritingMode aWM, PropertyProvider& aProvider) overflowRect.BStart(aWM) += gap * (side == eLogicalSideBStart ? -1 : 1); } - Properties().Set(EmphasisMarkProperty(), info); + SetProperty(EmphasisMarkProperty(), info); return overflowRect.GetPhysicalRect(aWM, frameSize.GetPhysicalSize(aWM)); } @@ -6432,7 +6431,7 @@ nsTextFrame::DrawEmphasisMarks(gfxContext* aContext, WritingMode aWM, const nscolor* aDecorationOverrideColor, PropertyProvider* aProvider) { - const EmphasisMarkInfo* info = Properties().Get(EmphasisMarkProperty()); + const EmphasisMarkInfo* info = GetProperty(EmphasisMarkProperty()); if (!info) { return; } @@ -7584,7 +7583,7 @@ nsTextFrame::GetChildFrameContainingOffset(int32_t aContentOffset, int32_t offset = mContentOffset; // Try to look up the offset to frame property - nsTextFrame* cachedFrame = Properties().Get(OffsetToFrameProperty()); + nsTextFrame* cachedFrame = GetProperty(OffsetToFrameProperty()); if (cachedFrame) { f = cachedFrame; @@ -7632,7 +7631,7 @@ nsTextFrame::GetChildFrameContainingOffset(int32_t aContentOffset, *aOutFrame = f; // cache the frame we found - Properties().Set(OffsetToFrameProperty(), f); + SetProperty(OffsetToFrameProperty(), f); f->AddStateBits(TEXT_IN_OFFSET_CACHE); return NS_OK; @@ -8169,7 +8168,7 @@ nsTextFrame::GetFontSizeInflation() const if (!HasFontSizeInflation()) { return 1.0f; } - return Properties().Get(FontSizeInflationProperty()); + return GetProperty(FontSizeInflationProperty()); } void @@ -8178,13 +8177,13 @@ nsTextFrame::SetFontSizeInflation(float aInflation) if (aInflation == 1.0f) { if (HasFontSizeInflation()) { RemoveStateBits(TEXT_HAS_FONT_INFLATION); - Properties().Delete(FontSizeInflationProperty()); + DeleteProperty(FontSizeInflationProperty()); } return; } AddStateBits(TEXT_HAS_FONT_INFLATION); - Properties().Set(FontSizeInflationProperty(), aInflation); + SetProperty(FontSizeInflationProperty(), aInflation); } /* virtual */ @@ -9319,9 +9318,9 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth, gfxFloat em = fm->EmHeight(); // Compress the characters in horizontal axis if necessary. if (width <= em) { - Properties().Remove(TextCombineScaleFactorProperty()); + RemoveProperty(TextCombineScaleFactorProperty()); } else { - Properties().Set(TextCombineScaleFactorProperty(), em / width); + SetProperty(TextCombineScaleFactorProperty(), em / width); finalSize.ISize(wm) = em; } // Make the characters be in an 1em square. @@ -10049,13 +10048,13 @@ nsTextFrame::AssignJustificationGaps( static_assert(sizeof(aAssign) == 1, "The encoding might be broken if JustificationAssignment " "is larger than 1 byte"); - Properties().Set(JustificationAssignmentProperty(), encoded); + SetProperty(JustificationAssignmentProperty(), encoded); } mozilla::JustificationAssignment nsTextFrame::GetJustificationAssignment() const { - int32_t encoded = Properties().Get(JustificationAssignmentProperty()); + int32_t encoded = GetProperty(JustificationAssignmentProperty()); mozilla::JustificationAssignment result; result.mGapsAtStart = encoded >> 8; result.mGapsAtEnd = encoded & 0xFF; diff --git a/layout/mathml/nsMathMLContainerFrame.cpp b/layout/mathml/nsMathMLContainerFrame.cpp index ad1b13efd..93b631c9d 100644 --- a/layout/mathml/nsMathMLContainerFrame.cpp +++ b/layout/mathml/nsMathMLContainerFrame.cpp @@ -134,7 +134,7 @@ nsMathMLContainerFrame::SaveReflowAndBoundingMetricsFor(nsIFrame* { ReflowOutput* reflowOutput = new ReflowOutput(aReflowOutput); reflowOutput->mBoundingMetrics = aBoundingMetrics; - aFrame->Properties().Set(HTMLReflowOutputProperty(), reflowOutput); + aFrame->SetProperty(HTMLReflowOutputProperty(), reflowOutput); } // helper method to facilitate getting the reflow and bounding metrics @@ -147,7 +147,7 @@ nsMathMLContainerFrame::GetReflowAndBoundingMetricsFor(nsIFrame* aFra NS_PRECONDITION(aFrame, "null arg"); ReflowOutput* reflowOutput = - aFrame->Properties().Get(HTMLReflowOutputProperty()); + aFrame->GetProperty(HTMLReflowOutputProperty()); // IMPORTANT: This function is only meant to be called in Place() methods // where it is assumed that SaveReflowAndBoundingMetricsFor has recorded the @@ -175,9 +175,8 @@ void nsMathMLContainerFrame::ClearSavedChildMetrics() { nsIFrame* childFrame = mFrames.FirstChild(); - FramePropertyTable* props = PresContext()->PropertyTable(); while (childFrame) { - props->Delete(childFrame, HTMLReflowOutputProperty()); + childFrame->DeleteProperty(HTMLReflowOutputProperty()); childFrame = childFrame->GetNextSibling(); } } diff --git a/layout/mathml/nsMathMLmtableFrame.cpp b/layout/mathml/nsMathMLmtableFrame.cpp index a706fb483..fd184e637 100644 --- a/layout/mathml/nsMathMLmtableFrame.cpp +++ b/layout/mathml/nsMathMLmtableFrame.cpp @@ -167,8 +167,7 @@ FindCellProperty(const nsIFrame* aCellFrame, nsTArray* propertyData = nullptr; while (currentFrame) { - FrameProperties props = currentFrame->Properties(); - propertyData = props.Get(aFrameProperty); + propertyData = currentFrame->GetProperty(aFrameProperty); bool frameIsTable = (currentFrame->GetType() == nsGkAtoms::tableFrame); if (propertyData || frameIsTable) @@ -361,8 +360,7 @@ ParseFrameAttribute(nsIFrame* aFrame, if (valueList) { // The code reading the property assumes that this list is nonempty. NS_ASSERTION(valueList->Length() >= 1, "valueList should not be empty!"); - FrameProperties props = aFrame->Properties(); - props.Set(AttributeToProperty(aAttribute), valueList); + aFrame->SetProperty(AttributeToProperty(aAttribute), valueList); } else { ReportParseError(aFrame, aAttribute->GetUTF16String(), attrValue.get()); } @@ -769,8 +767,7 @@ nsMathMLmtableWrapperFrame::AttributeChanged(int32_t aNameSpaceID, aAttribute == nsGkAtoms::columnalign_ || aAttribute == nsGkAtoms::columnlines_) { // clear any cached property list for this table - presContext->PropertyTable()-> - Delete(tableFrame, AttributeToProperty(aAttribute)); + tableFrame->DeleteProperty(AttributeToProperty(aAttribute)); // Reparse the new attribute on the table. ParseFrameAttribute(tableFrame, aAttribute, true); } else { @@ -1120,7 +1117,7 @@ nsMathMLmtrFrame::AttributeChanged(int32_t aNameSpaceID, return NS_OK; } - presContext->PropertyTable()->Delete(this, AttributeToProperty(aAttribute)); + DeleteProperty(AttributeToProperty(aAttribute)); bool allowMultiValues = (aAttribute == nsGkAtoms::columnalign_); @@ -1219,8 +1216,7 @@ nsMathMLmtdFrame::AttributeChanged(int32_t aNameSpaceID, if (aAttribute == nsGkAtoms::rowalign_ || aAttribute == nsGkAtoms::columnalign_) { - nsPresContext* presContext = PresContext(); - presContext->PropertyTable()->Delete(this, AttributeToProperty(aAttribute)); + DeleteProperty(AttributeToProperty(aAttribute)); // Reparse the attribute. ParseFrameAttribute(this, aAttribute, false); diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp index e5a03333f..6ba267ee8 100644 --- a/layout/svg/SVGTextFrame.cpp +++ b/layout/svg/SVGTextFrame.cpp @@ -1328,7 +1328,7 @@ NS_DECLARE_FRAME_PROPERTY_DELETABLE(TextNodeCorrespondenceProperty, static uint32_t GetUndisplayedCharactersBeforeFrame(nsTextFrame* aFrame) { - void* value = aFrame->Properties().Get(TextNodeCorrespondenceProperty()); + void* value = aFrame->GetProperty(TextNodeCorrespondenceProperty()); TextNodeCorrespondence* correspondence = static_cast(value); if (!correspondence) { @@ -1517,8 +1517,8 @@ TextNodeCorrespondenceRecorder::TraverseAndRecord(nsIFrame* aFrame) } // Set the frame property. - frame->Properties().Set(TextNodeCorrespondenceProperty(), - new TextNodeCorrespondence(undisplayed)); + frame->SetProperty(TextNodeCorrespondenceProperty(), + new TextNodeCorrespondence(undisplayed)); // Remember how far into the current nsTextNode we are. mNodeCharIndex = frame->GetContentEnd(); @@ -3391,7 +3391,7 @@ SVGTextFrame::HandleAttributeChangeInDescendant(Element* aElement, // Blow away our reference, if any nsIFrame* childElementFrame = aElement->GetPrimaryFrame(); if (childElementFrame) { - childElementFrame->Properties().Delete( + childElementFrame->DeleteProperty( nsSVGEffects::HrefAsTextPathProperty()); NotifyGlyphMetricsChange(); } @@ -4817,7 +4817,7 @@ SVGPathElement* SVGTextFrame::GetTextPathPathElement(nsIFrame* aTextPathFrame) { nsSVGTextPathProperty *property = - aTextPathFrame->Properties().Get(nsSVGEffects::HrefAsTextPathProperty()); + aTextPathFrame->GetProperty(nsSVGEffects::HrefAsTextPathProperty()); if (!property) { nsIContent* content = aTextPathFrame->GetContent(); diff --git a/layout/svg/nsSVGEffects.cpp b/layout/svg/nsSVGEffects.cpp index e75c973c8..ca4c5778c 100644 --- a/layout/svg/nsSVGEffects.cpp +++ b/layout/svg/nsSVGEffects.cpp @@ -480,27 +480,26 @@ GetOrCreateFilterProperty(nsIFrame* aFrame) if (!effects->HasFilters()) return nullptr; - FrameProperties props = aFrame->Properties(); - nsSVGFilterProperty *prop = props.Get(nsSVGEffects::FilterProperty()); + nsSVGFilterProperty *prop = + aFrame->GetProperty(nsSVGEffects::FilterProperty()); if (prop) return prop; prop = new nsSVGFilterProperty(effects->mFilters, aFrame); NS_ADDREF(prop); - props.Set(nsSVGEffects::FilterProperty(), prop); + aFrame->SetProperty(nsSVGEffects::FilterProperty(), prop); return prop; } static nsSVGMaskProperty* GetOrCreateMaskProperty(nsIFrame* aFrame) { - FrameProperties props = aFrame->Properties(); - nsSVGMaskProperty *prop = props.Get(nsSVGEffects::MaskProperty()); + nsSVGMaskProperty *prop = aFrame->GetProperty(nsSVGEffects::MaskProperty()); if (prop) return prop; prop = new nsSVGMaskProperty(aFrame); NS_ADDREF(prop); - props.Set(nsSVGEffects::MaskProperty(), prop); + aFrame->SetProperty(nsSVGEffects::MaskProperty(), prop); return prop; } @@ -512,13 +511,12 @@ GetEffectProperty(nsIURI* aURI, nsIFrame* aFrame, if (!aURI) return nullptr; - FrameProperties props = aFrame->Properties(); - T* prop = props.Get(aProperty); + T* prop = aFrame->GetProperty(aProperty); if (prop) return prop; prop = new T(aURI, aFrame, false); NS_ADDREF(prop); - props.Set(aProperty, prop); + aFrame->SetProperty(aProperty, prop); return prop; } @@ -553,11 +551,11 @@ nsSVGEffects::GetPaintingPropertyForURI(nsIURI* aURI, nsIFrame* aFrame, if (!aURI) return nullptr; - FrameProperties props = aFrame->Properties(); - nsSVGEffects::URIObserverHashtable *hashtable = props.Get(aProperty); + nsSVGEffects::URIObserverHashtable *hashtable = + aFrame->GetProperty(aProperty); if (!hashtable) { hashtable = new nsSVGEffects::URIObserverHashtable(); - props.Set(aProperty, hashtable); + aFrame->SetProperty(aProperty, hashtable); } nsSVGPaintingProperty* prop = static_cast(hashtable->GetWeak(aURI)); @@ -689,16 +687,15 @@ nsSVGEffects::UpdateEffects(nsIFrame* aFrame) NS_ASSERTION(aFrame->GetContent()->IsElement(), "aFrame's content should be an element"); - FrameProperties props = aFrame->Properties(); - props.Delete(FilterProperty()); - props.Delete(MaskProperty()); - props.Delete(ClipPathProperty()); - props.Delete(MarkerBeginProperty()); - props.Delete(MarkerMiddleProperty()); - props.Delete(MarkerEndProperty()); - props.Delete(FillProperty()); - props.Delete(StrokeProperty()); - props.Delete(BackgroundImageProperty()); + aFrame->DeleteProperty(FilterProperty()); + aFrame->DeleteProperty(MaskProperty()); + aFrame->DeleteProperty(ClipPathProperty()); + aFrame->DeleteProperty(MarkerBeginProperty()); + aFrame->DeleteProperty(MarkerMiddleProperty()); + aFrame->DeleteProperty(MarkerEndProperty()); + aFrame->DeleteProperty(FillProperty()); + aFrame->DeleteProperty(StrokeProperty()); + aFrame->DeleteProperty(BackgroundImageProperty()); // Ensure that the filter is repainted correctly // We can't do that in DoUpdate as the referenced frame may not be valid @@ -725,7 +722,7 @@ nsSVGEffects::GetFilterProperty(nsIFrame* aFrame) if (!aFrame->StyleEffects()->HasFilters()) return nullptr; - return aFrame->Properties().Get(FilterProperty()); + return aFrame->GetProperty(FilterProperty()); } void @@ -835,7 +832,7 @@ nsSVGEffects::InvalidateRenderingObservers(nsIFrame* aFrame) return; // If the rendering has changed, the bounds may well have changed too: - aFrame->Properties().Delete(nsSVGUtils::ObjectBoundingBoxProperty()); + aFrame->DeleteProperty(nsSVGUtils::ObjectBoundingBoxProperty()); nsSVGRenderingObserverList *observerList = GetObserverList(content->AsElement()); @@ -864,7 +861,7 @@ nsSVGEffects::InvalidateDirectRenderingObservers(Element* aElement, uint32_t aFl nsIFrame* frame = aElement->GetPrimaryFrame(); if (frame) { // If the rendering has changed, the bounds may well have changed too: - frame->Properties().Delete(nsSVGUtils::ObjectBoundingBoxProperty()); + frame->DeleteProperty(nsSVGUtils::ObjectBoundingBoxProperty()); } if (aElement->HasRenderingObservers()) { diff --git a/layout/svg/nsSVGEffects.h b/layout/svg/nsSVGEffects.h index 0cf9b1500..b8b2e53c1 100644 --- a/layout/svg/nsSVGEffects.h +++ b/layout/svg/nsSVGEffects.h @@ -7,7 +7,7 @@ #define NSSVGEFFECTS_H_ #include "mozilla/Attributes.h" -#include "FramePropertyTable.h" +#include "FrameProperties.h" #include "mozilla/dom/Element.h" #include "nsHashKeys.h" #include "nsID.h" diff --git a/layout/svg/nsSVGFilterFrame.cpp b/layout/svg/nsSVGFilterFrame.cpp index 13ce16993..3b99f413e 100644 --- a/layout/svg/nsSVGFilterFrame.cpp +++ b/layout/svg/nsSVGFilterFrame.cpp @@ -107,7 +107,7 @@ nsSVGFilterFrame::GetReferencedFilter() return nullptr; nsSVGPaintingProperty *property = - Properties().Get(nsSVGEffects::HrefAsPaintingProperty()); + GetProperty(nsSVGEffects::HrefAsPaintingProperty()); if (!property) { // Fetch our Filter element's href or xlink:href attribute @@ -183,7 +183,7 @@ nsSVGFilterFrame::AttributeChanged(int32_t aNameSpaceID, aNameSpaceID == kNameSpaceID_None) && aAttribute == nsGkAtoms::href) { // Blow away our reference, if any - Properties().Delete(nsSVGEffects::HrefAsPaintingProperty()); + DeleteProperty(nsSVGEffects::HrefAsPaintingProperty()); mNoHRefURI = false; // And update whoever references us nsSVGEffects::InvalidateDirectRenderingObservers(this); diff --git a/layout/svg/nsSVGGradientFrame.cpp b/layout/svg/nsSVGGradientFrame.cpp index 2d7684f5a..340cfa881 100644 --- a/layout/svg/nsSVGGradientFrame.cpp +++ b/layout/svg/nsSVGGradientFrame.cpp @@ -72,7 +72,7 @@ nsSVGGradientFrame::AttributeChanged(int32_t aNameSpaceID, aNameSpaceID == kNameSpaceID_None) && aAttribute == nsGkAtoms::href) { // Blow away our reference, if any - Properties().Delete(nsSVGEffects::HrefAsPaintingProperty()); + DeleteProperty(nsSVGEffects::HrefAsPaintingProperty()); mNoHRefURI = false; // And update whoever references us nsSVGEffects::InvalidateDirectRenderingObservers(this); @@ -316,7 +316,7 @@ nsSVGGradientFrame::GetReferencedGradient() return nullptr; nsSVGPaintingProperty *property = - Properties().Get(nsSVGEffects::HrefAsPaintingProperty()); + GetProperty(nsSVGEffects::HrefAsPaintingProperty()); if (!property) { // Fetch our gradient element's href or xlink:href attribute diff --git a/layout/svg/nsSVGIntegrationUtils.cpp b/layout/svg/nsSVGIntegrationUtils.cpp index 0003e1a73..4ce2941d4 100644 --- a/layout/svg/nsSVGIntegrationUtils.cpp +++ b/layout/svg/nsSVGIntegrationUtils.cpp @@ -75,7 +75,7 @@ public: private: static nsRect GetPreEffectsVisualOverflowRect(nsIFrame* aFrame) { - nsRect* r = aFrame->Properties().Get(nsIFrame::PreEffectsBBoxProperty()); + nsRect* r = aFrame->GetProperty(nsIFrame::PreEffectsBBoxProperty()); if (r) { return *r; } @@ -113,8 +113,7 @@ private: NS_ASSERTION(aFrame->GetParent()->StyleContext()->GetPseudo() == nsCSSAnonBoxes::mozAnonymousBlock, "How did we getting here, then?"); - NS_ASSERTION(!aFrame->Properties().Get( - aFrame->PreTransformOverflowAreasProperty()), + NS_ASSERTION(!aFrame->GetProperty(aFrame->PreTransformOverflowAreasProperty()), "GetVisualOverflowRect() won't return the pre-effects rect!"); return aFrame->GetVisualOverflowRect(); } diff --git a/layout/svg/nsSVGPatternFrame.cpp b/layout/svg/nsSVGPatternFrame.cpp index 198163d7f..2cd7eeaad 100644 --- a/layout/svg/nsSVGPatternFrame.cpp +++ b/layout/svg/nsSVGPatternFrame.cpp @@ -89,7 +89,7 @@ nsSVGPatternFrame::AttributeChanged(int32_t aNameSpaceID, aNameSpaceID == kNameSpaceID_None) && aAttribute == nsGkAtoms::href) { // Blow away our reference, if any - Properties().Delete(nsSVGEffects::HrefAsPaintingProperty()); + DeleteProperty(nsSVGEffects::HrefAsPaintingProperty()); mNoHRefURI = false; // And update whoever references us nsSVGEffects::InvalidateDirectRenderingObservers(this); @@ -548,7 +548,7 @@ nsSVGPatternFrame::GetReferencedPattern() return nullptr; nsSVGPaintingProperty *property = - Properties().Get(nsSVGEffects::HrefAsPaintingProperty()); + GetProperty(nsSVGEffects::HrefAsPaintingProperty()); if (!property) { // Fetch our pattern element's href or xlink:href attribute diff --git a/layout/svg/nsSVGUtils.cpp b/layout/svg/nsSVGUtils.cpp index 98e5f9b5f..c3394e292 100644 --- a/layout/svg/nsSVGUtils.cpp +++ b/layout/svg/nsSVGUtils.cpp @@ -1060,10 +1060,9 @@ nsSVGUtils::GetBBox(nsIFrame *aFrame, uint32_t aFlags) return bbox; } - FrameProperties props = aFrame->Properties(); if (aFlags == eBBoxIncludeFillGeometry) { - gfxRect* prop = props.Get(ObjectBoundingBoxProperty()); + gfxRect* prop = aFrame->GetProperty(ObjectBoundingBoxProperty()); if (prop) { return *prop; } @@ -1139,7 +1138,7 @@ nsSVGUtils::GetBBox(nsIFrame *aFrame, uint32_t aFlags) if (aFlags == eBBoxIncludeFillGeometry) { // Obtaining the bbox for objectBoundingBox calculations is common so we // cache the result for future calls, since calculation can be expensive: - props.Set(ObjectBoundingBoxProperty(), new gfxRect(bbox)); + aFrame->SetProperty(ObjectBoundingBoxProperty(), new gfxRect(bbox)); } return bbox; diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 4c11d2704..b9b6ca5fe 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -272,13 +272,12 @@ nsTableFrame::RegisterPositionedTablePart(nsIFrame* aFrame) tableFrame = static_cast(tableFrame->FirstContinuation()); // Retrieve the positioned parts array for this table. - FrameProperties props = tableFrame->Properties(); - FrameTArray* positionedParts = props.Get(PositionedTablePartArray()); + FrameTArray* positionedParts = tableFrame->GetProperty(PositionedTablePartArray()); // Lazily create the array if it doesn't exist yet. if (!positionedParts) { positionedParts = new FrameTArray; - props.Set(PositionedTablePartArray(), positionedParts); + tableFrame->SetProperty(PositionedTablePartArray(), positionedParts); } // Add this frame to the list. @@ -302,8 +301,7 @@ nsTableFrame::UnregisterPositionedTablePart(nsIFrame* aFrame, tableFrame = static_cast(tableFrame->FirstContinuation()); // Retrieve the positioned parts array for this table. - FrameProperties props = tableFrame->Properties(); - FrameTArray* positionedParts = props.Get(PositionedTablePartArray()); + FrameTArray* positionedParts = tableFrame->GetProperty(PositionedTablePartArray()); // Remove the frame. MOZ_ASSERT(positionedParts && positionedParts->Contains(aFrame), @@ -1992,7 +1990,7 @@ nsTableFrame::FixupPositionedTableParts(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, const ReflowInput& aReflowInput) { - FrameTArray* positionedParts = Properties().Get(PositionedTablePartArray()); + FrameTArray* positionedParts = GetProperty(PositionedTablePartArray()); if (!positionedParts) { return; } @@ -2653,13 +2651,18 @@ nsTableFrame::GetUsedMargin() const NS_DECLARE_FRAME_PROPERTY_DELETABLE(TableBCProperty, BCPropertyData) BCPropertyData* -nsTableFrame::GetBCProperty(bool aCreateIfNecessary) const +nsTableFrame::GetBCProperty() const { - FrameProperties props = Properties(); - BCPropertyData* value = props.Get(TableBCProperty()); - if (!value && aCreateIfNecessary) { + return GetProperty(TableBCProperty()); +} + +BCPropertyData* +nsTableFrame::GetOrCreateBCProperty() +{ + BCPropertyData* value = GetProperty(TableBCProperty()); + if (!value) { value = new BCPropertyData(); - props.Set(TableBCProperty(), value); + SetProperty(TableBCProperty(), value); } return value; @@ -4103,7 +4106,7 @@ nsTableFrame::AddBCDamageArea(const TableArea& aValue) SetNeedToCalcBCBorders(true); // Get the property - BCPropertyData* value = GetBCProperty(true); + BCPropertyData* value = GetOrCreateBCProperty(); if (value) { #ifdef DEBUG VerifyNonNegativeDamageRect(value->mDamageArea); @@ -4143,7 +4146,7 @@ nsTableFrame::SetFullBCDamageArea() SetNeedToCalcBCBorders(true); - BCPropertyData* value = GetBCProperty(true); + BCPropertyData* value = GetOrCreateBCProperty(); if (value) { value->mDamageArea = TableArea(0, 0, GetColCount(), GetRowCount()); } @@ -4310,7 +4313,7 @@ BCMapCellInfo::BCMapCellInfo(nsTableFrame* aTableFrame) : mTableFrame(aTableFrame) , mNumTableRows(aTableFrame->GetRowCount()) , mNumTableCols(aTableFrame->GetColCount()) - , mTableBCData(mTableFrame->Properties().Get(TableBCProperty())) + , mTableBCData(mTableFrame->GetProperty(TableBCProperty())) , mTableWM(aTableFrame->StyleContext()) { ResetCellInfo(); diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h index a78625339..7e56c28c1 100644 --- a/layout/tables/nsTableFrame.h +++ b/layout/tables/nsTableFrame.h @@ -809,7 +809,8 @@ protected: void SetBorderCollapse(bool aValue); - BCPropertyData* GetBCProperty(bool aCreateIfNecessary = false) const; + BCPropertyData* GetBCProperty() const; + BCPropertyData* GetOrCreateBCProperty(); void SetFullBCDamageArea(); void CalcBCBorders(); diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp index 81b5d6699..1b6051ef2 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -978,7 +978,7 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext, // MovePositionBy does internally. (This codepath should really // be merged into the else below if we can.) nsMargin* computedOffsetProp = - kidFrame->Properties().Get(nsIFrame::ComputedOffsetProperty()); + kidFrame->GetProperty(nsIFrame::ComputedOffsetProperty()); // Bug 975644: a position:sticky kid can end up with a null // property value here. LogicalMargin computedOffsets(wm, computedOffsetProp ? @@ -1417,16 +1417,14 @@ nsTableRowFrame::SetUnpaginatedBSize(nsPresContext* aPresContext, nscoord aValue) { NS_ASSERTION(!GetPrevInFlow(), "program error"); - // Get the property - aPresContext->PropertyTable()-> - Set(this, RowUnpaginatedHeightProperty(), aValue); + // Set the property + SetProperty(RowUnpaginatedHeightProperty(), aValue); } nscoord nsTableRowFrame::GetUnpaginatedBSize() { - FrameProperties props = FirstInFlow()->Properties(); - return props.Get(RowUnpaginatedHeightProperty()); + return GetProperty(RowUnpaginatedHeightProperty()); } void nsTableRowFrame::SetContinuousBCBorderWidth(LogicalSide aForSide, diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 60596f12b..8f014b204 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -1910,7 +1910,7 @@ nsTableRowGroupFrame::ClearRowCursor() } RemoveStateBits(NS_ROWGROUP_HAS_ROW_CURSOR); - Properties().Delete(RowCursorProperty()); + DeleteProperty(RowCursorProperty()); } nsTableRowGroupFrame::FrameCursorData* @@ -1934,7 +1934,7 @@ nsTableRowGroupFrame::SetupRowCursor() FrameCursorData* data = new FrameCursorData(); if (!data) return nullptr; - Properties().Set(RowCursorProperty(), data); + SetProperty(RowCursorProperty(), data); AddStateBits(NS_ROWGROUP_HAS_ROW_CURSOR); return data; } @@ -1946,7 +1946,7 @@ nsTableRowGroupFrame::GetFirstRowContaining(nscoord aY, nscoord* aOverflowAbove) return nullptr; } - FrameCursorData* property = Properties().Get(RowCursorProperty()); + FrameCursorData* property = GetProperty(RowCursorProperty()); uint32_t cursorIndex = property->mCursorIndex; uint32_t frameCount = property->mFrames.Length(); if (cursorIndex >= frameCount) diff --git a/layout/tables/nsTableWrapperFrame.cpp b/layout/tables/nsTableWrapperFrame.cpp index e44652a73..f0b6d1512 100644 --- a/layout/tables/nsTableWrapperFrame.cpp +++ b/layout/tables/nsTableWrapperFrame.cpp @@ -246,7 +246,7 @@ nsTableWrapperFrame::InitChildReflowInput(nsPresContext& aPresContext, } // Propagate our stored CB size if present, minus any margins. if (!HasAnyStateBits(NS_FRAME_OUT_OF_FLOW)) { - LogicalSize* cb = Properties().Get(GridItemCBSizeProperty()); + LogicalSize* cb = GetProperty(GridItemCBSizeProperty()); if (cb) { cbSize.emplace(*cb); *cbSize -= aReflowInput.ComputedLogicalMargin().Size(wm); @@ -953,7 +953,7 @@ nsTableWrapperFrame::Reflow(nsPresContext* aPresContext, // for the table frame if we are bsize constrained and the caption is above // or below the inner table. Also reduce the CB size that we store for // our children in case we're a grid item, by the same amount. - LogicalSize* cbSize = Properties().Get(GridItemCBSizeProperty()); + LogicalSize* cbSize = GetProperty(GridItemCBSizeProperty()); if (NS_UNCONSTRAINEDSIZE != aOuterRI.AvailableBSize() || cbSize) { nscoord captionBSize = 0; nscoord captionISize = 0; diff --git a/layout/xul/nsBox.cpp b/layout/xul/nsBox.cpp index f7ec5fead..787758b15 100644 --- a/layout/xul/nsBox.cpp +++ b/layout/xul/nsBox.cpp @@ -144,10 +144,9 @@ nsBox::BeginXULLayout(nsBoxLayoutState& aState) // Another copy-over from ReflowInput. // Since we are in reflow, we don't need to store these properties anymore. - FrameProperties props = Properties(); - props.Delete(UsedBorderProperty()); - props.Delete(UsedPaddingProperty()); - props.Delete(UsedMarginProperty()); + DeleteProperty(UsedBorderProperty()); + DeleteProperty(UsedPaddingProperty()); + DeleteProperty(UsedMarginProperty()); #ifdef DEBUG_LAYOUT PropagateDebug(aState); diff --git a/layout/xul/nsMenuFrame.cpp b/layout/xul/nsMenuFrame.cpp index ea968fab5..67fcdbe43 100644 --- a/layout/xul/nsMenuFrame.cpp +++ b/layout/xul/nsMenuFrame.cpp @@ -273,7 +273,7 @@ nsMenuFrame::GetPopupList() const if (!HasPopup()) { return nullptr; } - nsFrameList* prop = Properties().Get(PopupListProperty()); + nsFrameList* prop = GetProperty(PopupListProperty()); NS_ASSERTION(prop && prop->GetLength() == 1 && prop->FirstChild()->GetType() == nsGkAtoms::menuPopupFrame, "popup list should have exactly one nsMenuPopupFrame"); @@ -284,7 +284,7 @@ void nsMenuFrame::DestroyPopupList() { NS_ASSERTION(HasPopup(), "huh?"); - nsFrameList* prop = Properties().Remove(PopupListProperty()); + nsFrameList* prop = RemoveProperty(PopupListProperty()); NS_ASSERTION(prop && prop->IsEmpty(), "popup list must exist and be empty when destroying"); RemoveStateBits(NS_STATE_MENU_HAS_POPUP_LIST); @@ -300,7 +300,7 @@ nsMenuFrame::SetPopupFrame(nsFrameList& aFrameList) // Remove the frame from the list and store it in a nsFrameList* property. aFrameList.RemoveFrame(popupFrame); nsFrameList* popupList = new (PresContext()->PresShell()) nsFrameList(popupFrame, popupFrame); - Properties().Set(PopupListProperty(), popupList); + SetProperty(PopupListProperty(), popupList); AddStateBits(NS_STATE_MENU_HAS_POPUP_LIST); break; } -- cgit v1.2.3