Bug 189507 - [JSC] Optimize Array#indexOf in C++ runtime
Summary: [JSC] Optimize Array#indexOf in C++ runtime
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Yusuke Suzuki
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2018-09-11 10:54 PDT by Yusuke Suzuki
Modified: 2018-09-19 22:55 PDT (History)
7 users (show)

See Also:


Attachments
Patch (11.26 KB, patch)
2018-09-11 10:55 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Archive of layout-test-results from ews107 for mac-sierra-wk2 (3.51 MB, application/zip)
2018-09-11 12:17 PDT, EWS Watchlist
no flags Details
Archive of layout-test-results from ews112 for mac-sierra (3.15 MB, application/zip)
2018-09-11 12:45 PDT, EWS Watchlist
no flags Details
Archive of layout-test-results from ews126 for ios-simulator-wk2 (2.60 MB, application/zip)
2018-09-11 12:57 PDT, EWS Watchlist
no flags Details
Archive of layout-test-results from ews103 for mac-sierra (2.49 MB, application/zip)
2018-09-11 13:32 PDT, EWS Watchlist
no flags Details
Archive of layout-test-results from ews124 for ios-simulator-wk2 (2.74 MB, application/zip)
2018-09-11 14:59 PDT, EWS Watchlist
no flags Details
Patch (11.21 KB, patch)
2018-09-12 08:05 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (18.94 KB, patch)
2018-09-12 08:58 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (20.35 KB, patch)
2018-09-12 09:05 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (20.48 KB, patch)
2018-09-12 14:27 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (21.72 KB, patch)
2018-09-18 19:08 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (22.01 KB, patch)
2018-09-19 19:40 PDT, Yusuke Suzuki
saam: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Yusuke Suzuki 2018-09-11 10:54:11 PDT
web-tooling-benchmark babylon shows that C++ runtime of Array#indexOf takes so much time (According to Linux perf, it shows 6.9% of the main thread, lol).
Our C++ Array#indexOf is too naive. It repeatedly calls getProperty function, which is not so fast.

We can add a fast path for JSArray, which should be similar to the thing implemented in DFG / FTL.
Comment 1 Yusuke Suzuki 2018-09-11 10:55:14 PDT
Created attachment 349410 [details]
Patch
Comment 2 EWS Watchlist 2018-09-11 12:17:01 PDT
Comment on attachment 349410 [details]
Patch

Attachment 349410 [details] did not pass mac-wk2-ews (mac-wk2):
Output: https://webkit-queues.webkit.org/results/9175067

New failing tests:
ietestcenter/Javascript/15.4.4.14-5-3.html
ietestcenter/Javascript/15.4.4.14-5-10.html
ietestcenter/Javascript/15.4.4.14-6-1.html
ietestcenter/Javascript/15.4.4.14-5-15.html
ietestcenter/Javascript/15.4.4.14-5-1.html
ietestcenter/Javascript/15.4.4.14-8-9.html
ietestcenter/Javascript/15.4.4.14-5-31.html
ietestcenter/Javascript/15.4.4.14-8-1.html
ietestcenter/Javascript/15.4.4.14-5-20.html
ietestcenter/Javascript/15.4.4.14-8-3.html
ietestcenter/Javascript/15.4.4.14-7-1.html
js/dom/array-indexof.html
ietestcenter/Javascript/15.4.4.14-5-11.html
ietestcenter/Javascript/15.4.4.14-5-2.html
ietestcenter/Javascript/15.4.4.14-5-18.html
ietestcenter/Javascript/15.4.4.14-5-32.html
ietestcenter/Javascript/15.4.4.14-5-19.html
ietestcenter/Javascript/15.4.4.14-7-4.html
Comment 3 EWS Watchlist 2018-09-11 12:17:03 PDT
Created attachment 349421 [details]
Archive of layout-test-results from ews107 for mac-sierra-wk2

The attached test failures were seen while running run-webkit-tests on the mac-wk2-ews.
Bot: ews107  Port: mac-sierra-wk2  Platform: Mac OS X 10.12.6
Comment 4 EWS Watchlist 2018-09-11 12:23:59 PDT
Comment on attachment 349410 [details]
Patch

Attachment 349410 [details] did not pass jsc-ews (mac):
Output: https://webkit-queues.webkit.org/results/9175059

