Make @Array(size) a bytecode intrinsic
authorsbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 18 Aug 2016 17:17:41 +0000 (17:17 +0000)
committersbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 18 Aug 2016 17:17:41 +0000 (17:17 +0000)
https://bugs.webkit.org/show_bug.cgi?id=160867

Reviewed by Mark Lam.

There were a few places in the code where we were emitting `@Array(size)`
or `new @Array(size)`. Since we have a bytecode operation that already
represents this, called new_array_with_size, it's faster to just make a
bytecode intrinsic for the this operation. This patch does that and
the intrinsic is called `@newArrayWithSize`. This might be around a
1% speedup on ES6 sample bench, but it's within the noise. This is just
a good bytecode operation to have because it's common enough to
create arrays and it's good to make that fast in all tiers.

* builtins/ArrayConstructor.js:
(of):
(from):
* builtins/ArrayPrototype.js:
(filter):
(map):
(sort.stringSort):
(sort):
(concatSlowPath):
* bytecode/BytecodeIntrinsicRegistry.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::BytecodeIntrinsicNode::emit_intrinsic_isObject):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_newArrayWithSize):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@204597 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/builtins/ArrayConstructor.js
Source/JavaScriptCore/builtins/ArrayPrototype.js
Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h
Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

index 75c8b1e..4f1c57f 100644 (file)
@@ -1,3 +1,33 @@
+2016-08-18  Saam Barati  <sbarati@apple.com>
+
+        Make @Array(size) a bytecode intrinsic
+        https://bugs.webkit.org/show_bug.cgi?id=160867
+
+        Reviewed by Mark Lam.
+
+        There were a few places in the code where we were emitting `@Array(size)`
+        or `new @Array(size)`. Since we have a bytecode operation that already
+        represents this, called new_array_with_size, it's faster to just make a
+        bytecode intrinsic for the this operation. This patch does that and
+        the intrinsic is called `@newArrayWithSize`. This might be around a
+        1% speedup on ES6 sample bench, but it's within the noise. This is just
+        a good bytecode operation to have because it's common enough to
+        create arrays and it's good to make that fast in all tiers.
+
+        * builtins/ArrayConstructor.js:
+        (of):
+        (from):
+        * builtins/ArrayPrototype.js:
+        (filter):
+        (map):
+        (sort.stringSort):
+        (sort):
+        (concatSlowPath):
+        * bytecode/BytecodeIntrinsicRegistry.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::BytecodeIntrinsicNode::emit_intrinsic_isObject):
+        (JSC::BytecodeIntrinsicNode::emit_intrinsic_newArrayWithSize):
+
 2016-08-18  Rawinder Singh  <rawinder.singh-webkit@cisra.canon.com.au>
 
         [web-animations] Add Animatable, AnimationEffect, KeyframeEffect and Animation interface
index 41bc78e..5cc9e77 100644 (file)
@@ -28,7 +28,7 @@ function of(/* items... */)
     "use strict";
 
     var length = arguments.length;
-    var array = @isConstructor(this) ? new this(length) : new @Array(length);
+    var array = @isConstructor(this) ? new this(length) : @newArrayWithSize(length);
     for (var k = 0; k < length; ++k)
         @putByValDirect(array, k, arguments[k]);
     array.length = length;
@@ -87,7 +87,7 @@ function from(items /*, mapFn, thisArg */)
     var arrayLike = @Object(items);
     var arrayLikeLength = @toLength(arrayLike.length);
 
-    var result = @isConstructor(thisObj) ? new thisObj(arrayLikeLength) : new @Array(arrayLikeLength);
+    var result = @isConstructor(thisObj) ? new thisObj(arrayLikeLength) : @newArrayWithSize(arrayLikeLength);
 
     var k = 0;
     while (k < arrayLikeLength) {
index a47bf6b..09d6448 100644 (file)
@@ -213,7 +213,7 @@ function filter(callback /*, thisArg */)
         }
     }
     if (constructor === @Array || constructor === @undefined)
-        result = [];
+        result = @newArrayWithSize(0);
     else
         result = new constructor(0);
 
@@ -262,7 +262,7 @@ function map(callback /*, thisArg */)
         }
     }
     if (constructor === @Array || constructor === @undefined)
-        result = @Array(length);
+        result = @newArrayWithSize(length);
     else
         result = new constructor(length);
 
@@ -630,7 +630,7 @@ function sort(comparator)
 
         var valueCount = compact(array, length);
 
-        var strings = new @Array(valueCount);
+        var strings = @newArrayWithSize(valueCount);
         for (var i = 0; i < valueCount; ++i)
             strings[i] = { string: @toString(array[i]), value: array[i] };
 
@@ -680,7 +680,7 @@ function concatSlowPath()
     var argCount = arguments.length;
     var result;
     if (constructor === @Array || constructor === @undefined)
-        result = [];
+        result = @newArrayWithSize(0);
     else
         result = new constructor(0);
     var resultIsArray = @isJSArray(result);
index e10ec23..a9d48ce 100644 (file)
@@ -47,7 +47,8 @@ class Identifier;
     macro(tryGetById) \
     macro(putByValDirect) \
     macro(toNumber) \
-    macro(toString)
+    macro(toString) \
+    macro(newArrayWithSize) \
 
 #define JSC_COMMON_BYTECODE_INTRINSIC_CONSTANTS_EACH_NAME(macro) \
     macro(undefined) \
index 4b2d5ba..e945e1a 100644 (file)
@@ -953,6 +953,17 @@ RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isObject(BytecodeGenerator& ge
     return generator.moveToDestinationIfNeeded(dst, generator.emitIsObject(generator.tempDestination(dst), src.get()));
 }
 
+RegisterID* BytecodeIntrinsicNode::emit_intrinsic_newArrayWithSize(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst)
+{
+    ArgumentListNode* node = m_args->m_listNode;
+    RefPtr<RegisterID> size = generator.emitNode(node);
+    ASSERT(!node->m_next);
+
+    RefPtr<RegisterID> finalDestination = generator.finalDestination(dst);
+    generator.emitNewArrayWithSize(finalDestination.get(), size.get());
+    return finalDestination.get();
+}
+
 
 #define JSC_DECLARE_BYTECODE_INTRINSIC_CONSTANT_GENERATORS(name) \
     RegisterID* BytecodeIntrinsicNode::emit_intrinsic_##name(BytecodeGenerator& generator, RegisterID* dst) \