-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
inline callbacks #5081
inline callbacks #5081
Conversation
60e5471
to
529a833
Compare
lib/JITIDL/JITTypes.h
Outdated
@@ -641,11 +652,14 @@ typedef struct FunctionJITTimeDataIDL | |||
|
|||
unsigned int inlineeCount; | |||
unsigned int ldFldInlineeCount; | |||
unsigned int callbackInlineeCount; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we put this int down in the X64_PAD4 space after callbackInlinees?
Js::FunctionInfo * functionInfo = GetCallSiteCallbackInfo(inliner, profiledCallSiteId); | ||
if (functionInfo) | ||
{ | ||
return Inline(inliner, functionInfo, false, false, true, GetConstantArgInfo(inliner, profiledCallSiteId), profiledCallSiteId, recursiveInlineDepth, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
false [](start = 45, length = 5)
How do we guarantee at this point that it's not a constructor call?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
constructor call is specific to the callsite, not the function. It is set true for calls of the form new foo()
. At the point callback info is collected, we don't know how the callsite will use the callback function. The result of guessing wrong here is either failing to serialize data that could have been used, or serializing data that won't be used, but neither case is fatal
@@ -105,6 +107,10 @@ class InliningDecider | |||
Output::Print(__VA_ARGS__); \ | |||
Output::Flush(); \ | |||
} | |||
#define INLINE_TRACE_AND_TESTTRACE(...) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for cleaning this up :)
//------------------------------------------------------------------------------------------------------- | ||
// Copyright (C) Microsoft. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. | ||
//------------------------------------------------------------------------------------------------------- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there other configurations that might be worth testing? Maybe passing the callback through multiple layers like function Dispatch2(f) { Dispatch(f); }
or a callback that calls things like function Dispatch3(f) { f(Foo); }
where we call Dispatch3(Dispatch)
after the warmup?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or maybe a case where the callback isn't the first param
In reply to: 185833307 [](ancestors = 185833307)
@@ -46,6 +47,9 @@ namespace Js | |||
// accurate count. | |||
Field(uint) ldFldInlineeCount; | |||
|
|||
// Number of functions passed as arguments to be inlined. | |||
Field(uint) callbackInlineeCount; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We currently have four unused bytes after globalObjTypeSpecFldInfoCount; could this go up there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This member isn't actually needed. I'm going to remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
6a75574
to
530b02e
Compare
// False if there is more than one ArgIn that is a function object or a function object with arg number greater than MaxInlineeArgoutCount | ||
Field(uint8) canInlineCallback : 1; | ||
|
||
Field(uint8) isConstructor : 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added that before looking into what/how that tracks. thanks for catching that.
…thout callbacks Rather than store the callback info in the CallSiteInfo, allocate it as needed stored on the function body, similar to how PolymorphicInlineData is handled.
Merge pull request #5081 from sigatrev:inlineCallbacks This commit adds tracking of up to 1 function passed as an argument to any given callsite, and provides the neccessary data to the JIT to inline it. The inliner is able to follow the single-def chain up multiple functions to find the approriate data, allowing inling to occur at megamorphic in cases where the function is a callback. This will allow more efficient javascript implementations of built-ins like filter and sort.
This commit adds tracking of up to 1 function passed as an argument to any given callsite, and provides the neccessary data to the JIT to inline it. The inliner is able to follow the single-def chain up multiple functions to find the approriate data, allowing inling to occur at megamorphic in cases where the function is a callback. This will allow more efficient javascript implementations of built-ins like filter and sort.