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

Remove non INPLACE_RUNTIME NativeAOT paths, cleanup exceptions #100379

Closed
wants to merge 6 commits into from

Conversation

MichalPetryka
Copy link
Contributor

Continuation of #99778

@MichalStrehovsky
Copy link
Member

If we're removing INPLACE_RUNTIME, we should be sure that this is the layering we actually want, in the theoretical case that we'd need to extract a shared piece (for e.g. sharing between multiple dlls loaded in the same process, etc.). There's a lot more that can/should be ripped out here if that's what we want.

Casting and interface dispatch would probably go to a CoreLib and they would not be part of the runtime anymore.

But exception handling - I don't have much clarity about that.

I've been avoiding touching this so that I don't have to think about this. Some of this code could in theory be compiled into an obj file that is linked into coreclr.dll at some point and then we do need a form of INPLACE_RUNTIME. Similarly for the NAOT scenario I mentioned in the first paragraph.

I'd leave these questions for Jan, I'm sure he already has some thoughts. This is all the thoughts I have around it.

@@ -432,7 +431,7 @@ private static unsafe object CheckCastClassSpecial(MethodTable* pTargetType, obj
goto done;

// They don't cast to any other class
goto fail;
ThrowHelper.ThrowInvalidCastException();
Copy link
Member

Choose a reason for hiding this comment

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

Is this introducing a frame to this method? This structuring was obviously deliberate and matches ChkCastClassSpecial in the other corelib. What motivates this change?

Comment on lines -970 to -972
// Would not be inlined, but still need to mark NoInlining so that it doesn't throw off tail calls
[MethodImpl(MethodImplOptions.NoInlining)]
private static unsafe object ThrowInvalidCastException(MethodTable* pMT)
Copy link
Member

Choose a reason for hiding this comment

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

ThrowHelper.ThrowInvalidCastException looks different (doesn't return object, is not marked noinlining). Are we deoptimizing codegen or are the underlying RyuJIT issues fixed up?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

RyuJIT understands and special cases throw helpers that aren't marked with NoInlining so this should improve the codegen or keep it the same.

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've checked and the codegen is different, the JIT now puts the throw in a cold block at the end of the method instead of a tailcall in the middle. I'd argue it's better since the need for a jump for the exception shouldn't matter much.

@agocke agocke added the needs-author-action An issue or pull request that requires more info or actions from the author. label May 20, 2024
@jkotas
Copy link
Member

jkotas commented Jun 18, 2024

@MichalPetryka Are you interested in finishing this PR?

@MichalPetryka
Copy link
Contributor Author

@MichalPetryka Are you interested in finishing this PR?

I'll get back to it tomorrow.

@@ -1081,38 +989,9 @@ private static uint CalculateCodeOffset(byte* pbControlPC, in MethodRegionInfo m
return false;
}

#if DEBUG && !INPLACE_RUNTIME && NATIVEAOT
private static MethodTable* s_pLowLevelObjectType;
private static void AssertNotRuntimeObject(MethodTable* pClauseType)
Copy link
Member

Choose a reason for hiding this comment

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

This still looks valuable if we expect exception handling would still use some C# code and might end up being shared between all managed runtime instances within a process (for loading-multiple-nativeAOT-dlls-in-the-same-process-and sharing-low-level-runtime case).

I don't know how such layering would look like, so I defer to Jan. The existing INPLACE_LAYERING was known to actually work because it was used like that in .NET Native. I don't know about this new layering.

Copy link
Member

Choose a reason for hiding this comment

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

I think that the shared component should be GC and GC support like thread suspension, not much else. Ideally, we would have an option to run in a configuration where a CoreCLR instance and native AOT instances would be able to share one process wide GC instance. Exception handling, casting, interface dispatch should be all private per-runtime. I think that the .NET Native design where these services tried to be in the shared component was problematic.

With this plan, the shared component may still need some managed code that can be stackwalked for good perf, but it should not need to do any allocations or handle exceptions on its own. We would use compiler/linker to enforce that. It means that it should be fine to delete this code.

Comment on lines -473 to -475

fail:
return ThrowInvalidCastException(pTargetType);
Copy link
Member

Choose a reason for hiding this comment

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

My old comment still stands - this is the existing structuring in the other copy of TypeCast.cs used with JIT.

They should be in sync, so either do the same change there (better to be 100% sure this will not deoptimize codegen) or undo it here.

}

return result;
}

private static unsafe object IsInstanceOfVariantType(MethodTable* pTargetType, object obj)
{
Debug.Assert(obj is not null);
Copy link
Member

Choose a reason for hiding this comment

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

These new asserts are not useful. We'll nullref on the subsequent line which is as good as an assert.

Debug.Assert is not low level enough to be callable from casting code. We could end up with reentrancy and then instead of troubleshooting an easy nullref, we need to troubleshoot a stack overflow or something worse.

@agocke agocke added the needs-author-action An issue or pull request that requires more info or actions from the author. label Aug 26, 2024
Copy link
Contributor

This pull request has been automatically marked no-recent-activity because it has not had any activity for 14 days. It will be closed if no further activity occurs within 14 more days. Any new comment (by anyone, not necessarily the author) will remove no-recent-activity.

Copy link
Contributor

This pull request will now be closed since it had been marked no-recent-activity but received no further activity in the past 14 days. It is still possible to reopen or comment on the pull request, but please note that it will be locked if it remains inactive for another 30 days.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-NativeAOT-coreclr community-contribution Indicates that the PR has been added by a community member needs-author-action An issue or pull request that requires more info or actions from the author. no-recent-activity
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants