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

JIT: support OSR for synchronized methods #61712

Merged
merged 3 commits into from
Nov 18, 2021

Conversation

AndyAyersMS
Copy link
Member

OSR methods share the "monitor acquired" flag with the original method.
The monitor acquired flag is s bit of non-IL live state that must be
tecorded in the patchpoint.

Also, OSR methods only need to release the monitor as acquisition can
only happen in the original method.

OSR methods share the "monitor acquired" flag with the original method.
The monitor acquired flag is s bit of non-IL live state that must be
tecorded in the patchpoint.

Also, OSR methods only need to release the monitor as acquisition can
only happen in the original method.
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Nov 17, 2021
@ghost
Copy link

ghost commented Nov 17, 2021

Tagging subscribers to this area: @JulieLeeMSFT
See info in area-owners.md if you want to be subscribed.

Issue Details

OSR methods share the "monitor acquired" flag with the original method.
The monitor acquired flag is s bit of non-IL live state that must be
tecorded in the patchpoint.

Also, OSR methods only need to release the monitor as acquisition can
only happen in the original method.

Author: AndyAyersMS
Assignees: -
Labels:

area-CodeGen-coreclr

Milestone: -

@AndyAyersMS
Copy link
Member Author

@dotnet/jit-contrib PTAL


for (int i = 0; i < 100_000; i++)
{
s = z.F();
Copy link
Member

Choose a reason for hiding this comment

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

Does it make sense to verify Monitor.IsEntered(this) inside the loop?

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure, will add this.

Comment on lines 45 to 50
if (result == 100) {
Console.WriteLine("SUCCESS");
}
else {
Console.WriteLine("FAILURE");
}
Copy link
Member

Choose a reason for hiding this comment

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

Nit:

Suggested change
if (result == 100) {
Console.WriteLine("SUCCESS");
}
else {
Console.WriteLine("FAILURE");
}
if (result == 100)
{
Console.WriteLine("SUCCESS");
}
else
{
Console.WriteLine("FAILURE");
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed.

Copy link
Member

@jakobbotsch jakobbotsch left a comment

Choose a reason for hiding this comment

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

LGTM otherwise.

@AndyAyersMS
Copy link
Member Author

/azp run runtime-jit-experimental

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Member

@BruceForstall BruceForstall left a comment

Choose a reason for hiding this comment

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

I was going to ask how this works on x86, but I guess OSR isn't enabled for x86.

BasicBlock* tryBegBB = fgNewBBafter(BBJ_NONE, fgFirstBB, false);
BasicBlock* tryNextBB = tryBegBB->bbNext;
BasicBlock* tryLastBB = fgLastBB;
BasicBlock* const tryBegBB = fgSplitBlockAtEnd(fgFirstBB);
Copy link
Member

Choose a reason for hiding this comment

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

Why was the switch from fgNewBBafter to fgSplitBlockAtEnd required?

Copy link
Member Author

Choose a reason for hiding this comment

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

Because in OSR methods fgFirstBB may not be BBJ_NONE.

Copy link
Member

Choose a reason for hiding this comment

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

Even after calling fgEnsureFirstBBisScratch()?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, because fgEnsureFirstBBisScratch will just return if the first bb is already scratch.

For OSR we've already called this and messed with the resulting flow. See fgFixEntryFlowForOSR.

@AndyAyersMS
Copy link
Member Author

I guess OSR isn't enabled for x86.

Right, not yet enabled anywhere but x64.

Arm64 support is next, then maybe I'll look at what we'd need to do for x86.

@AndyAyersMS
Copy link
Member Author

Seeing a few unexpected OSR stress issues. Will need to investigate.

@AndyAyersMS
Copy link
Member Author

AndyAyersMS commented Nov 18, 2021

Bug was that if you managed to remove all the EH table entries we'd null out the EH table. Then when we'd go to add a new entry for the synchronous try/fault we don't realize the table is gone and the jit goes boom.

We could probably hit this with the right test case even without OSR (only dead EH in a synchronous method).

@AndyAyersMS
Copy link
Member Author

/azp run runtime-jit-experimental

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@AndyAyersMS
Copy link
Member Author

Back down to the "expected" set of failures, with one exception in osr + pc (likely unrelated). I'll track this one separately.

;; win x64 JIT\Performance\CodeQuality\Bytemark

Assert failure(PID 1908 [0x00000774], Thread: 7728 [0x1e30]): ((FARPROC) (TADDR)m_pvHJRetAddr) != NULL

CORECLR! Thread::HijackThread + 0x2FB (0x00007ffb92d5261b) CORECLR! Thread::HandledJITCase + 0x30B (0x00007ffb92d5225b)
CORECLR! ThreadSuspend::SuspendRuntime + 0x7C5 (0x00007ffb92d58755) CORECLR! ThreadSuspend::SuspendEE + 0x253 (0x00007ffb92d57e33)
CORECLR! CallCountingManager::StopAndDeleteAllCallCountingStubs + 0x126 (0x00007ffb9281b906) CORECLR! TieredCompilationManager::DoBackgroundWork + 0xBF3 (0x00007ffb92a72533)
CORECLR! TieredCompilationManager::BackgroundWorkerStart + 0x207 (0x00007ffb92a711e7) CORECLR! TieredCompilationManager::BackgroundWorkerBootstrapper1 + 0xDD (0x00007ffb92a70f7d)
CORECLR! ManagedThreadBase_DispatchInner + 0xB4 (0x00007ffb92a64854) CORECLR! ManagedThreadBase_DispatchMiddle + 0xB6 (0x00007ffb92a64956)
File: D:\a_work\1\s\src\coreclr\vm\threadsuspend.cpp Line: 4741
Image: C:\h\w\A5630913\p\corerun.exe

@AndyAyersMS
Copy link
Member Author

@BruceForstall want to take one last look? I had to make a change in jiteh.cpp to fix this issue.

@BruceForstall
Copy link
Member

We could probably hit this with the right test case even without OSR (only dead EH in a synchronous method).

Looks like we only ever removed EH clauses after the code to add sync method EH, so it wouldn't hit before. The jiteh.cpp change makes sense: there's no reason to remove the table if compHndBBtabCount is correctly zero; since compHndBBtabAllocCount represents the actual size of the table.

@ghost ghost locked as resolved and limited conversation to collaborators Dec 19, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants