Backed out changesets 6ee4b6cc240c, a818fd0874fe, and 70803a5f4683 (bug 1033442) for multiple crashtest oranges.

This commit is contained in:
Ryan VanderMeulen 2014-08-08 21:54:58 -04:00
parent 3027419040
commit 7d00738b7a
29 changed files with 156 additions and 203 deletions

View File

@ -1067,7 +1067,7 @@ class HashTable : private AllocPolicy
"newly-calloc'd tables have to be considered empty");
static_assert(sMaxCapacity <= SIZE_MAX / sizeof(Entry),
"would overflow allocating max number of entries");
return alloc.template pod_calloc<Entry>(capacity);
return static_cast<Entry*>(alloc.calloc_(capacity * sizeof(Entry)));
}
static void destroyTable(AllocPolicy &alloc, Entry *oldTable, uint32_t capacity)

View File

@ -563,16 +563,6 @@ 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>

View File

@ -519,24 +519,18 @@ class LifoAllocPolicy
void *malloc_(size_t bytes) {
return fb == Fallible ? alloc_.alloc(bytes) : alloc_.allocInfallible(bytes);
}
template <typename T>
T *pod_calloc(size_t numElems) {
if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
return nullptr;
T *p = (T *)malloc_(numElems * sizeof(T));
void *calloc_(size_t bytes) {
void *p = malloc_(bytes);
if (fb == Fallible && !p)
return nullptr;
memset(p, 0, numElems * sizeof(T));
memset(p, 0, bytes);
return p;
}
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));
void *realloc_(void *p, size_t oldBytes, size_t bytes) {
void *n = malloc_(bytes);
if (fb == Fallible && !n)
return nullptr;
memcpy(n, p, Min(oldSize * sizeof(T), newSize * sizeof(T)));
memcpy(n, p, Min(oldBytes, bytes));
return n;
}
void free_(void *p) {

View File

@ -585,13 +585,16 @@ 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 obj->zone()->pod_realloc<HeapSlot>(oldSlots, oldCount, newCount);
return static_cast<HeapSlot *>(cx_->realloc_(oldSlots, oldSize, newSize));
}
if (!isInsideNewspace(oldSlots))
return reallocateHugeSlots(obj, oldSlots, oldCount, newCount);
return reallocateHugeSlots(oldSlots, oldSize, newSize);
// No-op if we're shrinking, we can't make use of the freed portion.
if (newCount < oldCount)
@ -601,7 +604,6 @@ ForkJoinNursery::reallocateSlots(JSObject *obj, HeapSlot *oldSlots,
if (!newSlots)
return nullptr;
size_t oldSize = oldCount * sizeof(HeapSlot);
js_memcpy(newSlots, oldSlots, oldSize);
return newSlots;
}
@ -648,10 +650,9 @@ ForkJoinNursery::allocateHugeSlots(size_t nslots)
}
HeapSlot *
ForkJoinNursery::reallocateHugeSlots(JSObject *obj, HeapSlot *oldSlots,
uint32_t oldCount, uint32_t newCount)
ForkJoinNursery::reallocateHugeSlots(HeapSlot *oldSlots, uint32_t oldSize, uint32_t newSize)
{
HeapSlot *newSlots = obj->zone()->pod_realloc<HeapSlot>(oldSlots, oldCount, newCount);
HeapSlot *newSlots = static_cast<HeapSlot *>(cx_->realloc_(oldSlots, oldSize, newSize));
if (!newSlots)
return newSlots;

View File

@ -210,8 +210,7 @@ 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(JSObject *obj, HeapSlot *oldSlots,
uint32_t oldCount, uint32_t newCount);
HeapSlot *reallocateHugeSlots(HeapSlot *oldSlots, uint32_t oldSize, uint32_t newSize);
// Walk the list of registered slot arrays and free them all.
void sweepHugeSlots();

View File

@ -103,24 +103,17 @@ class IonAllocPolicy
void *malloc_(size_t bytes) {
return alloc_.allocate(bytes);
}
template <typename T>
T *pod_calloc(size_t numElems) {
if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
return nullptr;
T *p = (T *)alloc_.allocate(numElems * sizeof(T));
void *calloc_(size_t bytes) {
void *p = alloc_.allocate(bytes);
if (p)
memset(p, 0, numElems * sizeof(T));
memset(p, 0, bytes);
return p;
}
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));
void *realloc_(void *p, size_t oldBytes, size_t bytes) {
void *n = malloc_(bytes);
if (!n)
return n;
memcpy(n, p, Min(oldSize * sizeof(T), newSize * sizeof(T)));
memcpy(n, p, Min(oldBytes, bytes));
return n;
}
void free_(void *p) {
@ -139,6 +132,19 @@ class OldIonAllocPolicy
void *malloc_(size_t bytes) {
return GetIonContext()->temp->allocate(bytes);
}
void *calloc_(size_t bytes) {
void *p = GetIonContext()->temp->allocate(bytes);
if (p)
memset(p, 0, bytes);
return p;
}
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 {

View File

@ -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;

View File

@ -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);

View File

@ -52,7 +52,7 @@ RematerializedFrame::New(ThreadSafeContext *cx, uint8_t *top, InlineFrameIterato
(numActualArgs + iter.script()->nfixed()) * sizeof(Value) -
sizeof(Value); // 1 Value included in sizeof(RematerializedFrame)
void *buf = cx->pod_calloc<uint8_t>(numBytes);
void *buf = cx->calloc_(numBytes);
if (!buf)
return nullptr;

View File

@ -26,10 +26,8 @@ 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); }
template <typename T> T *pod_realloc(T *p, size_t oldSize, size_t newSize) {
return js_pod_realloc<T>(p, oldSize, newSize);
}
void *calloc_(size_t bytes) { return js_calloc(bytes); }
void *realloc_(void *p, size_t oldBytes, size_t bytes) { return js_realloc(p, bytes); }
void free_(void *p) { js_free(p); }
void reportAllocOverflow() const {}
};
@ -64,19 +62,17 @@ class TempAllocPolicy
return p;
}
template <typename T>
T *pod_calloc(size_t numElems) {
T *p = js_pod_calloc<T>(numElems);
void *calloc_(size_t bytes) {
void *p = js_calloc(bytes);
if (MOZ_UNLIKELY(!p))
p = (T *)onOutOfMemory(reinterpret_cast<void *>(1), numElems * sizeof(T));
p = onOutOfMemory(nullptr, bytes);
return p;
}
template <typename T>
T *pod_realloc(T *prior, size_t oldSize, size_t newSize) {
T *p2 = js_pod_realloc<T>(prior, oldSize, newSize);
void *realloc_(void *p, size_t oldBytes, size_t bytes) {
void *p2 = js_realloc(p, bytes);
if (MOZ_UNLIKELY(!p2))
p2 = (T *)onOutOfMemory(p2, newSize * sizeof(T));
p2 = onOutOfMemory(p2, bytes);
return p2;
}

View File

@ -1439,12 +1439,11 @@ JS_malloc(JSContext *cx, size_t nbytes)
}
JS_PUBLIC_API(void *)
JS_realloc(JSContext *cx, void *p, size_t oldBytes, size_t newBytes)
JS_realloc(JSContext *cx, void *p, size_t nbytes)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
return static_cast<void *>(cx->zone()->pod_realloc<uint8_t>(static_cast<uint8_t *>(p), oldBytes,
newBytes));
return cx->realloc_(p, nbytes);
}
JS_PUBLIC_API(void)

