mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out changesets 6ee4b6cc240c, a818fd0874fe, and 70803a5f4683 (bug 1033442) for multiple crashtest oranges.
This commit is contained in:
parent
e1afa19e1c
commit
7cc7f6d261
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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_); }
|
||||
};
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
};
|
||||
|
@ -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 {}
|
||||
};
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 {}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user