зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1033442 - Remove non-pod realloc from MallocProvider and AllocPolicy; r=jonco
This commit is contained in:
Родитель
529830df2e
Коммит
3353a9fb7c
|
@ -563,6 +563,16 @@ js_pod_calloc(size_t numElems)
|
|||
return (T *)js_calloc(numElems * sizeof(T));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static MOZ_ALWAYS_INLINE T *
|
||||
js_pod_realloc(T *prior, size_t oldSize, size_t newSize)
|
||||
{
|
||||
MOZ_ASSERT(!(oldSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value));
|
||||
if (newSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
|
||||
return nullptr;
|
||||
return (T *)js_realloc(prior, newSize * sizeof(T));
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
template<typename T>
|
||||
|
|
|
@ -529,11 +529,14 @@ class LifoAllocPolicy
|
|||
memset(p, 0, numElems * sizeof(T));
|
||||
return p;
|
||||
}
|
||||
void *realloc_(void *p, size_t oldBytes, size_t bytes) {
|
||||
void *n = malloc_(bytes);
|
||||
template <typename T>
|
||||
T *pod_realloc(T *p, size_t oldSize, size_t newSize) {
|
||||
if (newSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
|
||||
return nullptr;
|
||||
T *n = (T *)malloc_(newSize * sizeof(T));
|
||||
if (fb == Fallible && !n)
|
||||
return nullptr;
|
||||
memcpy(n, p, Min(oldBytes, bytes));
|
||||
memcpy(n, p, Min(oldSize * sizeof(T), newSize * sizeof(T)));
|
||||
return n;
|
||||
}
|
||||
void free_(void *p) {
|
||||
|
|
|
@ -585,16 +585,13 @@ ForkJoinNursery::reallocateSlots(JSObject *obj, HeapSlot *oldSlots,
|
|||
if (newCount & mozilla::tl::MulOverflowMask<sizeof(HeapSlot)>::value)
|
||||
return nullptr;
|
||||
|
||||
size_t oldSize = oldCount * sizeof(HeapSlot);
|
||||
size_t newSize = newCount * sizeof(HeapSlot);
|
||||
|
||||
if (!isInsideNewspace(obj)) {
|
||||
JS_ASSERT_IF(oldSlots, !isInsideNewspace(oldSlots));
|
||||
return static_cast<HeapSlot *>(cx_->realloc_(oldSlots, oldSize, newSize));
|
||||
return obj->zone()->pod_realloc<HeapSlot>(oldSlots, oldCount, newCount);
|
||||
}
|
||||
|
||||
if (!isInsideNewspace(oldSlots))
|
||||
return reallocateHugeSlots(oldSlots, oldSize, newSize);
|
||||
return reallocateHugeSlots(obj, oldSlots, oldCount, newCount);
|
||||
|
||||
// No-op if we're shrinking, we can't make use of the freed portion.
|
||||
if (newCount < oldCount)
|
||||
|
@ -604,6 +601,7 @@ ForkJoinNursery::reallocateSlots(JSObject *obj, HeapSlot *oldSlots,
|
|||
if (!newSlots)
|
||||
return nullptr;
|
||||
|
||||
size_t oldSize = oldCount * sizeof(HeapSlot);
|
||||
js_memcpy(newSlots, oldSlots, oldSize);
|
||||
return newSlots;
|
||||
}
|
||||
|
@ -650,9 +648,10 @@ ForkJoinNursery::allocateHugeSlots(size_t nslots)
|
|||
}
|
||||
|
||||
HeapSlot *
|
||||
ForkJoinNursery::reallocateHugeSlots(HeapSlot *oldSlots, uint32_t oldSize, uint32_t newSize)
|
||||
ForkJoinNursery::reallocateHugeSlots(JSObject *obj, HeapSlot *oldSlots,
|
||||
uint32_t oldCount, uint32_t newCount)
|
||||
{
|
||||
HeapSlot *newSlots = static_cast<HeapSlot *>(cx_->realloc_(oldSlots, oldSize, newSize));
|
||||
HeapSlot *newSlots = obj->zone()->pod_realloc<HeapSlot>(oldSlots, oldCount, newCount);
|
||||
if (!newSlots)
|
||||
return newSlots;
|
||||
|
||||
|
|
|
@ -210,7 +210,8 @@ class ForkJoinNursery
|
|||
// Reallocate an external slot array, unregister the old array and
|
||||
// register the new array. If the allocation fails then leave
|
||||
// everything unchanged.
|
||||
HeapSlot *reallocateHugeSlots(HeapSlot *oldSlots, uint32_t oldSize, uint32_t newSize);
|
||||
HeapSlot *reallocateHugeSlots(JSObject *obj, HeapSlot *oldSlots,
|
||||
uint32_t oldCount, uint32_t newCount);
|
||||
|
||||
// Walk the list of registered slot arrays and free them all.
|
||||
void sweepHugeSlots();
|
||||
|
|
|
@ -112,11 +112,15 @@ class IonAllocPolicy
|
|||
memset(p, 0, numElems * sizeof(T));
|
||||
return p;
|
||||
}
|
||||
void *realloc_(void *p, size_t oldBytes, size_t bytes) {
|
||||
void *n = malloc_(bytes);
|
||||
template <typename T>
|
||||
T *pod_realloc(T *p, size_t oldSize, size_t newSize) {
|
||||
MOZ_ASSERT(!(oldSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value));
|
||||
if (newSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
|
||||
return nullptr;
|
||||
T *n = (T *)malloc_(newSize * sizeof(T));
|
||||
if (!n)
|
||||
return n;
|
||||
memcpy(n, p, Min(oldBytes, bytes));
|
||||
memcpy(n, p, Min(oldSize * sizeof(T), newSize * sizeof(T)));
|
||||
return n;
|
||||
}
|
||||
void free_(void *p) {
|
||||
|
@ -135,13 +139,6 @@ class OldIonAllocPolicy
|
|||
void *malloc_(size_t bytes) {
|
||||
return GetIonContext()->temp->allocate(bytes);
|
||||
}
|
||||
void *realloc_(void *p, size_t oldBytes, size_t bytes) {
|
||||
void *n = malloc_(bytes);
|
||||
if (!n)
|
||||
return n;
|
||||
memcpy(n, p, Min(oldBytes, bytes));
|
||||
return n;
|
||||
}
|
||||
void free_(void *p) {
|
||||
}
|
||||
void reportAllocOverflow() const {
|
||||
|
|
|
@ -1054,7 +1054,7 @@ MPhi::reserveLength(size_t length)
|
|||
{
|
||||
// Initializes a new MPhi to have an Operand vector of at least the given
|
||||
// capacity. This permits use of addInput() instead of addInputSlow(), the
|
||||
// latter of which may call realloc_().
|
||||
// latter of which may call realloc().
|
||||
JS_ASSERT(numOperands() == 0);
|
||||
#if DEBUG
|
||||
capacity_ = length;
|
||||
|
|
|
@ -5250,7 +5250,7 @@ class MPhi MOZ_FINAL : public MDefinition, public InlineListNode<MPhi>
|
|||
// Use only if capacity has been reserved by reserveLength
|
||||
void addInput(MDefinition *ins);
|
||||
|
||||
// Appends a new input to the input vector. May call realloc_().
|
||||
// Appends a new input to the input vector. May call realloc().
|
||||
// Prefer reserveLength() and addInput() instead, where possible.
|
||||
bool addInputSlow(MDefinition *ins, bool *ptypeChange = nullptr);
|
||||
|
||||
|
|
|
@ -27,7 +27,9 @@ class SystemAllocPolicy
|
|||
public:
|
||||
void *malloc_(size_t bytes) { return js_malloc(bytes); }
|
||||
template <typename T> T *pod_calloc(size_t numElems) { return js_pod_calloc<T>(numElems); }
|
||||
void *realloc_(void *p, size_t oldBytes, size_t bytes) { return js_realloc(p, bytes); }
|
||||
template <typename T> T *pod_realloc(T *p, size_t oldSize, size_t newSize) {
|
||||
return js_pod_realloc<T>(p, oldSize, newSize);
|
||||
}
|
||||
void free_(void *p) { js_free(p); }
|
||||
void reportAllocOverflow() const {}
|
||||
};
|
||||
|
@ -70,10 +72,11 @@ class TempAllocPolicy
|
|||
return p;
|
||||
}
|
||||
|
||||
void *realloc_(void *p, size_t oldBytes, size_t bytes) {
|
||||
void *p2 = js_realloc(p, bytes);
|
||||
template <typename T>
|
||||
T *pod_realloc(T *prior, size_t oldSize, size_t newSize) {
|
||||
T *p2 = js_pod_realloc<T>(prior, oldSize, newSize);
|
||||
if (MOZ_UNLIKELY(!p2))
|
||||
p2 = onOutOfMemory(p2, bytes);
|
||||
p2 = (T *)onOutOfMemory(p2, newSize * sizeof(T));
|
||||
return p2;
|
||||
}
|
||||
|
||||
|
|
|
@ -1439,11 +1439,12 @@ JS_malloc(JSContext *cx, size_t nbytes)
|
|||
}
|
||||
|
||||
JS_PUBLIC_API(void *)
|
||||
JS_realloc(JSContext *cx, void *p, size_t nbytes)
|
||||
JS_realloc(JSContext *cx, void *p, size_t oldBytes, size_t newBytes)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
return cx->realloc_(p, nbytes);
|
||||
return static_cast<void *>(cx->zone()->pod_realloc<uint8_t>(static_cast<uint8_t *>(p), oldBytes,
|
||||
newBytes));
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
|
|
|
@ -1861,7 +1861,7 @@ extern JS_PUBLIC_API(void *)
|
|||
JS_malloc(JSContext *cx, size_t nbytes);
|
||||
|
||||
extern JS_PUBLIC_API(void *)
|
||||
JS_realloc(JSContext *cx, void *p, size_t nbytes);
|
||||
JS_realloc(JSContext *cx, void *p, size_t oldBytes, size_t newBytes);
|
||||
|
||||
/*
|
||||
* A wrapper for js_free(p) that may delay js_free(p) invocation as a
|
||||
|
|
|
@ -982,7 +982,6 @@ class ContextAllocPolicy
|
|||
MOZ_IMPLICIT ContextAllocPolicy(ThreadSafeContext *cx) : cx_(cx) {}
|
||||
ThreadSafeContext *context() const { return cx_; }
|
||||
void *malloc_(size_t bytes) { return cx_->malloc_(bytes); }
|
||||
void *realloc_(void *p, size_t oldBytes, size_t bytes) { return cx_->realloc_(p, oldBytes, bytes); }
|
||||
void free_(void *p) { js_free(p); }
|
||||
void reportAllocOverflow() const { js_ReportAllocationOverflow(cx_); }
|
||||
};
|
||||
|
|
|
@ -499,7 +499,7 @@ ReadEvalPrintLoop(JSContext *cx, Handle<JSObject*> global, FILE *in, FILE *out,
|
|||
* coincides with the end of a line.
|
||||
*/
|
||||
int startline = lineno;
|
||||
typedef Vector<char, 32, ContextAllocPolicy> CharBuffer;
|
||||
typedef Vector<char, 32> CharBuffer;
|
||||
CharBuffer buffer(cx);
|
||||
do {
|
||||
ScheduleWatchdog(cx->runtime(), -1);
|
||||
|
@ -1507,7 +1507,7 @@ ReadLine(JSContext *cx, unsigned argc, jsval *vp)
|
|||
char *tmp;
|
||||
bufsize *= 2;
|
||||
if (bufsize > buflength) {
|
||||
tmp = (char *) JS_realloc(cx, buf, bufsize);
|
||||
tmp = static_cast<char *>(JS_realloc(cx, buf, bufsize / 2, bufsize));
|
||||
} else {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
tmp = nullptr;
|
||||
|
@ -1529,7 +1529,7 @@ ReadLine(JSContext *cx, unsigned argc, jsval *vp)
|
|||
}
|
||||
|
||||
/* Shrink the buffer to the real size. */
|
||||
char *tmp = static_cast<char*>(JS_realloc(cx, buf, buflength));
|
||||
char *tmp = static_cast<char *>(JS_realloc(cx, buf, bufsize, buflength));
|
||||
if (!tmp) {
|
||||
JS_free(cx, buf);
|
||||
return false;
|
||||
|
|
|
@ -275,17 +275,22 @@ ArrayBufferObject::class_constructor(JSContext *cx, unsigned argc, Value *vp)
|
|||
static void *
|
||||
AllocateArrayBufferContents(JSContext *maybecx, uint32_t nbytes, void *oldptr = nullptr, size_t oldnbytes = 0)
|
||||
{
|
||||
void *p;
|
||||
uint8_t *p;
|
||||
|
||||
// if oldptr is given, then we need to do a realloc
|
||||
if (oldptr) {
|
||||
p = maybecx ? maybecx->runtime()->reallocCanGC(oldptr, nbytes) : js_realloc(oldptr, nbytes);
|
||||
uint8_t *prior = static_cast<uint8_t *>(oldptr);
|
||||
p = maybecx
|
||||
? maybecx->runtime()->pod_reallocCanGC<uint8_t>(prior, oldnbytes, nbytes)
|
||||
: js_pod_realloc<uint8_t>(prior, oldnbytes, nbytes);
|
||||
|
||||
// if we grew the array, we need to set the new bytes to 0
|
||||
if (p && nbytes > oldnbytes)
|
||||
memset(reinterpret_cast<uint8_t *>(p) + oldnbytes, 0, nbytes - oldnbytes);
|
||||
memset(p + oldnbytes, 0, nbytes - oldnbytes);
|
||||
} else {
|
||||
p = maybecx ? maybecx->runtime()->callocCanGC(nbytes) : js_calloc(nbytes);
|
||||
p = maybecx
|
||||
? maybecx->runtime()->pod_callocCanGC<uint8_t>(nbytes)
|
||||
: js_pod_calloc<uint8_t>(nbytes);
|
||||
}
|
||||
|
||||
if (!p && maybecx)
|
||||
|
|
|
@ -59,30 +59,6 @@ struct MallocProvider
|
|||
return MOZ_LIKELY(!!p) ? p : client->onOutOfMemory(nullptr, bytes);
|
||||
}
|
||||
|
||||
void *realloc_(void *p, size_t oldBytes, size_t newBytes) {
|
||||
Client *client = static_cast<Client *>(this);
|
||||
/*
|
||||
* For compatibility we do not account for realloc that decreases
|
||||
* previously allocated memory.
|
||||
*/
|
||||
if (newBytes > oldBytes)
|
||||
client->updateMallocCounter(newBytes - oldBytes);
|
||||
void *p2 = js_realloc(p, newBytes);
|
||||
return MOZ_LIKELY(!!p2) ? p2 : client->onOutOfMemory(p, newBytes);
|
||||
}
|
||||
|
||||
void *realloc_(void *p, size_t bytes) {
|
||||
Client *client = static_cast<Client *>(this);
|
||||
/*
|
||||
* For compatibility we do not account for realloc that increases
|
||||
* previously allocated memory.
|
||||
*/
|
||||
if (!p)
|
||||
client->updateMallocCounter(bytes);
|
||||
void *p2 = js_realloc(p, bytes);
|
||||
return MOZ_LIKELY(!!p2) ? p2 : client->onOutOfMemory(p, bytes);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T *pod_malloc() {
|
||||
return (T *)malloc_(sizeof(T));
|
||||
|
@ -118,7 +94,7 @@ struct MallocProvider
|
|||
|
||||
template <class T>
|
||||
T *
|
||||
pod_calloc(size_t numElems, JSCompartment *comp = nullptr, JSContext *cx = nullptr) {
|
||||
pod_calloc(size_t numElems) {
|
||||
if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
|
||||
Client *client = static_cast<Client *>(this);
|
||||
client->reportAllocationOverflow();
|
||||
|
@ -136,16 +112,27 @@ struct MallocProvider
|
|||
|
||||
template <class T>
|
||||
mozilla::UniquePtr<T[], JS::FreePolicy>
|
||||
make_zeroed_pod_array(size_t numElems,
|
||||
JSCompartment *comp = nullptr,
|
||||
JSContext *cx = nullptr)
|
||||
{
|
||||
return mozilla::UniquePtr<T[], JS::FreePolicy>(pod_calloc<T>(numElems, comp, cx));
|
||||
make_zeroed_pod_array(size_t numElems) {
|
||||
return mozilla::UniquePtr<T[], JS::FreePolicy>(pod_calloc<T>(numElems));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T *pod_realloc(T *prior, size_t oldSize, size_t newSize) {
|
||||
return (T *)realloc_(prior, oldSize * sizeof(T), newSize * sizeof(T));
|
||||
Client *client = static_cast<Client *>(this);
|
||||
T *p = js_pod_realloc(prior, oldSize, newSize);
|
||||
if (MOZ_LIKELY(p)) {
|
||||
// For compatibility we do not account for realloc that decreases
|
||||
// previously allocated memory.
|
||||
if (newSize > oldSize)
|
||||
client->updateMallocCounter((newSize - oldSize) * sizeof(T));
|
||||
return p;
|
||||
}
|
||||
if (newSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
|
||||
client->reportAllocationOverflow();
|
||||
return nullptr;
|
||||
}
|
||||
client->onOutOfMemory(prior, newSize * sizeof(T));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JS_DECLARE_NEW_METHODS(new_, malloc_, MOZ_ALWAYS_INLINE)
|
||||
|
|
|
@ -1371,18 +1371,28 @@ struct JSRuntime : public JS::shadow::Runtime,
|
|||
|
||||
static const unsigned LARGE_ALLOCATION = 25 * 1024 * 1024;
|
||||
|
||||
void *callocCanGC(size_t bytes) {
|
||||
void *p = (void *)pod_calloc<uint8_t>(bytes);
|
||||
template <typename T>
|
||||
T *pod_callocCanGC(size_t numElems) {
|
||||
T *p = pod_calloc<T>(numElems);
|
||||
if (MOZ_LIKELY(!!p))
|
||||
return p;
|
||||
return onOutOfMemoryCanGC(reinterpret_cast<void *>(1), bytes);
|
||||
if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
|
||||
reportAllocationOverflow();
|
||||
return nullptr;
|
||||
}
|
||||
return (T *)onOutOfMemoryCanGC(reinterpret_cast<void *>(1), numElems * sizeof(T));
|
||||
}
|
||||
|
||||
void *reallocCanGC(void *p, size_t bytes) {
|
||||
void *p2 = realloc_(p, bytes);
|
||||
template <typename T>
|
||||
T *pod_reallocCanGC(T *p, size_t oldSize, size_t newSize) {
|
||||
T *p2 = pod_realloc<T>(p, oldSize, newSize);
|
||||
if (MOZ_LIKELY(!!p2))
|
||||
return p2;
|
||||
return onOutOfMemoryCanGC(p, bytes);
|
||||
if (newSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
|
||||
reportAllocationOverflow();
|
||||
return nullptr;
|
||||
}
|
||||
return (T *)onOutOfMemoryCanGC(p, newSize * sizeof(T));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1658,7 +1668,11 @@ class RuntimeAllocPolicy
|
|||
return runtime->pod_calloc<T>(numElems);
|
||||
}
|
||||
|
||||
void *realloc_(void *p, size_t bytes) { return runtime->realloc_(p, bytes); }
|
||||
template <typename T>
|
||||
T *pod_realloc(T *p, size_t oldSize, size_t newSize) {
|
||||
return runtime->pod_realloc<T>(p, oldSize, newSize);
|
||||
}
|
||||
|
||||
void free_(void *p) { js_free(p); }
|
||||
void reportAllocOverflow() const {}
|
||||
};
|
||||
|
|
|
@ -28,8 +28,7 @@ ExtractWellSized(ExclusiveContext *cx, Buffer &cb)
|
|||
/* For medium/big buffers, avoid wasting more than 1/4 of the memory. */
|
||||
JS_ASSERT(capacity >= length);
|
||||
if (length > Buffer::sMaxInlineStorage && capacity - length > length / 4) {
|
||||
size_t bytes = sizeof(CharT) * (length + 1);
|
||||
CharT *tmp = (CharT *)cx->realloc_(buf, bytes);
|
||||
CharT *tmp = cx->zone()->pod_realloc<CharT>(buf, capacity, length + 1);
|
||||
if (!tmp) {
|
||||
js_free(buf);
|
||||
return nullptr;
|
||||
|
|
|
@ -33,8 +33,8 @@ class StringBuffer
|
|||
* The Vector's buffer is taken by the new string so use
|
||||
* ContextAllocPolicy.
|
||||
*/
|
||||
typedef Vector<Latin1Char, 64, ContextAllocPolicy> Latin1CharBuffer;
|
||||
typedef Vector<jschar, 32, ContextAllocPolicy> TwoByteCharBuffer;
|
||||
typedef Vector<Latin1Char, 64> Latin1CharBuffer;
|
||||
typedef Vector<jschar, 32> TwoByteCharBuffer;
|
||||
|
||||
ExclusiveContext *cx;
|
||||
|
||||
|
|
|
@ -213,8 +213,8 @@ private:
|
|||
// nsIUnicodeDecoder::Convert may use fewer than srcLength PRUnichars
|
||||
if (unicharLength + 1 < srcLength + 1) {
|
||||
char16_t *shrunkUnichars =
|
||||
(char16_t *)JS_realloc(cx, unichars,
|
||||
(unicharLength + 1) * sizeof(char16_t));
|
||||
static_cast<char16_t *>(JS_realloc(cx, unichars, srcLength + 1,
|
||||
unicharLength + 1));
|
||||
if (shrunkUnichars)
|
||||
unichars = shrunkUnichars;
|
||||
}
|
||||
|
|
|
@ -126,9 +126,12 @@ public:
|
|||
}
|
||||
|
||||
// This realloc_ is required for this to be a JS container AllocPolicy.
|
||||
static void* realloc_(void* aPtr, size_t aOldSize, size_t aNewSize)
|
||||
template <typename T>
|
||||
static T* pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize)
|
||||
{
|
||||
return InfallibleAllocPolicy::realloc_(aPtr, aNewSize);
|
||||
if (aNewSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
|
||||
return nullptr;
|
||||
return (T*)InfallibleAllocPolicy::realloc_((void *)aPtr, aNewSize * sizeof(T));
|
||||
}
|
||||
|
||||
static void* memalign_(size_t aAlignment, size_t aSize)
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#ifndef mozilla_AllocPolicy_h
|
||||
#define mozilla_AllocPolicy_h
|
||||
|
||||
#include "mozilla/TemplateLib.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
@ -28,10 +30,9 @@ namespace mozilla {
|
|||
* Responsible for OOM reporting when null is returned.
|
||||
* - template <typename T> T* pod_calloc(size_t)
|
||||
* Responsible for OOM reporting when null is returned.
|
||||
* - void* realloc_(void*, size_t, size_t)
|
||||
* Responsible for OOM reporting when null is returned. The *used* bytes
|
||||
* of the previous buffer is passed in (rather than the old allocation
|
||||
* size), in addition to the *new* allocation size requested.
|
||||
* - template <typename T> T* pod_realloc(T*, size_t, size_t)
|
||||
* Responsible for OOM reporting when null is returned. The old allocation
|
||||
* size is passed in, in addition to the new allocation size requested.
|
||||
* - void free_(void*)
|
||||
* - void reportAllocOverflow() const
|
||||
* Called on allocation overflow (that is, an allocation implicitly tried
|
||||
|
@ -61,9 +62,12 @@ public:
|
|||
return static_cast<T*>(calloc(aNumElems, sizeof(T)));
|
||||
}
|
||||
|
||||
void* realloc_(void* aPtr, size_t aOldBytes, size_t aBytes)
|
||||
template <typename T>
|
||||
T* pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize)
|
||||
{
|
||||
return realloc(aPtr, aBytes);
|
||||
if (aNewSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
|
||||
return nullptr;
|
||||
return static_cast<T*>(realloc(aPtr, aNewSize * sizeof(T)));
|
||||
}
|
||||
|
||||
void free_(void* aPtr)
|
||||
|
|
|
@ -204,9 +204,7 @@ struct VectorImpl<T, N, AP, ThisVector, true>
|
|||
{
|
||||
MOZ_ASSERT(!aV.usingInlineStorage());
|
||||
MOZ_ASSERT(!CapacityHasExcessSpace<T>(aNewCap));
|
||||
size_t oldSize = sizeof(T) * aV.mCapacity;
|
||||
size_t newSize = sizeof(T) * aNewCap;
|
||||
T* newbuf = reinterpret_cast<T*>(aV.realloc_(aV.mBegin, oldSize, newSize));
|
||||
T* newbuf = aV.template pod_realloc<T>(aV.mBegin, aV.mCapacity, aNewCap);
|
||||
if (!newbuf) {
|
||||
return false;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче