Ensure that typed array constructors are crankshaftable.
authordslomov@chromium.org <dslomov@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 6 Nov 2013 16:28:38 +0000 (16:28 +0000)
committerdslomov@chromium.org <dslomov@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 6 Nov 2013 16:28:38 +0000 (16:28 +0000)
Also, do not allocate sub-closures for every call to typed array constructor.

R=yangguo@chromium.org

Review URL: https://codereview.chromium.org/59913003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17528 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/typedarray.js

index f2b5d2d..20a50c5 100644 (file)
@@ -48,65 +48,66 @@ FUNCTION(9, Uint8ClampedArray, 1)
 endmacro
 
 macro TYPED_ARRAY_CONSTRUCTOR(ARRAY_ID, NAME, ELEMENT_SIZE)
-  function NAMEConstructor(arg1, arg2, arg3) {
-    function ConstructByArrayBuffer(obj, buffer, byteOffset, length) {
-      var offset = ToPositiveInteger(byteOffset, "invalid_typed_array_length")
+  function NAMEConstructByArrayBuffer(obj, buffer, byteOffset, length) {
+    var offset = ToPositiveInteger(byteOffset, "invalid_typed_array_length")
 
-      if (offset % ELEMENT_SIZE !== 0) {
-        throw MakeRangeError("invalid_typed_array_alignment",
-            "start offset", "NAME", ELEMENT_SIZE);
-      }
-      var bufferByteLength = %ArrayBufferGetByteLength(buffer);
-      if (offset > bufferByteLength) {
-        throw MakeRangeError("invalid_typed_array_offset");
-      }
+    if (offset % ELEMENT_SIZE !== 0) {
+      throw MakeRangeError("invalid_typed_array_alignment",
+          "start offset", "NAME", ELEMENT_SIZE);
+    }
+    var bufferByteLength = buffer.byteLength;
+    if (offset > bufferByteLength) {
+      throw MakeRangeError("invalid_typed_array_offset");
+    }
 
-      var newByteLength;
-      var newLength;
-      if (IS_UNDEFINED(length)) {
-        if (bufferByteLength % ELEMENT_SIZE !== 0) {
-          throw MakeRangeError("invalid_typed_array_alignment",
-            "byte length", "NAME", ELEMENT_SIZE);
-        }
-        newByteLength = bufferByteLength - offset;
-        newLength = newByteLength / ELEMENT_SIZE;
-      } else {
-        var newLength = ToPositiveInteger(length, "invalid_typed_array_length");
-        newByteLength = newLength * ELEMENT_SIZE;
-      }
-      if (offset + newByteLength > bufferByteLength) {
-        throw MakeRangeError("invalid_typed_array_length");
+    var newByteLength;
+    var newLength;
+    if (IS_UNDEFINED(length)) {
+      if (bufferByteLength % ELEMENT_SIZE !== 0) {
+        throw MakeRangeError("invalid_typed_array_alignment",
+          "byte length", "NAME", ELEMENT_SIZE);
       }
-      %TypedArrayInitialize(obj, ARRAY_ID, buffer, offset, newByteLength);
+      newByteLength = bufferByteLength - offset;
+      newLength = newByteLength / ELEMENT_SIZE;
+    } else {
+      var newLength = ToPositiveInteger(length, "invalid_typed_array_length");
+      newByteLength = newLength * ELEMENT_SIZE;
     }
-
-    function ConstructByLength(obj, length) {
-      var l = ToPositiveInteger(length, "invalid_typed_array_length");
-      var byteLength = l * ELEMENT_SIZE;
-      var buffer = new $ArrayBuffer(byteLength);
-      %TypedArrayInitialize(obj, ARRAY_ID, buffer, 0, byteLength);
+    if (offset + newByteLength > bufferByteLength) {
+      throw MakeRangeError("invalid_typed_array_length");
     }
+    %TypedArrayInitialize(obj, ARRAY_ID, buffer, offset, newByteLength);
+  }
 
-    function ConstructByArrayLike(obj, arrayLike) {
-      var length = arrayLike.length;
-      var l = ToPositiveInteger(length, "invalid_typed_array_length");
-      if(!%TypedArrayInitializeFromArrayLike(obj, ARRAY_ID, arrayLike, l)) {
-        for (var i = 0; i < l; i++) {
-          // It is crucial that we let any execptions from arrayLike[i]
-          // propagate outside the function.
-          obj[i] = arrayLike[i];
-        }
+  function NAMEConstructByLength(obj, length) {
+    var l = ToPositiveInteger(length, "invalid_typed_array_length");
+    var byteLength = l * ELEMENT_SIZE;
+    var buffer = new $ArrayBuffer(byteLength);
+    %TypedArrayInitialize(obj, ARRAY_ID, buffer, 0, byteLength);
+  }
+
+  function NAMEConstructByArrayLike(obj, arrayLike) {
+    var length = arrayLike.length;
+    var l = ToPositiveInteger(length, "invalid_typed_array_length");
+    if(!%TypedArrayInitializeFromArrayLike(obj, ARRAY_ID, arrayLike, l)) {
+      for (var i = 0; i < l; i++) {
+        // It is crucial that we let any execptions from arrayLike[i]
+        // propagate outside the function.
+        obj[i] = arrayLike[i];
       }
     }
+  }
+
+  function NAMEConstructor(arg1, arg2, arg3) {
 
     if (%_IsConstructCall()) {
       if (IS_ARRAYBUFFER(arg1)) {
-        ConstructByArrayBuffer(this, arg1, arg2, arg3);
+        NAMEConstructByArrayBuffer(this, arg1, arg2, arg3);
       } else if (IS_NUMBER(arg1) || IS_STRING(arg1) ||
                  IS_BOOLEAN(arg1) || IS_UNDEFINED(arg1)) {
-        ConstructByLength(this, arg1);
+        NAMEConstructByLength(this, arg1);
       } else {
-        ConstructByArrayLike(this, arg1);
+        NAMEConstructByArrayLike(this, arg1);
       }
     } else {
       throw MakeTypeError("constructor_not_function", ["NAME"])
@@ -284,7 +285,6 @@ function SetupTypedArray(constructor, fun, elementSize) {
   ));
 }
 
-
 macro SETUP_TYPED_ARRAY(ARRAY_ID, NAME, ELEMENT_SIZE)
   SetupTypedArray (global.NAME, NAMEConstructor, ELEMENT_SIZE);
 endmacro