diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 73b17aedf51e28..c1f59c124b6769 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -1713,12 +1713,7 @@ private void resolveToken(ref CORINFO_RESOLVED_TOKEN pResolvedToken) _compilation.TypeSystemContext.EnsureLoadableType(owningClass); #endif -#if READYTORUN - if (recordToken) - { - _compilation.NodeFactory.Resolver.AddModuleTokenForField(field, HandleToModuleToken(ref pResolvedToken)); - } -#else +#if !READYTORUN _compilation.NodeFactory.MetadataManager.GetDependenciesDueToAccess(ref _additionalDependencies, _compilation.NodeFactory, (MethodIL)methodIL, field); #endif } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/FieldFixupSignature.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/FieldFixupSignature.cs index 4cf38ae5ee601c..93c5569c5b01ea 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/FieldFixupSignature.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/FieldFixupSignature.cs @@ -17,15 +17,15 @@ public class FieldFixupSignature : Signature public const int MaxCheckableOffset = 0x1FFFFFFF; private readonly ReadyToRunFixupKind _fixupKind; - private readonly FieldDesc _fieldDesc; + private readonly FieldWithToken _fieldWithToken; - public FieldFixupSignature(ReadyToRunFixupKind fixupKind, FieldDesc fieldDesc, NodeFactory factory) + public FieldFixupSignature(ReadyToRunFixupKind fixupKind, FieldWithToken fieldWithToken, NodeFactory factory) { _fixupKind = fixupKind; - _fieldDesc = fieldDesc; + _fieldWithToken = fieldWithToken; // Ensure types in signature are loadable and resolvable, otherwise we'll fail later while emitting the signature - ((CompilerTypeSystemContext)fieldDesc.Context).EnsureLoadableType(fieldDesc.OwningType); + ((CompilerTypeSystemContext)fieldWithToken.Field.Context).EnsureLoadableType(fieldWithToken.Field.OwningType); } public override int ClassCode => 271828182; @@ -38,19 +38,19 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { dataBuilder.AddSymbol(this); - IEcmaModule targetModule = factory.SignatureContext.GetTargetModule(_fieldDesc); + IEcmaModule targetModule = _fieldWithToken.Token.Module; SignatureContext innerContext = dataBuilder.EmitFixup(factory, _fixupKind, targetModule, factory.SignatureContext); uint baseOffset = 0; - uint fieldOffset = (uint)_fieldDesc.Offset.AsInt; + uint fieldOffset = (uint)_fieldWithToken.Field.Offset.AsInt; if (_fixupKind == ReadyToRunFixupKind.Verify_FieldOffset) { - TypeDesc baseType = _fieldDesc.OwningType.BaseType; - if ((_fieldDesc.OwningType.BaseType != null) - && !_fieldDesc.IsStatic - && !_fieldDesc.OwningType.IsValueType) + TypeDesc baseType = _fieldWithToken.Field.OwningType.BaseType; + if ((_fieldWithToken.Field.OwningType.BaseType != null) + && !_fieldWithToken.Field.IsStatic + && !_fieldWithToken.Field.OwningType.IsValueType) { - MetadataType owningType = (MetadataType)_fieldDesc.OwningType; + MetadataType owningType = (MetadataType)_fieldWithToken.Field.OwningType; baseOffset = (uint)owningType.FieldBaseOffset().AsInt; if (factory.CompilationModuleGroup.NeedsAlignmentBetweenBaseTypeAndDerived((MetadataType)baseType, owningType)) { @@ -67,7 +67,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) dataBuilder.EmitUInt(fieldOffset); } - dataBuilder.EmitFieldSignature(_fieldDesc, innerContext); + dataBuilder.EmitFieldSignature(_fieldWithToken, innerContext); } return dataBuilder.ToObjectData(); @@ -77,7 +77,7 @@ public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilde { sb.Append(nameMangler.CompilationUnitPrefix); sb.Append($@"FieldFixupSignature({_fixupKind.ToString()}): "); - sb.Append(nameMangler.GetMangledFieldName(_fieldDesc)); + _fieldWithToken.AppendMangledName(nameMangler, sb); } public override int CompareToImpl(ISortableNode other, CompilerComparer comparer) @@ -87,7 +87,7 @@ public override int CompareToImpl(ISortableNode other, CompilerComparer comparer if (result != 0) return result; - return comparer.Compare(_fieldDesc, otherNode._fieldDesc); + return _fieldWithToken.CompareTo(otherNode._fieldWithToken, comparer); } } } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/GenericLookupSignature.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/GenericLookupSignature.cs index eae25a978cb17e..05287235097ad9 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/GenericLookupSignature.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/GenericLookupSignature.cs @@ -22,7 +22,7 @@ public class GenericLookupSignature : Signature private readonly MethodWithToken _methodArgument; - private readonly FieldDesc _fieldArgument; + private readonly FieldWithToken _fieldArgument; private readonly GenericContext _methodContext; @@ -31,7 +31,7 @@ public GenericLookupSignature( ReadyToRunFixupKind fixupKind, TypeDesc typeArgument, MethodWithToken methodArgument, - FieldDesc fieldArgument, + FieldWithToken fieldArgument, GenericContext methodContext) { Debug.Assert(typeArgument != null || methodArgument != null || fieldArgument != null); @@ -64,7 +64,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) } else if (_fieldArgument != null) { - targetModule = factory.SignatureContext.GetTargetModule(_fieldArgument); + targetModule = _fieldArgument.Token.Module; } else { @@ -173,7 +173,7 @@ public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilde } if (_fieldArgument != null) { - sb.Append(nameMangler.GetMangledFieldName(_fieldArgument)); + _fieldArgument.AppendMangledName(nameMangler, sb); } sb.Append(" ("); _methodContext.AppendMangledName(nameMangler, sb); @@ -210,7 +210,7 @@ public override int CompareToImpl(ISortableNode other, CompilerComparer comparer if (otherNode._fieldArgument == null) return 1; - result = comparer.Compare(_fieldArgument, otherNode._fieldArgument); + result = _fieldArgument.CompareTo(otherNode._fieldArgument, comparer); if (result != 0) return result; } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ModuleTokenResolver.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ModuleTokenResolver.cs index 0abaedfa8e0218..e9ec9f6e0396a0 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ModuleTokenResolver.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ModuleTokenResolver.cs @@ -27,8 +27,6 @@ public class ModuleTokenResolver /// private readonly ConcurrentDictionary _typeToRefTokens = new ConcurrentDictionary(); - private readonly ConcurrentDictionary _fieldToRefTokens = new ConcurrentDictionary(); - private readonly CompilationModuleGroup _compilationModuleGroup; private Func _moduleIndexLookup; @@ -127,36 +125,6 @@ public ModuleToken GetModuleTokenForMethod(MethodDesc method, bool allowDynamica } } - public ModuleToken GetModuleTokenForField(FieldDesc field, bool throwIfNotFound = true) - { - if (_compilationModuleGroup.VersionsWithType(field.OwningType) && field is EcmaField ecmaField) - { - return new ModuleToken(ecmaField.Module, ecmaField.Handle); - } - - TypeDesc owningCanonType = field.OwningType.ConvertToCanonForm(CanonicalFormKind.Specific); - FieldDesc canonField = field; - if (owningCanonType != field.OwningType) - { - canonField = CompilerContext.GetFieldForInstantiatedType(field.GetTypicalFieldDefinition(), (InstantiatedType)owningCanonType); - } - - ModuleToken token; - if (_fieldToRefTokens.TryGetValue(canonField, out token)) - { - return token; - } - - if (throwIfNotFound) - { - throw new NotImplementedException(field.ToString()); - } - else - { - return default(ModuleToken); - } - } - public void AddModuleTokenForMethod(MethodDesc method, ModuleToken token) { if (token.TokenType == CorTokenType.mdtMethodSpec) @@ -188,35 +156,6 @@ private void AddModuleTokenForFieldReference(TypeDesc owningType, ModuleToken to memberRef.DecodeFieldSignature(new TokenResolverProvider(this, token.Module), this); } - public void AddModuleTokenForField(FieldDesc field, ModuleToken token) - { - if (_compilationModuleGroup.VersionsWithType(field.OwningType) && field.OwningType is EcmaType) - { - // We don't need to store handles within the current compilation group - // as we can read them directly from the ECMA objects. - return; - } - - TypeDesc owningCanonType = field.OwningType.ConvertToCanonForm(CanonicalFormKind.Specific); - FieldDesc canonField = field; - if (owningCanonType != field.OwningType) - { - canonField = CompilerContext.GetFieldForInstantiatedType(field.GetTypicalFieldDefinition(), (InstantiatedType)owningCanonType); - } - - SetModuleTokenForTypeSystemEntity(_fieldToRefTokens, canonField, token); - - switch (token.TokenType) - { - case CorTokenType.mdtMemberRef: - AddModuleTokenForFieldReference(owningCanonType, token); - break; - - default: - throw new NotImplementedException(); - } - } - // Add TypeSystemEntity -> ModuleToken mapping to a ConcurrentDictionary. Using CompareTo sort the token used, so it will // be consistent in all runs of the compiler void SetModuleTokenForTypeSystemEntity(ConcurrentDictionary dictionary, T tse, ModuleToken token) diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.cs index 01bb5fe766d78d..fe5595531ad810 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.cs @@ -530,23 +530,17 @@ private void EmitMethodSpecificationSignature(MethodWithToken method, } } - public void EmitFieldSignature(FieldDesc field, SignatureContext context) + public void EmitFieldSignature(FieldWithToken field, SignatureContext context) { uint fieldSigFlags = 0; - TypeDesc canonOwnerType = field.OwningType.ConvertToCanonForm(CanonicalFormKind.Specific); TypeDesc ownerType = null; - if (canonOwnerType.HasInstantiation) + if (field.OwningTypeNotDerivedFromToken) { - ownerType = field.OwningType; + ownerType = field.Field.OwningType; fieldSigFlags |= (uint)ReadyToRunFieldSigFlags.READYTORUN_FIELD_SIG_OwnerType; } - if (canonOwnerType != field.OwningType) - { - // Convert field to canonical form as this is what the field - module token lookup stores - field = field.Context.GetFieldForInstantiatedType(field.GetTypicalFieldDefinition(), (InstantiatedType)canonOwnerType); - } - ModuleToken fieldToken = context.GetModuleTokenForField(field); + ModuleToken fieldToken = field.Token; switch (fieldToken.TokenType) { case CorTokenType.mdtMemberRef: diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureContext.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureContext.cs index 84ac68fb24208a..2e251e60b91902 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureContext.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureContext.cs @@ -66,11 +66,6 @@ public IEcmaModule GetTargetModule(TypeDesc type) return LocalContext; } - public IEcmaModule GetTargetModule(FieldDesc field) - { - return GetModuleTokenForField(field).Module; - } - public IEcmaModule GetTargetModule(MethodDesc method) { return GetModuleTokenForMethod(method).Module; @@ -86,11 +81,6 @@ public ModuleToken GetModuleTokenForMethod(MethodDesc method) return Resolver.GetModuleTokenForMethod(method, throwIfNotFound: false, allowDynamicallyCreatedReference: false); } - public ModuleToken GetModuleTokenForField(FieldDesc field, bool throwIfNotFound = true) - { - return Resolver.GetModuleTokenForField(field, throwIfNotFound); - } - public bool Equals(SignatureContext other) { return GlobalContext == other.GlobalContext diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.cs index 940daa8294ccc3..1fff139e7c179c 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.cs @@ -65,7 +65,7 @@ private void CreateNodeCaches() new ReadyToRunInstructionSetSupportSignature(key)); }); - _fieldAddressCache = new NodeCache(key => + _fieldAddressCache = new NodeCache(key => { return new DelayLoadHelperImport( _codegenNodeFactory, @@ -75,7 +75,7 @@ private void CreateNodeCaches() ); }); - _fieldOffsetCache = new NodeCache(key => + _fieldOffsetCache = new NodeCache(key => { return new PrecodeHelperImport( _codegenNodeFactory, @@ -91,7 +91,7 @@ private void CreateNodeCaches() ); }); - _checkFieldOffsetCache = new NodeCache(key => + _checkFieldOffsetCache = new NodeCache(key => { return new PrecodeHelperImport( _codegenNodeFactory, @@ -241,7 +241,7 @@ private ISymbolNode CreateReadyToRunHelper(ReadyToRunHelperKey key) return CreateMethodHandleHelper((MethodWithToken)key.Target); case ReadyToRunHelperId.FieldHandle: - return CreateFieldHandleHelper((FieldDesc)key.Target); + return CreateFieldHandleHelper((FieldWithToken)key.Target); case ReadyToRunHelperId.CctorTrigger: return CreateCctorTrigger((TypeDesc)key.Target); @@ -361,7 +361,7 @@ private ISymbolNode CreateMethodHandleHelper(MethodWithToken method) isInstantiatingStub: useInstantiatingStub)); } - private ISymbolNode CreateFieldHandleHelper(FieldDesc field) + private ISymbolNode CreateFieldHandleHelper(FieldWithToken field) { return new PrecodeHelperImport( _codegenNodeFactory, @@ -395,25 +395,25 @@ private ISymbolNode CreateMethodDictionary(MethodWithToken method) isInstantiatingStub: true)); } - private NodeCache _fieldAddressCache; + private NodeCache _fieldAddressCache; - public ISymbolNode FieldAddress(FieldDesc fieldDesc) + public ISymbolNode FieldAddress(FieldWithToken fieldWithToken) { - return _fieldAddressCache.GetOrAdd(fieldDesc); + return _fieldAddressCache.GetOrAdd(fieldWithToken); } - private NodeCache _fieldOffsetCache; + private NodeCache _fieldOffsetCache; - public ISymbolNode FieldOffset(FieldDesc fieldDesc) + public ISymbolNode FieldOffset(FieldWithToken fieldWithToken) { - return _fieldOffsetCache.GetOrAdd(fieldDesc); + return _fieldOffsetCache.GetOrAdd(fieldWithToken); } - private NodeCache _checkFieldOffsetCache; + private NodeCache _checkFieldOffsetCache; - public ISymbolNode CheckFieldOffset(FieldDesc fieldDesc) + public ISymbolNode CheckFieldOffset(FieldWithToken fieldWithToken) { - return _checkFieldOffsetCache.GetOrAdd(fieldDesc); + return _checkFieldOffsetCache.GetOrAdd(fieldWithToken); } private NodeCache _fieldBaseOffsetCache; @@ -502,7 +502,7 @@ private struct GenericLookupKey : IEquatable public readonly ReadyToRunFixupKind FixupKind; public readonly TypeDesc TypeArgument; public readonly MethodWithToken MethodArgument; - public readonly FieldDesc FieldArgument; + public readonly FieldWithToken FieldArgument; public readonly GenericContext MethodContext; public GenericLookupKey( @@ -510,7 +510,7 @@ public GenericLookupKey( ReadyToRunFixupKind fixupKind, TypeDesc typeArgument, MethodWithToken methodArgument, - FieldDesc fieldArgument, + FieldWithToken fieldArgument, GenericContext methodContext) { LookupKind = lookupKind; @@ -603,7 +603,7 @@ public ISymbolNode GenericLookupHelper( return GenericLookupFieldHelper( runtimeLookupKind, ReadyToRunFixupKind.FieldHandle, - (FieldDesc)helperArgument, + (FieldWithToken)helperArgument, methodContext); default: @@ -622,9 +622,9 @@ private ISymbolNode GenericLookupTypeHelper( { typeArgument = methodWithToken.Method.OwningType; } - else if (helperArgument is FieldDesc fieldDesc) + else if (helperArgument is FieldWithToken fieldWithToken) { - typeArgument = fieldDesc.OwningType; + typeArgument = fieldWithToken.Field.OwningType; } else { @@ -638,7 +638,7 @@ private ISymbolNode GenericLookupTypeHelper( private ISymbolNode GenericLookupFieldHelper( CORINFO_RUNTIME_LOOKUP_KIND runtimeLookupKind, ReadyToRunFixupKind fixupKind, - FieldDesc fieldArgument, + FieldWithToken fieldArgument, GenericContext methodContext) { GenericLookupKey key = new GenericLookupKey(runtimeLookupKind, fixupKind, typeArgument: null, methodArgument: null, fieldArgument: fieldArgument, methodContext); diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/RuntimeDeterminedTypeHelper.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/RuntimeDeterminedTypeHelper.cs index 1af2b045acba46..f2f56713670d9a 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/RuntimeDeterminedTypeHelper.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/RuntimeDeterminedTypeHelper.cs @@ -146,6 +146,15 @@ public static bool Equals(FieldDesc field1, FieldDesc field2) RuntimeDeterminedTypeHelper.Equals(field1.FieldType, field2.FieldType); } + public static bool Equals(FieldWithToken field1, FieldWithToken field2) + { + if (field1 == null || field2 == null) + { + return field1 == null && field2 == null; + } + return RuntimeDeterminedTypeHelper.Equals(field1.Field, field2.Field); + } + public static int GetHashCode(Instantiation instantiation) { int hashcode = unchecked(instantiation.Length << 24); @@ -198,5 +207,14 @@ public static int GetHashCode(FieldDesc field) } return unchecked(GetHashCode(field.OwningType) + 97 * GetHashCode(field.FieldType) + 31 * field.Name.GetHashCode()); } + + public static int GetHashCode(FieldWithToken field) + { + if (field == null) + { + return 0; + } + return GetHashCode(field.Field); + } } } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index dce751e370c76b..4d07cd8e68610c 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -37,6 +37,82 @@ public RequiresRuntimeJitIfUsedSymbol(string message) public string Message { get; } } + public class FieldWithToken : IEquatable + { + public readonly FieldDesc Field; + public readonly ModuleToken Token; + public readonly bool OwningTypeNotDerivedFromToken; + + public FieldWithToken(FieldDesc field, ModuleToken token) + { + Field = field; + Token = token; + if (token.TokenType == CorTokenType.mdtMemberRef) + { + var memberRef = token.MetadataReader.GetMemberReference((MemberReferenceHandle)token.Handle); + switch (memberRef.Parent.Kind) + { + case HandleKind.TypeDefinition: + case HandleKind.TypeReference: + case HandleKind.TypeSpecification: + OwningTypeNotDerivedFromToken = token.Module.GetType(memberRef.Parent) != field.OwningType; + break; + + default: + break; + } + } + } + + public override bool Equals(object obj) + { + return obj is FieldWithToken fieldWithToken && + Equals(fieldWithToken); + } + + public override int GetHashCode() + { + return Field.GetHashCode() ^ unchecked(17 * Token.GetHashCode()); + } + + public bool Equals(FieldWithToken fieldWithToken) + { + if (fieldWithToken == null) + return false; + + return Field == fieldWithToken.Field && Token.Equals(fieldWithToken.Token); + } + + public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) + { + sb.Append(nameMangler.GetMangledFieldName(Field)); + sb.Append("; "); + sb.Append(Token.ToString()); + } + + public override string ToString() + { + StringBuilder debuggingName = new StringBuilder(); + debuggingName.Append(Field.ToString()); + + debuggingName.Append("; "); + debuggingName.Append(Token.ToString()); + + return debuggingName.ToString(); + } + + public int CompareTo(FieldWithToken other, TypeSystemComparer comparer) + { + int result; + + result = comparer.Compare(Field, other.Field); + if (result != 0) + return result; + + return Token.CompareTo(other.Token); + } + } + public class MethodWithToken { public readonly MethodDesc Method; @@ -660,6 +736,10 @@ private bool getReadyToRunHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref MethodDesc sharedMethod = methodIL.OwningMethod.GetSharedRuntimeFormMethodTarget(); helperArg = new MethodWithToken(methodDesc, HandleToModuleToken(ref pResolvedToken), constrainedType, unboxing: false, context: sharedMethod); } + else if (helperArg is FieldDesc fieldDesc) + { + helperArg = new FieldWithToken(fieldDesc, HandleToModuleToken(ref pResolvedToken)); + } GenericContext methodContext = new GenericContext(entityFromContext(pResolvedToken.tokenContext)); ISymbolNode helper = _compilation.SymbolNodeFactory.GenericLookupHelper( @@ -1041,6 +1121,12 @@ private bool canTailCall(CORINFO_METHOD_STRUCT_* callerHnd, CORINFO_METHOD_STRUC return true; } + private FieldWithToken ComputeFieldWithToken(FieldDesc field, ref CORINFO_RESOLVED_TOKEN pResolvedToken) + { + ModuleToken token = HandleToModuleToken(ref pResolvedToken); + return new FieldWithToken(field, token); + } + private MethodWithToken ComputeMethodWithToken(MethodDesc method, ref CORINFO_RESOLVED_TOKEN pResolvedToken, TypeDesc constrainedType, bool unboxing) { ModuleToken token = HandleToModuleToken(ref pResolvedToken, method, out object context, ref constrainedType); @@ -1416,7 +1502,7 @@ private void getFieldInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_MET if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && (fieldOffset <= FieldFixupSignature.MaxCheckableOffset)) { // ENCODE_CHECK_FIELD_OFFSET - AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); + AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(ComputeFieldWithToken(field, ref pResolvedToken))); } } else @@ -1457,7 +1543,7 @@ private void getFieldInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_MET // Static fields outside of the version bubble need to be accessed using the ENCODE_FIELD_ADDRESS // helper in accordance with ZapInfo::getFieldInfo in CoreCLR. - pResult->fieldLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.FieldAddress(field)); + pResult->fieldLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.FieldAddress(ComputeFieldWithToken(field, ref pResolvedToken))); pResult->helper = CorInfoHelpFunc.CORINFO_HELP_READYTORUN_STATIC_BASE; @@ -1470,7 +1556,7 @@ private void getFieldInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_MET if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && (fieldOffset <= FieldFixupSignature.MaxCheckableOffset)) { // ENCODE_CHECK_FIELD_OFFSET - AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); + AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(ComputeFieldWithToken(field, ref pResolvedToken))); } pResult->fieldLookup = CreateConstLookupToSymbol( @@ -1493,7 +1579,7 @@ private void getFieldInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_MET pResult->accessAllowed = CorInfoIsAccessAllowedResult.CORINFO_ACCESS_ALLOWED; pResult->offset = fieldOffset; - EncodeFieldBaseOffset(field, pResult, callerMethod); + EncodeFieldBaseOffset(field, ref pResolvedToken, pResult, callerMethod); // TODO: We need to implement access checks for fields and methods. See JitInterface.cpp in mrtjit // and STS::AccessCheck::CanAccess. @@ -2407,7 +2493,7 @@ private void embedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool case CorInfoGenericHandleType.CORINFO_HANDLETYPE_FIELD: symbolNode = _compilation.SymbolNodeFactory.CreateReadyToRunHelper( ReadyToRunHelperId.FieldHandle, - HandleToObject(pResolvedToken.hField)); + ComputeFieldWithToken(HandleToObject(pResolvedToken.hField), ref pResolvedToken)); break; default: @@ -2455,7 +2541,7 @@ private void PreventRecursiveFieldInlinesOutsideVersionBubble(FieldDesc field, M } } - private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult, MethodDesc callerMethod) + private void EncodeFieldBaseOffset(FieldDesc field, ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_FIELD_INFO* pResult, MethodDesc callerMethod) { TypeDesc pMT = field.OwningType; @@ -2471,7 +2557,7 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult, if (pResult->offset > FieldFixupSignature.MaxCheckableOffset) throw new RequiresRuntimeJitException(callerMethod.ToString() + " -> " + field.ToString()); - AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); + AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(ComputeFieldWithToken(field, ref pResolvedToken))); // No-op other than generating the check field offset fixup } else @@ -2481,7 +2567,7 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult, // ENCODE_FIELD_OFFSET pResult->offset = 0; pResult->fieldAccessor = CORINFO_FIELD_ACCESSOR.CORINFO_FIELD_INSTANCE_WITH_BASE; - pResult->fieldLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.FieldOffset(field)); + pResult->fieldLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.FieldOffset(ComputeFieldWithToken(field, ref pResolvedToken))); } } else if (pMT.IsValueType) @@ -2490,7 +2576,7 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult, { // ENCODE_CHECK_FIELD_OFFSET if (_compilation.CompilationModuleGroup.VersionsWithType(field.OwningType)) // Only verify versions with types - AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); + AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(ComputeFieldWithToken(field, ref pResolvedToken))); } // ENCODE_NONE } @@ -2500,14 +2586,14 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult, { // ENCODE_CHECK_FIELD_OFFSET if (_compilation.CompilationModuleGroup.VersionsWithType(field.OwningType)) // Only verify versions with types - AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); + AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(ComputeFieldWithToken(field, ref pResolvedToken))); } // ENCODE_NONE } else if (TypeCannotUseBasePlusOffsetEncoding(pMT.BaseType as MetadataType)) { // ENCODE_CHECK_FIELD_OFFSET - AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); + AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(ComputeFieldWithToken(field, ref pResolvedToken))); // No-op other than generating the check field offset fixup } else @@ -2518,7 +2604,7 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult, { // ENCODE_CHECK_FIELD_OFFSET if (_compilation.CompilationModuleGroup.VersionsWithType(field.OwningType)) // Only verify versions with types - AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); + AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(ComputeFieldWithToken(field, ref pResolvedToken))); } // ENCODE_FIELD_BASE_OFFSET