New failing tests:
stress/array-indexof-negative-index.js.dfg-maximal-flush-validate-no-cjit
stress/array-indexof-negative-index.js.default
mozilla-tests.yaml/js1_6/Array/regress-290592.js.mozilla
stress/array-indexof-index.js.ftl-no-cjit-no-inline-validate
mozilla-tests.yaml/js1_6/Array/regress-290592.js.mozilla-ftl-eager-no-cjit-validate-phases
stress/array-indexof-index.js.dfg-eager
stress/array-indexof-index.js.ftl-eager
mozilla-tests.yaml/js1_6/Array/regress-290592.js.mozilla-llint
stress/array-indexof-index.js.ftl-no-cjit-validate-sampling-profiler
mozilla-tests.yaml/js1_6/Array/regress-290592.js.mozilla-no-ftl
stress/array-indexof-negative-index.js.ftl-no-cjit-no-inline-validate
stress/array-indexof-index.js.ftl-no-cjit-small-pool
stress/array-indexof-index.js.default
mozilla-tests.yaml/js1_6/Array/regress-290592.js.mozilla-dfg-eager-no-cjit-validate-phases
stress/array-indexof-negative-index.js.ftl-eager-no-cjit-b3o1
ChakraCore.yaml/ChakraCore/test/Array/array_indexOf.js.default
stress/array-indexof-negative-index.js.no-cjit-validate-phases
stress/array-indexof-index.js.no-cjit-collect-continuously
mozilla-tests.yaml/js1_6/Array/regress-290592.js.mozilla-baseline
stress/array-indexof-negative-index.js.ftl-no-cjit-validate-sampling-profiler
stress/array-indexof-negative-index.js.no-llint
stress/array-indexof-index.js.ftl-eager-no-cjit-b3o1
stress/array-indexof-index.js.no-cjit-validate-phases
stress/array-indexof-index.js.dfg-eager-no-cjit-validate
stress/array-indexof-negative-index.js.ftl-no-cjit-b3o1
stress/array-indexof-negative-index.js.dfg-eager-no-cjit-validate
stress/array-indexof-negative-index.js.ftl-eager-no-cjit
stress/array-indexof-negative-index.js.no-ftl
stress/array-indexof-index.js.ftl-eager-no-cjit
stress/array-indexof-negative-index.js.ftl-eager
stress/array-indexof-index.js.dfg-maximal-flush-validate-no-cjit
stress/array-indexof-negative-index.js.no-cjit-collect-continuously
stress/array-indexof-negative-index.js.ftl-no-cjit-small-pool
stress/array-indexof-index.js.ftl-no-cjit-no-put-stack-validate
stress/array-indexof-index.js.no-llint
stress/array-indexof-index.js.no-ftl
stress/array-indexof-index.js.ftl-no-cjit-b3o1
stress/array-indexof-negative-index.js.dfg-eager
stress/array-indexof-negative-index.js.ftl-no-cjit-no-put-stack-validate
apiTests
Comment 5 EWS Watchlist 2018-09-11 12:45:30 PDT
Comment on attachment 349410 [details]
Patch

Attachment 349410 [details] did not pass mac-debug-ews (mac):
Output: https://webkit-queues.webkit.org/results/9175265

New failing tests:
ietestcenter/Javascript/15.4.4.14-5-3.html
ietestcenter/Javascript/15.4.4.14-5-10.html
ietestcenter/Javascript/15.4.4.14-8-3.html
ietestcenter/Javascript/15.4.4.14-5-15.html
ietestcenter/Javascript/15.4.4.14-5-1.html
ietestcenter/Javascript/15.4.4.14-8-9.html
ietestcenter/Javascript/15.4.4.14-5-31.html
ietestcenter/Javascript/15.4.4.14-8-1.html
ietestcenter/Javascript/15.4.4.14-5-20.html
ietestcenter/Javascript/15.4.4.14-6-1.html
ietestcenter/Javascript/15.4.4.14-7-1.html
js/dom/array-indexof.html
ietestcenter/Javascript/15.4.4.14-5-11.html
ietestcenter/Javascript/15.4.4.14-5-2.html
ietestcenter/Javascript/15.4.4.14-5-18.html
ietestcenter/Javascript/15.4.4.14-5-32.html
ietestcenter/Javascript/15.4.4.14-5-19.html
ietestcenter/Javascript/15.4.4.14-7-4.html
Comment 6 EWS Watchlist 2018-09-11 12:45:32 PDT
Created attachment 349423 [details]
Archive of layout-test-results from ews112 for mac-sierra

