forked from mirrors/gecko-dev
Bug 1309552 - Specify buffer size when freeing data in AllocPolicy, r=waldo.
--HG-- extra : rebase_source : f4e2d9f8831cf41c19d592ce252e87161f32250b
This commit is contained in:
parent
9624bb7849
commit
f6b8e6f81c
14 changed files with 54 additions and 37 deletions
|
|
@ -40,7 +40,7 @@ class SystemAllocPolicy
|
||||||
template <typename T> T* pod_realloc(T* p, size_t oldSize, size_t newSize) {
|
template <typename T> T* pod_realloc(T* p, size_t oldSize, size_t newSize) {
|
||||||
return maybe_pod_realloc<T>(p, oldSize, newSize);
|
return maybe_pod_realloc<T>(p, oldSize, newSize);
|
||||||
}
|
}
|
||||||
void free_(void* p) { js_free(p); }
|
template <typename T> void free_(T* p, size_t numElems = 0) { js_free(p); }
|
||||||
void reportAllocOverflow() const {}
|
void reportAllocOverflow() const {}
|
||||||
bool checkSimulatedOOM() const {
|
bool checkSimulatedOOM() const {
|
||||||
return !js::oom::ShouldFailWithOOM();
|
return !js::oom::ShouldFailWithOOM();
|
||||||
|
|
@ -119,7 +119,8 @@ class TempAllocPolicy
|
||||||
return p2;
|
return p2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_(void* p) {
|
template <typename T>
|
||||||
|
void free_(T* p, size_t numElems = 0) {
|
||||||
js_free(p);
|
js_free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -161,7 +162,7 @@ class ZoneAllocPolicy
|
||||||
template <typename T> inline T* pod_calloc(size_t numElems);
|
template <typename T> inline T* pod_calloc(size_t numElems);
|
||||||
template <typename T> inline T* pod_realloc(T* p, size_t oldSize, size_t newSize);
|
template <typename T> inline T* pod_realloc(T* p, size_t oldSize, size_t newSize);
|
||||||
|
|
||||||
void free_(void* p) { js_free(p); }
|
template <typename T> void free_(T* p, size_t numElems = 0) { js_free(p); }
|
||||||
void reportAllocOverflow() const {}
|
void reportAllocOverflow() const {}
|
||||||
|
|
||||||
MOZ_MUST_USE bool checkSimulatedOOM() const {
|
MOZ_MUST_USE bool checkSimulatedOOM() const {
|
||||||
|
|
|
||||||
|
|
@ -1319,7 +1319,7 @@ class HashTable : private AllocPolicy
|
||||||
Entry* end = oldTable + capacity;
|
Entry* end = oldTable + capacity;
|
||||||
for (Entry* e = oldTable; e < end; ++e)
|
for (Entry* e = oldTable; e < end; ++e)
|
||||||
e->~Entry();
|
e->~Entry();
|
||||||
alloc.free_(oldTable);
|
alloc.free_(oldTable, capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -1587,7 +1587,7 @@ class HashTable : private AllocPolicy
|
||||||
}
|
}
|
||||||
|
|
||||||
// All entries have been destroyed, no need to destroyTable.
|
// All entries have been destroyed, no need to destroyTable.
|
||||||
this->free_(oldTable);
|
this->free_(oldTable, oldCap);
|
||||||
return Rehashed;
|
return Rehashed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1033,7 +1033,8 @@ class LifoAllocPolicy
|
||||||
T* pod_realloc(T* p, size_t oldSize, size_t newSize) {
|
T* pod_realloc(T* p, size_t oldSize, size_t newSize) {
|
||||||
return maybe_pod_realloc<T>(p, oldSize, newSize);
|
return maybe_pod_realloc<T>(p, oldSize, newSize);
|
||||||
}
|
}
|
||||||
void free_(void* p) {
|
template <typename T>
|
||||||
|
void free_(T* p, size_t numElems) {
|
||||||
}
|
}
|
||||||
void reportAllocOverflow() const {
|
void reportAllocOverflow() const {
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,7 @@ class OrderedHashTable
|
||||||
uint32_t capacity = uint32_t(buckets * fillFactor());
|
uint32_t capacity = uint32_t(buckets * fillFactor());
|
||||||
Data* dataAlloc = alloc.template pod_malloc<Data>(capacity);
|
Data* dataAlloc = alloc.template pod_malloc<Data>(capacity);
|
||||||
if (!dataAlloc) {
|
if (!dataAlloc) {
|
||||||
alloc.free_(tableAlloc);
|
alloc.free_(tableAlloc, buckets);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -142,8 +142,8 @@ class OrderedHashTable
|
||||||
|
|
||||||
~OrderedHashTable() {
|
~OrderedHashTable() {
|
||||||
forEachRange<Range::onTableDestroyed>();
|
forEachRange<Range::onTableDestroyed>();
|
||||||
alloc.free_(hashTable);
|
alloc.free_(hashTable, hashBuckets());
|
||||||
freeData(data, dataLength);
|
freeData(data, dataLength, dataCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the number of elements in the table. */
|
/* Return the number of elements in the table. */
|
||||||
|
|
@ -248,7 +248,9 @@ class OrderedHashTable
|
||||||
if (dataLength != 0) {
|
if (dataLength != 0) {
|
||||||
Data** oldHashTable = hashTable;
|
Data** oldHashTable = hashTable;
|
||||||
Data* oldData = data;
|
Data* oldData = data;
|
||||||
|
uint32_t oldHashBuckets = hashBuckets();
|
||||||
uint32_t oldDataLength = dataLength;
|
uint32_t oldDataLength = dataLength;
|
||||||
|
uint32_t oldDataCapacity = dataCapacity;
|
||||||
|
|
||||||
hashTable = nullptr;
|
hashTable = nullptr;
|
||||||
if (!init()) {
|
if (!init()) {
|
||||||
|
|
@ -257,8 +259,8 @@ class OrderedHashTable
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc.free_(oldHashTable);
|
alloc.free_(oldHashTable, oldHashBuckets);
|
||||||
freeData(oldData, oldDataLength);
|
freeData(oldData, oldDataLength, oldDataCapacity);
|
||||||
forEachRange<&Range::onClear>();
|
forEachRange<&Range::onClear>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -630,9 +632,9 @@ class OrderedHashTable
|
||||||
(--p)->~Data();
|
(--p)->~Data();
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeData(Data* data, uint32_t length) {
|
void freeData(Data* data, uint32_t length, uint32_t capacity) {
|
||||||
destroyData(data, length);
|
destroyData(data, length);
|
||||||
alloc.free_(data);
|
alloc.free_(data, capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
Data* lookup(const Lookup& l, HashNumber h) {
|
Data* lookup(const Lookup& l, HashNumber h) {
|
||||||
|
|
@ -704,7 +706,7 @@ class OrderedHashTable
|
||||||
uint32_t newCapacity = uint32_t(newHashBuckets * fillFactor());
|
uint32_t newCapacity = uint32_t(newHashBuckets * fillFactor());
|
||||||
Data* newData = alloc.template pod_malloc<Data>(newCapacity);
|
Data* newData = alloc.template pod_malloc<Data>(newCapacity);
|
||||||
if (!newData) {
|
if (!newData) {
|
||||||
alloc.free_(newHashTable);
|
alloc.free_(newHashTable, newHashBuckets);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -720,8 +722,8 @@ class OrderedHashTable
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(wp == newData + liveCount);
|
MOZ_ASSERT(wp == newData + liveCount);
|
||||||
|
|
||||||
alloc.free_(hashTable);
|
alloc.free_(hashTable, hashBuckets());
|
||||||
freeData(data, dataLength);
|
freeData(data, dataLength, dataCapacity);
|
||||||
|
|
||||||
hashTable = newHashTable;
|
hashTable = newHashTable;
|
||||||
data = newData;
|
data = newData;
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,8 @@ class JitAllocPolicy
|
||||||
T* pod_realloc(T* ptr, size_t oldSize, size_t newSize) {
|
T* pod_realloc(T* ptr, size_t oldSize, size_t newSize) {
|
||||||
return maybe_pod_realloc<T>(ptr, oldSize, newSize);
|
return maybe_pod_realloc<T>(ptr, oldSize, newSize);
|
||||||
}
|
}
|
||||||
void free_(void* p) {
|
template <typename T>
|
||||||
|
void free_(T* p, size_t numElems = 0) {
|
||||||
}
|
}
|
||||||
void reportAllocOverflow() const {
|
void reportAllocOverflow() const {
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -244,7 +244,8 @@ public:
|
||||||
return static_cast<T*>(moz_xrealloc(aPtr, aNewSize * sizeof(T)));
|
return static_cast<T*>(moz_xrealloc(aPtr, aNewSize * sizeof(T)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_(void* aPtr)
|
template <typename T>
|
||||||
|
void free_(T* aPtr, size_t aNumElems = 0)
|
||||||
{
|
{
|
||||||
free_impl(aPtr);
|
free_impl(aPtr);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,8 @@ public:
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_(void* aPtr) { gMallocTable.free(aPtr); }
|
template <typename T>
|
||||||
|
static void free_(T* aPtr, size_t aSize = 0) { gMallocTable.free(aPtr); }
|
||||||
|
|
||||||
static char* strdup_(const char* aStr)
|
static char* strdup_(const char* aStr)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,11 @@ namespace mozilla {
|
||||||
* - template <typename T> T* pod_realloc(T*, size_t, size_t)
|
* - template <typename T> T* pod_realloc(T*, size_t, size_t)
|
||||||
* Responsible for OOM reporting when null is returned. The old allocation
|
* Responsible for OOM reporting when null is returned. The old allocation
|
||||||
* size is passed in, in addition to the new allocation size requested.
|
* size is passed in, in addition to the new allocation size requested.
|
||||||
* - void free_(void*)
|
* - template <typename T> void free_(T*, size_t)
|
||||||
|
* The capacity passed in must match the old allocation size.
|
||||||
|
* - template <typename T> void free_(T*)
|
||||||
|
* Frees a buffer without knowing its allocated size. This might not be
|
||||||
|
* implemented by allocation policies that need the allocation size.
|
||||||
* - void reportAllocOverflow() const
|
* - void reportAllocOverflow() const
|
||||||
* Called on allocation overflow (that is, an allocation implicitly tried
|
* Called on allocation overflow (that is, an allocation implicitly tried
|
||||||
* to allocate more than the available memory space -- think allocating an
|
* to allocate more than the available memory space -- think allocating an
|
||||||
|
|
@ -114,7 +118,8 @@ public:
|
||||||
return maybe_pod_realloc<T>(aPtr, aOldSize, aNewSize);
|
return maybe_pod_realloc<T>(aPtr, aOldSize, aNewSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_(void* aPtr)
|
template <typename T>
|
||||||
|
void free_(T* aPtr, size_t aNumElems = 0)
|
||||||
{
|
{
|
||||||
free(aPtr);
|
free(aPtr);
|
||||||
}
|
}
|
||||||
|
|
@ -175,7 +180,8 @@ public:
|
||||||
MOZ_CRASH("NeverAllocPolicy::pod_realloc");
|
MOZ_CRASH("NeverAllocPolicy::pod_realloc");
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_(void* aPtr)
|
template <typename T>
|
||||||
|
void free_(T* aPtr, size_t aNumElems = 0)
|
||||||
{
|
{
|
||||||
MOZ_CRASH("NeverAllocPolicy::free_");
|
MOZ_CRASH("NeverAllocPolicy::free_");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ class BufferList : private AllocPolicy
|
||||||
{
|
{
|
||||||
if (mOwning) {
|
if (mOwning) {
|
||||||
for (Segment& segment : mSegments) {
|
for (Segment& segment : mSegments) {
|
||||||
this->free_(segment.mData);
|
this->free_(segment.mData, segment.mCapacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mSegments.clear();
|
mSegments.clear();
|
||||||
|
|
@ -367,7 +367,7 @@ class BufferList : private AllocPolicy
|
||||||
MOZ_ASSERT(mOwning);
|
MOZ_ASSERT(mOwning);
|
||||||
|
|
||||||
if (!mSegments.append(Segment(aData, aSize, aCapacity))) {
|
if (!mSegments.append(Segment(aData, aSize, aCapacity))) {
|
||||||
this->free_(aData);
|
this->free_(aData, aCapacity);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
mSize += aSize;
|
mSize += aSize;
|
||||||
|
|
@ -394,7 +394,7 @@ private:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (!mSegments.append(Segment(data, aSize, aCapacity))) {
|
if (!mSegments.append(Segment(data, aSize, aCapacity))) {
|
||||||
this->free_(data);
|
this->free_(data, aCapacity);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
mSize += aSize;
|
mSize += aSize;
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ public:
|
||||||
Segment* segment;
|
Segment* segment;
|
||||||
while ((segment = mSegments.popFirst())) {
|
while ((segment = mSegments.popFirst())) {
|
||||||
segment->~Segment();
|
segment->~Segment();
|
||||||
this->free_(segment);
|
this->free_(segment, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -218,7 +218,7 @@ public:
|
||||||
if (!last->Length()) {
|
if (!last->Length()) {
|
||||||
mSegments.popLast();
|
mSegments.popLast();
|
||||||
last->~Segment();
|
last->~Segment();
|
||||||
this->free_(last);
|
this->free_(last, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -251,7 +251,7 @@ public:
|
||||||
// Destroying the segment destroys all elements contained therein.
|
// Destroying the segment destroys all elements contained therein.
|
||||||
mSegments.popLast();
|
mSegments.popLast();
|
||||||
last->~Segment();
|
last->~Segment();
|
||||||
this->free_(last);
|
this->free_(last, 1);
|
||||||
|
|
||||||
MOZ_ASSERT(aNumElements >= segmentLen);
|
MOZ_ASSERT(aNumElements >= segmentLen);
|
||||||
aNumElements -= segmentLen;
|
aNumElements -= segmentLen;
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ struct VectorImpl
|
||||||
new_(dst, std::move(*src));
|
new_(dst, std::move(*src));
|
||||||
}
|
}
|
||||||
VectorImpl::destroy(aV.beginNoCheck(), aV.endNoCheck());
|
VectorImpl::destroy(aV.beginNoCheck(), aV.endNoCheck());
|
||||||
aV.free_(aV.mBegin);
|
aV.free_(aV.mBegin, aV.mTail.mCapacity);
|
||||||
aV.mBegin = newbuf;
|
aV.mBegin = newbuf;
|
||||||
/* aV.mLength is unchanged. */
|
/* aV.mLength is unchanged. */
|
||||||
aV.mTail.mCapacity = aNewCap;
|
aV.mTail.mCapacity = aNewCap;
|
||||||
|
|
@ -244,7 +244,7 @@ struct VectorImpl<T, N, AP, true>
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!aV.mLength) {
|
if (!aV.mLength) {
|
||||||
aV.free_(aV.mBegin);
|
aV.free_(aV.mBegin, aV.mTail.mCapacity);
|
||||||
aV.mBegin = aV.inlineStorage();
|
aV.mBegin = aV.inlineStorage();
|
||||||
aV.mTail.mCapacity = aV.kInlineCapacity;
|
aV.mTail.mCapacity = aV.kInlineCapacity;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
@ -927,7 +927,7 @@ Vector<T, N, AP>::~Vector()
|
||||||
MOZ_REENTRANCY_GUARD_ET_AL;
|
MOZ_REENTRANCY_GUARD_ET_AL;
|
||||||
Impl::destroy(beginNoCheck(), endNoCheck());
|
Impl::destroy(beginNoCheck(), endNoCheck());
|
||||||
if (!usingInlineStorage()) {
|
if (!usingInlineStorage()) {
|
||||||
this->free_(beginNoCheck());
|
this->free_(beginNoCheck(), mTail.mCapacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1238,7 +1238,7 @@ Vector<T, N, AP>::clearAndFree()
|
||||||
if (usingInlineStorage()) {
|
if (usingInlineStorage()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->free_(beginNoCheck());
|
this->free_(beginNoCheck(), mTail.mCapacity);
|
||||||
mBegin = inlineStorage();
|
mBegin = inlineStorage();
|
||||||
mTail.mCapacity = kInlineCapacity;
|
mTail.mCapacity = kInlineCapacity;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
@ -1511,7 +1511,7 @@ Vector<T, N, AP>::replaceRawBuffer(T* aP, size_t aLength, size_t aCapacity)
|
||||||
/* Destroy what we have. */
|
/* Destroy what we have. */
|
||||||
Impl::destroy(beginNoCheck(), endNoCheck());
|
Impl::destroy(beginNoCheck(), endNoCheck());
|
||||||
if (!usingInlineStorage()) {
|
if (!usingInlineStorage()) {
|
||||||
this->free_(beginNoCheck());
|
this->free_(beginNoCheck(), mTail.mCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Take in the new buffer. */
|
/* Take in the new buffer. */
|
||||||
|
|
@ -1526,7 +1526,7 @@ Vector<T, N, AP>::replaceRawBuffer(T* aP, size_t aLength, size_t aCapacity)
|
||||||
mTail.mCapacity = kInlineCapacity;
|
mTail.mCapacity = kInlineCapacity;
|
||||||
Impl::moveConstruct(mBegin, aP, aP + aLength);
|
Impl::moveConstruct(mBegin, aP, aP + aLength);
|
||||||
Impl::destroy(aP, aP + aLength);
|
Impl::destroy(aP, aP + aLength);
|
||||||
this->free_(aP);
|
this->free_(aP, aCapacity);
|
||||||
} else {
|
} else {
|
||||||
mBegin = aP;
|
mBegin = aP;
|
||||||
mLength = aLength;
|
mLength = aLength;
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,8 @@ public:
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_(void* aPtr) { free(aPtr); }
|
template <typename T>
|
||||||
|
void free_(T* aPtr, size_t aNumElems = 0) { free(aPtr); }
|
||||||
|
|
||||||
void reportAllocOverflow() const {}
|
void reportAllocOverflow() const {}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,8 @@ public:
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_(void* aPtr) { free(aPtr); }
|
template <typename T>
|
||||||
|
void free_(T* aPtr, size_t aNumElems = 0) { free(aPtr); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// We want to test Append(), which is fallible and marked with
|
// We want to test Append(), which is fallible and marked with
|
||||||
|
|
|
||||||
|
|
@ -165,11 +165,13 @@ class MOZ_STACK_CLASS SprintfState final : private mozilla::PrintfTarget, privat
|
||||||
if (off + len >= mMaxlen) {
|
if (off + len >= mMaxlen) {
|
||||||
/* Grow the buffer */
|
/* Grow the buffer */
|
||||||
newlen = mMaxlen + ((len > 32) ? len : 32);
|
newlen = mMaxlen + ((len > 32) ? len : 32);
|
||||||
newbase = static_cast<char*>(this->maybe_pod_realloc(mBase, mMaxlen, newlen));
|
newbase = this->template maybe_pod_malloc<char>(newlen);
|
||||||
if (!newbase) {
|
if (!newbase) {
|
||||||
/* Ran out of memory */
|
/* Ran out of memory */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
memcpy(newbase, mBase, mMaxlen);
|
||||||
|
this->free_(mBase);
|
||||||
mBase = newbase;
|
mBase = newbase;
|
||||||
mMaxlen = newlen;
|
mMaxlen = newlen;
|
||||||
mCur = mBase + off;
|
mCur = mBase + off;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue