RESOLVED FIXED 189507
[JSC] Optimize Array#indexOf in C++ runtime
https://bugs.webkit.org/show_bug.cgi?id=189507
Summary [JSC] Optimize Array#indexOf in C++ runtime
Yusuke Suzuki
Reported 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.
Attachments
Patch (11.26 KB, patch)
2018-09-11 10:55 PDT, Yusuke Suzuki
no flags
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
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
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
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
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
Patch (11.21 KB, patch)
2018-09-12 08:05 PDT, Yusuke Suzuki
no flags
Patch (18.94 KB, patch)
2018-09-12 08:58 PDT, Yusuke Suzuki
no flags
Patch (20.35 KB, patch)
2018-09-12 09:05 PDT, Yusuke Suzuki
no flags
Patch (20.48 KB, patch)
2018-09-12 14:27 PDT, Yusuke Suzuki
no flags
Patch (21.72 KB, patch)
2018-09-18 19:08 PDT, Yusuke Suzuki
no flags
Patch (22.01 KB, patch)
2018-09-19 19:40 PDT, Yusuke Suzuki
saam: review+
Yusuke Suzuki
Comment 1 2018-09-11 10:55:14 PDT
EWS Watchlist
Comment 2 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
EWS Watchlist
Comment 3 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
EWS Watchlist
Comment 4 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
EWS Watchlist
Comment 5 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
EWS Watchlist
Comment 6 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
EWS Watchlist
Comment 7 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
EWS Watchlist
Comment 8 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
EWS Watchlist
Comment 9 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
EWS Watchlist
Comment 10 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
EWS Watchlist
Comment 11 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
EWS Watchlist
Comment 12 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
Yusuke Suzuki
Comment 13 2018-09-12 08:05:15 PDT
Yusuke Suzuki
Comment 14 2018-09-12 08:58:20 PDT
Yusuke Suzuki
Comment 15 2018-09-12 09:05:35 PDT
Yusuke Suzuki
Comment 16 2018-09-12 14:27:56 PDT
Saam Barati
Comment 17 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?
Saam Barati
Comment 18 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
Yusuke Suzuki
Comment 19 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)`.
Yusuke Suzuki
Comment 20 2018-09-18 19:08:05 PDT
Saam Barati
Comment 21 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?
Yusuke Suzuki
Comment 22 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.`
Yusuke Suzuki
Comment 23 2018-09-19 19:40:14 PDT
Yusuke Suzuki
Comment 24 2018-09-19 22:54:34 PDT
Radar WebKit Bug Importer
Comment 25 2018-09-19 22:55:25 PDT
Note You need to log in before you can comment on or make changes to this bug.