@@ -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