Bug 847698 - Move most slot allocation closer to object creation; r=bhackett

--HG--
extra : rebase_source : 307f719ea2827f3216d021779638d5708f14ca4e
This commit is contained in:
Terrence Cole 2013-03-03 12:43:40 -08:00
parent 26a927b213
commit 641cbf28dc
6 changed files with 38 additions and 53 deletions

View File

@ -392,7 +392,7 @@ NewPropertyIteratorObject(JSContext *cx, unsigned flags)
return NULL;
RawObject obj = JSObject::create(cx, ITERATOR_FINALIZE_KIND,
GetInitialHeap(GenericObject, clasp), shape, type, NULL);
GetInitialHeap(GenericObject, clasp), shape, type);
if (!obj)
return NULL;

View File

@ -1193,23 +1193,15 @@ NewObject(JSContext *cx, Class *clasp, types::TypeObject *type_, JSObject *paren
if (!shape)
return NULL;
HeapSlot *slots;
if (!PreallocateObjectDynamicSlots(cx, shape, &slots))
return NULL;
gc::InitialHeap heap = GetInitialHeap(newKind, clasp);
JSObject *obj = JSObject::create(cx, kind, heap, shape, type, slots);
if (!obj) {
js_free(slots);
JSObject *obj = JSObject::create(cx, kind, heap, shape, type);
if (!obj)
return NULL;
}
if (newKind == SingletonObject) {
RootedObject nobj(cx, obj);
if (!JSObject::setSingletonType(cx, nobj)) {
js_free(slots);
if (!JSObject::setSingletonType(cx, nobj))
return NULL;
}
obj = nobj;
}

View File

@ -296,13 +296,16 @@ class JSObject : public js::ObjectImpl
/* As above, but does not change the slot span. */
inline void setLastPropertyInfallible(js::RawShape shape);
/* Make a non-array object with the specified initial state. */
/*
* Make a non-array object with the specified initial state. This method
* takes ownership of any extantSlots it is passed.
*/
static inline JSObject *create(JSContext *cx,
js::gc::AllocKind kind,
js::gc::InitialHeap heap,
js::HandleShape shape,
js::HandleTypeObject type,
js::HeapSlot *slots);
js::HeapSlot *extantSlots = NULL);
/* Make an array object with the specified initial state. */
static inline JSObject *createArray(JSContext *cx,

View File

@ -924,7 +924,8 @@ JSObject::isDebugScope() const
/* static */ inline JSObject *
JSObject::create(JSContext *cx, js::gc::AllocKind kind, js::gc::InitialHeap heap,
js::HandleShape shape, js::HandleTypeObject type, js::HeapSlot *slots)
js::HandleShape shape, js::HandleTypeObject type,
js::HeapSlot *extantSlots /* = NULL */)
{
/*
* Callers must use dynamicSlotsCount to size the initial slot array of the
@ -934,15 +935,28 @@ JSObject::create(JSContext *cx, js::gc::AllocKind kind, js::gc::InitialHeap heap
JS_ASSERT(shape && type);
JS_ASSERT(type->clasp == shape->getObjectClass());
JS_ASSERT(type->clasp != &js::ArrayClass);
JS_ASSERT(!!dynamicSlotsCount(shape->numFixedSlots(), shape->slotSpan()) == !!slots);
JS_ASSERT(js::gc::GetGCKindSlots(kind, type->clasp) == shape->numFixedSlots());
JS_ASSERT(cx->compartment == type->compartment());
JS_ASSERT_IF(type->clasp->flags & JSCLASS_BACKGROUND_FINALIZE, IsBackgroundFinalized(kind));
JS_ASSERT_IF(type->clasp->finalize, heap == js::gc::TenuredHeap);
JS_ASSERT_IF(extantSlots, dynamicSlotsCount(shape->numFixedSlots(), shape->slotSpan()));
js::HeapSlot *slots = extantSlots;
if (!slots) {
size_t nDynamicSlots = dynamicSlotsCount(shape->numFixedSlots(), shape->slotSpan());
if (nDynamicSlots) {
slots = cx->pod_malloc<js::HeapSlot>(nDynamicSlots);
if (!slots)
return NULL;
js::Debug_SetSlotRangeToCrashOnTouch(slots, nDynamicSlots);
}
}
JSObject *obj = js_NewGCObject<js::CanGC>(cx, kind, heap);
if (!obj)
if (!obj) {
js_free(slots);
return NULL;
}
obj->shape_.init(shape);
obj->type_.init(type);
@ -1726,24 +1740,6 @@ GuessArrayGCKind(size_t numSlots)
return gc::FINALIZE_OBJECT8;
}
/*
* Fill slots with the initial slot array to use for a newborn object which
* may or may not need dynamic slots.
*/
inline bool
PreallocateObjectDynamicSlots(JSContext *cx, RawShape shape, HeapSlot **slots)
{
if (size_t count = JSObject::dynamicSlotsCount(shape->numFixedSlots(), shape->slotSpan())) {
*slots = cx->pod_malloc<HeapSlot>(count);
if (!*slots)
return false;
Debug_SetSlotRangeToCrashOnTouch(*slots, count);
return true;
}
*slots = NULL;
return true;
}
inline bool
DefineConstructorAndPrototype(JSContext *cx, Handle<GlobalObject*> global,
JSProtoKey key, HandleObject ctor, HandleObject proto)

View File

@ -159,7 +159,7 @@ ArgumentsObject::create(JSContext *cx, HandleScript script, HandleFunction calle
ClearAllBitArrayElements(data->deletedBits, numDeletedWords);
RawObject obj = JSObject::create(cx, FINALIZE_KIND, GetInitialHeap(GenericObject, clasp),
shape, type, NULL);
shape, type);
if (!obj) {
js_free(data);
return NULL;

View File

@ -168,17 +168,15 @@ CallObject::createTemplateObject(JSContext *cx, HandleScript script)
if (!type)
return NULL;
HeapSlot *slots;
if (!PreallocateObjectDynamicSlots(cx, shape, &slots))
gc::AllocKind kind = gc::GetGCObjectKind(shape->numFixedSlots());
JS_ASSERT(CanBeFinalizedInBackground(kind, &CallClass));
kind = gc::GetBackgroundAllocKind(kind);
JSObject *obj = JSObject::create(cx, kind, gc::TenuredHeap, shape, type);
if (!obj)
return NULL;
CallObject *callobj = CallObject::create(cx, shape, type, slots);
if (!callobj) {
js_free(slots);
return NULL;
}
return callobj;
return &obj->asCall();
}
/*
@ -296,7 +294,7 @@ DeclEnvObject::createTemplateObject(JSContext *cx, HandleFunction fun)
if (!emptyDeclEnvShape)
return NULL;
RootedObject obj(cx, JSObject::create(cx, FINALIZE_KIND, gc::DefaultHeap, emptyDeclEnvShape, type, NULL));
RootedObject obj(cx, JSObject::create(cx, FINALIZE_KIND, gc::DefaultHeap, emptyDeclEnvShape, type));
if (!obj)
return NULL;
@ -338,7 +336,7 @@ WithObject::create(JSContext *cx, HandleObject proto, HandleObject enclosing, ui
if (!shape)
return NULL;
RootedObject obj(cx, JSObject::create(cx, FINALIZE_KIND, gc::DefaultHeap, shape, type, NULL));
RootedObject obj(cx, JSObject::create(cx, FINALIZE_KIND, gc::DefaultHeap, shape, type));
if (!obj)
return NULL;
@ -612,13 +610,9 @@ ClonedBlockObject::create(JSContext *cx, Handle<StaticBlockObject *> block, Abst
if (!type)
return NULL;
HeapSlot *slots;
if (!PreallocateObjectDynamicSlots(cx, block->lastProperty(), &slots))
return NULL;
RootedShape shape(cx, block->lastProperty());
RootedObject obj(cx, JSObject::create(cx, FINALIZE_KIND, gc::TenuredHeap, shape, type, slots));
RootedObject obj(cx, JSObject::create(cx, FINALIZE_KIND, gc::TenuredHeap, shape, type));
if (!obj)
return NULL;
@ -676,7 +670,7 @@ StaticBlockObject::create(JSContext *cx)
if (!emptyBlockShape)
return NULL;
JSObject *obj = JSObject::create(cx, FINALIZE_KIND, gc::TenuredHeap, emptyBlockShape, type, NULL);
JSObject *obj = JSObject::create(cx, FINALIZE_KIND, gc::TenuredHeap, emptyBlockShape, type);
if (!obj)
return NULL;