View File

@ -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 oldBytes, size_t newBytes);
JS_realloc(JSContext *cx, void *p, size_t nbytes);
/*
* A wrapper for js_free(p) that may delay js_free(p) invocation as a

View File

@ -982,6 +982,8 @@ class ContextAllocPolicy
MOZ_IMPLICIT ContextAllocPolicy(ThreadSafeContext *cx) : cx_(cx) {}
ThreadSafeContext *context() const { return cx_; }
void *malloc_(size_t bytes) { return cx_->malloc_(bytes); }
void *calloc_(size_t bytes) { return cx_->calloc_(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_); }
};

View File

@ -3443,7 +3443,7 @@ CheckNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun)
size_t numBytes = sizeof(TypeNewScript)
+ (initializerList.length() * sizeof(TypeNewScript::Initializer));
TypeNewScript *newScript = (TypeNewScript *) type->zone()->pod_calloc<uint8_t>(numBytes);
TypeNewScript *newScript = (TypeNewScript *) cx->calloc_(numBytes);
if (!newScript)
return;
@ -3606,7 +3606,7 @@ JSScript::makeTypes(JSContext *cx)
unsigned count = TypeScript::NumTypeSets(this);
TypeScript *typeScript = (TypeScript *)
zone()->pod_calloc<uint8_t>(TypeScript::SizeIncludingTypeArray(count));
cx->calloc_(TypeScript::SizeIncludingTypeArray(count));
if (!typeScript)
return false;

View File

@ -1784,7 +1784,7 @@ js_NewGenerator(JSContext *cx, const InterpreterRegs &stackRegs)
JS_ASSERT(nbytes % sizeof(Value) == 0);
JS_STATIC_ASSERT(sizeof(InterpreterFrame) % sizeof(HeapValue) == 0);
JSGenerator *gen = (JSGenerator *) obj->zone()->pod_calloc<uint8_t>(nbytes);
JSGenerator *gen = (JSGenerator *) cx->calloc_(nbytes);
if (!gen)
return nullptr;

View File

@ -1138,8 +1138,8 @@ JSScript::initScriptCounts(JSContext *cx)
for (jsbytecode *pc = code(); pc < codeEnd(); pc += GetBytecodeLength(pc))
n += PCCounts::numCounts(JSOp(*pc));
size_t nbytes = (length() * sizeof(PCCounts)) + (n * sizeof(double));
uint8_t *base = zone()->pod_calloc<uint8_t>(nbytes);
size_t bytes = (length() * sizeof(PCCounts)) + (n * sizeof(double));
char *base = (char *) cx->calloc_(bytes);
if (!base)
return false;
@ -1155,7 +1155,7 @@ JSScript::initScriptCounts(JSContext *cx)
compartment()->scriptCountsMap = map;
}
uint8_t *cursor = base;
char *cursor = base;
ScriptCounts scriptCounts;
scriptCounts.pcCountsVector = (PCCounts *) cursor;
@ -1177,7 +1177,7 @@ JSScript::initScriptCounts(JSContext *cx)
}
hasScriptCounts_ = true; // safe to set this; we can't fail after this point
JS_ASSERT(size_t(cursor - base) == nbytes);
JS_ASSERT(size_t(cursor - base) == bytes);
/* Enable interrupts in any interpreter frames running on this script. */
for (ActivationIterator iter(cx->runtime()); !iter.done(); ++iter) {
@ -2358,15 +2358,14 @@ JSScript::Create(ExclusiveContext *cx, HandleObject enclosingScope, bool savedCa
}
static inline uint8_t *
AllocScriptData(JS::Zone *zone, size_t size)
AllocScriptData(ExclusiveContext *cx, size_t size)
{
if (!size)
return nullptr;
uint8_t *data = zone->pod_calloc<uint8_t>(JS_ROUNDUP(size, sizeof(Value)));
uint8_t *data = static_cast<uint8_t *>(cx->calloc_(JS_ROUNDUP(size, sizeof(Value))));
if (!data)
return nullptr;
JS_ASSERT(size_t(data) % sizeof(Value) == 0);
// All script data is optional, so size might be 0. In that case, we don't care about alignment.
JS_ASSERT(size == 0 || size_t(data) % sizeof(Value) == 0);
return data;
}
@ -2377,9 +2376,13 @@ JSScript::partiallyInit(ExclusiveContext *cx, HandleScript script, uint32_t ncon
{
size_t size = ScriptDataSize(script->bindings.count(), nconsts, nobjects, nregexps, ntrynotes,
nblockscopes);
script->data = AllocScriptData(script->zone(), size);
if (size && !script->data)
return false;
if (size > 0) {
script->data = AllocScriptData(cx, size);
if (!script->data)
return false;
} else {
script->data = nullptr;
}
script->dataSize_ = size;
JS_ASSERT(nTypeSets <= UINT16_MAX);
@ -2887,8 +2890,8 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun,
/* Script data */
size_t size = src->dataSize();
uint8_t *data = AllocScriptData(cx->zone(), size);
if (size && !data)
uint8_t *data = AllocScriptData(cx, size);
if (!data)
return nullptr;
/* Bindings */
@ -3149,7 +3152,7 @@ JSScript::ensureHasDebugScript(JSContext *cx)
return true;
size_t nbytes = offsetof(DebugScript, breakpoints) + length() * sizeof(BreakpointSite*);
DebugScript *debug = (DebugScript *) zone()->pod_calloc<uint8_t>(nbytes);
DebugScript *debug = (DebugScript *) cx->calloc_(nbytes);
if (!debug)
return false;

View File

@ -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> CharBuffer;
typedef Vector<char, 32, ContextAllocPolicy> 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 = static_cast<char *>(JS_realloc(cx, buf, bufsize / 2, bufsize));
tmp = (char *) JS_realloc(cx, buf, 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, bufsize, buflength));
char *tmp = static_cast<char*>(JS_realloc(cx, buf, buflength));
if (!tmp) {
JS_free(cx, buf);
return false;

View File

@ -275,22 +275,17 @@ ArrayBufferObject::class_constructor(JSContext *cx, unsigned argc, Value *vp)
static void *
AllocateArrayBufferContents(JSContext *maybecx, uint32_t nbytes, void *oldptr = nullptr, size_t oldnbytes = 0)
{
uint8_t *p;
void *p;
// if oldptr is given, then we need to do a realloc
if (oldptr) {
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);
p = maybecx ? maybecx->runtime()->reallocCanGC(oldptr, nbytes) : js_realloc(oldptr, nbytes);
// if we grew the array, we need to set the new bytes to 0
if (p && nbytes > oldnbytes)
memset(p + oldnbytes, 0, nbytes - oldnbytes);
memset(reinterpret_cast<uint8_t *>(p) + oldnbytes, 0, nbytes - oldnbytes);
} else {
p = maybecx
? maybecx->runtime()->pod_callocCanGC<uint8_t>(nbytes)
: js_pod_calloc<uint8_t>(nbytes);
p = maybecx ? maybecx->runtime()->callocCanGC(nbytes) : js_calloc(nbytes);
}
if (!p && maybecx)

View File

@ -23,10 +23,6 @@
* - TempAllocPolicy: Adds automatic error reporting to the provided
* Context when allocations fail.
*
* - ContextAllocPolicy: forwards to the JSContext MallocProvider.
*
* - RuntimeAllocPolicy: forwards to the JSRuntime MallocProvider.
*
* - MallocProvider. A mixin base class that handles automatically updating
* the GC's state in response to allocations that are tied to a GC lifetime
* or are for a particular GC purpose. These allocators must only be used
@ -59,6 +55,37 @@ struct MallocProvider
return MOZ_LIKELY(!!p) ? p : client->onOutOfMemory(nullptr, bytes);
}
void *calloc_(size_t bytes) {
Client *client = static_cast<Client *>(this);
client->updateMallocCounter(bytes);
void *p = js_calloc(bytes);
return MOZ_LIKELY(!!p) ? p : client->onOutOfMemory(reinterpret_cast<void *>(1), 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));
@ -66,14 +93,7 @@ struct MallocProvider
template <class T>
T *pod_calloc() {
Client *client = static_cast<Client *>(this);
client->updateMallocCounter(sizeof(T));
T *p = js_pod_calloc<T>();
if (MOZ_UNLIKELY(!p)) {
client->onOutOfMemory(reinterpret_cast<void *>(1), sizeof(T));
return nullptr;
}
return p;
return (T *)calloc_(sizeof(T));
}
template <class T>
@ -94,47 +114,30 @@ struct MallocProvider
template <class T>
T *
pod_calloc(size_t numElems) {
pod_calloc(size_t numElems, JSCompartment *comp = nullptr, JSContext *cx = nullptr) {
if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
Client *client = static_cast<Client *>(this);
client->reportAllocationOverflow();
return nullptr;
}
Client *client = static_cast<Client *>(this);
client->updateMallocCounter(numElems * sizeof(T));
T *p = js_pod_calloc<T>(numElems);
if (MOZ_UNLIKELY(!p)) {
client->onOutOfMemory(reinterpret_cast<void *>(1), sizeof(T));
return nullptr;
}
return p;
return (T *)calloc_(numElems * sizeof(T));
}
template <class T>
mozilla::UniquePtr<T[], JS::FreePolicy>
make_zeroed_pod_array(size_t numElems) {
return mozilla::UniquePtr<T[], JS::FreePolicy>(pod_calloc<T>(numElems));
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));
}
template <class T>
T *pod_realloc(T *prior, size_t oldSize, size_t newSize) {
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;
return (T *)realloc_(prior, oldSize * sizeof(T), newSize * sizeof(T));
}
JS_DECLARE_NEW_METHODS(new_, malloc_, MOZ_ALWAYS_INLINE)
JS_DECLARE_MAKE_METHODS(make_unique, new_, MOZ_ALWAYS_INLINE)
};

