-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Jitted Code Pitching Feature implemented #10496
Conversation
Testing of Checked and Debug builds on the CoreCLR test suite with the environment variables
does not show any regression |
bcf3769
to
b4d51a5
Compare
@dotnet-bot test Windows_NT x86 Checked Build and Test |
CC: @noahfalk |
I haven't had a chance to go through this in depth, I'll try to make time to give it more scrutiny soon (tomorrow?). For now a few thoughts on various areas:
|
@noahfalk |
Its cool stuff you are working on here @sergign60. I've been taking a closer look through this and had some follow up comments. IMO the minimum bar to check this in should be:
The main thing that prevents this from being ready for checkin are a number of places where it adds some confusion/complexity - some easy to remedy but others might take a little more legwork:
|
@noahfalk thanks for your comments. I'll look at them more closely at the nearest weekend. |
@noahfalk thanks again for your comments. As you can see I did renaming work. |
f518059
to
f2677ff
Compare
@noahfalk |
f9a9dc4
to
88dd36d
Compare
1238b23
to
d656778
Compare
@noahfalk @janvorli
|
I'm happy 👍 @janvorli - I know you are pretty busy at the moment. Could you let us know if you intended to review this, if you'd like me to find someone else in your stead, or you want to go ahead and merge this without further review? Thanks! |
@noahfalk I'd like to find some time and review it too. I hope I'll be able to do that tomorrow morning. |
src/inc/clrconfigvalues.h
Outdated
RETAIL_CONFIG_DWORD_INFO(INTERNAL_JitPitchEnabled, W("JitPitchEnabled"), (DWORD)0, "Set it to 1 to enable Jit Pitching") | ||
RETAIL_CONFIG_DWORD_INFO(INTERNAL_JitPitchMemThreshold, W("JitPitchMemThreshold"), (DWORD)0, "Pitching jits when code heap usage is larger than this (in bytes)") | ||
RETAIL_CONFIG_DWORD_INFO(INTERNAL_JitPitchMethodSizeThreshold, W("JitPitchMethodSizeThreshold"), (DWORD)0, "Pitching jit for methods whose native code size larger than this (in bytes)") | ||
RETAIL_CONFIG_DWORD_INFO(INTERNAL_JitPitchMaxLevel, W("JitPitchMaxLevel"), (DWORD)0, "Pitching jits for all methods as it possible") |
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 don't understand the description.
src/inc/clrconfigvalues.h
Outdated
RETAIL_CONFIG_DWORD_INFO(INTERNAL_JitPitchMethodSizeThreshold, W("JitPitchMethodSizeThreshold"), (DWORD)0, "Pitching jit for methods whose native code size larger than this (in bytes)") | ||
RETAIL_CONFIG_DWORD_INFO(INTERNAL_JitPitchMaxLevel, W("JitPitchMaxLevel"), (DWORD)0, "Pitching jits for all methods as it possible") | ||
RETAIL_CONFIG_DWORD_INFO(INTERNAL_JitPitchTimeInterval, W("JitPitchTimeInterval"), (DWORD)0, "Time interval between jit pitchings in ms") | ||
RETAIL_CONFIG_DWORD_INFO(INTERNAL_JitPitchPrintStat, W("JitPitchPrintStat"), (DWORD)0, "Print statistics about Jit Pitching") |
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.
A nit - can you please unify the casing of the "pitching jit" in the descriptions? At some places it is "Jit Pitching", at others "jit pitching".
src/vm/codepitchingmanager.cpp
Outdated
(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_JitPitchMemThreshold) == 0)) | ||
return FALSE; | ||
|
||
if (this == NULL) |
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 would prefer not to introduce more of checks of this to NULL which is against the C++ standard. We have the warning for such compares disabled since it would be difficult to modify historical code at some places to not to do that, but it would be better to not to add more of those.
C++ standard says that calling a method with null this
pointer causes undefined behavior.
Could you please add NULL checks at the caller sites where such checks are needed instead?
MethodDesc* pMD = pCf->GetFunction(); | ||
|
||
// Filter out methods we don't care about | ||
if (pMD == nullptr || !pMD->IsPitchable()) |
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.
A nit - your change uses nullptr and NULL kind of randomly. Could you please pick one of those and use it in your new code for the sake of consistency?
src/vm/codepitchingmanager.cpp
Outdated
if ((CLRConfig::GetConfigValue(CLRConfig::INTERNAL_JitPitchEnabled) != 0) && | ||
(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_JitPitchMemThreshold) != 0) && | ||
(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_JitPitchTimeInterval) == 0 || | ||
((::GetTickCount() - s_JitPitchLastTick) > CLRConfig::GetConfigValue(CLRConfig::INTERNAL_JitPitchTimeInterval)))) |
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.
If the system was running for more than 49.7, the GetTickCount result wraps around and so this interval measurement will stop working.
Using GetTickCount64 would probably be the easiest fix.
src/vm/codepitchingmanager.cpp
Outdated
pMD->PitchNativeCode(); | ||
} | ||
} | ||
for (PtrHashMap::PtrIterator i = s_pExecutedMethods->begin(); !i.end();) |
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.
A nit - can you please reuse the i
from the above? It is confusing in the debugger when there are two variables of the same name.
src/vm/codepitchingmanager.cpp
Outdated
if (s_pPitchingCandidateMethods == NULL) | ||
{ | ||
SimpleWriteLockHolder swlh(s_pPitchingCandidateMethodsLock); | ||
if (s_pPitchingCandidateMethods == NULL) |
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.
The lazy initialization of all the maps and locks make the code harder to read, obscuring the real functionality. It doesn't seem to save much. It seems it would be better to just allocate all of them in a single initialization function where you would know that the pitching is active. Did you have any particular reason for using the lazy allocations?
src/vm/codepitchingmanager.cpp
Outdated
MethodDesc *pMD = (MethodDesc *) i.GetValue(); | ||
UPTR key = (UPTR)GetFullHash(pMD); | ||
++i; | ||
s_pExecutedMethods->DeleteValue(key, (LPVOID)pMD); |
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.
Is it really ok to delete values from the hash map during the iteration?
src/vm/codepitchingmanager.cpp
Outdated
{ | ||
if (pMD->IsPitchable()) | ||
{ | ||
if (sizeOfCode > 0 && CLRConfig::GetConfigValue(CLRConfig::INTERNAL_JitPitchMethodSizeThreshold) < sizeOfCode) |
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.
The first part of the condition is not necessary, the second would never pass for sizeOfCode being zero.
src/vm/codepitchingmanager.cpp
Outdated
{ | ||
SimpleWriteLockHolder swlh(s_pPitchingCandidateMethodsLock); | ||
s_pPitchingCandidateMethods->DeleteValue(key, (LPVOID)this); | ||
s_pPitchingCandidateMethods->Compact(); |
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.
@sergign60 Last detail I wonder about - do we need to run the Compact after each DeleteValue? Does the s_pExecutedMethods->Clear() call happen that rarely that we care about the fact that the hash map is not compact?
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.
@janvorli I think it's not needed. I'll 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.
@janvorli I need some time for testing
e2a8c87
to
5dfaf38
Compare
@noahfalk @janvorli
|
0310171
to
1ee7be6
Compare
@sergign60 - sorry I had forgotten about this for a while, are you ready to have this merged now? I think earlier there were some CI issues but it appears you got those addressed and both JanV and I are happy with it. I have another PR that is going to have merge conflicts so I'd like to get yours in ASAP and then I can merge on top of it. Otherwise if yours doesn't go in now you will need to do some merge work after my PR commits. |
@noahfalk yes, I'm ready to merge it |
@noahfalk many thanks for your help! |
@sergign60 - very welcome and thanks for all your work : ) |
The given pull request proposes a way for resolving issue "Jitted Code Dropping Support" #6757
Its distinctive features and algorithm are:
./build.sh cmakeargs -DFEATURE_JIT_PITCHING=true