Backed out 2 changesets (bug 1591366) for causing failures in table-grid-item-dynamic-004.html CLOSED TREE

Backed out changeset 19be43686dc0 (bug 1591366)
Backed out changeset a2b6f6abda6e (bug 1591366)
This commit is contained in:
Noemi Erli 2021-09-18 02:42:58 +03:00
Родитель 91aa2e2b9c
Коммит bb5d736641
6 изменённых файлов: 62 добавлений и 205 удалений

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

@ -64,7 +64,7 @@ struct FramePropertyDescriptorUntyped {
template <typename T>
struct FramePropertyDescriptor : public FramePropertyDescriptorUntyped {
typedef void Destructor(T* aPropertyValue);
typedef void DestructorWithFrame(const nsIFrame* aFrame, T* aPropertyValue);
typedef void DestructorWithFrame(const nsIFrame* aaFrame, T* aPropertyValue);
template <Destructor Dtor>
static constexpr const FramePropertyDescriptor<T> NewWithDestructor() {
@ -98,9 +98,9 @@ struct FramePropertyDescriptor : public FramePropertyDescriptorUntyped {
};
// SmallValueHolder<T> is a placeholder intended to be used as template
// argument of FramePropertyDescriptor for types which can fit directly into our
// internal value slot (i.e. types that can fit in 64 bits). This class should
// never be defined, so that we won't use it for unexpected purpose by mistake.
// 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 <typename T>
class SmallValueHolder;
@ -121,6 +121,12 @@ struct FramePropertyTypeHelper<SmallValueHolder<T>> {
* 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:
@ -150,8 +156,8 @@ class FrameProperties {
template <typename T>
void Set(Descriptor<T> aProperty, PropertyType<T> aValue,
const nsIFrame* aFrame) {
uint64_t v = ReinterpretHelper<T>::ToInternalValue(aValue);
SetInternal(aProperty, v, aFrame);
void* ptr = ReinterpretHelper<T>::ToPointer(aValue);
SetInternal(aProperty, ptr, aFrame);
}
/**
@ -160,8 +166,8 @@ class FrameProperties {
template <typename T>
void Add(Descriptor<T> aProperty, PropertyType<T> aValue) {
MOZ_ASSERT(!Has(aProperty), "duplicate frame property");
uint64_t v = ReinterpretHelper<T>::ToInternalValue(aValue);
AddInternal(aProperty, v);
void* ptr = ReinterpretHelper<T>::ToPointer(aValue);
AddInternal(aProperty, ptr);
}
/**
@ -198,8 +204,8 @@ class FrameProperties {
template <typename T>
PropertyType<T> Get(Descriptor<T> aProperty,
bool* aFoundResult = nullptr) const {
uint64_t v = GetInternal(aProperty, aFoundResult);
return ReinterpretHelper<T>::FromInternalValue(v);
void* ptr = GetInternal(aProperty, aFoundResult);
return ReinterpretHelper<T>::FromPointer(ptr);
}
/**
@ -215,8 +221,8 @@ class FrameProperties {
*/
template <typename T>
PropertyType<T> Take(Descriptor<T> aProperty, bool* aFoundResult = nullptr) {
uint64_t v = TakeInternal(aProperty, aFoundResult);
return ReinterpretHelper<T>::FromInternalValue(v);
void* ptr = TakeInternal(aProperty, aFoundResult);
return ReinterpretHelper<T>::FromPointer(ptr);
}
/**
@ -273,63 +279,62 @@ class FrameProperties {
FrameProperties(const FrameProperties&) = delete;
FrameProperties& operator=(const FrameProperties&) = delete;
inline void SetInternal(UntypedDescriptor aProperty, uint64_t aValue,
inline void SetInternal(UntypedDescriptor aProperty, void* aValue,
const nsIFrame* aFrame);
inline void AddInternal(UntypedDescriptor aProperty, uint64_t aValue);
inline void AddInternal(UntypedDescriptor aProperty, void* aValue);
inline uint64_t GetInternal(UntypedDescriptor aProperty,
bool* aFoundResult) const;
inline void* GetInternal(UntypedDescriptor aProperty,
bool* aFoundResult) const;
inline uint64_t TakeInternal(UntypedDescriptor aProperty, bool* aFoundResult);
inline void* TakeInternal(UntypedDescriptor aProperty, bool* aFoundResult);
inline void RemoveInternal(UntypedDescriptor aProperty,
const nsIFrame* aFrame);
template <typename T>
struct ReinterpretHelper {
static_assert(sizeof(PropertyType<T>) <= sizeof(uint64_t),
"size of the value must never be larger than 64 bits");
static_assert(sizeof(PropertyType<T>) <= sizeof(void*),
"size of the value must never be larger than a pointer");
static uint64_t ToInternalValue(PropertyType<T> aValue) {
uint64_t v = 0;
memcpy(&v, &aValue, sizeof(aValue));
return v;
static void* ToPointer(PropertyType<T> aValue) {
void* ptr = nullptr;
memcpy(&ptr, &aValue, sizeof(aValue));
return ptr;
}
static PropertyType<T> FromInternalValue(uint64_t aInternalValue) {
static PropertyType<T> FromPointer(void* aPtr) {
PropertyType<T> value;
memcpy(&value, &aInternalValue, sizeof(value));
memcpy(&value, &aPtr, sizeof(value));
return value;
}
};
template <typename T>
struct ReinterpretHelper<T*> {
static void* ToPointer(T* aValue) { return static_cast<void*>(aValue); }
static T* FromPointer(void* aPtr) { return static_cast<T*>(aPtr); }
};
/**
* Stores a property descriptor/value pair.
*/
struct PropertyValue {
PropertyValue() : mProperty(nullptr), mValue(0) {}
PropertyValue(UntypedDescriptor aProperty, uint64_t aValue)
PropertyValue() : mProperty(nullptr), mValue(nullptr) {}
PropertyValue(UntypedDescriptor aProperty, void* aValue)
: mProperty(aProperty), mValue(aValue) {}
// NOTE: This function converts our internal 64-bit-integer representation
// to a pointer-type representation. This is lossy on 32-bit systems, but it
// should be fine, as long as we *only* do this in cases where we're sure
// that the stored property-value is in fact a pointer. And we should have
// that assurance, since only pointer-typed frame properties are expected to
// have a destructor
void DestroyValueFor(const nsIFrame* aFrame) {
if (mProperty->mDestructor) {
mProperty->mDestructor(
ReinterpretHelper<void*>::FromInternalValue(mValue));
mProperty->mDestructor(mValue);
} else if (mProperty->mDestructorWithFrame) {
mProperty->mDestructorWithFrame(
aFrame, ReinterpretHelper<void*>::FromInternalValue(mValue));
mProperty->mDestructorWithFrame(aFrame, mValue);
}
}
UntypedDescriptor mProperty;
uint64_t mValue;
void* mValue;
};
/**
@ -352,29 +357,28 @@ class FrameProperties {
nsTArray<PropertyValue> mProperties;
};
inline uint64_t FrameProperties::GetInternal(UntypedDescriptor aProperty,
bool* aFoundResult) const {
inline void* FrameProperties::GetInternal(UntypedDescriptor aProperty,
bool* aFoundResult) const {
MOZ_ASSERT(aProperty, "Null property?");
return mProperties.ApplyIf(
aProperty, 0, PropertyComparator(),
[&aFoundResult](const PropertyValue& aPV) -> uint64_t {
[&aFoundResult](const PropertyValue& aPV) -> void* {
if (aFoundResult) {
*aFoundResult = true;
}
return aPV.mValue;
},
[&aFoundResult]() -> uint64_t {
[&aFoundResult]() -> void* {
if (aFoundResult) {
*aFoundResult = false;
}
return 0;
return nullptr;
});
}
inline void FrameProperties::SetInternal(UntypedDescriptor aProperty,
uint64_t aValue,
const nsIFrame* aFrame) {
void* aValue, const nsIFrame* aFrame) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aProperty, "Null property?");
@ -388,15 +392,15 @@ inline void FrameProperties::SetInternal(UntypedDescriptor aProperty,
}
inline void FrameProperties::AddInternal(UntypedDescriptor aProperty,
uint64_t aValue) {
void* aValue) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aProperty, "Null property?");
mProperties.AppendElement(PropertyValue(aProperty, aValue));
}
inline uint64_t FrameProperties::TakeInternal(UntypedDescriptor aProperty,
bool* aFoundResult) {
inline void* FrameProperties::TakeInternal(UntypedDescriptor aProperty,
bool* aFoundResult) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aProperty, "Null property?");
@ -405,14 +409,14 @@ inline uint64_t FrameProperties::TakeInternal(UntypedDescriptor aProperty,
if (aFoundResult) {
*aFoundResult = false;
}
return 0;
return nullptr;
}
if (aFoundResult) {
*aFoundResult = true;
}
uint64_t result = mProperties.Elements()[index].mValue;
void* result = mProperties.Elements()[index].mValue;
mProperties.RemoveElementAt(index);
return result;

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

@ -253,7 +253,7 @@ void nsContainerFrame::DestroyFrom(nsIFrame* aDestructRoot,
if (MOZ_UNLIKELY(!mProperties.IsEmpty())) {
using T = mozilla::FrameProperties::UntypedDescriptor;
bool hasO = false, hasOC = false, hasEOC = false, hasBackdrop = false;
mProperties.ForEach([&](const T& aProp, uint64_t) {
mProperties.ForEach([&](const T& aProp, void*) {
if (aProp == OverflowProperty()) {
hasO = true;
} else if (aProp == OverflowContainersProperty()) {
@ -332,24 +332,22 @@ void nsContainerFrame::GetChildLists(nsTArray<ChildList>* aLists) const {
mFrames.AppendIfNonempty(aLists, kPrincipalList);
using T = mozilla::FrameProperties::UntypedDescriptor;
mProperties.ForEach([this, aLists](const T& aProp, uint64_t aValue) {
mProperties.ForEach([this, aLists](const T& aProp, void* aValue) {
typedef const nsFrameList* L;
if (aProp == OverflowProperty()) {
reinterpret_cast<L>(aValue)->AppendIfNonempty(aLists, kOverflowList);
L(aValue)->AppendIfNonempty(aLists, kOverflowList);
} else if (aProp == OverflowContainersProperty()) {
MOZ_ASSERT(IsFrameOfType(nsIFrame::eCanContainOverflowContainers),
"found unexpected OverflowContainersProperty");
Unused << this; // silence clang -Wunused-lambda-capture in opt builds
reinterpret_cast<L>(aValue)->AppendIfNonempty(aLists,
kOverflowContainersList);
L(aValue)->AppendIfNonempty(aLists, kOverflowContainersList);
} else if (aProp == ExcessOverflowContainersProperty()) {
MOZ_ASSERT(IsFrameOfType(nsIFrame::eCanContainOverflowContainers),
"found unexpected ExcessOverflowContainersProperty");
Unused << this; // silence clang -Wunused-lambda-capture in opt builds
reinterpret_cast<L>(aValue)->AppendIfNonempty(
aLists, kExcessOverflowContainersList);
L(aValue)->AppendIfNonempty(aLists, kExcessOverflowContainersList);
} else if (aProp == BackdropProperty()) {
reinterpret_cast<L>(aValue)->AppendIfNonempty(aLists, kBackdropList);
L(aValue)->AppendIfNonempty(aLists, kBackdropList);
}
return true;
});

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

@ -49,8 +49,6 @@ using TrackListValue =
using TrackRepeat = StyleGenericTrackRepeat<LengthPercentage, StyleInteger>;
using NameList = StyleOwnedSlice<StyleCustomIdent>;
using SizingConstraint = nsGridContainerFrame::SizingConstraint;
using GridItemCachedBAxisMeasurement =
nsGridContainerFrame::CachedBAxisMeasurement;
static const int32_t kMaxLine = StyleMAX_GRID_LINE;
static const int32_t kMinLine = StyleMIN_GRID_LINE;
@ -5022,19 +5020,6 @@ static nscoord MeasuringReflow(nsIFrame* aChild,
nsIFrame::ReflowChildFlags::NoMoveFrame |
nsIFrame::ReflowChildFlags::NoSizeView |
nsIFrame::ReflowChildFlags::NoDeleteNextInFlowChild;
if (StaticPrefs::layout_css_grid_item_baxis_measurement_enabled()) {
bool found;
GridItemCachedBAxisMeasurement cachedMeasurement =
aChild->GetProperty(GridItemCachedBAxisMeasurement::Prop(), &found);
if (found && cachedMeasurement.IsValidFor(aChild, aCBSize)) {
childSize.BSize(wm) = cachedMeasurement.BSize();
nsContainerFrame::FinishReflowChild(aChild, pc, childSize, &childRI, wm,
LogicalPoint(wm), nsSize(), flags);
return cachedMeasurement.BSize();
}
}
parent->ReflowChild(aChild, pc, childSize, childRI, wm, LogicalPoint(wm),
nsSize(), flags, childStatus);
nsContainerFrame::FinishReflowChild(aChild, pc, childSize, &childRI, wm,
@ -5042,26 +5027,6 @@ static nscoord MeasuringReflow(nsIFrame* aChild,
#ifdef DEBUG
parent->RemoveProperty(nsContainerFrame::DebugReflowingWithInfiniteISize());
#endif
if (StaticPrefs::layout_css_grid_item_baxis_measurement_enabled()) {
bool found;
GridItemCachedBAxisMeasurement cachedMeasurement =
aChild->GetProperty(GridItemCachedBAxisMeasurement::Prop(), &found);
if (!found &&
GridItemCachedBAxisMeasurement::CanCacheMeasurement(aChild, aCBSize)) {
GridItemCachedBAxisMeasurement cachedMeasurement(aChild, aCBSize,
childSize.BSize(wm));
aChild->SetProperty(GridItemCachedBAxisMeasurement::Prop(),
cachedMeasurement);
} else if (found) {
if (GridItemCachedBAxisMeasurement::CanCacheMeasurement(aChild,
aCBSize)) {
cachedMeasurement.Update(aChild, aCBSize, childSize.BSize(wm));
} else {
aChild->RemoveProperty(GridItemCachedBAxisMeasurement::Prop());
}
}
}
return childSize.BSize(wm);
}
@ -8445,8 +8410,8 @@ nscoord nsGridContainerFrame::ReflowChildren(GridReflowInput& aState,
if (!child->IsPlaceholderFrame()) {
info = &aState.mGridItems[aState.mIter.ItemIndex()];
}
ReflowInFlowChild(child, info, aContainerSize, Nothing(), nullptr, aState,
aContentArea, aDesiredSize, aStatus);
ReflowInFlowChild(*aState.mIter, info, aContainerSize, Nothing(), nullptr,
aState, aContentArea, aDesiredSize, aStatus);
MOZ_ASSERT(aStatus.IsComplete(),
"child should be complete in unconstrained reflow");
}

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

@ -10,7 +10,6 @@
#define nsGridContainerFrame_h___
#include "mozilla/CSSOrderAwareFrameIterator.h"
#include "mozilla/MathAlgorithms.h"
#include "mozilla/Maybe.h"
#include "mozilla/HashTable.h"
#include "nsContainerFrame.h"
@ -535,104 +534,6 @@ class nsGridContainerFrame final : public nsContainerFrame {
// Our baselines, one per BaselineSharingGroup per axis.
PerLogicalAxis<PerBaseline<nscoord>> mBaseline;
public:
// A cached result for a grid item's block-axis measuring reflow. This
// cache prevents us from doing exponential reflows in cases of deeply
// nested grid frames.
//
// We store the cached value in the grid item's frame property table.
//
// We cache the following as a "key"
// - The size of the grid area in the item's inline axis
// - The item's block axis baseline padding
// ...and we cache the following as the "value",
// - The item's border-box BSize
class CachedBAxisMeasurement {
public:
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(Prop, CachedBAxisMeasurement)
CachedBAxisMeasurement(const nsIFrame* aFrame, const LogicalSize& aCBSize,
const nscoord aBSize)
: mKey(aFrame, aCBSize), mBSize(aBSize) {}
CachedBAxisMeasurement() = default;
bool IsValidFor(const nsIFrame* aFrame, const LogicalSize& aCBSize) const {
if (!CanCacheMeasurement(aFrame, aCBSize)) {
return false;
}
return mKey == Key(aFrame, aCBSize);
}
static bool CanCacheMeasurement(const nsIFrame* aFrame,
const LogicalSize& aCBSize) {
return Key::CanHash(aFrame, aCBSize);
}
nscoord BSize() const { return mBSize; }
void Update(const nsIFrame* aFrame, const LogicalSize& aCBSize,
const nscoord aBSize) {
MOZ_ASSERT(CanCacheMeasurement(aFrame, aCBSize));
mKey.mHashKey = Key::GenerateHash(aFrame, aCBSize);
mBSize = aBSize;
}
private:
struct Key {
// mHashKey is generated by combining these 2 variables together
// 1. The containing block size in the item's inline axis used
// for measuring reflow
// 2. The item's baseline padding property
uint32_t mHashKey;
Key() = default;
Key(const nsIFrame* aFrame, const LogicalSize& aCBSize) {
MOZ_ASSERT(CanHash(aFrame, aCBSize));
mHashKey = GenerateHash(aFrame, aCBSize);
}
void UpdateHash(const nsIFrame* aFrame, const LogicalSize& aCBSize) {
MOZ_ASSERT(CanHash(aFrame, aCBSize));
mHashKey = GenerateHash(aFrame, aCBSize);
}
static uint32_t GenerateHash(const nsIFrame* aFrame,
const LogicalSize& aCBSize) {
MOZ_ASSERT(CanHash(aFrame, aCBSize));
nscoord gridAreaISize = aCBSize.ISize(aFrame->GetWritingMode());
nscoord bBaselinePaddingProperty =
abs(aFrame->GetProperty(nsIFrame::BBaselinePadProperty()));
uint_fast8_t bitsNeededForISize = mozilla::FloorLog2(gridAreaISize) + 1;
return (gridAreaISize << (32 - bitsNeededForISize)) |
bBaselinePaddingProperty;
}
static bool CanHash(const nsIFrame* aFrame, const LogicalSize& aCBSize) {
uint_fast8_t bitsNeededForISize =
mozilla::FloorLog2(aCBSize.ISize(aFrame->GetWritingMode())) + 1;
uint_fast8_t bitsNeededForBBaselinePadding =
mozilla::FloorLog2(
abs(aFrame->GetProperty(nsIFrame::BBaselinePadProperty()))) +
1;
return bitsNeededForISize + bitsNeededForBBaselinePadding <= 32;
}
bool operator==(const Key& aOther) const {
return mHashKey == aOther.mHashKey;
}
};
Key mKey;
nscoord mBSize;
};
};
#endif /* nsGridContainerFrame_h___ */

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

@ -71,7 +71,6 @@
#include "nsInlineFrame.h"
#include "nsFrameSelection.h"
#include "nsGkAtoms.h"
#include "nsGridContainerFrame.h"
#include "nsCSSAnonBoxes.h"
#include "nsCanvasFrame.h"
@ -5751,10 +5750,6 @@ void nsIFrame::MarkIntrinsicISizesDirty() {
if (HasAnyStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT)) {
nsFontInflationData::MarkFontInflationDataTextDirty(this);
}
if (StaticPrefs::layout_css_grid_item_baxis_measurement_enabled()) {
RemoveProperty(nsGridContainerFrame::CachedBAxisMeasurement::Prop());
}
}
void nsIFrame::MarkSubtreeDirty() {

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

@ -6990,12 +6990,6 @@
mirror: always
rust: true
# Is support for caching an grid item's block axis measurement enabled?
- name: layout.css.grid-item-baxis-measurement.enabled
type: bool
value: @IS_NIGHTLY_BUILD@
mirror: always
# Is support for CSS masonry layout enabled?
- name: layout.css.grid-template-masonry-value.enabled
type: RelaxedAtomicBool