RESOLVED FIXED 161879
Speed up Function.prototype.bind a bit by making it a builtin
https://bugs.webkit.org/show_bug.cgi?id=161879
Summary Speed up Function.prototype.bind a bit by making it a builtin
Saam Barati
Reported 2016-09-12 15:42:51 PDT
Speedometer spends about 10% of its time in this function. I have a 10-15% speedup by rewriting it as a builtin. This isn't going to be a huge win for speedometer, but since 10-15% is significant, we might as well land it.
Attachments
patch (12.87 KB, patch)
2016-09-12 16:48 PDT, Saam Barati
no flags
patch (12.83 KB, patch)
2016-09-12 16:52 PDT, Saam Barati
buildbot: commit-queue-
Archive of layout-test-results from ews107 for mac-yosemite-wk2 (857.01 KB, application/zip)
2016-09-12 17:46 PDT, Build Bot
no flags
patch (13.00 KB, patch)
2016-09-12 17:56 PDT, Saam Barati
no flags
Oliver Hunt
Comment 1 2016-09-12 15:51:21 PDT
There's an older bug somewhere where i did this with a bunch of the required logic. There were issues i was having making the logic universally faster at that time. (Part of the reason for .@call and .@apply exist :D )
Saam Barati
Comment 2 2016-09-12 16:02:39 PDT
(In reply to comment #1) > There's an older bug somewhere where i did this with a bunch of the required > logic. There were issues i was having making the logic universally faster at > that time. > > (Part of the reason for .@call and .@apply exist :D ) I don't think this needs to @call or @apply anything. It's basically just inspecting arguments, and maybe building an array. And doing some property accesses. So I think property accesses, argument length introspection, happen to be faster in JS, especially once we get to the JITs and the call may be inlined. I needed to make a few helper functions for a few operations that Function.prototype.bind does.
Saam Barati
Comment 3 2016-09-12 16:48:46 PDT
Saam Barati
Comment 4 2016-09-12 16:52:45 PDT
Build Bot
Comment 5 2016-09-12 17:46:43 PDT
Comment on attachment 288641 [details] patch Attachment 288641 [details] did not pass mac-wk2-ews (mac-wk2): Output: http://webkit-queues.webkit.org/results/2062262 New failing tests: js/dom/function-bind.html
Build Bot
Comment 6 2016-09-12 17:46:47 PDT
Created attachment 288649 [details] Archive of layout-test-results from ews107 for mac-yosemite-wk2 The attached test failures were seen while running run-webkit-tests on the mac-wk2-ews. Bot: ews107 Port: mac-yosemite-wk2 Platform: Mac OS X 10.10.5
Oliver Hunt
Comment 7 2016-09-12 17:52:03 PDT
Comment on attachment 288641 [details] patch Oh, i see what you're doing - the prior work endeavored to avoid a custom object for jsboundfunction.
Filip Pizlo
Comment 8 2016-09-12 17:54:58 PDT
(In reply to comment #7) > Comment on attachment 288641 [details] > patch > > Oh, i see what you're doing - the prior work endeavored to avoid a custom > object for jsboundfunction. @Oliver: not sure if this helps add context, but JSC already has super fast bound function calls for the common case that you didn't add any additional args. It's the actual function.bind - the creation of the bound function object - that is slow right now.
Saam Barati
Comment 9 2016-09-12 17:56:18 PDT
Created attachment 288651 [details] patch update test results for new error message.
Saam Barati
Comment 10 2016-09-12 18:58:06 PDT
(In reply to comment #7) > Comment on attachment 288641 [details] > patch > > Oh, i see what you're doing - the prior work endeavored to avoid a custom > object for jsboundfunction. Yeah it might be worth it to make this even faster. This was just low hanging fruit, so I decided to translate the C function into JS. However, to make this faster, I think we'd ideally want to be able to inline the allocation of the actual bound function cell into the JITs. This would be nice. There are some weird things that constructor does, so it would probably require more work than just translating the creation into assembly.
WebKit Commit Bot
Comment 11 2016-09-12 19:59:42 PDT
Comment on attachment 288651 [details] patch Clearing flags on attachment: 288651 Committed r205848: <http://trac.webkit.org/changeset/205848>
WebKit Commit Bot
Comment 12 2016-09-12 19:59:46 PDT
All reviewed patches have been landed. Closing bug.
Oliver Hunt
Comment 13 2016-09-12 20:49:16 PDT
(In reply to comment #10) > (In reply to comment #7) > > Comment on attachment 288641 [details] > > patch > > > > Oh, i see what you're doing - the prior work endeavored to avoid a custom > > object for jsboundfunction. > > Yeah it might be worth it to make this even faster. This was just low > hanging fruit, so I decided to translate the C function into JS. > However, to make this faster, I think we'd ideally want to be able > to inline the allocation of the actual bound function cell into the > JITs. This would be nice. There are some weird things that constructor does, > so it would probably require more work than just translating the creation > into > assembly. The old patch literally had code along the lines of if (arguments.length == 1) { let thisValue = arguments[0]; let self = this; return function() { return self.@apply(thisValue, arguments); } } let args = [...arguments] let thisValue = args.shift(); // i think? return function() { return function() { if (arguments.length == 0) return self.@apply(thisValue, args); return self.@apply(thisValue, [...args, ...arguments]); } }
Filip Pizlo
Comment 14 2016-09-12 21:37:08 PDT
(In reply to comment #13) > (In reply to comment #10) > > (In reply to comment #7) > > > Comment on attachment 288641 [details] > > > patch > > > > > > Oh, i see what you're doing - the prior work endeavored to avoid a custom > > > object for jsboundfunction. > > > > Yeah it might be worth it to make this even faster. This was just low > > hanging fruit, so I decided to translate the C function into JS. > > However, to make this faster, I think we'd ideally want to be able > > to inline the allocation of the actual bound function cell into the > > JITs. This would be nice. There are some weird things that constructor does, > > so it would probably require more work than just translating the creation > > into > > assembly. > > The old patch literally had code along the lines of > > if (arguments.length == 1) { > let thisValue = arguments[0]; > let self = this; > return function() { return self.@apply(thisValue, arguments); } > } > > let args = [...arguments] > let thisValue = args.shift(); // i think? > return function() { > return function() { > if (arguments.length == 0) > return self.@apply(thisValue, args); > return self.@apply(thisValue, [...args, ...arguments]); > } > } I don't think this is as good though. For example: return function() { return self.@apply(thisValue, arguments); } This is worse than the current special bound function with its special JIT thunk. That thunk means that even before any warmup, bound function calls are fast. This would mean that bound function calls would only become fast if you did enough of them.
Note You need to log in before you can comment on or make changes to this bug.