Changeset 216137 in webkit


Ignore:
Timestamp:
May 3, 2017 1:33:01 PM (7 years ago)
Author:
keith_miller@apple.com
Message:

Different behaviour with the .sort(callback) method (unlike Firefox & Chrome)
https://bugs.webkit.org/show_bug.cgi?id=47825

Reviewed by Saam Barati.

JSTests:

  • stress/sorting-boolean-result-comparator.js: Added.

(checkArray):

Source/JavaScriptCore:

This patch makes our sort function match the behavior of Firefox
and Chrome when the result of the comparison function is a
boolean. When we first switched to using merge sort, it regressed
JQuery sorting of DOM nodes by 30%. The regression was do to the
fact that JQuery was using compareDocumentPosition to compare the
locations of objects. Since one of the benchmarks would pass a
reverse sorted list to the sort function we would end up walking
the entire DOM to do comparisons. The solution to this was to
merge based on comparison(right, left) rather than
comparison(left, right). Although, in practice this does nothing
since sort could just as easily receive an already sorted list and
we're back in the same spot.

The downside of sorting with comparison(right, left) is that to
maintain stability when sorting, you only want to merge from right
when the comparison function returns a negative value. This is
where the problem with booleans comes in. Since booleans toNumber
false to 0 and true to 1 both values are "equal". This patch fixes
this by special casing boolean return values.

  • builtins/ArrayPrototype.js:

(sort.merge):

LayoutTests:

Fix broken test.

  • http/tests/inspector/worker/blob-script-with-cross-domain-imported-scripts-expected.txt:
Location:
trunk
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r216090 r216137  
     12017-05-03  Keith Miller  <keith_miller@apple.com>
     2
     3        Different behaviour with the .sort(callback) method (unlike Firefox & Chrome)
     4        https://bugs.webkit.org/show_bug.cgi?id=47825
     5
     6        Reviewed by Saam Barati.
     7
     8        * stress/sorting-boolean-result-comparator.js: Added.
     9        (checkArray):
     10
    1112017-05-02  David Kilzer  <ddkilzer@apple.com>
    212
  • trunk/LayoutTests/ChangeLog

    r216136 r216137  
     12017-05-03  Keith Miller  <keith_miller@apple.com>
     2
     3        Different behaviour with the .sort(callback) method (unlike Firefox & Chrome)
     4        https://bugs.webkit.org/show_bug.cgi?id=47825
     5
     6        Reviewed by Saam Barati.
     7
     8        Fix broken test.
     9
     10        * http/tests/inspector/worker/blob-script-with-cross-domain-imported-scripts-expected.txt:
     11
    1122017-05-03  Matt Lewis  <jlewis3@apple.com>
    213
  • trunk/LayoutTests/http/tests/inspector/worker/blob-script-with-cross-domain-imported-scripts-expected.txt

    r210279 r216137  
    99http://localhost:8000/inspector/worker/resources/worker-blob-import-script.js
    1010SCRIPTS:
    11 blob:<sanitized>
    1211http://localhost:8000/inspector/worker/resources/worker-blob-script.js
    1312http://localhost:8000/inspector/worker/resources/worker-blob-import-script.js
     13blob:<sanitized>
    1414
  • trunk/Source/JavaScriptCore/ChangeLog

    r216122 r216137  
     12017-05-03  Keith Miller  <keith_miller@apple.com>
     2
     3        Different behaviour with the .sort(callback) method (unlike Firefox & Chrome)
     4        https://bugs.webkit.org/show_bug.cgi?id=47825
     5
     6        Reviewed by Saam Barati.
     7
     8        This patch makes our sort function match the behavior of Firefox
     9        and Chrome when the result of the comparison function is a
     10        boolean. When we first switched to using merge sort, it regressed
     11        JQuery sorting of DOM nodes by 30%. The regression was do to the
     12        fact that JQuery was using compareDocumentPosition to compare the
     13        locations of objects. Since one of the benchmarks would pass a
     14        reverse sorted list to the sort function we would end up walking
     15        the entire DOM to do comparisons. The solution to this was to
     16        merge based on comparison(right, left) rather than
     17        comparison(left, right). Although, in practice this does nothing
     18        since sort could just as easily receive an already sorted list and
     19        we're back in the same spot.
     20
     21        The downside of sorting with comparison(right, left) is that to
     22        maintain stability when sorting, you only want to merge from right
     23        when the comparison function returns a negative value. This is
     24        where the problem with booleans comes in. Since booleans toNumber
     25        false to 0 and true to 1 both values are "equal". This patch fixes
     26        this by special casing boolean return values.
     27
     28
     29        * builtins/ArrayPrototype.js:
     30        (sort.merge):
     31
    1322017-05-03  Andy VanWagoner  <thetalecrafter@gmail.com>
    233
  • trunk/Source/JavaScriptCore/builtins/ArrayPrototype.js

    r212019 r216137  
    544544        for (var dstIndex = left; dstIndex < rightEnd; ++dstIndex) {
    545545            if (right < rightEnd) {
    546                 if (left >= leftEnd || comparator(src[right], src[left]) < 0) {
     546                if (left >= leftEnd) {
    547547                    dst[dstIndex] = src[right++];
    548548                    continue;
    549549                }
     550
     551                let comparisonResult = comparator(src[right], src[left]);
     552                if ((typeof comparisonResult === "boolean" && !comparisonResult) || comparisonResult < 0) {
     553                    dst[dstIndex] = src[right++];
     554                    continue;
     555                }
     556
    550557            }
    551558
Note: See TracChangeset for help on using the changeset viewer.