Bug 1166041 - Add some assertions to help catch leaked slots memory r=terrence
authorJon Coppeard <jcoppeard@mozilla.com>
Fri, 12 Jun 2015 10:11:07 +0100
changeset 280938 70e774f5c1524032700924ff68da59ba772fb7bb
parent 280937 ab92f3c0291618bd2362dc47361e522973df8569
child 280939 d3df23a5ad6281a27d2306e3aee99add48045fb9
push id897
push userjlund@mozilla.com
push dateMon, 14 Sep 2015 18:56:12 +0000
treeherdermozilla-release@9411e2d2b214 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs1166041
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1166041 - Add some assertions to help catch leaked slots memory r=terrence
js/src/gc/Allocator.cpp
js/src/gc/Nursery.cpp
js/src/vm/NativeObject.cpp
--- a/js/src/gc/Allocator.cpp
+++ b/js/src/gc/Allocator.cpp
@@ -105,16 +105,18 @@ js::Allocate(ExclusiveContext* cx, Alloc
     MOZ_ASSERT(IsObjectAllocKind(kind));
     size_t thingSize = Arena::thingSize(kind);
 
     MOZ_ASSERT(thingSize == Arena::thingSize(kind));
     MOZ_ASSERT(thingSize >= sizeof(JSObject_Slots0));
     static_assert(sizeof(JSObject_Slots0) >= CellSize,
                   "All allocations must be at least the allocator-imposed minimum size.");
 
+    MOZ_ASSERT_IF(nDynamicSlots != 0, clasp->isNative());
+
     // Off-main-thread alloc cannot trigger GC or make runtime assertions.
     if (!cx->isJSContext())
         return GCRuntime::tryNewTenuredObject<NoGC>(cx, kind, thingSize, nDynamicSlots);
 
     JSContext* ncx = cx->asJSContext();
     JSRuntime* rt = ncx->runtime();
     if (!rt->gc.checkAllocatorState<allowGC>(ncx, kind))
         return nullptr;
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -192,16 +192,17 @@ js::Nursery::allocateObject(JSContext* c
     /* Make the object allocation. */
     JSObject* obj = static_cast<JSObject*>(allocate(size));
     if (!obj)
         return nullptr;
 
     /* If we want external slots, add them. */
     HeapSlot* slots = nullptr;
     if (numDynamic) {
+        MOZ_ASSERT(clasp->isNative());
         slots = static_cast<HeapSlot*>(allocateBuffer(cx->zone(), numDynamic * sizeof(HeapSlot)));
         if (!slots) {
             /*
              * It is safe to leave the allocated object uninitialized, since we
              * do not visit unallocated things in the nursery.
              */
             return nullptr;
         }
--- a/js/src/vm/NativeObject.cpp
+++ b/js/src/vm/NativeObject.cpp
@@ -328,18 +328,20 @@ NativeObject::setLastPropertyMakeNonNati
     MOZ_ASSERT(!inDictionaryMode());
     MOZ_ASSERT(!shape->getObjectClass()->isNative());
     MOZ_ASSERT(shape->compartment() == compartment());
     MOZ_ASSERT(shape->slotSpan() == 0);
     MOZ_ASSERT(shape->numFixedSlots() == 0);
 
     if (hasDynamicElements())
         js_free(getElementsHeader());
-    if (hasDynamicSlots())
+    if (hasDynamicSlots()) {
         js_free(slots_);
+        slots_ = nullptr;
+    }
 
     shape_ = shape;
 }
 
 void
 NativeObject::setLastPropertyMakeNative(ExclusiveContext* cx, Shape* shape)
 {
     MOZ_ASSERT(getClass()->isNative());
@@ -391,16 +393,17 @@ NativeObject::growSlots(ExclusiveContext
      * Slot capacities are determined by the span of allocated objects. Due to
      * the limited number of bits to store shape slots, object growth is
      * throttled well before the slot capacity can overflow.
      */
     NativeObject::slotsSizeMustNotOverflow();
     MOZ_ASSERT(newCount < NELEMENTS_LIMIT);
 
     if (!oldCount) {
+        MOZ_ASSERT(!slots_);
         slots_ = AllocateObjectBuffer<HeapSlot>(cx, this, newCount);
         if (!slots_)
             return false;
         Debug_SetSlotRangeToCrashOnTouch(slots_, newCount);
         return true;
     }
 
     HeapSlot* newslots = ReallocateObjectBuffer<HeapSlot>(cx, this, slots_, oldCount, newCount);