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

Implement simple version of On Stack Replacement (OSR) #32969

Merged
merged 36 commits into from
Mar 17, 2020

Conversation

AndyAyersMS
Copy link
Member

Add support to runtime and jit to allow switching from unoptimized to
optimized code for a method while the method has active stack frames.

Details in the included document.

Add support to runtime and jit to allow switching from unoptimized to
optimized code for a method while the method has active stack frames.

Details in the included document.
@AndyAyersMS
Copy link
Member Author

AndyAyersMS commented Feb 28, 2020

cc @dotnet/jit-contrib @jkotas @noahfalk

Not "in plan" for 5.0, but would like to get this into the main code base so we can refine and gain experience over time, similar to what we did with tiered compilation.

Currently built by default (for x64), but not enabled by default. There should be minimal impact when not enabled (one extra byte in debug info per method). The plan is to create a special CI leg to enable ongoing testing.

To enable one must set COMPlus_TC_QuickJitForLoops=1 and COMPlus_TC_OnStackReplacement=1.

When enabled, methods with loops get jitted at Tier0 and get extra code for patchpoints; cost is about 2% of Tier0 code size, and also get patchpoint info. Net size impact is estimated to be around 10 bytes of code and data per Tier0 method (~100 bytes for each method with patchpoints).

Many of the file changes are boilerplate. Interesting areas to focus on:

  • the new runtime helper
  • the way patchpoint info is conveyed to, stored, and retrieved by the runtime
  • the way the jit inserts patchpoints and creates patchpoint info
  • the way the jit handles an OSR jit request (mainly frame layout and prolog code changes)

More thinking about trigger policies is needed; what's there now is plausible but has some quirks.

I have run through scenarios reported vs 3.0 where QJFL=1 caused steady-state perf losses, and OSR recovers those. I have also run through scenarios where QJFL=0 caused startup losses, and OSR recovers those.

NYI for non-x64. arm64 would probably come next, and might be challenging given the diversity of stack frame styles.

Passes Tier1 tests on x64 in "aggressive" OSR mode (produce OSR method and transition the first time a patchpoint is reached).

@BruceForstall
Copy link
Member

cc @davidwrighton

