Пример #1
0
MiscContainer*
nsAttrValue::ClearMiscContainer()
{
  MiscContainer* cont = nullptr;
  if (BaseType() == eOtherBase) {
    cont = GetMiscContainer();
    if (cont->IsRefCounted() && cont->mValue.mRefCount > 1) {
      // This MiscContainer is shared, we need a new one.
      NS_RELEASE(cont);

      cont = new MiscContainer;
      SetPtrValueAndType(cont, eOtherBase);
    }
    else {
      switch (cont->mType) {
        case eCSSStyleRule:
        {
          MOZ_ASSERT(cont->mValue.mRefCount == 1);
          cont->Release();
          cont->Evict();
          NS_RELEASE(cont->mValue.mCSSStyleRule);
          break;
        }
        case eURL:
        {
          NS_RELEASE(cont->mValue.mURL);
          break;
        }
        case eImage:
        {
          NS_RELEASE(cont->mValue.mImage);
          break;
        }
        case eAtomArray:
        {
          delete cont->mValue.mAtomArray;
          break;
        }
        case eIntMarginValue:
        {
          delete cont->mValue.mIntMargin;
          break;
        }
        default:
        {
          break;
        }
      }
    }
    ResetMiscAtomOrString();
  }
  else {
    ResetIfSet();
  }

  return cont;
}
Пример #2
0
size_t
nsAttrValue::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
{
  size_t n = 0;

  switch (BaseType()) {
    case eStringBase:
    {
      nsStringBuffer* str = static_cast<nsStringBuffer*>(GetPtr());
      n += str ? str->SizeOfIncludingThisIfUnshared(aMallocSizeOf) : 0;
      break;
    }
    case eOtherBase:
    {
      MiscContainer* container = GetMiscContainer();
      if (!container) {
        break;
      }
      if (container->IsRefCounted() && container->mValue.mRefCount > 1) {
        // We don't report this MiscContainer at all in order to avoid
        // twice-reporting it.
        // TODO DMD, bug 1027551 - figure out how to report this ref-counted
        // object just once.
        break;
      }
      n += aMallocSizeOf(container);

      void* otherPtr = MISC_STR_PTR(container);
      // We only count the size of the object pointed by otherPtr if it's a
      // string. When it's an atom, it's counted separatly.
      if (otherPtr &&
          static_cast<ValueBaseType>(container->mStringBits & NS_ATTRVALUE_BASETYPE_MASK) == eStringBase) {
        nsStringBuffer* str = static_cast<nsStringBuffer*>(otherPtr);
        n += str ? str->SizeOfIncludingThisIfUnshared(aMallocSizeOf) : 0;
      }

      if (Type() == eCSSDeclaration && container->mValue.mCSSDeclaration) {
        // TODO: mCSSDeclaration might be owned by another object which
        //       would make us count them twice, bug 677493.
        // Bug 1281964: For ServoDeclarationBlock if we do measure we'll
        // need a way to call the Servo heap_size_of function.
        //n += container->mCSSDeclaration->SizeOfIncludingThis(aMallocSizeOf);
      } else if (Type() == eAtomArray && container->mValue.mAtomArray) {
        // Don't measure each nsIAtom, they are measured separatly.
        n += container->mValue.mAtomArray->ShallowSizeOfIncludingThis(aMallocSizeOf);
      }
      break;
    }
    case eAtomBase:    // Atoms are counted separately.
    case eIntegerBase: // The value is in mBits, nothing to do.
      break;
  }

  return n;
}
Пример #3
0
void
nsAttrValue::Reset()
{
  switch(BaseType()) {
    case eStringBase:
    {
      nsStringBuffer* str = static_cast<nsStringBuffer*>(GetPtr());
      if (str) {
        str->Release();
      }

      break;
    }
    case eOtherBase:
    {
      MiscContainer* cont = GetMiscContainer();
      if (cont->IsRefCounted() && cont->mValue.mRefCount > 1) {
        NS_RELEASE(cont);
        break;
      }

      delete ClearMiscContainer();

      break;
    }
    case eAtomBase:
    {
      nsIAtom* atom = GetAtomValue();
      NS_RELEASE(atom);

      break;
    }
    case eIntegerBase:
    {
      break;
    }
  }

  mBits = 0;
}
Пример #4
0
void
nsAttrValue::SetTo(const nsAttrValue& aOther)
{
  if (this == &aOther) {
    return;
  }

  switch (aOther.BaseType()) {
    case eStringBase:
    {
      ResetIfSet();
      nsStringBuffer* str = static_cast<nsStringBuffer*>(aOther.GetPtr());
      if (str) {
        str->AddRef();
        SetPtrValueAndType(str, eStringBase);
      }
      return;
    }
    case eOtherBase:
    {
      break;
    }
    case eAtomBase:
    {
      ResetIfSet();
      nsIAtom* atom = aOther.GetAtomValue();
      NS_ADDREF(atom);
      SetPtrValueAndType(atom, eAtomBase);
      return;
    }
    case eIntegerBase:
    {
      ResetIfSet();
      mBits = aOther.mBits;
      return;      
    }
  }

  MiscContainer* otherCont = aOther.GetMiscContainer();
  if (otherCont->IsRefCounted()) {
    delete ClearMiscContainer();
    NS_ADDREF(otherCont);
    SetPtrValueAndType(otherCont, eOtherBase);
    return;
  }

  MiscContainer* cont = EnsureEmptyMiscContainer();
  switch (otherCont->mType) {
    case eInteger:
    {
      cont->mValue.mInteger = otherCont->mValue.mInteger;
      break;
    }
    case eEnum:
    {
      cont->mValue.mEnumValue = otherCont->mValue.mEnumValue;
      break;
    }
    case ePercent:
    {
      cont->mValue.mPercent = otherCont->mValue.mPercent;
      break;
    }
    case eColor:
    {
      cont->mValue.mColor = otherCont->mValue.mColor;
      break;
    }
    case eCSSStyleRule:
    {
      MOZ_CRASH("These should be refcounted!");
    }
    case eURL:
    {
      NS_ADDREF(cont->mValue.mURL = otherCont->mValue.mURL);
      break;
    }
    case eImage:
    {
      NS_ADDREF(cont->mValue.mImage = otherCont->mValue.mImage);
      break;
    }
    case eAtomArray:
    {
      if (!EnsureEmptyAtomArray() ||
          !GetAtomArrayValue()->AppendElements(*otherCont->mValue.mAtomArray)) {
        Reset();
        return;
      }
      break;
    }
    case eDoubleValue:
    {
      cont->mDoubleValue = otherCont->mDoubleValue;
      break;
    }
    case eIntMarginValue:
    {
      if (otherCont->mValue.mIntMargin)
        cont->mValue.mIntMargin =
          new nsIntMargin(*otherCont->mValue.mIntMargin);
      break;
    }
    default:
    {
      if (IsSVGType(otherCont->mType)) {
        // All SVG types are just pointers to classes and will therefore have
        // the same size so it doesn't really matter which one we assign
        cont->mValue.mSVGAngle = otherCont->mValue.mSVGAngle;
      } else {
        NS_NOTREACHED("unknown type stored in MiscContainer");
      }
      break;
    }
  }

  void* otherPtr = MISC_STR_PTR(otherCont);
  if (otherPtr) {
    if (static_cast<ValueBaseType>(otherCont->mStringBits & NS_ATTRVALUE_BASETYPE_MASK) ==
        eStringBase) {
      static_cast<nsStringBuffer*>(otherPtr)->AddRef();
    } else {
      static_cast<nsIAtom*>(otherPtr)->AddRef();
    }
    cont->mStringBits = otherCont->mStringBits;
  }
  // Note, set mType after switch-case, otherwise EnsureEmptyAtomArray doesn't
  // work correctly.
  cont->mType = otherCont->mType;
}