Bug 873142 - Do not shrink Arrays when tenuring; r=billm
authorTerrence Cole <terrence@mozilla.com>
Tue, 14 May 2013 13:09:26 -0700
changeset 132581 a8ec45bbe41a727b2e31deb43686c45661e7e75a
parent 132580 f4a05a051c9915a185015e00c5afb579d410778d
child 132582 c54119fefdc35b934e190614562fba72a9ca7f2d
push id24711
push userryanvm@gmail.com
push dateWed, 22 May 2013 16:29:12 +0000
treeherdermozilla-central@00b264c7cced [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs873142
milestone24.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 873142 - Do not shrink Arrays when tenuring; r=billm The JITs assume that the capacity will not change between the initarray and the actual initialization.
js/src/gc/Nursery.cpp
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -217,21 +217,26 @@ class MinorCollectionTracer : public JST
             zone->restoreNeedsBarrier();
     }
 };
 
 } /* namespace gc */
 } /* namespace js */
 
 static AllocKind
-GetObjectAllocKindForCopy(JSObject *obj)
+GetObjectAllocKindForCopy(JSRuntime *rt, JSObject *obj)
 {
     if (obj->isArray()) {
         JS_ASSERT(obj->numFixedSlots() == 0);
-        size_t nelements = obj->getDenseInitializedLength();
+
+        /* Use minimal size object if we are just going to copy the pointer. */
+        if (!IsInsideNursery(rt, (void *)obj->getElementsHeader()))
+            return FINALIZE_OBJECT0_BACKGROUND;
+
+        size_t nelements = obj->getDenseCapacity();
         return GetBackgroundAllocKind(GetGCArrayKind(nelements));
     }
 
     if (obj->isFunction())
         return obj->toFunction()->getAllocKind();
 
     AllocKind kind = GetGCObjectFixedSlotsKind(obj->numFixedSlots());
     if (CanBeFinalizedInBackground(kind, obj->getClass()))
@@ -257,17 +262,17 @@ js::Nursery::allocateFromTenured(Zone *z
 
     return t;
 }
 
 void *
 js::Nursery::moveToTenured(MinorCollectionTracer *trc, JSObject *src)
 {
     Zone *zone = src->zone();
-    AllocKind dstKind = GetObjectAllocKindForCopy(src);
+    AllocKind dstKind = GetObjectAllocKindForCopy(trc->runtime, src);
     JSObject *dst = static_cast<JSObject *>(allocateFromTenured(zone, dstKind));
     if (!dst)
         MOZ_CRASH();
 
     moveObjectToTenured(dst, src, dstKind);
 
     RelocationOverlay *overlay = reinterpret_cast<RelocationOverlay *>(src);
     overlay->forwardTo(dst);
@@ -321,16 +326,17 @@ js::Nursery::moveElementsToTenured(JSObj
 {
     if (src->hasEmptyElements())
         return;
 
     Allocator *alloc = &src->zone()->allocator;
     ObjectElements *srcHeader = src->getElementsHeader();
     ObjectElements *dstHeader;
 
+    /* TODO Bug 874151: Prefer to put element data inline if we have space. */
     if (!isInside(srcHeader)) {
         JS_ASSERT(src->elements == dst->elements);
         hugeSlots.remove(reinterpret_cast<HeapSlot*>(srcHeader));
         return;
     }
 
     /* ArrayBuffer stores byte-length, not Value count. */
     if (src->isArrayBuffer()) {
@@ -343,33 +349,31 @@ js::Nursery::moveElementsToTenured(JSObj
             dst->setFixedElements();
             dstHeader = dst->getElementsHeader();
         }
         js_memcpy(dstHeader, srcHeader, nbytes);
         dst->elements = dstHeader->elements();
         return;
     }
 
-    size_t nslots = ObjectElements::VALUES_PER_HEADER + srcHeader->initializedLength;
+    size_t nslots = ObjectElements::VALUES_PER_HEADER + srcHeader->capacity;
 
     /* Unlike other objects, Arrays can have fixed elements. */
     if (src->isArray() && nslots <= GetGCKindSlots(dstKind)) {
         dst->setFixedElements();
         dstHeader = dst->getElementsHeader();
         js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot));
-        dstHeader->capacity = GetGCKindSlots(dstKind) - ObjectElements::VALUES_PER_HEADER;
         return;
     }
 
     size_t nbytes = nslots * sizeof(HeapValue);
     dstHeader = static_cast<ObjectElements *>(alloc->malloc_(nbytes));
     if (!dstHeader)
         MOZ_CRASH();
     js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot));
-    dstHeader->capacity = srcHeader->initializedLength;
     dst->elements = dstHeader->elements();
 }
 
 static bool
 ShouldMoveToTenured(MinorCollectionTracer *trc, void **thingp)
 {
     Cell *cell = static_cast<Cell *>(*thingp);
     Nursery &nursery = *trc->nursery;