Пример #1
0
NS_IMETHODIMP
nsSupportsArray::Compact(void)
{
#if DEBUG_SUPPORTSARRAY
  PRUint32 oldArraySize = mArraySize;
#endif
  if ((mArraySize != mCount) && (kAutoArraySize < mArraySize)) {
    nsISupports** oldArray = mArray;
    if (mCount <= kAutoArraySize) {
      mArray = mAutoArray;
      mArraySize = kAutoArraySize;
    }
    else {
      mArray = new nsISupports*[mCount];
      if (!mArray) {
        mArray = oldArray;
        return NS_OK;
      }
      mArraySize = mCount;
    }
#if DEBUG_SUPPORTSARRAY
    if (oldArray == mArray &&
        oldArray != &(mAutoArray[0])) // can't happen without use of realloc
      ADD_TO_STATS(GrowInPlace,oldArraySize);
    if (oldArray != &(mAutoArray[0]))
      ADD_TO_STATS(AllocedOfSize,mArraySize*sizeof(mArray[0]));
#endif
    ::memcpy(mArray, oldArray, mCount * sizeof(nsISupports*));
    delete[] oldArray;
  }
  return NS_OK;
}
Пример #2
0
PRBool nsSupportsArray::GrowArrayBy(PRInt32 aGrowBy)
{
  // We have to grow the array. Grow by kGrowArrayBy slots if we're smaller
  // than kLinearThreshold bytes, or a power of two if we're larger.
  // This is much more efficient with most memory allocators, especially
  // if it's very large, or of the allocator is binned.
  if (aGrowBy < kGrowArrayBy)
    aGrowBy = kGrowArrayBy;

  PRUint32 newCount = mArraySize + aGrowBy;  // Minimum increase
  PRUint32 newSize = sizeof(mArray[0]) * newCount;

  if (newSize >= (PRUint32) kLinearThreshold)
  {
    // newCount includes enough space for at least kGrowArrayBy new slots.
    // Select the next power-of-two size in bytes above that if newSize is
    // not a power of two.
    if (newSize & (newSize - 1))
      newSize = PR_BIT(PR_CeilingLog2(newSize));

    newCount = newSize / sizeof(mArray[0]);
  }
  // XXX This would be far more efficient in many allocators if we used
  // XXX PR_Realloc(), etc
  nsISupports** oldArray = mArray;

  mArray = new nsISupports*[newCount];
  if (!mArray) {                    // ran out of memory
    mArray = oldArray;
    return PR_FALSE;
  }
  mArraySize = newCount;

#if DEBUG_SUPPORTSARRAY
  if (oldArray == mArray) // can't happen without use of realloc
    ADD_TO_STATS(GrowInPlace,mCount);
  ADD_TO_STATS(AllocedOfSize,mArraySize*sizeof(mArray[0]));
  if (mArraySize > mMaxSize)
  {
    ADD_TO_STATS(NumberOfSize,mArraySize*sizeof(mArray[0]));
    if (oldArray != &(mAutoArray[0]))
      SUB_FROM_STATS(NumberOfSize,mCount*sizeof(mArray[0]));
    mMaxSize = mArraySize;
  }
#endif
  if (oldArray) {                   // need to move old data
    if (0 < mCount) {
      ::memcpy(mArray, oldArray, mCount * sizeof(nsISupports*));
    }
    if (oldArray != &(mAutoArray[0])) {
      delete[] oldArray;
    }
  }

  return PR_TRUE;
}
Пример #3
0
nsAutoVoidArray::nsAutoVoidArray()
  : nsVoidArray()
{
  // Don't need to clear it.  Some users just call ReplaceElementAt(),
  // but we'll clear it at that time if needed to save CPU cycles.
#if DEBUG_VOIDARRAY
  mIsAuto = PR_TRUE;
  ADD_TO_STATS(MaxAuto,0);
#endif
  ResetToAutoBuffer();
}
Пример #4
0
nsSupportsArray::SizeTo(int32_t aSize)
{
#if DEBUG_SUPPORTSARRAY
  uint32_t oldArraySize = mArraySize;
#endif
  NS_ASSERTION(aSize >= 0, "negative aSize!");

  // XXX for aSize < mCount we could resize to mCount
  if (mArraySize == (uint32_t)aSize || (uint32_t)aSize < mCount) {
    return true;  // nothing to do
  }

  // switch back to autoarray if possible
  nsISupports** oldArray = mArray;
  if ((uint32_t)aSize <= kAutoArraySize) {
    mArray = mAutoArray;
    mArraySize = kAutoArraySize;
  } else {
    mArray = new nsISupports*[aSize];
    if (!mArray) {
      mArray = oldArray;
      return false;
    }
    mArraySize = aSize;
  }
#if DEBUG_SUPPORTSARRAY
  if (oldArray == mArray &&
      oldArray != &(mAutoArray[0])) { // can't happen without use of realloc
    ADD_TO_STATS(GrowInPlace, oldArraySize);
  }
  if (oldArray != &(mAutoArray[0])) {
    ADD_TO_STATS(AllocedOfSize, mArraySize * sizeof(mArray[0]));
  }
#endif
  ::memcpy(mArray, oldArray, mCount * sizeof(nsISupports*));
  if (oldArray != mAutoArray) {
    delete[] oldArray;
  }

  return true;
}
Пример #5
0
nsSupportsArray::nsSupportsArray()
{
  mArray = mAutoArray;
  mArraySize = kAutoArraySize;
  mCount = 0;
#if DEBUG_SUPPORTSARRAY
  mMaxCount = 0;
  mMaxSize = 0;
  ADD_TO_STATS(NumberOfSize,kAutoArraySize*sizeof(mArray[0]));
  MaxElements[0]++;
#endif
}
Пример #6
0
nsVoidArray::nsVoidArray()
  : mImpl(nsnull)
{
  MOZ_COUNT_CTOR(nsVoidArray);
#if DEBUG_VOIDARRAY
  mMaxCount = 0;
  mMaxSize = 0;
  mIsAuto = PR_FALSE;
  ADD_TO_STATS(NumberOfSize,0);
  MaxElements[0]++;
#endif
}
Пример #7
0
nsSupportsArray::SizeTo(PRInt32 aSize)
{
#if DEBUG_SUPPORTSARRAY
  PRUint32 oldArraySize = mArraySize;
#endif
  NS_ASSERTION(aSize >= 0, "negative aSize!");

  // XXX for aSize < mCount we could resize to mCount
  if (mArraySize == (PRUint32) aSize || (PRUint32) aSize < mCount)
    return PR_TRUE;     // nothing to do

  // switch back to autoarray if possible
  nsISupports** oldArray = mArray;
  if ((PRUint32) aSize <= kAutoArraySize) {
    mArray = mAutoArray;
    mArraySize = kAutoArraySize;
  }
  else {
    mArray = new nsISupports*[aSize];
    if (!mArray) {
      mArray = oldArray;
      return PR_FALSE;
    }
    mArraySize = aSize;
  }
#if DEBUG_SUPPORTSARRAY
  if (oldArray == mArray &&
      oldArray != &(mAutoArray[0])) // can't happen without use of realloc
    ADD_TO_STATS(GrowInPlace,oldArraySize);
  if (oldArray != &(mAutoArray[0]))
    ADD_TO_STATS(AllocedOfSize,mArraySize*sizeof(mArray[0]));
#endif
  ::memcpy(mArray, oldArray, mCount * sizeof(nsISupports*));
  if (oldArray != mAutoArray)
    delete[] oldArray;

  return PR_TRUE;
}
Пример #8
0
// This does all allocation/reallocation of the array.
// It also will compact down to N - good for things that might grow a lot
// at times,  but usually are smaller, like JS deferred GC releases.
PRBool nsVoidArray::SizeTo(PRInt32 aSize)
{
  PRUint32 oldsize = GetArraySize();
  PRBool isOwner = IsArrayOwner();
  PRBool hasAuto = HasAutoBuffer();

  if (aSize == (PRInt32) oldsize)
    return PR_TRUE; // no change

  if (aSize <= 0)
  {
    // free the array if allocated
    if (mImpl)
    {
      if (isOwner)
      {
        free(reinterpret_cast<char *>(mImpl));
        if (hasAuto) {
          static_cast<nsAutoVoidArray*>(this)->ResetToAutoBuffer();
        }
        else {
          mImpl = nsnull;
        }
      }
      else
      {
        mImpl->mCount = 0; // nsAutoVoidArray
      }
    }
    return PR_TRUE;
  }

  if (mImpl && isOwner)
  {
    // We currently own an array impl. Resize it appropriately.
    if (aSize < mImpl->mCount)
    {
      // XXX Note: we could also just resize to mCount
      return PR_TRUE;  // can't make it that small, ignore request
    }

    char* bytes = (char *) realloc(mImpl,SIZEOF_IMPL(aSize));
    Impl* newImpl = reinterpret_cast<Impl*>(bytes);
    if (!newImpl)
      return PR_FALSE;

#if DEBUG_VOIDARRAY
    if (mImpl == newImpl)
      ADD_TO_STATS(GrowInPlace,oldsize);
    ADD_TO_STATS(AllocedOfSize,SIZEOF_IMPL(aSize));
    if (aSize > mMaxSize)
    {
      ADD_TO_STATS(NumberOfSize,SIZEOF_IMPL(aSize));
      if (oldsize)
        SUB_FROM_STATS(NumberOfSize,oldsize);
      mMaxSize = aSize;
      if (mIsAuto)
      {
        ADD_TO_STATS(MaxAuto,SIZEOF_IMPL(aSize));
        SUB_FROM_STATS(MaxAuto,oldsize);
      }
    }
#endif
    SetArray(newImpl, aSize, newImpl->mCount, PR_TRUE, hasAuto);
    return PR_TRUE;
  }

  if ((PRUint32) aSize < oldsize) {
    // No point in allocating if it won't free the current Impl anyway.
    return PR_TRUE;
  }

  // just allocate an array
  // allocate the exact size requested
  char* bytes = (char *) malloc(SIZEOF_IMPL(aSize));
  Impl* newImpl = reinterpret_cast<Impl*>(bytes);
  if (!newImpl)
    return PR_FALSE;

#if DEBUG_VOIDARRAY
  ADD_TO_STATS(AllocedOfSize,SIZEOF_IMPL(aSize));
  if (aSize > mMaxSize)
  {
    ADD_TO_STATS(NumberOfSize,SIZEOF_IMPL(aSize));
    if (oldsize && !mImpl)
      SUB_FROM_STATS(NumberOfSize,oldsize);
    mMaxSize = aSize;
  }
#endif
  if (mImpl)
  {
#if DEBUG_VOIDARRAY
    ADD_TO_STATS(MaxAuto,SIZEOF_IMPL(aSize));
    SUB_FROM_STATS(MaxAuto,0);
    SUB_FROM_STATS(NumberOfSize,0);
    mIsAuto = PR_TRUE;
#endif
    // We must be growing an nsAutoVoidArray - copy since we didn't
    // realloc.
    memcpy(newImpl->mArray, mImpl->mArray,
                  mImpl->mCount * sizeof(mImpl->mArray[0]));
  }

  SetArray(newImpl, aSize, mImpl ? mImpl->mCount : 0, PR_TRUE, hasAuto);
  // no memset; handled later in ReplaceElementAt if needed
  return PR_TRUE;
}
Пример #9
0
// This does all allocation/reallocation of the array.
// It also will compact down to N - good for things that might grow a lot
// at times,  but usually are smaller, like JS deferred GC releases.
bool nsVoidArray::SizeTo(int32_t aSize)
{
  uint32_t oldsize = GetArraySize();

  if (aSize == (int32_t) oldsize)
    return true; // no change

  if (aSize <= 0)
  {
    // free the array if allocated
    if (mImpl)
    {
      free(reinterpret_cast<char *>(mImpl));
      mImpl = nullptr;
    }
    return true;
  }

  if (mImpl)
  {
    // We currently own an array impl. Resize it appropriately.
    if (aSize < mImpl->mCount)
    {
      // XXX Note: we could also just resize to mCount
      return true;  // can't make it that small, ignore request
    }

    char* bytes = (char *) realloc(mImpl,SIZEOF_IMPL(aSize));
    Impl* newImpl = reinterpret_cast<Impl*>(bytes);
    if (!newImpl)
      return false;

#if DEBUG_VOIDARRAY
    if (mImpl == newImpl)
      ADD_TO_STATS(GrowInPlace,oldsize);
    ADD_TO_STATS(AllocedOfSize,SIZEOF_IMPL(aSize));
    if (aSize > mMaxSize)
    {
      ADD_TO_STATS(NumberOfSize,SIZEOF_IMPL(aSize));
      if (oldsize)
        SUB_FROM_STATS(NumberOfSize,oldsize);
      mMaxSize = aSize;
      if (mIsAuto)
      {
        ADD_TO_STATS(MaxAuto,SIZEOF_IMPL(aSize));
        SUB_FROM_STATS(MaxAuto,oldsize);
      }
    }
#endif
    SetArray(newImpl, aSize, newImpl->mCount);
    return true;
  }

  if ((uint32_t) aSize < oldsize) {
    // No point in allocating if it won't free the current Impl anyway.
    return true;
  }

  // just allocate an array
  // allocate the exact size requested
  char* bytes = (char *) malloc(SIZEOF_IMPL(aSize));
  Impl* newImpl = reinterpret_cast<Impl*>(bytes);
  if (!newImpl)
    return false;

#if DEBUG_VOIDARRAY
  ADD_TO_STATS(AllocedOfSize,SIZEOF_IMPL(aSize));
  if (aSize > mMaxSize)
  {
    ADD_TO_STATS(NumberOfSize,SIZEOF_IMPL(aSize));
    if (oldsize && !mImpl)
      SUB_FROM_STATS(NumberOfSize,oldsize);
    mMaxSize = aSize;
  }
#endif
  if (mImpl)
  {
#if DEBUG_VOIDARRAY
    ADD_TO_STATS(MaxAuto,SIZEOF_IMPL(aSize));
    SUB_FROM_STATS(MaxAuto,0);
    SUB_FROM_STATS(NumberOfSize,0);
    mIsAuto = true;
#endif
    // We must be growing an nsAutoVoidArray - copy since we didn't
    // realloc.
    memcpy(newImpl->mArray, mImpl->mArray,
                  mImpl->mCount * sizeof(mImpl->mArray[0]));
  }

  SetArray(newImpl, aSize, mImpl ? mImpl->mCount : 0);
  // no memset; handled later in ReplaceElementAt if needed
  return true;
}