Bug 1107365 - Make TypedArray's set() method able to handle shared and nonshared. r=waldo
authorLars T Hansen <lhansen@mozilla.com>
Tue, 16 Dec 2014 04:43:26 +0100
changeset 219876 4b1566e6f3d0c0c21726657323a1355b4eea4637
parent 219875 389db774250d96f25a80567880395b33a64a786c
child 219877 9b4df39f37e8e3873f4e3235026ab4bce8b864d3
push id10419
push usercbook@mozilla.com
push dateTue, 16 Dec 2014 12:45:27 +0000
treeherderfx-team@ec87657146eb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswaldo
bugs1107365
milestone37.0a1
Bug 1107365 - Make TypedArray's set() method able to handle shared and nonshared. r=waldo
js/src/vm/TypedArrayCommon.h
--- a/js/src/vm/TypedArrayCommon.h
+++ b/js/src/vm/TypedArrayCommon.h
@@ -134,45 +134,48 @@ class ElementSpecific
 
   public:
     /*
      * Copy |source|'s elements into |target|, starting at |target[offset]|.
      * Act as if the assignments occurred from a fresh copy of |source|, in
      * case the two memory ranges overlap.
      */
     static bool
-    setFromTypedArray(JSContext *cx,
-                       Handle<SomeTypedArray*> target, Handle<SomeTypedArray*> source,
-                       uint32_t offset)
+    setFromAnyTypedArray(JSContext *cx,
+                         Handle<SomeTypedArray*> target, HandleObject source,
+                         uint32_t offset)
     {
         MOZ_ASSERT(SpecificArray::ArrayTypeID() == target->type(),
-                   "calling wrong setFromTypedArray specialization");
+                   "calling wrong setFromAnyTypedArray specialization");
 
         MOZ_ASSERT(offset <= target->length());
-        MOZ_ASSERT(source->length() <= target->length() - offset);
+        MOZ_ASSERT(AnyTypedArrayLength(source) <= target->length() - offset);
 
-        if (SomeTypedArray::sameBuffer(target, source))
-            return setFromOverlappingTypedArray(cx, target, source, offset);
+        if (source->is<SomeTypedArray>()) {
+            Rooted<SomeTypedArray*> src(cx, source.as<SomeTypedArray>());
+            if (SomeTypedArray::sameBuffer(target, src))
+                return setFromOverlappingTypedArray(cx, target, src, offset);
+        }
 
         T *dest = static_cast<T*>(target->viewData()) + offset;
-        uint32_t count = source->length();
+        uint32_t count = AnyTypedArrayLength(source);
 
-        if (source->type() == target->type()) {
-            mozilla::PodCopy(dest, static_cast<T*>(source->viewData()), count);
+        if (AnyTypedArrayType(source) == target->type()) {
+            mozilla::PodCopy(dest, static_cast<T*>(AnyTypedArrayViewData(source)), count);
             return true;
         }
 
 #ifdef __arm__
 #  define JS_VOLATILE_ARM volatile // Inhibit unaligned accesses on ARM.
 #else
 #  define JS_VOLATILE_ARM /* nothing */
 #endif
 
-        void *data = source->viewData();
-        switch (source->type()) {
+        void *data = AnyTypedArrayViewData(source);
+        switch (AnyTypedArrayType(source)) {
           case Scalar::Int8: {
             JS_VOLATILE_ARM
             int8_t *src = static_cast<int8_t*>(data);
 
             for (uint32_t i = 0; i < count; ++i)
                 *dest++ = T(*src++);
             break;
           }
@@ -222,17 +225,17 @@ class ElementSpecific
           case Scalar::Float64: {
             JS_VOLATILE_ARM
             double *src = static_cast<double*>(data);
             for (uint32_t i = 0; i < count; ++i)
                 *dest++ = T(*src++);
             break;
           }
           default:
-            MOZ_CRASH("setFromTypedArray with a typed array with bogus type");
+            MOZ_CRASH("setFromAnyTypedArray with a typed array with bogus type");
         }
 
 #undef JS_VOLATILE_ARM
 
         return true;
     }
 
     /*
@@ -241,18 +244,18 @@ class ElementSpecific
      * typed array.
      */
     static bool
     setFromNonTypedArray(JSContext *cx, Handle<SomeTypedArray*> target, HandleObject source,
                          uint32_t len, uint32_t offset = 0)
     {
         MOZ_ASSERT(target->type() == SpecificArray::ArrayTypeID(),
                    "target type and NativeType must match");
-        MOZ_ASSERT(!source->is<SomeTypedArray>(),
-                   "use setFromTypedArray instead of this method");
+        MOZ_ASSERT(!IsAnyTypedArray(source),
+                   "use setFromAnyTypedArray instead of this method");
 
         uint32_t i = 0;
         if (source->isNative()) {
             // Attempt fast-path infallible conversion of dense elements up to
             // the first potentially side-effectful lookup or conversion.
             uint32_t bound = Min(source->as<NativeObject>().getDenseInitializedLength(), len);
 
             T *dest = static_cast<T*>(target->viewData()) + offset;
@@ -664,24 +667,23 @@ class TypedArrayMethods
                 // the given offset is bogus
                 JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
                                      JSMSG_TYPED_ARRAY_BAD_INDEX, "2");
                 return false;
             }
         }
 
         RootedObject arg0(cx, &args[0].toObject());