The attached test failures were seen while running run-webkit-tests on the mac-debug-ews.
Bot: ews112  Port: mac-sierra  Platform: Mac OS X 10.12.6
Comment 7 EWS Watchlist 2018-09-11 12:57:53 PDT
Comment on attachment 349410 [details]
Patch

Attachment 349410 [details] did not pass ios-sim-ews (ios-simulator-wk2):
Output: https://webkit-queues.webkit.org/results/9175273

New failing tests:
ietestcenter/Javascript/15.4.4.14-5-3.html
ietestcenter/Javascript/15.4.4.14-5-10.html
ietestcenter/Javascript/15.4.4.14-6-1.html
ietestcenter/Javascript/15.4.4.14-5-15.html
ietestcenter/Javascript/15.4.4.14-5-1.html
ietestcenter/Javascript/15.4.4.14-8-9.html
ietestcenter/Javascript/15.4.4.14-5-31.html
ietestcenter/Javascript/15.4.4.14-8-1.html
ietestcenter/Javascript/15.4.4.14-5-20.html
ietestcenter/Javascript/15.4.4.14-8-3.html
ietestcenter/Javascript/15.4.4.14-7-1.html
js/dom/array-indexof.html
ietestcenter/Javascript/15.4.4.14-5-11.html
ietestcenter/Javascript/15.4.4.14-5-2.html
ietestcenter/Javascript/15.4.4.14-5-18.html
ietestcenter/Javascript/15.4.4.14-5-32.html
ietestcenter/Javascript/15.4.4.14-5-19.html
ietestcenter/Javascript/15.4.4.14-7-4.html
Comment 8 EWS Watchlist 2018-09-11 12:57:55 PDT
Created attachment 349425 [details]
Archive of layout-test-results from ews126 for ios-simulator-wk2

The attached test failures were seen while running run-webkit-tests on the ios-sim-ews.
Bot: ews126  Port: ios-simulator-wk2  Platform: Mac OS X 10.13.4
Comment 9 EWS Watchlist 2018-09-11 13:32:07 PDT
Comment on attachment 349410 [details]
Patch

Attachment 349410 [details] did not pass mac-ews (mac):
Output: https://webkit-queues.webkit.org/results/9176274

New failing tests:
ietestcenter/Javascript/15.4.4.14-5-3.html
ietestcenter/Javascript/15.4.4.14-5-10.html
ietestcenter/Javascript/15.4.4.14-6-1.html
ietestcenter/Javascript/15.4.4.14-5-15.html
ietestcenter/Javascript/15.4.4.14-5-1.html
ietestcenter/Javascript/15.4.4.14-8-9.html
ietestcenter/Javascript/15.4.4.14-5-31.html
ietestcenter/Javascript/15.4.4.14-8-1.html
ietestcenter/Javascript/15.4.4.14-5-20.html
ietestcenter/Javascript/15.4.4.14-8-3.html
ietestcenter/Javascript/15.4.4.14-7-1.html
js/dom/array-indexof.html
ietestcenter/Javascript/15.4.4.14-5-11.html
ietestcenter/Javascript/15.4.4.14-5-2.html
ietestcenter/Javascript/15.4.4.14-5-18.html
ietestcenter/Javascript/15.4.4.14-5-32.html
ietestcenter/Javascript/15.4.4.14-5-19.html
ietestcenter/Javascript/15.4.4.14-7-4.html
Comment 10 EWS Watchlist 2018-09-11 13:32:09 PDT
Created attachment 349437 [details]
Archive of layout-test-results from ews103 for mac-sierra

The attached test failures were seen while running run-webkit-tests on the mac-ews.
Bot: ews103  Port: mac-sierra  Platform: Mac OS X 10.12.6
Comment 11 EWS Watchlist 2018-09-11 14:59:24 PDT
Comment on attachment 349410 [details]
Patch