View File

@ -1371,28 +1371,18 @@ struct JSRuntime : public JS::shadow::Runtime,
static const unsigned LARGE_ALLOCATION = 25 * 1024 * 1024;
template <typename T>
T *pod_callocCanGC(size_t numElems) {
T *p = pod_calloc<T>(numElems);
void *callocCanGC(size_t bytes) {
void *p = calloc_(bytes);
if (MOZ_LIKELY(!!p))
return p;
if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
reportAllocationOverflow();
return nullptr;
}
return (T *)onOutOfMemoryCanGC(reinterpret_cast<void *>(1), numElems * sizeof(T));
return onOutOfMemoryCanGC(reinterpret_cast<void *>(1), bytes);
}
template <typename T>
T *pod_reallocCanGC(T *p, size_t oldSize, size_t newSize) {
T *p2 = pod_realloc<T>(p, oldSize, newSize);
void *reallocCanGC(void *p, size_t bytes) {
void *p2 = realloc_(p, bytes);
if (MOZ_LIKELY(!!p2))
return p2;
if (newSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
reportAllocationOverflow();
return nullptr;
}
return (T *)onOutOfMemoryCanGC(p, newSize * sizeof(T));
return onOutOfMemoryCanGC(p, bytes);
}
};
@ -1662,17 +1652,8 @@ class RuntimeAllocPolicy
public:
MOZ_IMPLICIT RuntimeAllocPolicy(JSRuntime *rt) : runtime(rt) {}
void *malloc_(size_t bytes) { return runtime->malloc_(bytes); }
template <typename T>
T *pod_calloc(size_t numElems) {
return runtime->pod_calloc<T>(numElems);
}
template <typename T>
T *pod_realloc(T *p, size_t oldSize, size_t newSize) {
return runtime->pod_realloc<T>(p, oldSize, newSize);
}
void *calloc_(size_t bytes) { return runtime->calloc_(bytes); }
void *realloc_(void *p, size_t bytes) { return runtime->realloc_(p, bytes); }
void free_(void *p) { js_free(p); }
void reportAllocOverflow() const {}
};

