Bug 1033442 - Allocate slots from the zone explicitly; r=jonco

--HG--
extra : rebase_source : 7ffba7878873100b101c886f3f3f040065ccad3b
This commit is contained in:
Terrence Cole 2014-08-05 14:06:35 -07:00
parent 0218fd8960
commit 662eb527cc
4 changed files with 43 additions and 42 deletions

View File

@ -179,7 +179,7 @@ js::Nursery::allocateObject(JSContext *cx, size_t size, size_t numDynamic)
HeapSlot *slots = nullptr;
if (numDynamic) {
slots = allocateHugeSlots(cx, numDynamic);
slots = allocateHugeSlots(cx->zone(), numDynamic);
if (MOZ_UNLIKELY(!slots))
return nullptr;
}
@ -189,7 +189,7 @@ js::Nursery::allocateObject(JSContext *cx, size_t size, size_t numDynamic)
if (obj)
obj->setInitialSlots(slots);
else
freeSlots(cx, slots);
freeSlots(slots);
TraceNurseryAlloc(obj, size);
return obj;
@ -217,44 +217,41 @@ js::Nursery::allocate(size_t size)
/* Internally, this function is used to allocate elements as well as slots. */
HeapSlot *
js::Nursery::allocateSlots(JSContext *cx, JSObject *obj, uint32_t nslots)
js::Nursery::allocateSlots(JSObject *obj, uint32_t nslots)
{
JS_ASSERT(obj);
JS_ASSERT(nslots > 0);
if (!IsInsideNursery(obj))
return cx->pod_malloc<HeapSlot>(nslots);
return obj->zone()->pod_malloc<HeapSlot>(nslots);
if (nslots > MaxNurserySlots)
return allocateHugeSlots(cx, nslots);
return allocateHugeSlots(obj->zone(), nslots);
size_t size = sizeof(HeapSlot) * nslots;
HeapSlot *slots = static_cast<HeapSlot *>(allocate(size));
if (slots)
return slots;
return allocateHugeSlots(cx, nslots);
return allocateHugeSlots(obj->zone(), nslots);
}
ObjectElements *
js::Nursery::allocateElements(JSContext *cx, JSObject *obj, uint32_t nelems)
js::Nursery::allocateElements(JSObject *obj, uint32_t nelems)
{
JS_ASSERT(nelems >= ObjectElements::VALUES_PER_HEADER);
return reinterpret_cast<ObjectElements *>(allocateSlots(cx, obj, nelems));
return reinterpret_cast<ObjectElements *>(allocateSlots(obj, nelems));
}
HeapSlot *
js::Nursery::reallocateSlots(JSContext *cx, JSObject *obj, HeapSlot *oldSlots,
js::Nursery::reallocateSlots(JSObject *obj, HeapSlot *oldSlots,
uint32_t oldCount, uint32_t newCount)
{
size_t oldSize = oldCount * sizeof(HeapSlot);
size_t newSize = newCount * sizeof(HeapSlot);
if (!IsInsideNursery(obj))
return static_cast<HeapSlot *>(cx->realloc_(oldSlots, oldSize, newSize));
return obj->zone()->pod_realloc<HeapSlot>(oldSlots, oldCount, newCount);
if (!isInside(oldSlots)) {
HeapSlot *newSlots = static_cast<HeapSlot *>(cx->realloc_(oldSlots, oldSize, newSize));
HeapSlot *newSlots = obj->zone()->pod_realloc<HeapSlot>(oldSlots, oldCount, newCount);
if (newSlots && oldSlots != newSlots) {
hugeSlots.remove(oldSlots);
/* If this put fails, we will only leak the slots. */
@ -267,23 +264,23 @@ js::Nursery::reallocateSlots(JSContext *cx, JSObject *obj, HeapSlot *oldSlots,
if (newCount < oldCount)
return oldSlots;
HeapSlot *newSlots = allocateSlots(cx, obj, newCount);
HeapSlot *newSlots = allocateSlots(obj, newCount);
if (newSlots)
PodCopy(newSlots, oldSlots, oldCount);
return newSlots;
}
ObjectElements *
js::Nursery::reallocateElements(JSContext *cx, JSObject *obj, ObjectElements *oldHeader,
js::Nursery::reallocateElements(JSObject *obj, ObjectElements *oldHeader,
uint32_t oldCount, uint32_t newCount)
{
HeapSlot *slots = reallocateSlots(cx, obj, reinterpret_cast<HeapSlot *>(oldHeader),
HeapSlot *slots = reallocateSlots(obj, reinterpret_cast<HeapSlot *>(oldHeader),
oldCount, newCount);
return reinterpret_cast<ObjectElements *>(slots);
}
void
js::Nursery::freeSlots(JSContext *cx, HeapSlot *slots)
js::Nursery::freeSlots(HeapSlot *slots)
{
if (!isInside(slots)) {
hugeSlots.remove(slots);
@ -292,9 +289,9 @@ js::Nursery::freeSlots(JSContext *cx, HeapSlot *slots)
}
HeapSlot *
js::Nursery::allocateHugeSlots(JSContext *cx, size_t nslots)
js::Nursery::allocateHugeSlots(JS::Zone *zone, size_t nslots)
{
HeapSlot *slots = cx->pod_malloc<HeapSlot>(nslots);
HeapSlot *slots = zone->pod_malloc<HeapSlot>(nslots);
/* If this put fails, we will only leak the slots. */
if (slots)
(void)hugeSlots.put(slots);

View File

@ -131,21 +131,21 @@ class Nursery
JSObject *allocateObject(JSContext *cx, size_t size, size_t numDynamic);
/* Allocate a slots array for the given object. */
HeapSlot *allocateSlots(JSContext *cx, JSObject *obj, uint32_t nslots);
HeapSlot *allocateSlots(JSObject *obj, uint32_t nslots);
/* Allocate an elements vector for the given object. */
ObjectElements *allocateElements(JSContext *cx, JSObject *obj, uint32_t nelems);
ObjectElements *allocateElements(JSObject *obj, uint32_t nelems);
/* Resize an existing slots array. */
HeapSlot *reallocateSlots(JSContext *cx, JSObject *obj, HeapSlot *oldSlots,
HeapSlot *reallocateSlots(JSObject *obj, HeapSlot *oldSlots,
uint32_t oldCount, uint32_t newCount);
/* Resize an existing elements vector. */
ObjectElements *reallocateElements(JSContext *cx, JSObject *obj, ObjectElements *oldHeader,
ObjectElements *reallocateElements(JSObject *obj, ObjectElements *oldHeader,
uint32_t oldCount, uint32_t newCount);
/* Free a slots array. */
void freeSlots(JSContext *cx, HeapSlot *slots);
void freeSlots(HeapSlot *slots);
typedef Vector<types::TypeObject *, 0, SystemAllocPolicy> TypeObjectList;
@ -292,7 +292,7 @@ class Nursery
JSRuntime *runtime() const { return runtime_; }
/* Allocates and registers external slots with the nursery. */
HeapSlot *allocateHugeSlots(JSContext *cx, size_t nslots);
HeapSlot *allocateHugeSlots(JS::Zone *zone, size_t nslots);
/* Allocates a new GC thing from the tenured generation during minor GC. */
void *allocateFromTenured(JS::Zone *zone, gc::AllocKind thingKind);

View File

@ -2374,13 +2374,13 @@ JSObject::ReserveForTradeGuts(JSContext *cx, JSObject *aArg, JSObject *bArg,
unsigned bdynamic = dynamicSlotsCount(reserved.newbfixed, a->slotSpan(), a->getClass());
if (adynamic) {
reserved.newaslots = cx->pod_malloc<HeapSlot>(adynamic);
reserved.newaslots = a->zone()->pod_malloc<HeapSlot>(adynamic);
if (!reserved.newaslots)
return false;
Debug_SetSlotRangeToCrashOnTouch(reserved.newaslots, adynamic);
}
if (bdynamic) {
reserved.newbslots = cx->pod_malloc<HeapSlot>(bdynamic);
reserved.newbslots = b->zone()->pod_malloc<HeapSlot>(bdynamic);
if (!reserved.newbslots)
return false;
Debug_SetSlotRangeToCrashOnTouch(reserved.newbslots, bdynamic);
@ -2856,13 +2856,13 @@ AllocateSlots(ThreadSafeContext *cx, JSObject *obj, uint32_t nslots)
{
#ifdef JSGC_GENERATIONAL
if (cx->isJSContext())
return cx->asJSContext()->runtime()->gc.nursery.allocateSlots(cx->asJSContext(), obj, nslots);
return cx->asJSContext()->runtime()->gc.nursery.allocateSlots(obj, nslots);
#endif
#ifdef JSGC_FJGENERATIONAL
if (cx->isForkJoinContext())
return cx->asForkJoinContext()->nursery().allocateSlots(obj, nslots);
#endif
return cx->pod_malloc<HeapSlot>(nslots);
return obj->zone()->pod_malloc<HeapSlot>(nslots);
}
// This will not run the garbage collector. If a nursery cannot accomodate the slot array
@ -2875,8 +2875,7 @@ ReallocateSlots(ThreadSafeContext *cx, JSObject *obj, HeapSlot *oldSlots,
{
#ifdef JSGC_GENERATIONAL
if (cx->isJSContext()) {
return cx->asJSContext()->runtime()->gc.nursery.reallocateSlots(cx->asJSContext(),
obj, oldSlots,
return cx->asJSContext()->runtime()->gc.nursery.reallocateSlots(obj, oldSlots,
oldCount, newCount);
}
#endif
@ -2886,8 +2885,7 @@ ReallocateSlots(ThreadSafeContext *cx, JSObject *obj, HeapSlot *oldSlots,
oldCount, newCount);
}
#endif
return (HeapSlot *)cx->realloc_(oldSlots, oldCount * sizeof(HeapSlot),
newCount * sizeof(HeapSlot));
return obj->zone()->pod_realloc<HeapSlot>(oldSlots, oldCount, newCount);
}
/* static */ bool
@ -2958,7 +2956,7 @@ FreeSlots(ThreadSafeContext *cx, HeapSlot *slots)
#ifdef JSGC_GENERATIONAL
// Note: threads without a JSContext do not have access to GGC nursery allocated things.
if (cx->isJSContext())
return cx->asJSContext()->runtime()->gc.nursery.freeSlots(cx->asJSContext(), slots);
return cx->asJSContext()->runtime()->gc.nursery.freeSlots(slots);
#endif
#ifdef JSGC_FJGENERATIONAL
if (cx->isForkJoinContext())
@ -3186,14 +3184,14 @@ AllocateElements(ThreadSafeContext *cx, JSObject *obj, uint32_t nelems)
{
#ifdef JSGC_GENERATIONAL
if (cx->isJSContext())
return cx->asJSContext()->runtime()->gc.nursery.allocateElements(cx->asJSContext(), obj, nelems);
return cx->asJSContext()->runtime()->gc.nursery.allocateElements(obj, nelems);
#endif
#ifdef JSGC_FJGENERATIONAL
if (cx->isForkJoinContext())
return cx->asForkJoinContext()->nursery().allocateElements(obj, nelems);
#endif
return static_cast<js::ObjectElements *>(cx->malloc_(nelems * sizeof(HeapValue)));
return reinterpret_cast<js::ObjectElements *>(obj->zone()->pod_malloc<HeapSlot>(nelems));
}
// This will not run the garbage collector. If a nursery cannot accomodate the element array
@ -3204,9 +3202,8 @@ ReallocateElements(ThreadSafeContext *cx, JSObject *obj, ObjectElements *oldHead
{
#ifdef JSGC_GENERATIONAL
if (cx->isJSContext()) {
return cx->asJSContext()->runtime()->gc.nursery.reallocateElements(cx->asJSContext(), obj,
oldHeader, oldCount,
newCount);
return cx->asJSContext()->runtime()->gc.nursery.reallocateElements(obj, oldHeader,
oldCount, newCount);
}
#endif
#ifdef JSGC_FJGENERATIONAL
@ -3216,8 +3213,9 @@ ReallocateElements(ThreadSafeContext *cx, JSObject *obj, ObjectElements *oldHead
}
#endif
return static_cast<js::ObjectElements *>(cx->realloc_(oldHeader, oldCount * sizeof(HeapSlot),
newCount * sizeof(HeapSlot)));
return reinterpret_cast<js::ObjectElements *>(
obj->zone()->pod_realloc<HeapSlot>(reinterpret_cast<HeapSlot *>(oldHeader),
oldCount, newCount));
}
// Round up |count| to one of our standard slot counts. Up to 1 mebislot (i.e.

View File

@ -132,6 +132,12 @@ struct MallocProvider
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) {
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)
};