-        if (arg0->is<SomeTypedArray>()) {
-            Rooted<SomeTypedArray*> source(cx, &arg0->as<SomeTypedArray>());
-            if (source->length() > target->length() - offset) {
+        if (IsAnyTypedArray(arg0)) {
+            if (AnyTypedArrayLength(arg0) > target->length() - offset) {
                 JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_BAD_ARRAY_LENGTH);
                 return false;
             }
 
-            if (!setFromTypedArray(cx, target, source, offset))
+            if (!setFromAnyTypedArray(cx, target, arg0, offset))
                 return false;
         } else {
             uint32_t len;
             if (!GetLengthProperty(cx, arg0, &len))
                 return false;
 
             if (uint32_t(offset) > target->length() || len > target->length() - offset) {
                 JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_BAD_ARRAY_LENGTH);
@@ -698,62 +700,62 @@ class TypedArrayMethods
 
     static bool
     setFromArrayLike(JSContext *cx, Handle<SomeTypedArray*> target, HandleObject source, uint32_t len,
                      uint32_t offset = 0)
     {
         MOZ_ASSERT(offset <= target->length());
         MOZ_ASSERT(len <= target->length() - offset);
 
-        if (source->is<SomeTypedArray>()) {
-            Rooted<SomeTypedArray*> src(cx, &source->as<SomeTypedArray>());
-            return setFromTypedArray(cx, target, src, offset);
-        }
+        if (IsAnyTypedArray(source))
+            return setFromAnyTypedArray(cx, target, source, offset);
 
         return setFromNonTypedArray(cx, target, source, len, offset);
     }
 
   private:
     static bool
-    setFromTypedArray(JSContext *cx, Handle<SomeTypedArray*> target, Handle<SomeTypedArray*> source,
-                      uint32_t offset)
+    setFromAnyTypedArray(JSContext *cx, Handle<SomeTypedArray*> target, HandleObject source,
+                         uint32_t offset)
     {
+        MOZ_ASSERT(IsAnyTypedArray(source), "use setFromNonTypedArray");
+
         switch (target->type()) {
           case Scalar::Int8:
-            return ElementSpecific<Int8ArrayType>::setFromTypedArray(cx, target, source, offset);
+            return ElementSpecific<Int8ArrayType>::setFromAnyTypedArray(cx, target, source, offset);
           case Scalar::Uint8:
-            return ElementSpecific<Uint8ArrayType>::setFromTypedArray(cx, target, source, offset);
+            return ElementSpecific<Uint8ArrayType>::setFromAnyTypedArray(cx, target, source, offset);
           case Scalar::Int16:
-            return ElementSpecific<Int16ArrayType>::setFromTypedArray(cx, target, source, offset);
+            return ElementSpecific<Int16ArrayType>::setFromAnyTypedArray(cx, target, source, offset);
           case Scalar::Uint16:
-            return ElementSpecific<Uint16ArrayType>::setFromTypedArray(cx, target, source, offset);
+            return ElementSpecific<Uint16ArrayType>::setFromAnyTypedArray(cx, target, source, offset);
           case Scalar::Int32:
-            return ElementSpecific<Int32ArrayType>::setFromTypedArray(cx, target, source, offset);
+            return ElementSpecific<Int32ArrayType>::setFromAnyTypedArray(cx, target, source, offset);
           case Scalar::Uint32:
-            return ElementSpecific<Uint32ArrayType>::setFromTypedArray(cx, target, source, offset);
+            return ElementSpecific<Uint32ArrayType>::setFromAnyTypedArray(cx, target, source, offset);
           case Scalar::Float32:
-            return ElementSpecific<Float32ArrayType>::setFromTypedArray(cx, target, source, offset);
+            return ElementSpecific<Float32ArrayType>::setFromAnyTypedArray(cx, target, source, offset);
           case Scalar::Float64:
-            return ElementSpecific<Float64ArrayType>::setFromTypedArray(cx, target, source, offset);
+            return ElementSpecific<Float64ArrayType>::setFromAnyTypedArray(cx, target, source, offset);
           case Scalar::Uint8Clamped:
-            return ElementSpecific<Uint8ClampedArrayType>::setFromTypedArray(cx, target, source, offset);
+            return ElementSpecific<Uint8ClampedArrayType>::setFromAnyTypedArray(cx, target, source, offset);
           case Scalar::Float32x4:
           case Scalar::Int32x4:
           case Scalar::MaxTypedArrayViewType:
             break;
         }
 
         MOZ_CRASH("nonsense target element type");
     }
 
     static bool
     setFromNonTypedArray(JSContext *cx, Handle<SomeTypedArray*> target, HandleObject source,
                          uint32_t len, uint32_t offset)
     {
-        MOZ_ASSERT(!source->is<SomeTypedArray>(), "use setFromTypedArray");
+        MOZ_ASSERT(!IsAnyTypedArray(source), "use setFromAnyTypedArray");
 
         switch (target->type()) {
           case Scalar::Int8:
             return ElementSpecific<Int8ArrayType>::setFromNonTypedArray(cx, target, source, len, offset);
           case Scalar::Uint8:
             return ElementSpecific<Uint8ArrayType>::setFromNonTypedArray(cx, target, source, len, offset);
           case Scalar::Int16:
             return ElementSpecific<Int16ArrayType>::setFromNonTypedArray(cx, target, source, len, offset);