@@ -552,6 +574,20 @@ void CompressDebugInfo::RestoreBoundariesAndVars(
if (pcVars != NULL) *pcVars = 0;
if (ppVars != NULL) *ppVars = NULL;

// Check flag byte and skip over any patchpoint info
Copy link
Member

Choose a reason for hiding this comment

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

This is changing the debug info format. The debug info format is part of R2R format, so changing it would need to touch number of places (e.g. src\coreclr\src\tools\crossgen2\ILCompiler.Reflection.ReadyToRun\DebugInfo.cs).

It may be easiest to append the extra stuff at the end, and look for it only when the method has patch info (e.g. only for JITed methods).

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, let me rework this.

Copy link
Member Author

Choose a reason for hiding this comment

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

Have looked at adding patchpoint info to the end of the compressed debug info blob, with the idea that some of the existing debug info producers/consumers would not need to change, but this seems fragile.

The current header record for the debug info just has the lengths of the two encoded sub-records. So there's no way to tell if what lies beyond the sub records is really patchpoint info or just random bytes.

Modifying the header to include more length info is similar in spirit to what I'm already doing. Adding a new header field -- either for overall length, for header length, or for patchpoint info length -- will require all producers and consumers to change.

Copy link
Member

Choose a reason for hiding this comment

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

I don't see any requirement that R2R debug format exactly match runtime format, though it currently does. We could allow them to diverge so that the runtime format supports the patchpoint data and the R2R one stays exactly how it is now. In the future they could again converge if/when we want to take an R2R format change.
Implementation-wise it appears minimal - a boolean flag on RestoreBoundariesAndVars indicating if the patchpoint length byte is expected, EEJitManager::GetBoundariesAndVars() sets it true, the other JitManagers set it false.

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated so only jitted code debug is impacted, and only when feature is defined.

Still may want to tweak this, say by putting the patchpoint info length in the header instead of a flag byte.

@danmoseley danmoseley added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Feb 29, 2020
@danmoseley
Copy link
Member

Please add exactly one area label to PR if bot fails to: it trains bot.

Copy link
Member

@noahfalk noahfalk left a comment

Choose a reason for hiding this comment

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

A few suggestions inline but this looked pretty good to me (I didn't look at the JIT parts). I'm happy to take a look at it again later after changes but don't feel that it has to block on me.

// Total size of this patchpoint info record, in bytes
unsigned PatchpointInfoSize() const
{
return m_patchpointInfoSize;
Copy link
Member

Choose a reason for hiding this comment

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

Nit: low hanging memory overhead optimization, we could eliminate m_patchpointInfoSize and write this as ComputeSize(m_numberOfLocals).

Copy link
Member Author

Choose a reason for hiding this comment

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

Done.

@@ -552,6 +574,20 @@ void CompressDebugInfo::RestoreBoundariesAndVars(
if (pcVars != NULL) *pcVars = 0;
if (ppVars != NULL) *ppVars = NULL;

// Check flag byte and skip over any patchpoint info
Copy link
Member

Choose a reason for hiding this comment

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

I don't see any requirement that R2R debug format exactly match runtime format, though it currently does. We could allow them to diverge so that the runtime format supports the patchpoint data and the R2R one stays exactly how it is now. In the future they could again converge if/when we want to take an R2R format change.
Implementation-wise it appears minimal - a boolean flag on RestoreBoundariesAndVars indicating if the patchpoint length byte is expected, EEJitManager::GetBoundariesAndVars() sets it true, the other JitManagers set it false.

// Request a new native version that is optimized.
CodeVersionManager::TableLockHolder lock(codeVersionManager);
ILCodeVersion ilCodeVersion = codeVersionManager->GetILCodeVersion(pMD, rejitId);
HRESULT hr = ilCodeVersion.AddNativeCodeVersion(pMD, NativeCodeVersion::OptimizationTier1, &osrNativeCodeVersion);
Copy link
Member

Choose a reason for hiding this comment

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

TieredCompilationManager promotion to tier1 first checks for the existence of a OptimizationTier1 code version before creating a new one. If one already exists then we assume that tier1 promotion is in progress and doesn't need to be repeated. This native code version will incorrectly cause normal Tier1 promotion to back off. Assuming that the check is modified to only consider non-OSR tier1 compilations then there remains a race-condition where this NativeCodeVersion appears to be a non-OSR version until the SetOSRInfo call below. I'd suggest making OSR info part of immutable NativeCodeVersion information that is written only once in the constructor. AddNativeCodeVersion would need to be refactored and SetOSRInfo removed.

Copy link
Member

Choose a reason for hiding this comment

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

Due to the check mentioned by @noahfalk and since the OSR code appears to be specific to each patchpoint, it may prevent a later normal transition to full tier 1 method code. The OSR code could have a different tier identifier but for now it may work to classify it as OptimizationTier0 instead.

Adding the code version to this collection is also a bit odd because it's not a version of code for the method, and it looks like there are already separate data structures tracking OSR code versions. I don't think it hurts much, for example the debugger would show OSR code versions as well. But I'm curious if a code version needs to be added at all, is it used somehow and if so could those cases use the other data structures instead?

Copy link
Member

Choose a reason for hiding this comment

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

is also a bit odd because it's not a version of code for the method

I suggest that we do think of OSR compilations as 'a version of code for the method'. It is a version that has a different entrypoint and ABI than we are used to, but for the majority of code interacting with CodeVersionManager that isn't an important distinction.

for example the debugger would show OSR code versions as well

That is a good thing : ) The debugger, profiler, and ETW should all be able to enumerate OSR code bodies as potential code regions that resolve to the same method.

I'm curious if a code version needs to be added at al

I believe it is an apt representation:
a) It is the identifier used by PrepareCode that identifies the code that needs to be created.
b) It allows the debugger, profiler, and ETW to enumerate the code regions

if so could those cases use the other data structures instead?

I'm sure it is possible, but the code complexity added to the patchpoint table, in PrepareCode, and in all the code version enumerators goes up significantly when we don't use NativeCodeVersion as a common abstraction. The complexity added to NativeCodeVersion to let it represent an OSR version appears far lower.

Copy link
Member

Choose a reason for hiding this comment

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

The complexity added to NativeCodeVersion to let it represent an OSR version appears far lower.

Maybe not worth the trouble, sounds fine to me

Copy link
Member Author

Choose a reason for hiding this comment

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

Am going to stick with a new native code version for now. This is no longer described as Tier1 -- it's now Tier1OSR, so should not confuse tiering...


// OSR is only supported on x64, currently.
#if !defined(TARGET_AMD64)
if (verbose > 1)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (verbose > 1)
#error OSR in not yet implemented for ABIs other than AMD64 yet

{
if (verbose > 1)
{
printf("### Runtime: INVALID patchpoint [%d] 0x%p\n", ppId, ip);
Copy link
Member

Choose a reason for hiding this comment

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

LOG(...) macro or STRESS_LOG(...) macro are prefered error logging mechanisms over printf. Log levels should also eliminate the need for manual verbosity checks.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done.

@@ -973,10 +973,13 @@ PCODE MethodDesc::JitCompileCodeLocked(PrepareCodeConfig* pConfig, JitListLockEn

// The profiler may have changed the code on the callback. Need to
// pick up the new code.
//
// (don't want this for OSR, need to see how it works)
Copy link
Member

Choose a reason for hiding this comment

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

Profilers achieve this modification using either SetILFunctionBody or RequestReJIT. The ReJIT case has its safety enforced by the runtime - each time the profiler calls RequestReJIT we allocate a new ILCodeVersion and every JIT request is bound to a particular NativeCodeVersion which in turn implies a specific ILCodeVersion. In the case of tiered compilation or OSR the NativeCodeVersion being constructed was bound to the same ILCodeVersion as the tier0 native code, regardless if the profiler has created some new IL versions in the meantime. For ReJIT GetAndVerifyILHeader() allows the IL code for a given ILCodeVersion to be provided by the profiler lazily, but it is still logically immutable. Whatever IL the profiler gives the runtime is cached in the ILCodeVersion object and that same IL is returned on every future query. We know that the tier0 code would have already requested IL so all the tier1 requests will be working off the runtime cached copy.

SetILFunction body is the older and less safe variation that currently relies on correct usage by profiler authors rather than runtime enforcement. The documentation tells them that they should not do this:

> The SetILFunctionBody method can be called on only those functions that have never been compiled by a just-in-time (JIT) compiler.

The current implementation of SetILFunctionBody overrides the IL of the initial ILCodeVersion. The runtime code treats that IL as if it were immutable, but clearly with abuse by the profiler author it wouldn't be. If a profiler is making these types of modifications and leaving tiered compilation enabled then they have already broken the tiered compilation case (tier0 and tier1 would use different IL). I could imagine that getting it wrong in the OSR case has more visble failure modes though. I haven't thought it through all the way, but probably a safer place to be in the future is to re-implement SetILFunctionBody so that it allocates new ILCodeVersions similar to ReJIT so that we can version it explicitly.

cc @davmason

Copy link
Member

Choose a reason for hiding this comment

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

Thanks @noahfalk. I agree there are some new rough edges here, but I don't think it's enough to block the feature on. I filed #33197 to track the work to get rid of the rough edges.

@noahfalk
Copy link
Member

noahfalk commented Mar 4, 2020

cc @kouvel @davmason for visibility around tiered compilation and profiling

@AndyAyersMS
Copy link
Member Author

Thanks for the feedback so far. Since this involves reworking the jit interface and that entails lots of coordinated edits, I'd like to get consensus on the overall structure, if possible. Here's what I propose given the suggestions above:

  • Make CORINFO_PATCHPOINT_INFO an opaque struct in corinfo.h
    • struct definition now private to jit
    • runtime either has simplified definition OR a duplicate definition OR we explicitly pass length into runtime methods that need it. Currently the runtime only needs to know the length. There is a future optimization we can do where upon transition we trim the original method frame down to the last live local, in which case the runtime would need to access more data.
    • update debug blob format for jitting only, per Noah's suggestion
  • Remove CORINFO_OSR_INFO struct definition
    • revert changes to CORINFO_METHOD_INFO
    • add new jit interface method getOSRInfo to fetch ppinfo and iloffset; jit calls this if OSR flag is set
    • add fields to hold data for this to CEEJitInfo (already has ppinfo field, but we now need to know now if the jit interface owns this data, or the runtime does)
    • add new private CEEJitInfo method SetOSRInfo to set these fields, called from JitUnsafeMethod
    • update OSR's NativeCodeVersion to hold ppinfo, iloffset, and set those in AddNativeCodeVersion

@jkotas
Copy link
Member

jkotas commented Mar 4, 2020

Sounds good to me.

CORINFO_PATCHPOINT_INFO

We may want to follow similar patterns for this as we follow for GCInfo.

@AndyAyersMS
Copy link
Member Author

We may want to follow similar patterns for this as we follow for GCInfo

You mean adding the definition for CORINFO_PATCHPOINT_INFO to src\inc? It is header-only.

@jkotas
Copy link
Member

jkotas commented Mar 4, 2020

I meant it more a conceptual comment:

GCInfo is opaque (compressed) blob. JIT has encoder for it, and the parts of the system that need to understand it have a decoder for it. Now that you are describing CORINFO_PATCHPOINT_INFO as opaque struct, it feels pretty similar.

@AndyAyersMS
Copy link
Member Author

That was already my conceptual viewpoint too. If moving the current CORINFO_PATCHPOINT_INFO definition over to a header in src\inc is not the right way to implement this, then I could use some more concrete guidance.

@jkotas
Copy link
Member

jkotas commented Mar 5, 2020

moving the current CORINFO_PATCHPOINT_INFO definition over to a header in src\inc

We use CORINFO_XXX for structures used for JIT/EE interface. All CORINFO_XXX structures are defined in corinfo.h/corjit.h.

The structures used to pass the data throughout the system do not have CORINFO_XXX prefix. A good example of prior art may be struct GCInfoToken. If you are moving CORINFO_PATCHPOINT_INFO into a separate file, it may make sense to rename it to just PatchPointInfo so that it does not look like JIT/EE interface structure.

@AndyAyersMS
Copy link
Member Author

Ok, good. So should it just be void* in corinfo.h, or an opaque PatchpointInfo?

Copy link
Contributor

@CarolEidt CarolEidt left a comment

Choose a reason for hiding this comment

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

Mostly comments on comments, but one question about struct promotion being disabled.
(I've only looked at the document and the JIT code).

docs/design/features/OnStackReplacement.md Outdated Show resolved Hide resolved
docs/design/features/OnStackReplacement.md Outdated Show resolved Hide resolved
docs/design/features/OnStackReplacement.md Outdated Show resolved Hide resolved
docs/design/features/OnStackReplacement.md Outdated Show resolved Hide resolved
docs/design/features/OnStackReplacement.md Show resolved Hide resolved
src/coreclr/src/jit/flowgraph.cpp Show resolved Hide resolved
assert(info.compILEntry >= 0);
BasicBlock* bbTarget = fgLookupBB(info.compILEntry);

fgEnsureFirstBBisScratch();
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it worth adding a call to fgFirstBBisScratch() (which has some self-consistency asserts) in the phase checks?

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 do.

The name doesn't quite convey the idea that this is method is nominally a "side effect free" predicate. Perhaps fgIsFirstBBScratch() would be an improvement?

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, that doesn't play out as well as I thought. Will leave name as is.

src/coreclr/src/jit/flowgraph.cpp Show resolved Hide resolved
// We need to trim the current try to begin at a different block. Normally
// this would be problematic as we don't have enough context to redirect
// all the incoming edges, but we know oldTryEntry is unreachable.
// So there are no incoming edges to worry about.
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm confused here as well. If there are no incoming edges, then why can't we just eliminate this try entry?

Copy link
Member Author

Choose a reason for hiding this comment

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

Normally you can't branch into the middle of a try; OSR changes this.

So we can have cases now where we just import the middle of a try, and need to trim both begin and end extents.

If a try entry is not imported, then none of the try entry predecessors could have been imported either (even though we can't enumerate them), so there are no "flowgraph live" references to oldTryEntry.

src/coreclr/src/jit/lclvars.cpp Show resolved Hide resolved
@jkotas
Copy link
Member

jkotas commented Mar 5, 2020

So should it just be void* in corinfo.h, or an opaque PatchpointInfo?

I do not have strong opinion.


// Find the il method version corresponding to this version of the method
// and set up a new native code version for it.
ReJITID rejitId = ReJitManager::GetReJitId(pMD, codeInfo.GetStartAddress());
Copy link
Member

Choose a reason for hiding this comment

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

Since this is code-versioning-specific and not profiler-rejit-specific, it may be better to use a different route. EECodeInfo now has a GetNativeCodeVersion() and from that the IL code version can be obtained (inside the lock). Both can be done inside the code versioning lock since the lock allows reentrancy.

Copy link
Member Author

Choose a reason for hiding this comment

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

Think this is now following your suggestion.

NativeCodeVersion osrNativeCodeVersion;
{
// Request a new native version that is optimized.
CodeVersionManager::TableLockHolder lock(codeVersionManager);
Copy link
Member

@kouvel kouvel Mar 5, 2020

Choose a reason for hiding this comment

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

This would conflict with my recent change that removed TableLockHolder, this is used instead in other places:

CodeVersionManager::LockHolder codeVersioningLockHolder;

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated.

// Request a new native version that is optimized.
CodeVersionManager::TableLockHolder lock(codeVersionManager);
ILCodeVersion ilCodeVersion = codeVersionManager->GetILCodeVersion(pMD, rejitId);
HRESULT hr = ilCodeVersion.AddNativeCodeVersion(pMD, NativeCodeVersion::OptimizationTier1, &osrNativeCodeVersion);
Copy link
Member

Choose a reason for hiding this comment

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

Due to the check mentioned by @noahfalk and since the OSR code appears to be specific to each patchpoint, it may prevent a later normal transition to full tier 1 method code. The OSR code could have a different tier identifier but for now it may work to classify it as OptimizationTier0 instead.

Adding the code version to this collection is also a bit odd because it's not a version of code for the method, and it looks like there are already separate data structures tracking OSR code versions. I don't think it hurts much, for example the debugger would show OSR code versions as well. But I'm curious if a code version needs to be added at all, is it used somehow and if so could those cases use the other data structures instead?

@@ -351,6 +351,9 @@ End
Crst JitGenericHandleCache
End

Crst JitPatchpoint
Copy link
Member

Choose a reason for hiding this comment

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

Maybe could reuse CrstLeafLock instead, as there appear to be are many different locks in that class

Copy link
Member Author

Choose a reason for hiding this comment

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

Can no longer be a leaf lock as we have to allocate while holding.

@AndyAyersMS
Copy link
Member Author

But I'm curious if a code version needs to be added at all, is it used somehow and if so could those cases use the other data structures instead?

It is only used to convey the extra information the jit needs for an OSR jit request. I could probably pass this information via the PrepareCodeConfig instead and not introduce a new code version.

@AndyAyersMS
Copy link
Member Author

Updated that bit. Looks like the crossgen comparison diff may be real, need to investigate.

@AndyAyersMS
Copy link
Member Author

Can't get the CoreCLR Pri0 Test Run Linux x64 checked failure to repro locally.

@AndyAyersMS
Copy link
Member Author

Seems like similar failures seen in #33562. I still cannot repro the linux checked failures locally.

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.

LGTM. A few minor comments.

// Invoke the helper to build the OSR method
osrMethodCode = HCCALL3(JIT_Patchpoint_Framed, pMD, codeInfo, ilOffset);

// If that failed, mark the patchpoint as invaild.
Copy link
Member

Choose a reason for hiding this comment

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

nit: typo: "invaild"

@@ -497,7 +498,7 @@ void Compiler::fgEnsureFirstBBisScratch()
}

//------------------------------------------------------------------------
// fgFirstBBisScratch: Check if fgFirstBB is a scratch block
// fgIsFirstBBScratch: Check if fgFirstBB is a scratch block
Copy link
Member

Choose a reason for hiding this comment

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

Did you intend to rename the function as well?

Copy link
Member Author

Choose a reason for hiding this comment

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

Renamed it and then decided to keep the original name. Missed undoing this one.

@@ -5983,6 +5989,29 @@ void Compiler::fgFindBasicBlocks()
return;
}

// If we are doing OSR, add an entry block that simply branches to the right IL offset.
// Might need to do something special if we're entering try regions?
if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_OSR))
Copy link
Member

Choose a reason for hiding this comment

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

=> opts.IsOSR()

Copy link
Member

Choose a reason for hiding this comment

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

(every usage of JIT_FLAG_OSR should go through that helper, right?)

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, will update.

@@ -20752,6 +20911,7 @@ void Compiler::fgDebugCheckBBlist(bool checkBBNum /* = false */, bool checkBBRef
#endif // DEBUG

fgDebugCheckBlockLinks();
fgFirstBBisScratch();
Copy link
Member

Choose a reason for hiding this comment

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

Do we always require the first BB to be scratch? Is that a new requirement?

Copy link
Member Author

Choose a reason for hiding this comment

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

No.

That method is called here just as a check. It verifies that if there is a scratch bb, that other expected invariants hold.

@@ -394,6 +394,11 @@ CONFIG_INTEGER(JitGuardedDevirtualizationGuessUniqueInterface, W("JitGuardedDevi
CONFIG_INTEGER(JitGuardedDevirtualizationGuessBestClass, W("JitGuardedDevirtualizationGuessBestClass"), 1)
#endif // DEBUG

// Enable insertion of patchpoints into Tier0 methods with loops.
CONFIG_INTEGER(JitPatchpoint, W("JitPatchpoint"), 0)
Copy link
Member

Choose a reason for hiding this comment

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

Do you enable OSR by setting COMPlus_JitPatchpoint=1? Seems like "OSR" and/or "On Stack Replacement" wording should be here, and maybe make it clear that this is the "root of all enablement", if so.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point, I should rename this to COMPlus_TC_OnStackReplacement or similar.

You also need to set COMPlus_TC_QuickJitForLoops=1 to turn this on.

Copy link
Member

Choose a reason for hiding this comment

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

You also need to set COMPlus_TC_QuickJitForLoops=1 to turn this on.

Could (should) you make COMPlus_TC_OnStackReplacement automatically set COMPlus_TC_QuickJitForLoops=1?

Copy link
Member

Choose a reason for hiding this comment

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

You could at least document that requirement here.


if (opts.IsOSR() && info.compPatchpointInfo->IsExposed(varDscInfo->varNum))
{
JITDUMP("-- V%02u is osr exposed\n", varDscInfo->varNum);
Copy link
Member

Choose a reason for hiding this comment

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

nit: "osr" should be all-caps "OSR" in all output (and comments)

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, will fix.

@AndyAyersMS
Copy link
Member Author

Need to wait for fix in #33580 before retesting.

@BruceForstall
Copy link
Member

BruceForstall commented Mar 14, 2020

You added a bunch of tests. Should you force them to be OSR tests by having their project files:

set COMPlus_TC_OnStackReplacement=1
set COMPlus_TC_QuickJitForLoops=1

For example, the way src\coreclr\tests\src\JIT\opt\ObjectStackAllocation\ObjectStackAllocationTests.csproj does it?

Or do you want to leave OSR testing to a special "off by default" pipeline as we've discussed?

@AndyAyersMS
Copy link
Member Author

You added a bunch of tests. Should you force them to be OSR tests

Yes, might as well. Also need to suppress patchpoint insertion if the OSR feature is not defined.

@AndyAyersMS AndyAyersMS marked this pull request as ready for review March 14, 2020 17:29
@AndyAyersMS
Copy link
Member Author

Think we're close enough now that this can come out of draft mode. Looks like I need to resolve another merge conflict.

@AndyAyersMS
Copy link
Member Author

@echesakovMSFT any tips for debugging the crossgen comparsion failure?

Also looks like that CI leg is archiving an entire repo + artifacts, 4GB of stuff; not sure if that's useful or unintentional.

@BruceForstall
Copy link
Member

It's failing crossgen-comparison with OSR disabled? With OSR disabled shouldn't R2R images be the same as before your PR?

@AndyAyersMS
Copy link
Member Author

AndyAyersMS commented Mar 15, 2020

Right, this should be no diff. Have tried looking at the changes themselves to see if anything jumps out, but didn't spot anything.

Will probably try looking for x64_arm crossgen diffs next, or grab the crossgen files and see where the diffs appear (R2R dump should work for this, right?).

[Edit: looks like we don't publish the crossgen files, there are empty "a" and "b" folders in the artifacts that I though might hold the binaries].

@echesakov
Copy link
Contributor

@echesakovMSFT any tips for debugging the crossgen comparsion failure?
Also looks like that CI leg is archiving an entire repo + artifacts, 4GB of stuff; not sure if that's useful or unintentional.

@AndyAyersMS

I would start with running crossarch compiler on the libraries that have mistmatch
You can get them from the ci workitem console log (https://helix.dot.net/api/2019-06-17/jobs/d4b65df1-fdf8-4d22-87bb-99b08c5ff252/workitems/WorkItem/console)

File hash sum mismatch for "CommandLine" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "ae460df2597669e120a3b0e21c67bf66a33bb0c3c60a199690a12e5449d97f78"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "25386e3f61434738f86a9174d5447d783478072270efb2faee6ac7b6a99d10b2"
File hash sum mismatch for "Microsoft.CSharp" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "aed5b863168d01681006e834746ec7235e1c5521507c325ce510c4a69b5379aa"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "37fe9a8ad95bf278c4f99336c8922f08ade0e999743e36eea604e1f579d671dc"
File hash sum mismatch for "Microsoft.CodeAnalysis" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "1f73c9de344abe19c9d549d316f6eab26be43d2b972315890e56fbce8815d116"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "30c62fb718c1e1a56f072776dae623be07fbe967b36671ef7fca8a06d85f0040"
File hash sum mismatch for "Microsoft.CodeAnalysis.CSharp" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "8870cb9abc64592a7b798e282be8d059c3cb970c2d3fae6068a4acffec5592c2"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "9d9d06af20041a14c06a56f911a35391ee3490cdf81dd7268188b555988fce4f"
File hash sum mismatch for "Microsoft.CodeAnalysis.VisualBasic" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "0e94c9f28b0822f81638adf2a777ef0c0dac549ccde9c392a922983166a2b365"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "7019b7724b78a8ef56abbed372cc742e9b3cfdfc10cb1a6312f38265fd464a35"
File hash sum mismatch for "Microsoft.Diagnostics.FastSerialization" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "336697caf16845399ec6b791316924eb4ed0e385e68a0d751f1929b667d3a280"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "605ab985643e8fefdb63f0315ec957dc5d23719111b8b18500d2054625d6fbab"
File hash sum mismatch for "Microsoft.Diagnostics.Tracing.TraceEvent" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "90c926495108f8a3b6fa3799ae008cb2cf4994a4c6ff7739849daa436879ab8e"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "6e0c6e0024358e5cdb705ff7b58944f938a514328ebfb20b4dd2f6a00865fdb7"
File hash sum mismatch for "Microsoft.Win32.Primitives" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "02fb20d682f2a711bd2b1faedbf92a8d1fe19aab7c340f855db640f8a03148f2"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "b7320f0fe28fbb8efdeb4c73538bff3ee3997d47c605ca0d05af6e11a99695d7"
File hash sum mismatch for "Microsoft.Win32.Registry" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "e95d0c5a067906bcef80d9fb8d478970972cc58b156810b9dda67a5c34cfd774"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "a708085a5dd0e143a61628b407ea32583e2961aa614831e69056c4b2928b22b3"
File hash sum mismatch for "Newtonsoft.Json" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "dc1df12e6320cdb93f13e6403d110240850d88901bea4191aac14ccaf5bb380b"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "16523cc074a0f4315609622b95b423828815ceae0d5be078b8fce5c8a5e658f5"
File hash sum mismatch for "System.Collections" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "9ae162900cac0023526c342609d460628b6459d7b3209e463443a8ce60aebb16"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "68f80296d38d222bf50f0a3c33c6e9301f78ea3452b8fe403ccf3ca4411b4faf"
File hash sum mismatch for "System.Collections.Concurrent" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "e4bc590a8f331dcf4811d2b6b400d481dd38e1ab3e89be43185af0a638a1b36e"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "e7f8e74adc28ceb0bdad0fdf3477f20b5e2234c83174f91d1b0fd0bc12b4bfc3"
File hash sum mismatch for "System.Collections.Immutable" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "9f50b04d41749e2c2591823461dba6978ca112ff29570003da136bdb4b6561db"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "ccef6fefff50c6c2d32b388f18032839cfdab463f8e3201f4dfb2a78bba1ea94"
File hash sum mismatch for "System.Collections.NonGeneric" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "1d97a067e259119b0b73f10250691bf1f51c00f55a2fdd810943b5cf82c3bad2"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "6946e814dec06615761a35138619412d9bb6f2a79d149484d21b4eab8ddc2496"
File hash sum mismatch for "System.Collections.Specialized" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "45da3b2755a3986823cbcf6b4eaf1845898d145df46178b54ad99c511025459c"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "a1707dc46a1be646ac36e71b36136769242d7842b3f3f402bed2523e8e8f2fe4"
File hash sum mismatch for "System.ComponentModel.Annotations" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "692a9267b582f4cdbfdf9fcc3a4ec9b9147eb61f2489c25437726dc1d685a1f6"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "02df0a9cb8531f590c1b98bc5524ac50969ef4ecd1931511262d7e15b306e1db"
File hash sum mismatch for "System.ComponentModel.EventBasedAsync" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "3ac1af206058d1d356b08a9dbb281913ac44309be6738a3b96d39905e6b30913"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "cefd008520bffc37e03ce08bb67cca709790bd2112d7ebce8cd8e3e76064d5ae"
File hash sum mismatch for "System.ComponentModel.Primitives" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "27077d1bce77c2c71ecaf6116244340b73f640598a1795f1b3708b3b19ca7053"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "fb4560f67e4be034720d06c7fff00d34c0c9dc497818db94a5ece12e03e5e6b0"
File hash sum mismatch for "System.ComponentModel.TypeConverter" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "cd3eed74d61beb3e37ee2d52b10656a1216dad933def6980c2b57c3d217fa135"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "37f68226da4011197f6fee2eaba79e3a37b014a89b7c7217962a058b944b4ad1"
File hash sum mismatch for "System.Console" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "5c9eece1ec2e24c149a20ab03f77fb62dc53282a38260e759fe12a14b9d7e61f"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "2ebb6ea3317f964da76808b0ed90d96d57908541b8b8f3e0cb48104e792da131"
File hash sum mismatch for "System.Data.Common" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "3efd83cbf959b1816655f34d075511423129bf13f2e947f79c5449698d91d25d"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "ce97a30521a1843787003d589d16259272a04924727884452719db46b387b13e"
File hash sum mismatch for "System.Diagnostics.DiagnosticSource" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "f6bc3d7c5e3a8c15cd08fcc585e057e79640319a7161c3cb35db5ee63df327eb"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "5f1fb649ba34608d1b71a6c492f191921b6be954077d9a5c127c4e4059992d2e"
File hash sum mismatch for "System.Diagnostics.EventLog" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "d1514fbe06898f13bc5c2c79492de50736839bb5a69da5b42ee681cf6ac532bf"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "951f712323060a81f26476a21f07273d074bb81ce0a4c1fa2fb1c7f47d338984"
File hash sum mismatch for "System.Diagnostics.FileVersionInfo" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "bf1688cf2255dfdf77454707cff0702fceeb717e6b7d10822c90de1a31f55086"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "2fa5e2e60cae84f7030d7310fd35402c77f1cc7cee97ded85696a9922c6dcc6a"
File hash sum mismatch for "System.Diagnostics.Process" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "5bb8fd6f78ec7bf6204c051ccad3c4d588a119a80407d3b7a216786939d9b978"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "d90e4b0f65443e610d7c0ae843f297f2bf1bf58949625f8f3953096f1d06652e"
File hash sum mismatch for "System.Diagnostics.StackTrace" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "148074430b90513cc26f821c95168c626f1b50a37ea27eb3b14e1ee51469d030"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "062c5d40ec2be05c1bf8b65e850121e0671bea3b0db86a2c7e25082de1e05f93"
File hash sum mismatch for "System.Diagnostics.TextWriterTraceListener" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "9df08fe8cc5cbd7ce5250072313324132a2a4573a76e205d417deda3786e5ed2"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "7509ec08f0dc6170d74a8bf7d2c58ae0aa615b29763a90b2ed5af8bbdf24ff77"
File hash sum mismatch for "System.Diagnostics.TraceSource" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "eb37d8f2d51667b47e15db7d9439947ca474851bc99785e5e8561f8e8a1ab824"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "0506a618376f81e686bf00c2c5b460dd8edf89974d6ec616b5bd687b251a11f7"
File hash sum mismatch for "System.Drawing.Primitives" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "6148463f3ef3bea7f9a365ac2fc230c90b5217451c66410ddaea850b7d2076d9"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "e2d18a129838ad37455a9870d618d2227fd493237c6c7ff4f7206c0c10927253"
File hash sum mismatch for "System.IO.Compression" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "2361634dce6dd87a2f4eb90269c6f44fe8b412016bf478dc8c1d1e848d68a533"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "e7c7ae2ac0df6c46ee05459c4d08937eaf1e5e3562cb0ef8c88806e950cb11ae"
File hash sum mismatch for "System.IO.Compression.Brotli" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "9cf634e43839fd46c600f5c364f4ae8a12e8cde403a6c99d61f3ded18402ee44"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "9925182b914af516725d0a45e55cf4f18b3ea3e7f76c9a5822cab0d62593203c"
File hash sum mismatch for "System.IO.Compression.ZipFile" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "6ba23c1424e693cc3d65e7afb6326c811d6f15b32f9eb19a691eb610f496ad9b"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "7e57d4dc1ffb75b6fa18a1ad0efae2e0e5299a97919c3b5a950e109e2269d3a5"
File hash sum mismatch for "System.IO.FileSystem" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "4bb16d9fbc4c6781797ddb55ce301a6d2e5b166a62db5a073614e9f64b0ab352"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "c2e7ed5d934b496dd3af26be90aa18296264612166e79973fe7291b993bdc644"
File hash sum mismatch for "System.IO.FileSystem.AccessControl" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "e47d40cf4e31553e727c070fda07a7b140a1365d976685e47f070edf0b75a341"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "136b8bb2884cbc22263771823be44047fc8d588451ea8b2c99710d71421dd0c1"
File hash sum mismatch for "System.IO.FileSystem.DriveInfo" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "b2a948e9b5a3ab4b1d4a02262ceb4c1090885d3db9b032967ec8780c3de79be2"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "57fcb35a7bc9499f930c6efcc8e7cc0f6ac5a329ae3d583e01d749eb48e8bdff"
File hash sum mismatch for "System.IO.FileSystem.Watcher" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "341524a724f2bda4c92e7716193976e03098c726de5d81712f988ab4cb7c7531"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "e4a33f5619007800a12851d565238c38725375a98ffb1e7d3cb507d2fa086913"
File hash sum mismatch for "System.IO.IsolatedStorage" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "34bba4f4e321cf0255f9a8c10151e8b3d83663b9671f5ebf7bcdf652e93fb9c6"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "3186b1501d9c1cd9c604ef0f85843cb7fa07f6dc1ec8eef8c7d0a60dafd9f234"
File hash sum mismatch for "System.IO.MemoryMappedFiles" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "f522176dfd56c28ec328c18d6333a5227cc9638c9c9d0effbfb448b29a7d1374"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "2a7074ecddc5b43078d1c1a617db8d7aa0481440da636285e432e93bc988efc8"
File hash sum mismatch for "System.IO.Pipes" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "5bb408404a748786f7fb3c022fd8f182fbe381f943f5ba7f8a5bf7a4ae72d1ba"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "497364b928ccfdcdd162c4d0e585dfbbad46ff61becf3a62ec98a73e699dbd2d"
File hash sum mismatch for "System.Linq" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "1ad577028f28c27eb8fae89ffa63011a5cbb40882fcf50155a208529b14094f0"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "c99638a249f76fc3323d60a140da0764859b54a58af835d9a9bf1480805d0506"
File hash sum mismatch for "System.Linq.Expressions" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "a8282e54e9e5b6875b8305ab215da0b3883fc8c242f23e8fb1e980698f0c65d1"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "e2b8d4d021fd49086140cd23a5a86db3b29f83755ea27ee744417893e6cf6a2b"
File size mismatch for "System.Linq.Expressions" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "6139904"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "6131712"
File hash sum mismatch for "System.Linq.Parallel" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "ee28fd182aa7f60245999b18ab59e2d911fc90a9caa7cf39ef2e30f6ed369838"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "0027c2b707e965ce40c597fb21cfd42acf8e4660c9a70bc8fd8dfa5f2a4fde72"
File hash sum mismatch for "System.Linq.Queryable" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "9447ab3fbf961a71c3e7bce6d2dff9792e88a30d723350ebe46ee01d01e91385"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "3ce0c46475d48c67979f859abc90c7076c2cff627674107686ad6fdb9b7dc8f7"
File hash sum mismatch for "System.Memory" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "c0a79dae009cd11b19ad31a83d21001d15b9bcce25377aaa350db187659efa70"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "f8d4266e3adddc7187804262d24aa0c2b7533edf4aad710e4109a2cb4cdc7bdf"
File hash sum mismatch for "System.Net.Http" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "48493922b26b543e3811f7cd2197ec5a6e7299c3f15d5c7c2210fad08b1359eb"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "9cdbfbe90c843d7964457e6e0a3607cca2adac82f55a1b91a192e3f94dc2cac6"
File hash sum mismatch for "System.Net.HttpListener" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "62164688fa684e40cef9099111a8128aa0c65a10465b300bf11715fb69a0abcc"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "49effe513ed5d7591b5cc61eec72e6e5d4d6fedc8e1522b6b0e1a9dcd0f23152"
File hash sum mismatch for "System.Net.Mail" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "b1d16fcfc6b0f0917de2f7c1b5f4cb5ffa0f9c811a62d122bca9213de979453b"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "7178397d47e7e01f88de15a66cb16b4b7179ac358df77d36b686495bcc5d5128"
File hash sum mismatch for "System.Net.NameResolution" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "880568a81096202116f8f0ee68c6798bb5fe18f9f8789aaa6b109f8453a9b8a9"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "7c7adda8a5803704adda3e45b2b515168398af3b30400d5688bdce084dba5dd1"
File hash sum mismatch for "System.Net.NetworkInformation" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "b8f1650fb4ccafb74c381caff1df4ee9bb64dcb91968dabed8c16c709124ebd0"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "4216befde0872121d5c3550e174ffdf17d883e4b8e19ce9d431ea97b8774b47c"
File hash sum mismatch for "System.Net.Ping" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "3e142e6c25b062b737d0b67e28c7d1b6f02856c809c95edb756a29920c39404e"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "ebad152a81bebff3d94192fd55e13c4ab66eafcce70a23b3a6a1412b2cdfffe9"
File hash sum mismatch for "System.Net.Primitives" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "b1538511d3f4e0ff81a02d813ebd454e69f944727832e107af19ab8362a42d3c"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "5dbb59da852d972248d2d60a329baa87f948a38388fe6bbbd4705a55f707623d"
File hash sum mismatch for "System.Net.Requests" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "5e43c50a6561ee896d72f47e94154417ad143a7eb85206ce7fd95b4f512aefd5"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "b3e3690f6eb459454fa4868442154b4bd685f9bc0641a0f47d571eed0c311dec"
File hash sum mismatch for "System.Net.Security" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "54d4abda28ed445f328d3731b571a098b2d27b9fd20242fb5960e3f62a75e57e"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "3738b6edf79dac5ea793eea5da3f2fd8fa51793a5a067c90d993e5299f9c50dc"
File hash sum mismatch for "System.Net.ServicePoint" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "6967f4197dfc2509de57f2047057effd5cc92cd71fce4edf5158f5ad6b4da986"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "e0d0690cc8278d98fd0b39117de54a96594e3a09827c47007b80d18afa06c6d9"
File hash sum mismatch for "System.Net.Sockets" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "91bbc9a6bd27db4dfb25d207ac95be836c391b05bd3f085d8f24befacb0c2422"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "a0e5cbe4376ca6151e17a5fda32f782f9b094fd779c424338b3325b1b2ba8d9b"
File hash sum mismatch for "System.Net.WebClient" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "bd2eeb435abc74ce2d06a2074b0ebc743bdc92341e8ecbd3e1e40af26996e445"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "6cfe2de6b52bb4fcd4f3317aaccd0680d9e01497dfb2de6ed74fd590d8835b4e"
File hash sum mismatch for "System.Net.WebHeaderCollection" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "81740494588a767e07332b16f59fe8f194f912ce2b76ea28c81170b69eb562a6"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "938a6e6cb65043a426e347a75da4270e410002c7a8176626865074f1f30492cc"
File hash sum mismatch for "System.Net.WebProxy" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "03e337e5b27d6891ea48366756be63c20ae67daca371b2c69c6ad4d24efa61e5"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "decc5cefd8261c739823be149370834b74a584f052e810c0fc9a7cae3bbcfa85"
File hash sum mismatch for "System.Net.WebSockets" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "c5921ed01bcac2444ae5817b83b89cc6a6298acf577883041259e6387bf2af99"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "cdc7410718d494401583f8b2ce13c3f2cf537e04cafaa4b140485b9a61437880"
File hash sum mismatch for "System.Net.WebSockets.Client" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "6c334873c24d9266881f93c4e670791e36db5712f662a9c9950be811d3750f5a"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "cc10e211a67d58d0774ad3c05ea5f42ef065e1e23a944b07725f992f10186907"
File hash sum mismatch for "System.ObjectModel" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "4e36c78b4a1d2e74e31df25a9e1cc37e43a7ce1454b875ddf8dfa27907a348a8"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "01a781b8406a5115f24a3b42e57defbb3a23305cd2155a6ad1ef1efcbfd14942"
File hash sum mismatch for "System.Private.CoreLib" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "a1b6c917e610d1c5395d208457d9ac3cf5159a6dc4e142c7f264edf5d8873d9c"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "2e25dcd248d468ebc2a776b9785db585660f50a246438caf3dd4de6489159e14"
File hash sum mismatch for "System.Private.DataContractSerialization" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "bf049b3ffb86d8c5201779d60db9f6fff5fac50d4731278e3afabd733c254d3c"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "1efa282f58ac02e53ee78043f5821332642b2108803855c4c4d500654c768677"
File hash sum mismatch for "System.Private.Uri" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "572373b1b774f100501b8f1e9703a0bdb5ce788546475b98f684d7309f5c6b79"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "eaa0dfbecf591d0d2386bc6d8a08d11271770ca516ebc5ff350faad495d34182"
File hash sum mismatch for "System.Private.Xml" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "bd2c8713bafc46ae65b6e47c6293a57aa538dd935dd027cd0b5d4cca0fecfa10"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "4d73482332873fa2315e357652d154a69441b484c3213e42e7d2ee65fac17f96"
File hash sum mismatch for "System.Private.Xml.Linq" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "6a0a2713a3bf8a2f7467fa45bd8fb08bb9c562c215bdef0b3b70030e343ea98a"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "5dc42303d446cf947a8f6d6d29e93911f07fd2937e21de0eed530656a8c13fed"
File hash sum mismatch for "System.Reflection.DispatchProxy" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "7cbfbe33001ea25a880ae94e949ba706ac9e8fbaa1913f0fabf993cb7cccbcf0"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "412b36473595ca77bb0ec71b2e048e7af86d1e508806934930c20e4ecd3e9b29"
File hash sum mismatch for "System.Reflection.Metadata" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "c0250341f8df3b1e72d79ef0ad885d32c3ce16d38499826f35e8ca93b0311833"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "696476846d2db1ac73cf10cb634773318622256651913079728ccaa531a229bd"
File hash sum mismatch for "System.Reflection.TypeExtensions" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "66610c7d1c93b07fcfecadf6b235328ca5a36c6fb08c3b23c6a0bad0bde5c5ad"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "03907a17a88948f1638989303dd494edef5d1cc184a6da6716d624f34ee89f71"
File hash sum mismatch for "System.Resources.Writer" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "a29571d8ea97af30a386d76b0a63b359024210833a4d36682d9d189f00c4a1f9"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "40daa2d307e203166ae792f331b6579dfe63441e488651e661b4565543b04fe1"
File hash sum mismatch for "System.Runtime.InteropServices" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "cedefb47f0ab0668eb2a9f4269588200b86f652d4cf1a6d510dea77ac17008ac"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "6901ffc96b4d65f80ecd19de09e9cd225e0bdf0f9ba906bd540cddee054d4b85"
File hash sum mismatch for "System.Runtime.InteropServices.RuntimeInformation" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "8b02e5d9fb8936cfdfe495915efad9b1cdd781aba7469d8230d7a67ab89a9d79"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "cec6feb9c0b29dfea10d73739cd01b6a8100a0b98576bb05abadf07d934c3274"
File hash sum mismatch for "System.Runtime.InteropServices.WindowsRuntime" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "d32140160c0c94d66a060484e088b45249e2d9e3a3f6c21ef9c8b22e1924b282"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "10f678a69d33d878a19ba4cb8005aedf1ba8d8543abf2a92541f6b4dacb58df6"
File hash sum mismatch for "System.Runtime.Numerics" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "bae13101dc82275ce1eb107df26e8599833c89047767549818b02b6390780893"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "ccbb0c4b5d4182183869b25b2054473f867d61bd62c866216b53354111632a45"
File hash sum mismatch for "System.Runtime.Serialization.Formatters" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "f0ed094ebea5a75ea9d13747d6032d05955d09ab72750d5b9af8166037dafceb"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "291347996ce208a19706e970d700e7ee06d78c1e6275f042ac8475e9535bde20"
File hash sum mismatch for "System.Runtime.Serialization.Primitives" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "9a99261d10e4f4113ba0201c09314c033d54e863aec236fdb8f2116e2595bb2f"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "4458e6038360df786b52a1746aca6c591b4370044d1e13d53a175a601ce23e19"
File hash sum mismatch for "System.Security.AccessControl" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "b7ecb563a15339efaa54cf9a3a5ff28c0febbb96d627e0c09727f3ee39dc9097"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "bfe7eedc9aac809e0d0bd12a45667680435c06728ebad570fba94a9f84e3c2fa"
File hash sum mismatch for "System.Security.Claims" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "a572fdf8bd4336a03686bb7200181f5cb47d5fbbe8e58095f0f0eb4974a049cc"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "46703c8911998382ec21dd1b65da8e62de5561da7978ec4f9d37eff10bf49975"
File hash sum mismatch for "System.Security.Cryptography.Algorithms" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "5000974e9230d55e204ac1c4ee43ff4d381381092871051d37db741946892613"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "7c59e3ff2d135d747a6859e7fdc2ab7fe473815103359a8c61b77f3e8ddc6ff4"
File hash sum mismatch for "System.Security.Cryptography.Cng" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "69602a87a25c28813bbf4239466e13502a08cb3cad6dd56907e3cfdb98b0efa9"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "73687f59b72ad059b0f215bf3f528f2262ffc85abb4916de23466e97db541b30"
File hash sum mismatch for "System.Security.Cryptography.Csp" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "17d1cb2934222c0a1885629367b5433a0109bdc7b6d97fcac31a9e8d5ad02141"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "cbb8895f354f05c892af17d59fd8e5370dbe2ea1092a4ddf0ea47f51fdb160e8"
File hash sum mismatch for "System.Security.Cryptography.Encoding" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "771423be3d758d243d0036fa984bde0b2deb704d80c6ceeaa10495740ec9e475"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "77d6237a3e0755c71c167ee4842e87e90d6c59e606cd3237b9567277fd218bad"
File hash sum mismatch for "System.Security.Cryptography.OpenSsl" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "7f10bddf3d753cce8f3d8803b2da7af8c84362866d59d7a7231ad61b0496faf1"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "0cb1b8083b681eade325e3923c8290969e0523b5a7490eed8c7672081d10b37c"
File hash sum mismatch for "System.Security.Cryptography.Primitives" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "f617d4c4c861442d4f1059bfbd4e116b2a1e3599152088192781b79a45d0b76c"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "f7a7e406af510f9196d394f9b61c58ba5ebb9b1a507445d4508551e1333696df"
File hash sum mismatch for "System.Security.Cryptography.X509Certificates" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "d4f5490b2f6e2024f4044a2c09fadfaf0f4e2d8d352ff0132f773945dc684698"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "f5d6f990764e57b087179bef34e1414da4cf964ea3e7cb77a970139ecfe9ea53"
File hash sum mismatch for "System.Security.Permissions" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "df520b6d0a2cd3c957c3c8ec6379d35f21e01dbd6fa901f8884ce78c80d12526"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "95d13908648150bf821ec3667049757d826bd86a75ffb49317a5a7952fb693b3"
File hash sum mismatch for "System.Security.Principal.Windows" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "837c3288aa5df12e0d429cd2616026b9f36110bec2c7a2675500823134823774"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "ae31ba720658523eb800f22201aef1e59357cc232daabeed36adcca311bd8915"
File hash sum mismatch for "System.Text.Encoding.CodePages" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "e6e6d29b2bd6c43fa8d5e1eea23b8db4b6fbd81a99b2853dd4949dafc71d5411"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "5ac32c02c3a08e6a55ec159a99310ab77f646a5613d0aadaea3ec8ea8e447937"
File hash sum mismatch for "System.Text.RegularExpressions" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "649b3e0faa0b9e84f9368df3dad2d661d528614e08ac058114e6223e6cf22b6c"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "b97053a01aa42f0f5ec64b009eb4d660f30cc7de5a174f5b1899b75dfcb0a55b"
File hash sum mismatch for "System.Threading" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "03be1ea51a6944cbfd09ff5ef36ad1126dd6126b125098e52b0f8fa9e8c2b562"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "5ee63f05ff7323a5354abf41d077e0f306cc68331988e053fe329438605d5fde"
File hash sum mismatch for "System.Threading.AccessControl" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "990beb258c09de3cb6d2ccc36aab8692ede66c7c6fe7cdf354e0cee4d0272b43"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "e59edfc2183677cc9f31b463b625b1f864e5fb91a2298d08d9fad4865651a7dc"
File hash sum mismatch for "System.Threading.Tasks.Dataflow" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "33f9393291aed08306fec6e59925e44b6e93e74615284c6ba0b45a0ac7efb088"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "3689b2ee5930a563280bab87919ad3fae7f22a16bb286867a84466db33a623d8"
File hash sum mismatch for "System.Threading.Tasks.Parallel" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "0d42a3dceb4e0b1c062626450c52c3238553a82430915219cd27cfc974aa0e22"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "1fc0e48186c62873f837944b3108d7a6e53b28251195067ae3d17cd85dd0f6d3"
File hash sum mismatch for "System.Transactions.Local" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "2ba155bd02a72a1e3adfa777f607c174a3780d516defd31cd79b1c7f31b349c5"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "0f7b68649657ba9187a1767ae7ba9d29ff866eae4bfe46032a57aec58fa3c4c6"
File hash sum mismatch for "System.Web.HttpUtility" assembly for files of type "NativeOrReadyToRunImage":
 - "/root/helix/work/workitem/log/Linux.x64_arm.Checked" has "0c53ca9e4bc39c1ceb36bb98c664342a97d5dcd5a138c25936bfaed9a612f4c4"
 - "/root/helix/work/workitem/log/Linux.arm.Checked" has "6173f0fa083aaa1b1bcf5efa2092c406e42a57616f7287c5ec1cf9fd2d960d44"

Then you need an arm machine to run native crossgen.

Then you would compare the resulting images with some kind of binary diff tool (I am using https://www.cjmweb.net/vbindiff/) to identify places where images are different. Make sure to ignore image checksums - I don't remember an exact file offset but it appears earlier in a PE image.

As soon as you identify a first point of real differences - use R2RDump to identify a corresponding section. In you case, there are any images that differ - so it should be something fundamental and easy to identify.

@AndyAyersMS
Copy link
Member Author

@echesakovMSFT thanks; working on doing just that. It sure would be nice, though, if the CI leg saved off at least one of the pairs of R2R images with diffs.

I am more interested in things I that should look for in my source changes that might lead to diffs. Have reviewed all the jit changes several times and don't see anything. I suppose it could be something in the runtime changes, maybe the changes to the layout of the debug blob, but none of that should be turned on in crossgen.

@AndyAyersMS
Copy link
Member Author

Think this is ready to merge...

@AndyAyersMS AndyAyersMS merged commit c6f540b into dotnet:master Mar 17, 2020
@AndyAyersMS AndyAyersMS deleted the OnStackReplacement branch March 17, 2020 00:30
@janvorli
Copy link
Member

@AndyAyersMS I've just found this PR has a bug. It has modified the managed CORINFO_METHOD_INFO, but is has left the native counterpart untouched:

struct CORINFO_METHOD_INFO
{
CORINFO_METHOD_HANDLE ftn;
CORINFO_MODULE_HANDLE scope;
BYTE * ILCode;
unsigned ILCodeSize;
unsigned maxStack;
unsigned EHcount;
CorInfoOptions options;
CorInfoRegionKind regionKind;
CORINFO_SIG_INFO args;
CORINFO_SIG_INFO locals;
};

This leads to overwriting of stack locals in crossgen2 in the call
if (!pParam->pThis->info.compCompHnd->getMethodInfo(pParam->fncHandle, &methInfo))
that ends up executing the following:
*methodInfo = default(CORINFO_METHOD_INFO);

It zeroes the native struct, but since the managed counterpart is larger, it ends up zeroing some data after the end.

@BruceForstall
Copy link
Member

@AndyAyersMS Did you see @janvorli's comment here? Did it get fixed?

@AndyAyersMS
Copy link
Member Author

Yes. Fixed by #34134.

@richlander richlander added the Epic Groups multiple user stories. Can be grouped under a theme. label Jun 1, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 10, 2020
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 Epic Groups multiple user stories. Can be grouped under a theme.
Projects
None yet
Development

Successfully merging this pull request may close these issues.