Attachment 349410 [details] did not pass ios-sim-ews (ios-simulator-wk2):
Output: https://webkit-queues.webkit.org/results/9177334

New failing tests:
ietestcenter/Javascript/15.4.4.14-5-3.html
ietestcenter/Javascript/15.4.4.14-5-10.html
ietestcenter/Javascript/15.4.4.14-6-1.html
ietestcenter/Javascript/15.4.4.14-5-15.html
ietestcenter/Javascript/15.4.4.14-5-1.html
ietestcenter/Javascript/15.4.4.14-8-9.html
ietestcenter/Javascript/15.4.4.14-5-31.html
ietestcenter/Javascript/15.4.4.14-8-1.html
ietestcenter/Javascript/15.4.4.14-5-20.html
ietestcenter/Javascript/15.4.4.14-8-3.html
ietestcenter/Javascript/15.4.4.14-7-1.html
js/dom/array-indexof.html
ietestcenter/Javascript/15.4.4.14-5-11.html
ietestcenter/Javascript/15.4.4.14-5-2.html
ietestcenter/Javascript/15.4.4.14-5-18.html
ietestcenter/Javascript/15.4.4.14-5-32.html
ietestcenter/Javascript/15.4.4.14-5-19.html
ietestcenter/Javascript/15.4.4.14-7-4.html
Comment 12 EWS Watchlist 2018-09-11 14:59:25 PDT
Created attachment 349465 [details]
Archive of layout-test-results from ews124 for ios-simulator-wk2

The attached test failures were seen while running run-webkit-tests on the ios-sim-ews.
Bot: ews124  Port: ios-simulator-wk2  Platform: Mac OS X 10.13.4
Comment 13 Yusuke Suzuki 2018-09-12 08:05:15 PDT
Created attachment 349546 [details]
Patch
Comment 14 Yusuke Suzuki 2018-09-12 08:58:20 PDT
Created attachment 349550 [details]
Patch
Comment 15 Yusuke Suzuki 2018-09-12 09:05:35 PDT
Created attachment 349553 [details]
Patch
Comment 16 Yusuke Suzuki 2018-09-12 14:27:56 PDT
Created attachment 349581 [details]
Patch
Comment 17 Saam Barati 2018-09-12 17:03:19 PDT
Comment on attachment 349581 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=349581&action=review

