From 641cbf28dca0e0e6f4c23d269249650dfa39e42e Mon Sep 17 00:00:00 2001 From: Terrence Cole Date: Sun, 3 Mar 2013 12:43:40 -0800 Subject: [PATCH] Bug 847698 - Move most slot allocation closer to object creation; r=bhackett --HG-- extra : rebase_source : 307f719ea2827f3216d021779638d5708f14ca4e --- js/src/jsiter.cpp | 2 +- js/src/jsobj.cpp | 14 +++---------- js/src/jsobj.h | 7 +++++-- js/src/jsobjinlines.h | 38 ++++++++++++++++------------------- js/src/vm/ArgumentsObject.cpp | 2 +- js/src/vm/ScopeObject.cpp | 28 ++++++++++---------------- 6 files changed, 38 insertions(+), 53 deletions(-) diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp index b66a259f44f..cd1bbe0c211 100644 --- a/js/src/jsiter.cpp +++ b/js/src/jsiter.cpp @@ -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; diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index c6611f004c5..53989e54f78 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -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; } diff --git a/js/src/jsobj.h b/js/src/jsobj.h index e93dc5bd4ec..0e3e997faaa 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -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, diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h index 1c9502f79c5..e139e85baf8 100644 --- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -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(nDynamicSlots); + if (!slots) + return NULL; + js::Debug_SetSlotRangeToCrashOnTouch(slots, nDynamicSlots); + } + } JSObject *obj = js_NewGCObject(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(count); - if (!*slots) - return false; - Debug_SetSlotRangeToCrashOnTouch(*slots, count); - return true; - } - *slots = NULL; - return true; -} - inline bool DefineConstructorAndPrototype(JSContext *cx, Handle global, JSProtoKey key, HandleObject ctor, HandleObject proto) diff --git a/js/src/vm/ArgumentsObject.cpp b/js/src/vm/ArgumentsObject.cpp index bea71750f47..034d151f18a 100644 --- a/js/src/vm/ArgumentsObject.cpp +++ b/js/src/vm/ArgumentsObject.cpp @@ -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; diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index 836c395968d..01f0087cc2e 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -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 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;