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:
Daniel Holbert
2025-04-22 06:17:57 +00:00
parent ca478a9264
commit 9708fc025a
2 changed files with 26 additions and 5 deletions

View File

@@ -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();

View File

@@ -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)