> Source/JavaScriptCore/runtime/ArrayPrototype.cpp:1172
> +        if (array->canFastIndexedAccess(vm)) {

Does this guarantee our prototype chain is sane?

> Source/JavaScriptCore/runtime/ArrayPrototype.cpp:1182
> +                    if (!canBeInt32(searchNumber))

Do you have tests for this? For NaN/Inf/-0, +0, etc

Does this in the spec use === semantics or the hashmap isEqual semantics?

> Source/JavaScriptCore/runtime/ArrayPrototype.cpp:1216
> +                    // Hole never matches since it is NaN.

I guess my above quetion applies here? Will
array.indexOf(NaN)
always return -1?

> Source/JavaScriptCore/runtime/JSArrayInlines.h:74
> +inline bool JSArray::canFastIndexedAccess(VM& vm)

I think you're missing something between "can" and "fast" in this name. Maybe: "canDoFastIndexedAccess" or "canDoFastIndexedAccesses"

> Source/JavaScriptCore/runtime/JSGlobalObjectInlines.h:58
> +

style: No need for this newline IMO

> Source/JavaScriptCore/runtime/MathCommon.h:190
> +    // Note: while this behavior is undefined for NaN and inf, the subsequent statement will catch these cases.

I don't understand this comment. What subsequent statement?
Comment 18 Saam Barati 2018-09-12 17:04:11 PDT
Comment on attachment 349581 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=349581&action=review

>> Source/JavaScriptCore/runtime/ArrayPrototype.cpp:1216
>> +                    // Hole never matches since it is NaN.
> 
> I guess my above quetion applies here? Will
> array.indexOf(NaN)
> always return -1?

I see from your tests that the answer is that [NaN].indexOf(NaN) === -1

Maybe it's worth stating in your comment that this uses === semantics instead of hashmap isEqual semantics
Comment 19 Yusuke Suzuki 2018-09-18 03:05:28 PDT
Comment on attachment 349581 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=349581&action=review

>> Source/JavaScriptCore/runtime/ArrayPrototype.cpp:1172
>> +        if (array->canFastIndexedAccess(vm)) {
> 
> Does this guarantee our prototype chain is sane?

Yes. It is guaranteed. And it is tested in array-indexof-prototype-trap.js and array-indexof-array-prototype-trap.js.

>> Source/JavaScriptCore/runtime/ArrayPrototype.cpp:1182
>> +                    if (!canBeInt32(searchNumber))
> 
> Do you have tests for this? For NaN/Inf/-0, +0, etc
> 
> Does this in the spec use === semantics or the hashmap isEqual semantics?

Yes, it is tested in array-indexof-negative-zero.js and array-indexof-hole-nan.js. And tests are added for Inf case too.
Array#indexOf uses `===` semantics.

>>> Source/JavaScriptCore/runtime/ArrayPrototype.cpp:1216
>>> +                    // Hole never matches since it is NaN.
>> 
>> I guess my above quetion applies here? Will
>> array.indexOf(NaN)
>> always return -1?
> 
> I see from your tests that the answer is that [NaN].indexOf(NaN) === -1
> 
> Maybe it's worth stating in your comment that this uses === semantics instead of hashmap isEqual semantics

Added.

>> Source/JavaScriptCore/runtime/JSArrayInlines.h:74
>> +inline bool JSArray::canFastIndexedAccess(VM& vm)
> 
> I think you're missing something between "can" and "fast" in this name. Maybe: "canDoFastIndexedAccess" or "canDoFastIndexedAccesses"

I think `canDoFastIndexedAccess` sounds nice. Fixed.

>> Source/JavaScriptCore/runtime/JSGlobalObjectInlines.h:58
>> +
> 
> style: No need for this newline IMO

Fixed.

>> Source/JavaScriptCore/runtime/MathCommon.h:190
>> +    // Note: while this behavior is undefined for NaN and inf, the subsequent statement will catch these cases.
> 
> I don't understand this comment. What subsequent statement?

`static_cast<int32_t>(value)` with `value` not in int32_t is an UB strictly speaking.
This comment is moved from `JSValue::JSValue(double d)`.
Comment 20 Yusuke Suzuki 2018-09-18 19:08:05 PDT
Created attachment 350087 [details]
Patch
Comment 21 Saam Barati 2018-09-19 15:44:31 PDT
Comment on attachment 350087 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=350087&action=review

> Source/JavaScriptCore/runtime/ArrayPrototype.cpp:1204
> +                    RETURN_IF_EXCEPTION(scope, encodedJSValue());

nit: I think you can just use "{ }" instead of "encodedJSValue()"

> Source/JavaScriptCore/runtime/MathCommon.h:190
> +    // Note: while this behavior is undefined for NaN and inf, the subsequent statement will catch these cases.

I'm still super confused about this comment. What "subsequent" statement are we talking about here? I only see one statement. How are we guaranteed we do the right thing in the NaN/inf cases in the DOUBLE array case?
Comment 22 Yusuke Suzuki 2018-09-19 19:39:26 PDT
Comment on attachment 350087 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=350087&action=review

>> Source/JavaScriptCore/runtime/ArrayPrototype.cpp:1204
>> +                    RETURN_IF_EXCEPTION(scope, encodedJSValue());
> 
> nit: I think you can just use "{ }" instead of "encodedJSValue()"

Fixed.

>> Source/JavaScriptCore/runtime/MathCommon.h:190
>> +    // Note: while this behavior is undefined for NaN and inf, the subsequent statement will catch these cases.
> 
> I'm still super confused about this comment. What "subsequent" statement are we talking about here? I only see one statement. How are we guaranteed we do the right thing in the NaN/inf cases in the DOUBLE array case?

I've changed this comment to `Note: strictly speaking this is an undefined behavior.`
Comment 23 Yusuke Suzuki 2018-09-19 19:40:14 PDT
Created attachment 350165 [details]
Patch
Comment 24 Yusuke Suzuki 2018-09-19 22:54:34 PDT
Committed r236240: <https://trac.webkit.org/changeset/236240>
Comment 25 Radar WebKit Bug Importer 2018-09-19 22:55:25 PDT
<rdar://problem/44629552>