Uh oh!
There was an error while loading. Please reload this page.
lib: faster type checks for some types - #15663
Conversation
There was a problem hiding this comment.
The args will always be a empty array. So you might just use a empty array that you pass in for the argumentsList instead of creating a new array each time?
There was a problem hiding this comment.
The spread syntax is actually faster than hardcoding an empty array by a good amount. Probably because of the fact that Reflect.apply is inlined.
There was a problem hiding this comment.
Interesting and good to know. In that case a comment about that would be good as well.
There was a problem hiding this comment.
Would you be so kind and add a comment that you added this to make sure it will not be manipulated by userland code?
cjihrig
commented
Sep 29, 2017
Having some of these type checking functions in |
TimothyGu
commented
Sep 29, 2017
@cjihrig The difference is that the type checkers in |
Right now we have type checking functions in |
TimothyGu
commented
Sep 29, 2017
@cjihrig Would |
cjihrig
commented
Sep 29, 2017
That works for me. |
bmeurer
commented
Sep 29, 2017
So I'm not entirely sure what is the scope of this change. Is it because |
TimothyGu
commented
Sep 29, 2017
No; this PR has two parts:
The change about |
bmeurer
commented
Sep 29, 2017
Ah, right, just discovered that. The |
lpinca
commented
Sep 29, 2017
Yes, I agree. No strong opinions, but maybe it's better to move that part to its own pr or commit. |
bmeurer
commented
Sep 29, 2017
Ok, I have a CL in flight that improves |
@bmeurer If possible, please optimize |
bb151db to
8d5d39dCompareTimothyGu
commented
Sep 30, 2017
@cjihrig Can you check if this version is acceptable for you? I've renamed it to |
bmeurer
left a comment
There was a problem hiding this comment.
@TimothyGu At this point, TypedArray.prototype[Symbol.toStringTag] is not really fast in V8. It's also not super-slow. I'll try to get that fixed and inlined next week.
As for this particular PR, I'm not sure uncurryThis is really optimized fully with V8 6.1.
There was a problem hiding this comment.
Have you checked the generated code for isUint8Array? I don't think we get the Reflect.apply optimization with V8 6.1 already.
There was a problem hiding this comment.
Yes I have:
--- Raw source ---(value) { return TypedArrayProto_toStringTag(value) === 'Uint8Array';}--- Optimized code ---optimization_id = 0source_position = 1086kind = OPTIMIZED_FUNCTIONname = isUint8Arraystack_slots = 4compiler = turbofanInstructions (size = 194)0x367169e055c0055pushrbp0x367169e055c11 4889e5 REX.W movqrbp,rsp0x367169e055c4456pushrsi0x367169e055c5557pushrdi0x367169e055c66 493ba5e80c0000 REX.W cmpq rsp,[r13+0xce8]0x367169e055cd d 0f8656000000 jna0x367169e05629 <+0x69>0x367169e055d313 48bf59b6c858e83c0000 REX.W movqrdi,0x3ce858c8b659 ;; object: 0x3ce858c8b659 <JSFunction b (sfi = 0x2fc5e3493879)>0x367169e055dd 1d 488b7727 REX.W movqrsi,[rdi+0x27]0x367169e055e121 488b5d10 REX.W movqrbx,[rbp+0x10]0x367169e055e52553pushrbx0x367169e055e626 498b55a0 REX.W movqrdx,[r13-0x60]0x367169e055ea 2a 33c0 xorl rax,rax0x367169e055ec 2c ff5737 call[rdi+0x37]0x367169e055ef 2f a801 testal,0x10x367169e055f131 0f844e000000 jz0x367169e05645 <+0x85>0x367169e055f737 488b58ff REX.W movqrbx,[rax-0x1]0x367169e055fb 3b f6430bc0 testb [rbx+0xb],0xc00x367169e055ff 3f 0f8545000000 jnz0x367169e0564a <+0x8a>0x367169e0560545 48bb711549e3c52f0000 REX.W movqrbx,0x2fc5e3491571 ;; object: 0x2fc5e3491571 <String[10]: Uint8Array>0x367169e0560f 4f 483bd8 REX.W cmpq rbx,rax0x367169e0561252 0f840b000000 jz0x367169e05623 <+0x63>0x367169e0561858 498b45c0 REX.W movqrax,[r13-0x40]0x367169e0561c 5c 488be5 REX.W movqrsp,rbp0x367169e0561f 5f 5d poprbp0x367169e0562060 c21000 ret0x100x367169e0562363 498b45b8 REX.W movqrax,[r13-0x48]0x367169e0562767 ebf3 jmp0x367169e0561c <+0x5c>0x367169e0562969 48bb1067f50000000000 REX.W movqrbx,0xf567100x367169e0563373 33c0 xorl rax,rax0x367169e0563575 488b75f8 REX.W movqrsi,[rbp-0x8]0x367169e0563979 e8a2efe7ff call0x367169c845e0 ;; code: STUB, CEntryStub, minor: 80x367169e0563e 7e eb93 jmp0x367169e055d3 <+0x13>0x367169e0564080 e8bbe9cfff call0x367169b04000 ;; deoptimization bailout 00x367169e0564585 e8c0e9cfff call0x367169b0400a ;; deoptimization bailout 10x367169e0564a 8a e8c5e9cfff call0x367169b04014 ;; deoptimization bailout 20x367169e0564f 8f e8cae9cfff call0x367169b0401e ;; deoptimization bailout 30x367169e056549490nop0x367169e056559590nop...Source positions: pc offset position26553691086Inlined functions (count = 1)0x3ce858ce6719 <SharedFunctionInfo args>Deoptimization Input Data (deopt points = 4) index bytecode-offset trampoline_pc pc02880 2f 11585 NA 215 8a NA 30 8f 7e Safepoints (size = 30)0x367169e055ef 2f 0000 (sp-> fp) 00x367169e0563e 7e 0000 (sp-> fp) 3RelocInfo (size = 11)0x367169e055d5 embedded object (0x3ce858c8b659 <JSFunction b (sfi = 0x2fc5e3493879)>)0x367169e05607 embedded object (0x2fc5e3491571 <String[10]: Uint8Array>)0x367169e0563a code target (STUB) (0x367169c845e0)0x367169e05641 runtime entry (deoptimization bailout 0)0x367169e05646 runtime entry (deoptimization bailout 1)0x367169e0564b runtime entry (deoptimization bailout 2)0x367169e05650 runtime entry (deoptimization bailout 3)--- End code ---Note: function b() is in fact %TypedArray%.prototype.toStringTag, and args is the name given to the wrapper function created in uncurryThis, which as you can tell is fully inlined.
Note 2: I don't really care if Reflect.apply is fully optimized for now, because regardless of that this function is much faster than the check we are currently using (#15663 (comment)).
There was a problem hiding this comment.
Ok, with more recent V8 this will get even better (I also have a patch to inline TypedArray.prototype[@@toStringTag]). Nevertheless, why don't we just use F.p.call here and avoid uncurryThis completely?
There was a problem hiding this comment.
@bmeurerFunction.prototype.call can be overwritten by userland code. I don't want that possibility for a type checking function.
There was a problem hiding this comment.
Nit: This took me some time to understand. Maybe just a comment would help, or inline the getterFunc to make it obvious what is being done.
This improves performance of ArrayBuffer.isView by roughly 2.5x itself, and enables optimizations across ArrayBuffer.isView calls, i.e. map checks can be eliminated across. This was discovered in a related Node pull request (nodejs/node#15663). Bug: v8:6868 Change-Id: I1d56ec385f8daa0e1d44d3bc4d6c9a5558ba4522 Reviewed-on: https://chromium-review.googlesource.com/691660 Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#48247}
TimothyGu
commented
Sep 30, 2017
@bmeurer thanks for taking a look!
Yeah I realized. The |
3a63918 to
6116c39CompareBridgeAR
commented
Oct 1, 2017
The TypedArray.prototype[Symbol.toStringTag] getter is currently the best (and as far as I can tell only definitely side-effect free) way to check whether an arbitrary object is a TypedArray - either generally TypedArray or a specific one like Uint8Array. Using the getter is thus emerging as the general pattern to detect TypedArrays, even Node.js now adapted it starting with nodejs/node#15663 for the isTypedArray and isUint8Array type checks in lib/internal/util/types.js now. The getter returns either the string with the TypedArray subclass name (i.e. "Uint8Array") or undefined if the receiver is not a TypedArray. This can be implemented with a simple elements kind dispatch, instead of checking the instance type and then loading the class name from the constructor, which requires a loop walking up the transition tree. This CL ports the builtin to CSA and TurboFan, and changes the logic to a simple elements kind check. On the micro-benchmark mentioned in the referenced bug, the time goes from testIsArrayBufferView: 565 ms. testIsTypedArray: 2403 ms. testIsUint8Array: 3847 ms. to testIsArrayBufferView: 566 ms. testIsTypedArray: 965 ms. testIsUint8Array: 965 ms. which presents an up to 4x improvement. Bug: v8:6874 Change-Id: I9c330b4529d9631df2f052acf023c6a4fae69611 Reviewed-on: https://chromium-review.googlesource.com/695021 Reviewed-by: Jaroslav Sevcik <jarin@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#48254}
bmeurer
commented
Oct 2, 2017
V8 optimization for |
MylesBorins
commented
Oct 3, 2017
This does not land cleanly on v8.x, could you please backport |
PR-URL: nodejs/node#15663 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Benedikt Meurer <benedikt.meurer@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
PR-URL: nodejs/node#15663 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Benedikt Meurer <benedikt.meurer@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Backport-PR-URL: nodejs#16073 PR-URL: nodejs#15663 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Benedikt Meurer <benedikt.meurer@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Backport-PR-URL: nodejs#16073 PR-URL: nodejs#15663 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Benedikt Meurer <benedikt.meurer@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Backport-PR-URL: #16073 PR-URL: #15663 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Benedikt Meurer <benedikt.meurer@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Backport-PR-URL: #16073 PR-URL: #15663 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Benedikt Meurer <benedikt.meurer@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
MylesBorins
commented
Nov 16, 2017
Should this be backported to |
This function was added by nodejs#15663, but was never documented. This commit documents it.
This function was added by #15663, but was never documented. This commit documents it. PR-URL: #33092 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Masashi Hirano <shisama07@gmail.com> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com> Reviewed-By: Andrey Pechkurov <apechkurov@gmail.com>
This function was added by #15663, but was never documented. This commit documents it. PR-URL: #33092 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Masashi Hirano <shisama07@gmail.com> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com> Reviewed-By: Andrey Pechkurov <apechkurov@gmail.com>
This function was added by #15663, but was never documented. This commit documents it. PR-URL: #33092 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Masashi Hirano <shisama07@gmail.com> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com> Reviewed-By: Andrey Pechkurov <apechkurov@gmail.com>
This function was added by #15663, but was never documented. This commit documents it. PR-URL: #33092 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Masashi Hirano <shisama07@gmail.com> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com> Reviewed-By: Andrey Pechkurov <apechkurov@gmail.com>
The JS<->C++ overhead is fairly high with TurboFan. If there is a way to do a reliable and performant type check in JS, use JS instead.
This PR introduces a new internal module that also protects against modification of the global environment by caching all utilized functions at Node.js startup.
Checklist
make -j4 test(UNIX), orvcbuild test(Windows) passesAffected core subsystem(s)
lib