Title: [267827] trunk/Source/_javascript_Core
Revision
267827
Author
ysuz...@apple.com
Date
2020-10-01 04:03:38 -0700 (Thu, 01 Oct 2020)

Log Message

[JSC] Define Array#sort's implementation functions as globalPrivate
https://bugs.webkit.org/show_bug.cgi?id=217168

Reviewed by Ross Kirsling.

Now, these Array#sort's implementation functions are not capturing any heap variables. So we can make them @globalPrivate,
this avoids function allocations in LLInt / Baseline / DFG in Array#sort.

* builtins/ArrayPrototype.js:
(globalPrivate.sortMin):
(globalPrivate.sortStringComparator):
(globalPrivate.sortCompact):
(globalPrivate.sortCommit):
(globalPrivate.sortMerge):
(globalPrivate.sortMergeSort):
(globalPrivate.sortBucketSort):
(sort):
(sort.min): Deleted.
(sort.stringComparator): Deleted.
(sort.compact): Deleted.
(sort.commit): Deleted.
(sort.merge): Deleted.
(sort.mergeSort): Deleted.
(sort.bucketSort): Deleted.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (267826 => 267827)


--- trunk/Source/_javascript_Core/ChangeLog	2020-10-01 10:51:29 UTC (rev 267826)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-10-01 11:03:38 UTC (rev 267827)
@@ -1,5 +1,32 @@
 2020-10-01  Yusuke Suzuki  <ysuz...@apple.com>
 
+        [JSC] Define Array#sort's implementation functions as globalPrivate
+        https://bugs.webkit.org/show_bug.cgi?id=217168
+
+        Reviewed by Ross Kirsling.
+
+        Now, these Array#sort's implementation functions are not capturing any heap variables. So we can make them @globalPrivate,
+        this avoids function allocations in LLInt / Baseline / DFG in Array#sort.
+
+        * builtins/ArrayPrototype.js:
+        (globalPrivate.sortMin):
+        (globalPrivate.sortStringComparator):
+        (globalPrivate.sortCompact):
+        (globalPrivate.sortCommit):
+        (globalPrivate.sortMerge):
+        (globalPrivate.sortMergeSort):
+        (globalPrivate.sortBucketSort):
+        (sort):
+        (sort.min): Deleted.
+        (sort.stringComparator): Deleted.
+        (sort.compact): Deleted.
+        (sort.commit): Deleted.
+        (sort.merge): Deleted.
+        (sort.mergeSort): Deleted.
+        (sort.bucketSort): Deleted.
+
+2020-10-01  Yusuke Suzuki  <ysuz...@apple.com>
+
         [JSC] Do not use std::function in setPrivateField and definePrivateField
         https://bugs.webkit.org/show_bug.cgi?id=217167
 

Modified: trunk/Source/_javascript_Core/builtins/ArrayPrototype.js (267826 => 267827)


--- trunk/Source/_javascript_Core/builtins/ArrayPrototype.js	2020-10-01 10:51:29 UTC (rev 267826)
+++ trunk/Source/_javascript_Core/builtins/ArrayPrototype.js	2020-10-01 11:03:38 UTC (rev 267827)
@@ -306,157 +306,180 @@
     return false;
 }
 
-function sort(comparator)
+@globalPrivate
+function sortMin(a, b)
 {
     "use strict";
 
-    function min(a, b)
-    {
-        return a < b ? a : b;
-    }
+    return a < b ? a : b;
+}
 