View File

@ -45,10 +45,10 @@ ShapeTable::init(ThreadSafeContext *cx, Shape *lastProp)
sizeLog2 = MIN_SIZE_LOG2;
/*
* Use rt->calloc for memory accounting and overpressure handling
* Use rt->calloc_ for memory accounting and overpressure handling
* without OOM reporting. See ShapeTable::change.
*/
entries = cx->pod_calloc<Shape *>(JS_BIT(sizeLog2));
entries = (Shape **) cx->calloc_(sizeOfEntries(JS_BIT(sizeLog2)));
if (!entries)
return false;
@ -260,7 +260,7 @@ ShapeTable::change(int log2Delta, ThreadSafeContext *cx)
int newlog2 = oldlog2 + log2Delta;
uint32_t oldsize = JS_BIT(oldlog2);
uint32_t newsize = JS_BIT(newlog2);
Shape **newTable = cx->pod_calloc<Shape *>(newsize);
Shape **newTable = (Shape **) cx->calloc_(sizeOfEntries(newsize));
if (!newTable)
return false;

View File

@ -161,6 +161,9 @@ struct ShapeTable {
/* By definition, hashShift = HASH_BITS - log2(capacity). */
uint32_t capacity() const { return JS_BIT(HASH_BITS - hashShift); }
/* Computes the size of the entries array for a given capacity. */
static size_t sizeOfEntries(size_t cap) { return cap * sizeof(Shape *); }
/*
* This counts the ShapeTable object itself (which must be
* heap-allocated) and its |entries| array.
@ -184,7 +187,7 @@ struct ShapeTable {
/*
* NB: init and change are fallible but do not report OOM, so callers can
* cope or ignore. They do however use the context's calloc method in
* cope or ignore. They do however use the context's calloc_ method in
* order to update the malloc counter on success.
*/
bool init(ThreadSafeContext *cx, Shape *lastProp);

View File

@ -28,7 +28,8 @@ 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) {
CharT *tmp = cx->zone()->pod_realloc<CharT>(buf, capacity, length + 1);
size_t bytes = sizeof(CharT) * (length + 1);
CharT *tmp = (CharT *)cx->realloc_(buf, bytes);
if (!tmp) {
js_free(buf);
return nullptr;

View File

@ -33,8 +33,8 @@ class StringBuffer
* The Vector's buffer is taken by the new string so use
* ContextAllocPolicy.
*/
typedef Vector<Latin1Char, 64> Latin1CharBuffer;
typedef Vector<jschar, 32> TwoByteCharBuffer;
typedef Vector<Latin1Char, 64, ContextAllocPolicy> Latin1CharBuffer;
typedef Vector<jschar, 32, ContextAllocPolicy> TwoByteCharBuffer;
ExclusiveContext *cx;

View File

@ -213,8 +213,8 @@ private:
// nsIUnicodeDecoder::Convert may use fewer than srcLength PRUnichars
if (unicharLength + 1 < srcLength + 1) {
char16_t *shrunkUnichars =
static_cast<char16_t *>(JS_realloc(cx, unichars, srcLength + 1,
unicharLength + 1));
(char16_t *)JS_realloc(cx, unichars,
(unicharLength + 1) * sizeof(char16_t));
if (shrunkUnichars)
unichars = shrunkUnichars;
}

View File

@ -61,12 +61,7 @@ private:
class SystemAllocPolicy {
public:
void *malloc_(size_t bytes) { return ::malloc(bytes); }
template <typename T>
T *pod_calloc(size_t numElems) {
return static_cast<T *>(::calloc(numElems, sizeof(T)));
}
void *calloc_(size_t bytes) { return ::calloc(bytes, 1); }
void *realloc_(void *p, size_t bytes) { return ::realloc(p, bytes); }
void free_(void *p) { ::free(p); }
void reportAllocOverflow() const {}

View File

@ -109,14 +109,6 @@ public:
return p;
}
template <typename T>
static T* pod_calloc(size_t aNumElems)
{
void* p = gMallocTable->calloc(aNumElems, sizeof(T));
ExitOnFailure(p);
return (T*)p;
}
// This realloc_ is the one we use for direct reallocs within DMD.
static void* realloc_(void* aPtr, size_t aNewSize)
{
@ -126,12 +118,9 @@ public:
}
// This realloc_ is required for this to be a JS container AllocPolicy.
template <typename T>
static T* pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize)
static void* realloc_(void* aPtr, size_t aOldSize, size_t aNewSize)
{
if (aNewSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
return nullptr;
return (T*)InfallibleAllocPolicy::realloc_((void *)aPtr, aNewSize * sizeof(T));
return InfallibleAllocPolicy::realloc_(aPtr, aNewSize);
}
static void* memalign_(size_t aAlignment, size_t aSize)

View File

@ -12,9 +12,6 @@
#ifndef mozilla_AllocPolicy_h
#define mozilla_AllocPolicy_h
#include "mozilla/NullPtr.h"
#include "mozilla/TemplateLib.h"
#include <stddef.h>
#include <stdlib.h>
@ -29,11 +26,12 @@ namespace mozilla {
* - public copy constructor, assignment, destructor
* - void* malloc_(size_t)
* Responsible for OOM reporting when null is returned.
* - template <typename T> T* pod_calloc(size_t)
* - void* calloc_(size_t)
* Responsible for OOM reporting when null is returned.
* - 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* 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.
* - void free_(void*)
* - void reportAllocOverflow() const
* Called on allocation overflow (that is, an allocation implicitly tried
@ -57,18 +55,14 @@ public:
return malloc(aBytes);
}
template <typename T>
T* pod_calloc(size_t aNumElems)
void* calloc_(size_t aBytes)
{
return static_cast<T*>(calloc(aNumElems, sizeof(T)));
return calloc(aBytes, 1);
}
template <typename T>
T* pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize)
void* realloc_(void* aPtr, size_t aOldBytes, size_t aBytes)
{
if (aNewSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
return nullptr;
return static_cast<T*>(realloc(aPtr, aNewSize * sizeof(T)));
return realloc(aPtr, aBytes);
}
void free_(void* aPtr)

View File

@ -204,7 +204,9 @@ struct VectorImpl<T, N, AP, ThisVector, true>
{
MOZ_ASSERT(!aV.usingInlineStorage());
MOZ_ASSERT(!CapacityHasExcessSpace<T>(aNewCap));
T* newbuf = aV.template pod_realloc<T>(aV.mBegin, aV.mCapacity, 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));
if (!newbuf) {
return false;
}