diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 84ee78fb0f2432..659567a2f4b52e 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -558,6 +558,8 @@ private void CompileMethodCleanup() _actualInstructionSetUnsupported = default(InstructionSetFlags); #endif + _instantiationToJitVisibleInstantiation = null; + _pgoResults.Clear(); } @@ -644,6 +646,25 @@ private bool Get_CORINFO_METHOD_INFO(MethodDesc method, MethodIL methodIL, CORIN return true; } + private Dictionary _instantiationToJitVisibleInstantiation = null; + private CORINFO_CLASS_STRUCT_** GetJitInstantiation(Instantiation inst) + { + IntPtr [] jitVisibleInstantiation; + if (_instantiationToJitVisibleInstantiation == null) + { + _instantiationToJitVisibleInstantiation = new Dictionary(); + } + + if (!_instantiationToJitVisibleInstantiation.TryGetValue(inst, out jitVisibleInstantiation)) + { + jitVisibleInstantiation = new IntPtr[inst.Length]; + for (int i = 0; i < inst.Length; i++) + jitVisibleInstantiation[i] = (IntPtr)ObjectToHandle(inst[i]); + _instantiationToJitVisibleInstantiation.Add(inst, jitVisibleInstantiation); + } + return (CORINFO_CLASS_STRUCT_**)GetPin(jitVisibleInstantiation); + } + private void Get_CORINFO_SIG_INFO(MethodDesc method, CORINFO_SIG_INFO* sig, bool suppressHiddenArgument = false) { Get_CORINFO_SIG_INFO(method.Signature, sig); @@ -668,10 +689,12 @@ private void Get_CORINFO_SIG_INFO(MethodDesc method, CORINFO_SIG_INFO* sig, bool sig->sigInst.classInstCount = (uint)owningTypeInst.Length; if (owningTypeInst.Length > 0) { - var classInst = new IntPtr[owningTypeInst.Length]; - for (int i = 0; i < owningTypeInst.Length; i++) - classInst[i] = (IntPtr)ObjectToHandle(owningTypeInst[i]); - sig->sigInst.classInst = (CORINFO_CLASS_STRUCT_**)GetPin(classInst); + sig->sigInst.classInst = GetJitInstantiation(owningTypeInst); + } + + if (method.Instantiation.Length != 0) + { + sig->sigInst.methInst = GetJitInstantiation(method.Instantiation); } } diff --git a/src/coreclr/tools/Common/TypeSystem/Common/Instantiation.cs b/src/coreclr/tools/Common/TypeSystem/Common/Instantiation.cs index 136f7f4e04b104..313a1b11c7a8af 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/Instantiation.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/Instantiation.cs @@ -11,7 +11,7 @@ namespace Internal.TypeSystem /// Represents a generic instantiation - a collection of generic parameters /// or arguments of a generic type or a generic method. /// - public struct Instantiation + public struct Instantiation : IEquatable { private TypeDesc[] _genericParameters; @@ -113,5 +113,33 @@ public bool MoveNext() return true; } } + + public bool Equals(Instantiation other) + { + if (_genericParameters.Length != other._genericParameters.Length) + return false; + + for (int i = 0; i < _genericParameters.Length; i++) + { + if (_genericParameters[i] != other._genericParameters[i]) + return false; + } + return true; + } + public override bool Equals(object o) + { + if (o is Instantiation inst) + return Equals(inst); + return false; + } + public override int GetHashCode() + { + int hashcode = 1; + foreach (var t in _genericParameters) + { + hashcode = (hashcode << 3) ^ t.GetHashCode(); + } + return hashcode; + } } }