-    function stringComparator(a, b)
-    {
-        var aString = a.string;
-        var bString = b.string;
+@globalPrivate
+function sortStringComparator(a, b)
+{
+    "use strict";
 
-        if (aString === bString)
-            return 0;
+    var aString = a.string;
+    var bString = b.string;
 
-        return aString > bString ? 1 : -1;
-    }
+    if (aString === bString)
+        return 0;
 
-    function compact(receiver, receiverLength, compacted, isStringSort)
-    {
-        var undefinedCount = 0;
-        var compactedIndex = 0;
+    return aString > bString ? 1 : -1;
+}
 
-        for (var i = 0; i < receiverLength; ++i) {
-            if (i in receiver) {
-                var value = receiver[i];
-                if (value === @undefined)
-                    ++undefinedCount;
-                else {
-                    @putByValDirect(compacted, compactedIndex, 
-                        isStringSort ? {string: @toString(value), value} : value);
-                    ++compactedIndex;
-                }
+@globalPrivate
+function sortCompact(receiver, receiverLength, compacted, isStringSort)
+{
+    "use strict";
+
+    var undefinedCount = 0;
+    var compactedIndex = 0;
+
+    for (var i = 0; i < receiverLength; ++i) {
+        if (i in receiver) {
+            var value = receiver[i];
+            if (value === @undefined)
+                ++undefinedCount;
+            else {
+                @putByValDirect(compacted, compactedIndex,
+                    isStringSort ? {string: @toString(value), value} : value);
+                ++compactedIndex;
             }
         }
-
-        return undefinedCount;
     }
 
+    return undefinedCount;
+}
+
+@globalPrivate
+function sortCommit(receiver, receiverLength, sorted, undefinedCount)
+{
+    "use strict";
+
     // Move undefineds and holes to the end of an array. Result is [values..., undefineds..., holes...].
-    function commit(receiver, receiverLength, sorted, undefinedCount)
-    {
-        @assert(@isJSArray(sorted));
-        var sortedLength = sorted.length;
-        @assert(sortedLength + undefinedCount <= receiverLength);
 
-        var i = 0;
-        if (@isJSArray(receiver) && sortedLength >= 64 && typeof sorted[0] !== "number") { // heuristic
-            @appendMemcpy(receiver, sorted, 0);
-            i = sortedLength;
-        } else {
-            for (; i < sortedLength; ++i)
-                receiver[i] = sorted[i];
-        }
+    @assert(@isJSArray(sorted));
+    var sortedLength = sorted.length;
+    @assert(sortedLength + undefinedCount <= receiverLength);
 
-        for (; i < sortedLength + undefinedCount; ++i)
-            receiver[i] = @undefined;
-
-        for (; i < receiverLength; ++i)
-            delete receiver[i];
+    var i = 0;
+    if (@isJSArray(receiver) && sortedLength >= 64 && typeof sorted[0] !== "number") { // heuristic
+        @appendMemcpy(receiver, sorted, 0);
+        i = sortedLength;
+    } else {
+        for (; i < sortedLength; ++i)
+            receiver[i] = sorted[i];
     }
 
-    function merge(dst, src, srcIndex, srcEnd, width, comparator)
-    {
-        var left = srcIndex;
-        var leftEnd = min(left + width, srcEnd);
-        var right = leftEnd;
-        var rightEnd = min(right + width, srcEnd);
+    for (; i < sortedLength + undefinedCount; ++i)
+        receiver[i] = @undefined;
 
-        for (var dstIndex = left; dstIndex < rightEnd; ++dstIndex) {
-            if (right < rightEnd) {
-                if (left >= leftEnd) {
-                    @putByValDirect(dst, dstIndex, src[right]);
-                    ++right;
-                    continue;
-                }
+    for (; i < receiverLength; ++i)
+        delete receiver[i];
+}
 
-                // See https://bugs.webkit.org/show_bug.cgi?id=47825 on boolean special-casing
-                var comparisonResult = comparator(src[right], src[left]);
-                if (comparisonResult === false || comparisonResult < 0) {
-                    @putByValDirect(dst, dstIndex, src[right]);
-                    ++right;
-                    continue;
-                }
 
+@globalPrivate
+function sortMerge(dst, src, srcIndex, srcEnd, width, comparator)
+{
+    "use strict";
+
+    var left = srcIndex;
+    var leftEnd = @sortMin(left + width, srcEnd);
+    var right = leftEnd;
+    var rightEnd = @sortMin(right + width, srcEnd);
+
+    for (var dstIndex = left; dstIndex < rightEnd; ++dstIndex) {
+        if (right < rightEnd) {
+            if (left >= leftEnd) {
+                @putByValDirect(dst, dstIndex, src[right]);
+                ++right;
+                continue;
             }
 
-            @putByValDirect(dst, dstIndex, src[left]);
-            ++left;
+            // See https://bugs.webkit.org/show_bug.cgi?id=47825 on boolean special-casing
+            var comparisonResult = comparator(src[right], src[left]);
+            if (comparisonResult === false || comparisonResult < 0) {
+                @putByValDirect(dst, dstIndex, src[right]);
+                ++right;
+                continue;
+            }
+
         }
+
+        @putByValDirect(dst, dstIndex, src[left]);
+        ++left;
     }
+}
 
-    function mergeSort(array, comparator)
-    {
-        var valueCount = array.length;
-        var buffer = @newArrayWithSize(valueCount);
+@globalPrivate
+function sortMergeSort(array, comparator)
+{
+    "use strict";
 
-        var dst = buffer;
-        var src = ""
-        for (var width = 1; width < valueCount; width *= 2) {
-            for (var srcIndex = 0; srcIndex < valueCount; srcIndex += 2 * width)
-                merge(dst, src, srcIndex, valueCount, width, comparator);
+    var valueCount = array.length;
+    var buffer = @newArrayWithSize(valueCount);
 
-            var tmp = src;
-            src = ""
-            dst = tmp;
-        }
+    var dst = buffer;
+    var src = ""
+    for (var width = 1; width < valueCount; width *= 2) {
+        for (var srcIndex = 0; srcIndex < valueCount; srcIndex += 2 * width)
+            @sortMerge(dst, src, srcIndex, valueCount, width, comparator);
 
-        return src;
+        var tmp = src;
+        src = ""
+        dst = tmp;
     }
 
-    function bucketSort(array, dst, bucket, depth)
-    {
-        if (bucket.length < 32 || depth > 32) {
-            var sorted = mergeSort(bucket, stringComparator);
-            for (var i = 0; i < sorted.length; ++i) {
-                @putByValDirect(array, dst, sorted[i].value);
-                ++dst;
-            }
-            return dst;
-        }
+    return src;
+}
 
-        var buckets = [ ];
-        for (var i = 0; i < bucket.length; ++i) {
-            var entry = bucket[i];
-            var string = entry.string;
-            if (string.length == depth) {
-                @putByValDirect(array, dst, entry.value);
-                ++dst;
-                continue;
-            }
+@globalPrivate
+function sortBucketSort(array, dst, bucket, depth)
+{
+    "use strict";
 
-            var c = string.@charCodeAt(depth);
-            var cBucket = buckets[c];
-            if (cBucket)
-                @putByValDirect(cBucket, cBucket.length, entry);
-            else
-                @putByValDirect(buckets, c, [ entry ]);
+    if (bucket.length < 32 || depth > 32) {
+        var sorted = @sortMergeSort(bucket, @sortStringComparator);
+        for (var i = 0; i < sorted.length; ++i) {
+            @putByValDirect(array, dst, sorted[i].value);
+            ++dst;
         }
+        return dst;
+    }
 
-        for (var i = 0; i < buckets.length; ++i) {
-            if (!buckets[i])
-                continue;
-            dst = bucketSort(array, dst, buckets[i], depth + 1);
+    var buckets = [ ];
+    for (var i = 0; i < bucket.length; ++i) {
+        var entry = bucket[i];
+        var string = entry.string;
+        if (string.length == depth) {
+            @putByValDirect(array, dst, entry.value);
+            ++dst;
+            continue;
         }
 
-        return dst;
+        var c = string.@charCodeAt(depth);
+        var cBucket = buckets[c];
+        if (cBucket)
+            @putByValDirect(cBucket, cBucket.length, entry);
+        else
+            @putByValDirect(buckets, c, [ entry ]);
     }
 
+    for (var i = 0; i < buckets.length; ++i) {
+        if (!buckets[i])
+            continue;
+        dst = @sortBucketSort(array, dst, buckets[i], depth + 1);
+    }
+
+    return dst;
+}
+
+function sort(comparator)
+{
+    "use strict";
+
     var isStringSort = false;
     if (comparator === @undefined)
         isStringSort = true;
@@ -473,15 +496,15 @@
 
     var compacted = [ ];
     var sorted = null;
-    var undefinedCount = compact(receiver, receiverLength, compacted, isStringSort);
+    var undefinedCount = @sortCompact(receiver, receiverLength, compacted, isStringSort);
 
     if (isStringSort) {
         sorted = @newArrayWithSize(compacted.length);
-        bucketSort(sorted, 0, compacted, 0);
+        @sortBucketSort(sorted, 0, compacted, 0);
     } else
-        sorted = mergeSort(compacted, comparator);
+        sorted = @sortMergeSort(compacted, comparator);
 
-    commit(receiver, receiverLength, sorted, undefinedCount);
+    @sortCommit(receiver, receiverLength, sorted, undefinedCount);
     return receiver;
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to