Bug 609896 - Optimize copy and initialization of DenseElements; r=billm
authorTerrence Cole <terrence@mozilla.com>
Wed, 25 Sep 2013 15:19:08 -0700
changeset 149389 2bbafd515595870e96e57214cfb5331171900970
parent 149388 1e6a27764acd0f9170d561f2a5748d0e7b74515f
child 149390 ff2b4ebb4053b5ce8d280003de59bd42e253ba9c
push id25386
push useremorley@mozilla.com
push dateTue, 01 Oct 2013 09:29:22 +0000
treeherdermozilla-central@6856c45f3688 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs609896
milestone27.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 609896 - Optimize copy and initialization of DenseElements; r=billm
js/public/GCAPI.h
js/src/jsobj.h
--- a/js/public/GCAPI.h
+++ b/js/public/GCAPI.h
@@ -3,17 +3,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef js_GCAPI_h
 #define js_GCAPI_h
 
 #include "mozilla/NullPtr.h"
- 
+
 #include "js/HeapAPI.h"
 #include "js/RootingAPI.h"
 #include "js/Value.h"
 
 namespace JS {
 
 #define GCREASONS(D)                            \
     /* Reasons internal to the JS engine */     \
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -14,16 +14,17 @@
  * ordered property names, called the map; and a dense vector of property
  * values, called slots.  The map/slot pointer pair is GC'ed, while the map
  * is reference counted and the slot vector is malloc'ed.
  */
 
 #include "mozilla/MemoryReporting.h"
 
 #include "gc/Marking.h"
+#include "js/GCAPI.h"
 #include "vm/ObjectImpl.h"
 #include "vm/Shape.h"
 
 namespace JS {
 struct ObjectsExtraSizes;
 }
 
 namespace js {
@@ -633,26 +634,31 @@ class JSObject : public js::ObjectImpl
                                                 uint32_t index, const js::Value &val);
     static inline void setDenseElementHole(js::ExclusiveContext *cx,
                                            js::HandleObject obj, uint32_t index);
     static inline void removeDenseElementForSparseIndex(js::ExclusiveContext *cx,
                                                         js::HandleObject obj, uint32_t index);
 
     void copyDenseElements(uint32_t dstStart, const js::Value *src, uint32_t count) {
         JS_ASSERT(dstStart + count <= getDenseCapacity());
-        JS::Zone *zone = this->zone();
-        for (uint32_t i = 0; i < count; ++i)
-            elements[dstStart + i].set(zone, this, js::HeapSlot::Element, dstStart + i, src[i]);
+        JSRuntime *rt = runtimeFromMainThread();
+        if (JS::IsIncrementalBarrierNeeded(rt)) {
+            JS::Zone *zone = this->zone();
+            for (uint32_t i = 0; i < count; ++i)
+                elements[dstStart + i].set(zone, this, js::HeapSlot::Element, dstStart + i, src[i]);
+        } else {
+            memcpy(&elements[dstStart], src, count * sizeof(js::HeapSlot));
+            DenseRangeWriteBarrierPost(rt, this, dstStart, count);
+        }
     }
 
     void initDenseElements(uint32_t dstStart, const js::Value *src, uint32_t count) {
         JS_ASSERT(dstStart + count <= getDenseCapacity());
-        JSRuntime *rt = runtimeFromMainThread();
-        for (uint32_t i = 0; i < count; ++i)
-            elements[dstStart + i].init(rt, this, js::HeapSlot::Element, dstStart + i, src[i]);
+        memcpy(&elements[dstStart], src, count * sizeof(js::HeapSlot));
+        DenseRangeWriteBarrierPost(runtimeFromMainThread(), this, dstStart, count);
     }
 
     void moveDenseElements(uint32_t dstStart, uint32_t srcStart, uint32_t count) {
         JS_ASSERT(dstStart + count <= getDenseCapacity());
         JS_ASSERT(srcStart + count <= getDenseInitializedLength());
 
         /*
          * Using memmove here would skip write barriers. Also, we need to consider