Skip to content
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

Merged
merged 3 commits into from
May 4, 2018
Merged

inline callbacks #5081

merged 3 commits into from
May 4, 2018

Conversation

sigatrev
Copy link
Contributor

@sigatrev sigatrev commented May 2, 2018

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.

@sigatrev sigatrev force-pushed the inlineCallbacks branch 3 times, most recently from 60e5471 to 529a833 Compare May 2, 2018 17:59
@sigatrev sigatrev force-pushed the inlineCallbacks branch from 529a833 to 77cebe2 Compare May 2, 2018 18:24
@@ -641,11 +652,14 @@ typedef struct FunctionJITTimeDataIDL

unsigned int inlineeCount;
unsigned int ldFldInlineeCount;
unsigned int callbackInlineeCount;
Copy link
Contributor

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);
Copy link
Contributor

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?

Copy link
Contributor Author

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(...) \
Copy link
Contributor

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.
//-------------------------------------------------------------------------------------------------------
Copy link
Contributor

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?

Copy link
Contributor

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;
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

@sethbrenith sethbrenith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@sigatrev sigatrev force-pushed the inlineCallbacks branch 2 times, most recently from 6a75574 to 530b02e Compare May 3, 2018 23:41
// 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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused?

Copy link
Contributor Author

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.
@sigatrev sigatrev force-pushed the inlineCallbacks branch from 530b02e to 7424ea9 Compare May 4, 2018 00:48
@chakrabot chakrabot merged commit 7424ea9 into chakra-core:master May 4, 2018
chakrabot pushed a commit that referenced this pull request May 4, 2018
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants