-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Conversation
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. |
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs
Outdated
Show resolved
Hide resolved
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs
Outdated
Show resolved
Hide resolved
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs
Outdated
Show resolved
Hide resolved
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs
Outdated
Show resolved
Hide resolved
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs
Outdated
Show resolved
Hide resolved
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs
Outdated
Show resolved
Hide resolved
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/MethodTable.Runtime.cs
Show resolved
Hide resolved
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs
Show resolved
Hide resolved
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs
Outdated
Show resolved
Hide resolved
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs
Outdated
Show resolved
Hide resolved
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs
Outdated
Show resolved
Hide resolved
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs
Outdated
Show resolved
Hide resolved
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ExceptionHandling.cs
Outdated
Show resolved
Hide resolved
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs
Outdated
Show resolved
Hide resolved
@@ -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(); |
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 this introducing a frame to this method? This structuring was obviously deliberate and matches ChkCastClassSpecial
in the other corelib. What motivates this change?
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs
Outdated
Show resolved
Hide resolved
src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs
Outdated
Show resolved
Hide resolved
// 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) |
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.
ThrowHelper.ThrowInvalidCastException looks different (doesn't return object, is not marked noinlining). Are we deoptimizing codegen or are the underlying RyuJIT issues fixed up?
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.
RyuJIT understands and special cases throw helpers that aren't marked with NoInlining
so this should improve the codegen or keep it the same.
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'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.
@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) |
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.
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.
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 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.
|
||
fail: | ||
return ThrowInvalidCastException(pTargetType); |
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.
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); |
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.
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.
This pull request has been automatically marked |
This pull request will now be closed since it had been marked |
Continuation of #99778