Bug 1742738 part 2: Tighten up tearoff-table removal for DOMSVGLength. r=firefox-svg-reviewers,longsonr
I'm doing this one in its own patch since it's slightly more subtle than the others, due to the existence of multiple instance-creation codepaths, some of which generate instances that never end up in the tearoff table. Differential Revision: https://phabricator.services.mozilla.com/D246063
This commit is contained in:
@@ -51,6 +51,7 @@ DOMSVGLength::DOMSVGLength(DOMSVGLengthList* aList, uint8_t aAttrEnum,
|
||||
mListIndex(aListIndex),
|
||||
mAttrEnum(aAttrEnum),
|
||||
mIsAnimValItem(aIsAnimValItem),
|
||||
mIsInTearoffTable(false),
|
||||
mUnit(SVGLength_Binding::SVG_LENGTHTYPE_NUMBER) {
|
||||
MOZ_ASSERT(aList, "bad arg");
|
||||
MOZ_ASSERT(mAttrEnum == aAttrEnum, "bitfield too small");
|
||||
@@ -63,6 +64,7 @@ DOMSVGLength::DOMSVGLength()
|
||||
mListIndex(0),
|
||||
mAttrEnum(0),
|
||||
mIsAnimValItem(false),
|
||||
mIsInTearoffTable(false),
|
||||
mUnit(SVGLength_Binding::SVG_LENGTHTYPE_NUMBER) {}
|
||||
|
||||
DOMSVGLength::DOMSVGLength(SVGAnimatedLength* aVal, SVGElement* aSVGElement,
|
||||
@@ -71,6 +73,7 @@ DOMSVGLength::DOMSVGLength(SVGAnimatedLength* aVal, SVGElement* aSVGElement,
|
||||
mListIndex(0),
|
||||
mAttrEnum(aVal->mAttrEnum),
|
||||
mIsAnimValItem(aAnimVal),
|
||||
mIsInTearoffTable(false),
|
||||
mUnit(SVGLength_Binding::SVG_LENGTHTYPE_NUMBER) {
|
||||
MOZ_ASSERT(aVal, "bad arg");
|
||||
MOZ_ASSERT(mAttrEnum == aVal->mAttrEnum, "bitfield too small");
|
||||
@@ -88,22 +91,33 @@ void DOMSVGLength::CleanupWeakRefs() {
|
||||
|
||||
// Similarly, we must update the tearoff table to remove its (non-owning)
|
||||
// pointer to mVal.
|
||||
if (nsCOMPtr<SVGElement> svg = do_QueryInterface(mOwner)) {
|
||||
auto& table = mIsAnimValItem ? sAnimSVGLengthTearOffTable
|
||||
: sBaseSVGLengthTearOffTable;
|
||||
table.RemoveTearoff(svg->GetAnimatedLength(mAttrEnum));
|
||||
if (mIsInTearoffTable) {
|
||||
nsCOMPtr<SVGElement> svg = do_QueryInterface(mOwner);
|
||||
MOZ_ASSERT(svg,
|
||||
"We need our svgElement reference in order to remove "
|
||||
"ourselves from tearoff table...");
|
||||
if (MOZ_LIKELY(svg)) {
|
||||
auto& table = mIsAnimValItem ? sAnimSVGLengthTearOffTable
|
||||
: sBaseSVGLengthTearOffTable;
|
||||
table.RemoveTearoff(svg->GetAnimatedLength(mAttrEnum));
|
||||
mIsInTearoffTable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<DOMSVGLength> DOMSVGLength::GetTearOff(SVGAnimatedLength* aVal,
|
||||
SVGElement* aSVGElement,
|
||||
bool aAnimVal) {
|
||||
MOZ_ASSERT(aVal && aSVGElement, "Expecting non-null aVal and aSVGElement");
|
||||
MOZ_ASSERT(aVal == aSVGElement->GetAnimatedLength(aVal->mAttrEnum),
|
||||
"Mismatched aVal/SVGElement?");
|
||||
auto& table =
|
||||
aAnimVal ? sAnimSVGLengthTearOffTable : sBaseSVGLengthTearOffTable;
|
||||
RefPtr<DOMSVGLength> domLength = table.GetTearoff(aVal);
|
||||
if (!domLength) {
|
||||
domLength = new DOMSVGLength(aVal, aSVGElement, aAnimVal);
|
||||
table.AddTearoff(aVal, domLength);
|
||||
domLength->mIsInTearoffTable = true;
|
||||
}
|
||||
|
||||
return domLength.forget();
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#define MOZ_SVG_LIST_INDEX_BIT_COUNT 22 // supports > 4 million list items
|
||||
#define MOZ_SVG_LIST_INDEX_BIT_COUNT 21 // supports > 2 million list items
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@@ -204,6 +204,13 @@ class DOMSVGLength final : public nsWrapperCache {
|
||||
uint32_t mAttrEnum : 4; // supports up to 16 attributes
|
||||
uint32_t mIsAnimValItem : 1;
|
||||
|
||||
// Tracks whether we're in the tearoff table. Initialized to false in the
|
||||
// ctor, but then immediately set to true after we're added to the table
|
||||
// (unless we're an instance created via 'Copy()'; those never get added to
|
||||
// the table). Updated to false when we're removed from the table (at which
|
||||
// point we're being destructed or soon-to-be destructed).
|
||||
uint32_t mIsInTearoffTable : 1;
|
||||
|
||||
// The following members are only used when we're not in a list:
|
||||
uint32_t mUnit : 5; // can handle 31 units (the 10 SVG 1.1 units + rem, vw,
|
||||
// vh, wm, calc + future additions)
|
||||
|
||||
Reference in New Issue
Block a user