Bug 773296 - Part 16: Add a ref-counted list nsCSSValue unit and use it for tranform lists; hold a strong reference to one on nsStyleDisplay. r=dbaron

This adds a new eCSSUnit_SharedList type for nsCSSValue, which is a
reference counted object that contains an nsCSSValueList.  We need this
so that nsStyleDisplay::mSpecifiedTransform can hold a strong reference
to a specified transform list value.  When 'transform' is specified
using a variable reference, the resulting nsCSSValue does not stick
around in the Declaration object, so we wouldn't be guaranteed that
it lives long enough for nsStyleDisplay to keep referencing it.
This commit is contained in:
Cameron McCormack
2013-12-12 13:09:44 +11:00
parent 615ac0aa43
commit 2d29cdbe6b
11 changed files with 165 additions and 26 deletions

View File

@@ -162,6 +162,10 @@ nsCSSValue::nsCSSValue(const nsCSSValue& aCopy)
else if (eCSSUnit_ListDep == mUnit) {
mValue.mListDependent = aCopy.mValue.mListDependent;
}
else if (eCSSUnit_SharedList == mUnit) {
mValue.mSharedList = aCopy.mValue.mSharedList;
mValue.mSharedList->AddRef();
}
else if (eCSSUnit_PairList == mUnit) {
mValue.mPairList = aCopy.mValue.mPairList;
mValue.mPairList->AddRef();
@@ -232,6 +236,9 @@ bool nsCSSValue::operator==(const nsCSSValue& aOther) const
else if (eCSSUnit_List == mUnit) {
return *mValue.mList == *aOther.mValue.mList;
}
else if (eCSSUnit_SharedList == mUnit) {
return *mValue.mSharedList == *aOther.mValue.mSharedList;
}
else if (eCSSUnit_PairList == mUnit) {
return *mValue.mPairList == *aOther.mValue.mPairList;
}
@@ -315,6 +322,8 @@ void nsCSSValue::DoReset()
mValue.mRect->Release();
} else if (eCSSUnit_List == mUnit) {
mValue.mList->Release();
} else if (eCSSUnit_SharedList == mUnit) {
mValue.mSharedList->Release();
} else if (eCSSUnit_PairList == mUnit) {
mValue.mPairList->Release();
}
@@ -513,6 +522,14 @@ nsCSSValueList* nsCSSValue::SetListValue()
return mValue.mList;
}
void nsCSSValue::SetSharedListValue(nsCSSValueSharedList* aList)
{
Reset();
mUnit = eCSSUnit_SharedList;
mValue.mSharedList = aList;
mValue.mSharedList->AddRef();
}
void nsCSSValue::SetDependentListValue(nsCSSValueList* aList)
{
Reset();
@@ -1198,6 +1215,8 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
GetRectValue().AppendToString(aProperty, aResult);
} else if (eCSSUnit_List == unit || eCSSUnit_ListDep == unit) {
GetListValue()->AppendToString(aProperty, aResult);
} else if (eCSSUnit_SharedList == unit) {
GetSharedListValue()->AppendToString(aProperty, aResult);
} else if (eCSSUnit_PairList == unit || eCSSUnit_PairListDep == unit) {
switch (aProperty) {
case eCSSProperty_font_feature_settings:
@@ -1258,6 +1277,7 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
case eCSSUnit_Rect: break;
case eCSSUnit_List: break;
case eCSSUnit_ListDep: break;
case eCSSUnit_SharedList: break;
case eCSSUnit_PairList: break;
case eCSSUnit_PairListDep: break;
@@ -1384,6 +1404,12 @@ nsCSSValue::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
case eCSSUnit_ListDep:
break;
// SharedList
case eCSSUnit_SharedList:
// Makes more sense not to measure, since it most cases the list
// will be shared.
break;
// PairList
case eCSSUnit_PairList:
n += mValue.mPairList->SizeOfIncludingThis(aMallocSizeOf);
@@ -1522,6 +1548,41 @@ nsCSSValueList_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) co
return n;
}
// --- nsCSSValueSharedList -----------------
nsCSSValueSharedList::~nsCSSValueSharedList()
{
MOZ_COUNT_DTOR(nsCSSValueSharedList);
if (mHead) {
NS_CSS_DELETE_LIST_MEMBER(nsCSSValueList, mHead, mNext);
delete mHead;
}
}
void
nsCSSValueSharedList::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
{
if (mHead) {
mHead->AppendToString(aProperty, aResult);
}
}
bool
nsCSSValueSharedList::operator==(const nsCSSValueSharedList& aOther) const
{
return !mHead == !aOther.mHead &&
(!mHead || *mHead == *aOther.mHead);
}
size_t
nsCSSValueSharedList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{
size_t n = 0;
n += aMallocSizeOf(this);
n += mHead->SizeOfIncludingThis(aMallocSizeOf);
return n;
}
// --- nsCSSRect -----------------
nsCSSRect::nsCSSRect(void)