Skip to content

Commit 848c729

Browse files
Avoid handing out duplicate CORINFO_MODULE_STRUCT_* handles (#94082)
RyuJIT depends on never seeing two different `CORINFO_MODULE_STRUCT` for the same thing. Fixes #93843.
1 parent 67a86a2 commit 848c729

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -707,9 +707,15 @@ private void CompileMethodCleanup()
707707
_instantiationToJitVisibleInstantiation = null;
708708

709709
_pgoResults.Clear();
710+
711+
// We need to clear out this cache because the next compilation could actually come up
712+
// with a different MethodIL for the same MethodDesc. This happens when we need to replace
713+
// a MethodIL with a throw helper.
714+
_methodILScopeToHandle.Clear();
710715
}
711716

712717
private Dictionary<object, IntPtr> _objectToHandle = new Dictionary<object, IntPtr>(new JitObjectComparer());
718+
private Dictionary<MethodDesc, IntPtr> _methodILScopeToHandle = new Dictionary<MethodDesc, IntPtr>(new JitObjectComparer());
713719
private List<object> _handleToObject = new List<object>();
714720

715721
private const int handleMultiplier = 8;
@@ -720,6 +726,13 @@ private void CompileMethodCleanup()
720726
#endif
721727

722728
private IntPtr ObjectToHandle(object obj)
729+
{
730+
// MethodILScopes need to go through ObjectToHandle(MethodILScope methodIL).
731+
Debug.Assert(obj is not MethodILScope);
732+
return ObjectToHandleUnchecked(obj);
733+
}
734+
735+
private IntPtr ObjectToHandleUnchecked(object obj)
723736
{
724737
// SuperPMI relies on the handle returned from this function being stable for the lifetime of the crossgen2 process
725738
// If handle deletion is implemented, please update SuperPMI
@@ -752,10 +765,19 @@ private object HandleToObject(void* handle)
752765
private FieldDesc HandleToObject(CORINFO_FIELD_STRUCT_* field) => (FieldDesc)HandleToObject((void*)field);
753766
private CORINFO_FIELD_STRUCT_* ObjectToHandle(FieldDesc field) => (CORINFO_FIELD_STRUCT_*)ObjectToHandle((object)field);
754767
private MethodILScope HandleToObject(CORINFO_MODULE_STRUCT_* module) => (MethodIL)HandleToObject((void*)module);
755-
private CORINFO_MODULE_STRUCT_* ObjectToHandle(MethodILScope methodIL) => (CORINFO_MODULE_STRUCT_*)ObjectToHandle((object)methodIL);
756768
private MethodSignature HandleToObject(MethodSignatureInfo* method) => (MethodSignature)HandleToObject((void*)method);
757769
private MethodSignatureInfo* ObjectToHandle(MethodSignature method) => (MethodSignatureInfo*)ObjectToHandle((object)method);
758770

771+
private CORINFO_MODULE_STRUCT_* ObjectToHandle(MethodILScope methodIL)
772+
{
773+
// RyuJIT requires CORINFO_MODULE_STRUCT to be unique. MethodILScope might not be unique
774+
// due to ILProvider cache purging. See https://github.com/dotnet/runtime/issues/93843.
775+
MethodDesc owningMethod = methodIL.OwningMethod;
776+
if (!_methodILScopeToHandle.TryGetValue(owningMethod, out IntPtr handle))
777+
_methodILScopeToHandle[owningMethod] = handle = ObjectToHandleUnchecked((object)methodIL);
778+
return (CORINFO_MODULE_STRUCT_*)handle;
779+
}
780+
759781
private bool Get_CORINFO_METHOD_INFO(MethodDesc method, MethodIL methodIL, CORINFO_METHOD_INFO* methodInfo)
760782
{
761783
if (methodIL == null)

0 commit comments

Comments
 (0)