Bug 1398751 - Part 1: Add fast-path for typed arrays in js::GetElements to speed-up Function.apply with typed arrays. r=evilpie
authorAndré Bargull <andre.bargull@gmail.com>
Mon, 11 Sep 2017 22:06:39 +0200
changeset 380346 fdbf2ccf813ece8338dc0ef37030b1056e61bf26
parent 380345 1cfe6ff240196f646da8c60d1ce3da2999613a09
child 380347 f0f98cfb1a45ae37fecba156e217aca5f31f1c70
push id94902
push userryanvm@gmail.com
push dateWed, 13 Sep 2017 01:29:21 +0000
treeherdermozilla-inbound@f0f98cfb1a45 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersevilpie
bugs1398751
milestone57.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 1398751 - Part 1: Add fast-path for typed arrays in js::GetElements to speed-up Function.apply with typed arrays. r=evilpie
js/src/jsarray.cpp
js/src/vm/TypedArrayObject.cpp
js/src/vm/TypedArrayObject.h
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -450,16 +450,24 @@ js::GetElements(JSContext* cx, HandleObj
     if (aobj->is<ArgumentsObject>()) {
         ArgumentsObject& argsobj = aobj->as<ArgumentsObject>();
         if (!argsobj.hasOverriddenLength()) {
             if (argsobj.maybeGetElements(0, length, vp))
                 return true;
         }
     }
 
+    if (aobj->is<TypedArrayObject>()) {
+        TypedArrayObject* typedArray = &aobj->as<TypedArrayObject>();
+        if (typedArray->length() == length) {
+            typedArray->getElements(vp);
+            return true;
+        }
+    }
+
     if (js::GetElementsOp op = aobj->getOpsGetElements()) {
         ElementAdder adder(cx, vp, length, ElementAdder::GetElement);
         return op(cx, aobj, 0, length, &adder);
     }
 
     for (uint32_t i = 0; i < length; i++) {
         if (!GetElement(cx, aobj, aobj, i, MutableHandleValue::fromMarkedLocation(&vp[i])))
             return false;
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -1882,16 +1882,35 @@ TypedArrayObject::setElement(TypedArrayO
       case Scalar::Int32x4:
       case Scalar::MaxTypedArrayViewType:
         break;
     }
 
     MOZ_CRASH("Unknown TypedArray type");
 }
 
+void
+TypedArrayObject::getElements(Value* vp)
+{
+    uint32_t length = this->length();
+    MOZ_ASSERT_IF(length > 0, !hasDetachedBuffer());
+
+    switch (type()) {
+#define GET_ELEMENTS(T, N) \
+      case Scalar::N: \
+        for (uint32_t i = 0; i < length; ++i, ++vp) \
+            *vp = N##Array::getIndexValue(this, i); \
+        break;
+JS_FOR_EACH_TYPED_ARRAY(GET_ELEMENTS)
+#undef GET_ELEMENTS
+      default:
+        MOZ_CRASH("Unknown TypedArray type");
+    }
+}
+
 /***
  *** JS impl
  ***/
 
 /*
  * TypedArrayObject boilerplate
  */
 
--- a/js/src/vm/TypedArrayObject.h
+++ b/js/src/vm/TypedArrayObject.h
@@ -178,16 +178,22 @@ class TypedArrayObject : public NativeOb
     void assertZeroLengthArrayData() const;
 #else
     void assertZeroLengthArrayData() const {};
 #endif
 
     Value getElement(uint32_t index);
     static void setElement(TypedArrayObject& obj, uint32_t index, double d);
 
+    /*
+     * Copy all elements from this typed array to vp. vp must point to rooted
+     * memory.
+     */
+    void getElements(Value* vp);
+
     void notifyBufferDetached(JSContext* cx, void* newData);
 
     static bool
     GetTemplateObjectForNative(JSContext* cx, Native native, uint32_t len,
                                MutableHandleObject res);
 
     /*
      * Byte length above which created typed arrays and data views will have