Bug 1207821 - Change the initialized length of an unboxed array in some places without triggering pre barriers, r=jandem.
authorBrian Hackett <bhackett1024@gmail.com>
Mon, 05 Oct 2015 10:05:19 -0600
changeset 299540 1963f6c813dc2d5329c8d21dc0b8f96f7d1509fb
parent 299539 a23e15cd4f078e7f49063d5e3c23d24d0925ad1b
child 299541 38bf82d22d67099b88d0faba28a5b3ce38380072
push id5392
push userraliiev@mozilla.com
push dateMon, 14 Dec 2015 20:08:23 +0000
treeherdermozilla-beta@16ce8562a975 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1207821
milestone44.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 1207821 - Change the initialized length of an unboxed array in some places without triggering pre barriers, r=jandem.
js/src/vm/UnboxedObject-inl.h
js/src/vm/UnboxedObject.cpp
js/src/vm/UnboxedObject.h
--- a/js/src/vm/UnboxedObject-inl.h
+++ b/js/src/vm/UnboxedObject-inl.h
@@ -190,33 +190,31 @@ UnboxedArrayObject::setLength(ExclusiveC
     }
 
     length_ = length;
 }
 
 inline void
 UnboxedArrayObject::setInitializedLength(uint32_t initlen)
 {
-    MOZ_ASSERT(initlen <= InitializedLengthMask);
     if (initlen < initializedLength()) {
         switch (elementType()) {
           case JSVAL_TYPE_STRING:
             for (size_t i = initlen; i < initializedLength(); i++)
                 triggerPreBarrier<JSVAL_TYPE_STRING>(i);
             break;
           case JSVAL_TYPE_OBJECT:
             for (size_t i = initlen; i < initializedLength(); i++)
                 triggerPreBarrier<JSVAL_TYPE_OBJECT>(i);
             break;
           default:
             MOZ_ASSERT(!UnboxedTypeNeedsPreBarrier(elementType()));
         }
     }
-    capacityIndexAndInitializedLength_ =
-        (capacityIndexAndInitializedLength_ & CapacityMask) | initlen;
+    setInitializedLengthNoBarrier(initlen);
 }
 
 template <JSValueType Type>
 inline bool
 UnboxedArrayObject::setElementSpecific(ExclusiveContext* cx, size_t index, const Value& v)
 {
     MOZ_ASSERT(index < initializedLength());
     MOZ_ASSERT(Type == elementType());
@@ -536,17 +534,17 @@ SetOrExtendBoxedOrUnboxedDenseElements(E
     if (i != count) {
         obj->as<UnboxedArrayObject>().setInitializedLength(start + count);
         if (updateTypes == ShouldUpdateTypes::DontUpdate) {
             for (; i < count; i++)
                 nobj->initElementNoTypeChangeSpecific<Type>(start + i, vp[i]);
         } else {
             for (; i < count; i++) {
                 if (!nobj->initElementSpecific<Type>(cx, start + i, vp[i])) {
-                    nobj->setInitializedLength(oldInitlen);
+                    nobj->setInitializedLengthNoBarrier(oldInitlen);
                     return DenseElementResult::Incomplete;
                 }
             }
         }
     }
 
     if (start + count >= nobj->length())
         nobj->setLength(cx, start + count);
--- a/js/src/vm/UnboxedObject.cpp
+++ b/js/src/vm/UnboxedObject.cpp
@@ -1469,17 +1469,17 @@ UnboxedArrayObject::obj_defineProperty(J
                     return false;
             }
             nobj->setInitializedLength(index + 1);
             if (nobj->initElement(cx, index, desc.value())) {
                 if (nobj->length() <= index)
                     nobj->setLengthInt32(index + 1);
                 return result.succeed();
             }
-            nobj->setInitializedLength(index);
+            nobj->setInitializedLengthNoBarrier(index);
         }
     }
 
     if (!convertToNative(cx, obj))
         return false;
 
     return DefineProperty(cx, obj, id, desc, result);
 }
@@ -1886,17 +1886,17 @@ GetValuesFromPreliminaryArrayObject(Arra
 }
 
 void
 UnboxedArrayObject::fillAfterConvert(ExclusiveContext* cx,
                                      const AutoValueVector& values, size_t* valueCursor)
 {
     MOZ_ASSERT(CapacityArray[1] == 0);
     setCapacityIndex(1);
-    setInitializedLength(0);
+    setInitializedLengthNoBarrier(0);
     setInlineElements();
 
     setLength(cx, NextValue(values, valueCursor).toInt32());
 
     int32_t initlen = NextValue(values, valueCursor).toInt32();
     if (!initlen)
         return;
 
--- a/js/src/vm/UnboxedObject.h
+++ b/js/src/vm/UnboxedObject.h
@@ -494,16 +494,22 @@ class UnboxedArrayObject : public JSObje
     void setLengthInt32(uint32_t length) {
         MOZ_ASSERT(length <= INT32_MAX);
         length_ = length;
     }
 
     inline void setLength(ExclusiveContext* cx, uint32_t len);
     inline void setInitializedLength(uint32_t initlen);
 
+    inline void setInitializedLengthNoBarrier(uint32_t initlen) {
+        MOZ_ASSERT(initlen <= InitializedLengthMask);
+        capacityIndexAndInitializedLength_ =
+            (capacityIndexAndInitializedLength_ & CapacityMask) | initlen;
+    }
+
   private:
     void setInlineElements() {
         elements_ = &inlineElements_[0];
     }
 
     void setCapacityIndex(uint32_t index) {
         MOZ_ASSERT(index <= (CapacityMask >> CapacityShift));
         capacityIndexAndInitializedLength_ =