There is a high misprediction rate for the common path in JIT_MonExit_Portable

With the common path action == AwareLock::LeaveHelperAction_None not being arranged as the common path in asm.
|
action = obj->LeaveObjMonitorHelper(GetThread()); |
|
if (action == AwareLock::LeaveHelperAction_None) |
|
{ |
|
return; |
|
} |

I've tried rearranging this in the C++; however it seems quite resistant to ordering change; perhaps PGO is incorrectly enforcing the order here?
Aside: I assume it needs to be a cmpxchg rather than just a volatile write because it may have changed from a lock to a lock+hashcode or perhaps signaling? Would there be any scope to having a lock object type that doesn't allow a hashcode or signaling, so it could just be a volatile write to unlock a non-recursive non-signaled lock? (as JIT_MonExit_Portable is quite expensive in the code I'm looking at as 3rd highest cost method)
There is a high misprediction rate for the common path in JIT_MonExit_Portable
With the common path
action == AwareLock::LeaveHelperAction_Nonenot being arranged as the common path in asm.runtime/src/coreclr/src/vm/jithelpers.cpp
Lines 3932 to 3936 in 8640eed
I've tried rearranging this in the C++; however it seems quite resistant to ordering change; perhaps PGO is incorrectly enforcing the order here?
Aside: I assume it needs to be a
cmpxchgrather than just a volatile write because it may have changed from a lock to a lock+hashcode or perhaps signaling? Would there be any scope to having a lock object type that doesn't allow a hashcode or signaling, so it could just be a volatile write to unlock a non-recursive non-signaled lock? (asJIT_MonExit_Portableis quite expensive in the code I'm looking at as 3rd highest cost method)