Commit 7fb1b2fe authored by Daniel Holbert's avatar Daniel Holbert Committed by Pier Angelo Vendrame
Browse files

Bug 1742738 part 2: Tighten up tearoff-table removal for DOMSVGLength....

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
parent 1620cb64
Loading
Loading
Loading
Loading
+18 −4
Original line number Diff line number Diff line
@@ -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)) {
  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();
+8 −1
Original line number Diff line number Diff line
@@ -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 {

@@ -198,6 +198,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)