Fix type generator test failures (#44041)
authorDavid Wrighton <davidwr@microsoft.com>
Sun, 1 Nov 2020 22:54:35 +0000 (14:54 -0800)
committerGitHub <noreply@github.com>
Sun, 1 Nov 2020 22:54:35 +0000 (14:54 -0800)
- Fix issue where method token referred to derived type but method was actually defined on base type
  - Previously the methods did not carry enough state to determine when to emit the owner type of the method, and which exact type was the owning type. The new logic computes it from the token in the presence of a proper instantiation context, which allows for correct operation.

- Fix issue where constrained dispatch on a method of a valuetype would not put in the correct owner type
  - Issue fixed by determining if the token resolves to a method on the same type as the eventual target method, or if it needs to have a specific owning type specified

In general these issues where both caused by confusion around exactly the correct owning type, and it turned out that computation could not be computed within the signature emitter code, but instead needed to be computed in the JIT at point of use. Fortunately, we had a structure `MethodWithToken` that is used in these (and only these situations). Finally, I also made a pass through the emitter and related logic to remove various band-aids that had built up over the last few years to make all the tests and applications pass. I believe that the new logic should be correct in the general case.

Bonus tweak...  Use parallelism when compiling the framework composite images with crossgen2, and fix bug in composite image generation where mangled symbol names might conflict.

Fixes #43466 and fixes #43467

17 files changed:
src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DelegateCtorSignature.cs
src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/FieldFixupSignature.cs
src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/InstanceEntryPointTableNode.cs
src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodFixupSignature.cs
src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.cs
src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs
src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.cs
src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
src/tests/build.cmd
src/tests/build.sh
src/tests/issues.targets
src/tests/readytorun/crossgen2/Program.cs
src/tests/readytorun/crossgen2/crossgen2smoke.csproj
src/tests/readytorun/crossgen2/crossgen2smoke_donotalwaysusecrossgen2.csproj [new file with mode: 0644]
src/tests/readytorun/crossgen2/helperdll.cs
src/tests/readytorun/crossgen2/helperildll.il
src/tests/readytorun/crossgen2/smoketest.targets [new file with mode: 0644]

index 5c2650c..c986357 100644 (file)
@@ -14,12 +14,12 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
 
         private readonly IMethodNode _targetMethod;
 
-        private readonly ModuleToken _methodToken;
+        private readonly MethodWithToken _methodToken;
 
         public DelegateCtorSignature(
             TypeDesc delegateType,
             IMethodNode targetMethod,
-            ModuleToken methodToken)
+            MethodWithToken methodToken)
         {
             _delegateType = delegateType;
             _targetMethod = targetMethod;
@@ -40,10 +40,10 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
 
             if (!relocsOnly)
             {
-                SignatureContext innerContext = builder.EmitFixup(factory, ReadyToRunFixupKind.DelegateCtor, _methodToken.Module, factory.SignatureContext);
+                SignatureContext innerContext = builder.EmitFixup(factory, ReadyToRunFixupKind.DelegateCtor, _methodToken.Token.Module, factory.SignatureContext);
 
                 builder.EmitMethodSignature(
-                    new MethodWithToken(_targetMethod.Method, _methodToken, constrainedType: null, unboxing: false),
+                    _methodToken,
                     enforceDefEncoding: false,
                     enforceOwningType: false,
                     innerContext,
@@ -88,7 +88,7 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
             if (result != 0)
                 return result;
 
-            return _methodToken.CompareTo(otherNode._methodToken);
+            return _methodToken.CompareTo(otherNode._methodToken, comparer);
         }
     }
 }
index 01098a7..62b5f5c 100644 (file)
@@ -68,7 +68,8 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
         public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
         {
             sb.Append(nameMangler.CompilationUnitPrefix);
-            sb.Append($@"TypeFixupSignature({_fixupKind.ToString()}): {_fieldDesc.ToString()}");
+            sb.Append($@"FieldFixupSignature({_fixupKind.ToString()}): ");
+            sb.Append(nameMangler.GetMangledFieldName(_fieldDesc));
         }
 
         public override int CompareToImpl(ISortableNode other, CompilerComparer comparer)
index e337c0e..03ccc73 100644 (file)
@@ -61,7 +61,7 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
 
                 ArraySignatureBuilder signatureBuilder = new ArraySignatureBuilder();
                 signatureBuilder.EmitMethodSignature(
-                    new MethodWithToken(method.Method, moduleToken, constrainedType: null, unboxing: false),
+                    new MethodWithToken(method.Method, moduleToken, constrainedType: null, unboxing: false, context: null),
                     enforceDefEncoding: true,
                     enforceOwningType: _factory.CompilationModuleGroup.EnforceOwningType(moduleToken.Module),
                     factory.SignatureContext,
index 58ea379..eaeddd9 100644 (file)
@@ -2,6 +2,9 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System;
+using System.Diagnostics;
+using System.Reflection.Metadata;
+using System.Reflection.Metadata.Ecma335;
 
 using Internal.JitInterface;
 using Internal.Text;
@@ -32,6 +35,8 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
             // Ensure types in signature are loadable and resolvable, otherwise we'll fail later while emitting the signature
             CompilerTypeSystemContext compilerContext = (CompilerTypeSystemContext)method.Method.Context;
             compilerContext.EnsureLoadableMethod(method.Method);
+            compilerContext.EnsureLoadableType(_method.OwningType);
+
             if (method.ConstrainedType != null)
                 compilerContext.EnsureLoadableType(method.ConstrainedType);
         }
@@ -68,8 +73,11 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
                     }
                     else if (_method.Token.TokenType == CorTokenType.mdtMemberRef)
                     {
-                        fixupKind = ReadyToRunFixupKind.MethodEntry_RefToken;
-                        optimized = true;
+                        if (!_method.OwningTypeNotDerivedFromToken)
+                        {
+                            fixupKind = ReadyToRunFixupKind.MethodEntry_RefToken;
+                            optimized = true;
+                        }
                     }
                 }
             }
@@ -80,13 +88,13 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
             {
                 if (method.Token.TokenType == CorTokenType.mdtMethodSpec)
                 {
-                    method = new MethodWithToken(method.Method, factory.SignatureContext.GetModuleTokenForMethod(method.Method, throwIfNotFound: false), method.ConstrainedType, unboxing: _method.Unboxing);
+                    method = new MethodWithToken(method.Method, factory.SignatureContext.GetModuleTokenForMethod(method.Method, throwIfNotFound: false), method.ConstrainedType, unboxing: _method.Unboxing, null);
                 }
                 else if (!optimized && (method.Token.TokenType == CorTokenType.mdtMemberRef))
                 {
                     if (method.Method.OwningType.GetTypeDefinition() is EcmaType)
                     {
-                        method = new MethodWithToken(method.Method, factory.SignatureContext.GetModuleTokenForMethod(method.Method, throwIfNotFound: false), method.ConstrainedType, unboxing: _method.Unboxing);
+                        method = new MethodWithToken(method.Method, factory.SignatureContext.GetModuleTokenForMethod(method.Method, throwIfNotFound: false), method.ConstrainedType, unboxing: _method.Unboxing, null);
                     }
                 }
             }
index fd80e7e..a91aeca 100644 (file)
@@ -412,62 +412,12 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
             {
                 flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_Constrained;
             }
-            if (enforceOwningType)
+            if (enforceOwningType || method.OwningTypeNotDerivedFromToken)
             {
                 flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType;
             }
 
-            if ((method.Method.HasInstantiation || method.Method.OwningType.HasInstantiation) && !method.Method.IsGenericMethodDefinition)
-            {
-                EmitMethodSpecificationSignature(method, flags, enforceDefEncoding, context);
-            }
-            else
-            {
-                switch (method.Token.TokenType)
-                {
-                    case CorTokenType.mdtMethodDef:
-                        {
-                            EmitUInt(flags);
-                            if ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0)
-                            {
-                                EmitTypeSignature(method.Method.OwningType, context);
-                            }
-                            EmitMethodDefToken(method.Token);
-                        }
-                        break;
-
-                    case CorTokenType.mdtMemberRef:
-                        {
-                            flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MemberRefToken;
-
-                            // Owner type is needed for type specs to instantiating stubs or generics with signature variables still present
-                            if (!method.Method.OwningType.IsDefType &&
-                                ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_InstantiatingStub) != 0 || method.Method.OwningType.ContainsSignatureVariables()))
-                            {
-                                flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType;
-                            }
-                            else if (method.Method.IsArrayMethod())
-                            {
-                                var memberRefMethod = method.Token.Module.GetMethod(MetadataTokens.EntityHandle((int)method.Token.Token));
-                                if (memberRefMethod.OwningType != method.Method.OwningType)
-                                {
-                                    flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType;
-                                }
-                            }
-
-                            EmitUInt(flags);
-                            if ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0)
-                            {
-                                EmitTypeSignature(method.Method.OwningType, context);
-                            }
-                            EmitMethodRefToken(method.Token);
-                        }
-                        break;
-
-                    default:
-                        throw new NotImplementedException();
-                }
-            }
+            EmitMethodSpecificationSignature(method, flags, enforceDefEncoding, context);
 
             if (method.ConstrainedType != null)
             {
@@ -491,7 +441,7 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
             uint flags, bool enforceDefEncoding, SignatureContext context)
         {
             ModuleToken methodToken = method.Token;
-            if (method.Method.HasInstantiation)
+            if (method.Method.HasInstantiation && !method.Method.IsGenericMethodDefinition)
             {
                 flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MethodInstantiation;
                 if (!method.Token.IsNull)
@@ -504,23 +454,7 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
                 }
             }
 
-            if (methodToken.IsNull && !enforceDefEncoding)
-            {
-                methodToken = context.GetModuleTokenForMethod(method.Method, throwIfNotFound: false);
-            }
-            if (methodToken.IsNull)
-            {
-                flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType;
-                methodToken = context.GetModuleTokenForMethod(method.Method);
-            }
-
-            if (method.Method.OwningType.HasInstantiation)
-            {
-                // resolveToken currently resolves the token in the context of a given scope;
-                // in such case, we receive a method on instantiated type along with the
-                // generic definition token.
-                flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType;
-            }
+            Debug.Assert(!methodToken.IsNull);
 
             switch (methodToken.TokenType)
             {
@@ -538,7 +472,8 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
             EmitUInt(flags);
             if ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0)
             {
-                EmitTypeSignature(method.Method.OwningType, context);
+                // The type here should be the type referred to by the memberref (if this is one, not the type where the method was eventually found!
+                EmitTypeSignature(method.OwningType, context);
             }
             EmitTokenRid(methodToken.Token);
             if ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MethodInstantiation) != 0)
index 9f9ebf9..cf1e452 100644 (file)
@@ -396,7 +396,7 @@ namespace ILCompiler.DependencyAnalysis
                 EcmaModule module = ((EcmaMethod)method.GetTypicalMethodDefinition()).Module;
                 ModuleToken moduleToken = Resolver.GetModuleTokenForMethod(method, throwIfNotFound: true);
 
-                IMethodNode methodNodeDebug = MethodEntrypoint(new MethodWithToken(method, moduleToken, constrainedType: null, unboxing: false), false, false);
+                IMethodNode methodNodeDebug = MethodEntrypoint(new MethodWithToken(method, moduleToken, constrainedType: null, unboxing: false, context: null), false, false);
                 MethodWithGCInfo methodCodeNodeDebug = methodNodeDebug as MethodWithGCInfo;
                 if (methodCodeNodeDebug == null && methodNodeDebug is DelayLoadMethodImport DelayLoadMethodImport)
                 {
index 1178d43..539d440 100644 (file)
@@ -124,7 +124,7 @@ namespace ILCompiler.DependencyAnalysis
                     _codegenNodeFactory,
                     _codegenNodeFactory.HelperImports,
                     ReadyToRunHelper.DelayLoad_Helper_ObjObj,
-                    new DelegateCtorSignature(ctorKey.Type, targetMethodNode, ctorKey.Method.Token));
+                    new DelegateCtorSignature(ctorKey.Type, targetMethodNode, ctorKey.Method));
             });
 
             _checkTypeLayoutCache = new NodeCache<TypeDesc, ISymbolNode>(key =>
index 3ca5d12..67a9f9e 100644 (file)
@@ -40,14 +40,139 @@ namespace Internal.JitInterface
         public readonly ModuleToken Token;
         public readonly TypeDesc ConstrainedType;
         public readonly bool Unboxing;
+        public readonly bool OwningTypeNotDerivedFromToken;
+        public readonly TypeDesc OwningType;
 
-        public MethodWithToken(MethodDesc method, ModuleToken token, TypeDesc constrainedType, bool unboxing)
+
+        public MethodWithToken(MethodDesc method, ModuleToken token, TypeDesc constrainedType, bool unboxing, object context)
         {
             Debug.Assert(!method.IsUnboxingThunk());
             Method = method;
             Token = token;
             ConstrainedType = constrainedType;
             Unboxing = unboxing;
+            OwningType = GetMethodTokenOwningType(this, constrainedType, context, out OwningTypeNotDerivedFromToken);
+        }
+
+        private static TypeDesc GetMethodTokenOwningType(MethodWithToken methodToken, TypeDesc constrainedType, object context, out bool owningTypeNotDerivedFromToken)
+        {
+            ModuleToken moduleToken = methodToken.Token;
+            owningTypeNotDerivedFromToken = false;
+
+            // Strip off method spec details. The owning type is only associated with a MethodDef or a MemberRef
+            if (moduleToken.TokenType == CorTokenType.mdtMethodSpec)
+            {
+                var methodSpecification = moduleToken.MetadataReader.GetMethodSpecification((MethodSpecificationHandle)moduleToken.Handle);
+                moduleToken = new ModuleToken(moduleToken.Module, methodSpecification.Method);
+            }
+
+            if (moduleToken.TokenType == CorTokenType.mdtMethodDef)
+            {
+                var methodDefinition = moduleToken.MetadataReader.GetMethodDefinition((MethodDefinitionHandle)moduleToken.Handle);
+                return HandleContext(moduleToken.Module, methodDefinition.GetDeclaringType(), methodToken.Method.OwningType, constrainedType, context, ref owningTypeNotDerivedFromToken);
+            }
+
+            // At this point moduleToken must point at a MemberRef.
+            Debug.Assert(moduleToken.TokenType == CorTokenType.mdtMemberRef);
+            var memberRef = moduleToken.MetadataReader.GetMemberReference((MemberReferenceHandle)moduleToken.Handle);
+            switch (memberRef.Parent.Kind)
+            {
+                case HandleKind.TypeDefinition:
+                case HandleKind.TypeReference:
+                case HandleKind.TypeSpecification:
+                    {
+                        return HandleContext(moduleToken.Module, memberRef.Parent, methodToken.Method.OwningType, constrainedType, context, ref owningTypeNotDerivedFromToken);
+                    }
+
+                default:
+                    return methodToken.Method.OwningType;
+            }
+
+            TypeDesc HandleContext(EcmaModule module, EntityHandle handle, TypeDesc methodTargetOwner, TypeDesc constrainedType, object context, ref bool owningTypeNotDerivedFromToken)
+            {
+                var tokenOnlyOwningType = module.GetType(handle);
+                TypeDesc actualOwningType;
+
+                if (context == null)
+                {
+                    actualOwningType = methodTargetOwner;
+                }
+                else
+                {
+                    Instantiation typeInstantiation;
+                    Instantiation methodInstantiation = new Instantiation();
+
+                    if (context is MethodDesc methodContext)
+                    {
+                        typeInstantiation = methodContext.OwningType.Instantiation;
+                        methodInstantiation = methodContext.Instantiation;
+                    }
+                    else
+                    {
+                        TypeDesc typeContext = (TypeDesc)context;
+                        typeInstantiation = typeContext.Instantiation;
+                    }
+
+                    var instantiatedOwningType = tokenOnlyOwningType.InstantiateSignature(typeInstantiation, methodInstantiation);
+                    var canonicalizedOwningType = instantiatedOwningType.ConvertToCanonForm(CanonicalFormKind.Specific);
+                    if ((instantiatedOwningType == canonicalizedOwningType) || (constrainedType != null))
+                    {
+                        actualOwningType = instantiatedOwningType;
+                    }
+                    else
+                    {
+                        actualOwningType = ComputeActualOwningType(methodTargetOwner, instantiatedOwningType, canonicalizedOwningType);
+
+                        // Implement via a helper function, so that managing the loop escape behavior is easier to read
+                        TypeDesc ComputeActualOwningType(TypeDesc methodTargetOwner, TypeDesc instantiatedOwningType, TypeDesc canonicalizedOwningType)
+                        {
+                            // Pick between Canonical and Exact OwningTypes.
+                            //
+                            // If the canonicalizedOwningType is the OwningType (or parent type) of the associated method
+                            //   Then return canonicalizedOwningType
+                            // Else If the Exact Owning type is the OwningType (or parent type) of the associated method
+                            //   Then return actualOwningType
+                            // Else If the canonicallized owningType (or canonicalized parent type) of the associated method
+                            //   Return the canonicalizedOwningType
+                            // Else
+                            //   Fail, unexpected behavior
+                            var currentType = canonicalizedOwningType;
+                            while (currentType != null)
+                            {
+                                if (currentType == methodTargetOwner)
+                                    return canonicalizedOwningType;
+                                currentType = currentType.BaseType;
+                            }
+
+                            currentType = instantiatedOwningType;
+                            while (currentType != null)
+                            {
+                                if (currentType == methodTargetOwner)
+                                    return instantiatedOwningType;
+                                currentType = currentType.BaseType;
+                            }
+
+                            currentType = canonicalizedOwningType;
+                            while (currentType != null)
+                            {
+                                currentType = currentType.ConvertToCanonForm(CanonicalFormKind.Specific);
+                                if (currentType == methodTargetOwner)
+                                    return canonicalizedOwningType;
+                                currentType = currentType.BaseType;
+                            }
+
+                            Debug.Assert(false);
+                            throw new Exception();
+                        }
+                    }
+                }
+
+                if (actualOwningType != tokenOnlyOwningType)
+                {
+                    owningTypeNotDerivedFromToken = true;
+                }
+                return actualOwningType;
+            }
         }
 
         public override bool Equals(object obj)
@@ -63,7 +188,15 @@ namespace Internal.JitInterface
 
         public bool Equals(MethodWithToken methodWithToken)
         {
-            return Method == methodWithToken.Method && Token.Equals(methodWithToken.Token) && ConstrainedType == methodWithToken.ConstrainedType && Unboxing == methodWithToken.Unboxing;
+            bool equals = Method == methodWithToken.Method && Token.Equals(methodWithToken.Token) && ConstrainedType == methodWithToken.ConstrainedType &&
+                   Unboxing == methodWithToken.Unboxing;
+            if (equals)
+            {
+                Debug.Assert(OwningTypeNotDerivedFromToken == methodWithToken.OwningTypeNotDerivedFromToken);
+                Debug.Assert(OwningType == methodWithToken.OwningType);
+            }
+            
+            return equals;
         }
 
         public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
@@ -103,7 +236,23 @@ namespace Internal.JitInterface
             if (result != 0)
                 return result;
 
-            return Unboxing.CompareTo(other.Unboxing);
+            result = Unboxing.CompareTo(other.Unboxing);
+            if (result != 0)
+                return result;
+
+            // The OwningType/OwningTypeNotDerivedFromToken shoud be equivalent if the above conditions are equal.
+            Debug.Assert(OwningTypeNotDerivedFromToken == other.OwningTypeNotDerivedFromToken);
+            Debug.Assert(OwningType == other.OwningType);
+
+            if (OwningTypeNotDerivedFromToken != other.OwningTypeNotDerivedFromToken)
+            {
+                if (OwningTypeNotDerivedFromToken)
+                    return 1;
+                else
+                    return -1;
+            }
+
+            return comparer.Compare(OwningType, other.OwningType);
         }
     }
 
@@ -326,7 +475,9 @@ namespace Internal.JitInterface
                         object helperArg = GetRuntimeDeterminedObjectForToken(ref pResolvedToken);
                         if (helperArg is MethodDesc methodDesc)
                         {
-                            helperArg = new MethodWithToken(methodDesc, HandleToModuleToken(ref pResolvedToken), constrainedType, unboxing: false);
+                            var methodIL = (MethodIL)HandleToObject((IntPtr)pResolvedToken.tokenScope);
+                            MethodDesc sharedMethod = methodIL.OwningMethod.GetSharedRuntimeFormMethodTarget();
+                            helperArg = new MethodWithToken(methodDesc, HandleToModuleToken(ref pResolvedToken), constrainedType, unboxing: false, context: sharedMethod);
                         }
 
                         GenericContext methodContext = new GenericContext(entityFromContext(pResolvedToken.tokenContext));
@@ -356,7 +507,7 @@ namespace Internal.JitInterface
             TypeDesc delegateTypeDesc = HandleToObject(delegateType);
             MethodDesc targetMethodDesc = HandleToObject(pTargetMethod.hMethod);
             Debug.Assert(!targetMethodDesc.IsUnboxingThunk());
-            MethodWithToken targetMethod = new MethodWithToken(targetMethodDesc, HandleToModuleToken(ref pTargetMethod), constrainedType: null, unboxing: false);
+            MethodWithToken targetMethod = new MethodWithToken(targetMethodDesc, HandleToModuleToken(ref pTargetMethod), constrainedType: null, unboxing: false, context: entityFromContext(pTargetMethod.tokenContext));
 
             pLookup.lookupKind.needsRuntimeLookup = false;
             pLookup.constLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.DelegateCtor(delegateTypeDesc, targetMethod));
@@ -680,7 +831,13 @@ namespace Internal.JitInterface
             return false;
         }
 
-        private ModuleToken HandleToModuleToken(ref CORINFO_RESOLVED_TOKEN pResolvedToken, MethodDesc methodDesc)
+        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);
+            return new MethodWithToken(method, token, constrainedType: constrainedType, unboxing: unboxing, context: context);
+        }
+
+        private ModuleToken HandleToModuleToken(ref CORINFO_RESOLVED_TOKEN pResolvedToken, MethodDesc methodDesc, out object context, ref TypeDesc constrainedType)
         {
             if (methodDesc != null && (_compilation.NodeFactory.CompilationModuleGroup.VersionsWithMethodBody(methodDesc) || methodDesc.IsPInvoke))
             {
@@ -688,12 +845,20 @@ namespace Internal.JitInterface
                     methodDesc?.GetTypicalMethodDefinition() is EcmaMethod ecmaMethod)
                 {
                     mdToken token = (mdToken)MetadataTokens.GetToken(ecmaMethod.Handle);
+
+                    // This is used for de-virtualization of non-generic virtual methods, and should be treated
+                    // as a the methodDesc parameter defining the exact OwningType, not doing resolution through the token.
+                    context = null;
+                    constrainedType = null;
+
                     return new ModuleToken(ecmaMethod.Module, token);
                 }
             }
 
+            context = entityFromContext(pResolvedToken.tokenContext);
             return HandleToModuleToken(ref pResolvedToken);
         }
+
         private ModuleToken HandleToModuleToken(ref CORINFO_RESOLVED_TOKEN pResolvedToken)
         {
             mdToken token = pResolvedToken.token;
@@ -1613,7 +1778,7 @@ namespace Internal.JitInterface
 
                         pResult->codePointerOrStubLookup.constLookup = CreateConstLookupToSymbol(
                             _compilation.SymbolNodeFactory.InterfaceDispatchCell(
-                                new MethodWithToken(targetMethod, HandleToModuleToken(ref pResolvedToken, targetMethod), constrainedType: null, unboxing: false),
+                                ComputeMethodWithToken(targetMethod, ref pResolvedToken, constrainedType: null, unboxing: false),
                                 MethodBeingCompiled));
 
                         // If the abi of the method isn't stable, this will cause a usage of the RequiresRuntimeJitSymbol, which will trigger a RequiresRuntimeJitException
@@ -1652,7 +1817,7 @@ namespace Internal.JitInterface
                         // READYTORUN: FUTURE: Direct calls if possible
                         pResult->codePointerOrStubLookup.constLookup = CreateConstLookupToSymbol(
                             _compilation.NodeFactory.MethodEntrypoint(
-                                new MethodWithToken(nonUnboxingMethod, HandleToModuleToken(ref pResolvedToken, nonUnboxingMethod), constrainedType, unboxing: isUnboxingStub),
+                                ComputeMethodWithToken(nonUnboxingMethod, ref pResolvedToken, constrainedType, unboxing: isUnboxingStub),
                                 isInstantiatingStub: useInstantiatingStub,
                                 isPrecodeImportRequired: (flags & CORINFO_CALLINFO_FLAGS.CORINFO_CALLINFO_LDFTN) != 0));
 
@@ -1675,7 +1840,7 @@ namespace Internal.JitInterface
                         bool atypicalCallsite = (flags & CORINFO_CALLINFO_FLAGS.CORINFO_CALLINFO_ATYPICAL_CALLSITE) != 0;
                         pResult->codePointerOrStubLookup.constLookup = CreateConstLookupToSymbol(
                             _compilation.NodeFactory.DynamicHelperCell(
-                                new MethodWithToken(targetMethod, HandleToModuleToken(ref pResolvedToken, targetMethod), constrainedType: null, unboxing: false),
+                                ComputeMethodWithToken(targetMethod, ref pResolvedToken, constrainedType: null, unboxing: false),
                                 useInstantiatingStub));
 
                         Debug.Assert(!pResult->sig.hasTypeArg());
@@ -1702,7 +1867,7 @@ namespace Internal.JitInterface
                     {
                         pResult->instParamLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.CreateReadyToRunHelper(
                             ReadyToRunHelperId.MethodDictionary,
-                            new MethodWithToken(targetMethod, HandleToModuleToken(ref pResolvedToken, targetMethod), constrainedType, unboxing: false)));
+                            ComputeMethodWithToken(targetMethod, ref pResolvedToken, constrainedType: constrainedType, unboxing: false)));
                     }
                     else
                     {
@@ -1941,7 +2106,7 @@ namespace Internal.JitInterface
 
                             symbolNode = _compilation.SymbolNodeFactory.CreateReadyToRunHelper(
                                 ReadyToRunHelperId.MethodHandle,
-                                new MethodWithToken(md, HandleToModuleToken(ref pResolvedToken), constrainedType: null, unboxing: unboxingStub));
+                                ComputeMethodWithToken(md, ref pResolvedToken, constrainedType: null, unboxing: unboxingStub));
                         }
                         break;
 
@@ -2179,7 +2344,7 @@ namespace Internal.JitInterface
                 methodDesc = rawPInvoke.Target;
             EcmaMethod ecmaMethod = (EcmaMethod)methodDesc;
             ModuleToken moduleToken = new ModuleToken(ecmaMethod.Module, ecmaMethod.Handle);
-            MethodWithToken methodWithToken = new MethodWithToken(ecmaMethod, moduleToken, constrainedType: null, unboxing: false);
+            MethodWithToken methodWithToken = new MethodWithToken(ecmaMethod, moduleToken, constrainedType: null, unboxing: false, context: null);
 
             if (ecmaMethod.IsSuppressGCTransition())
             {
index ea6d47d..499e069 100644 (file)
@@ -637,7 +637,7 @@ set __CrossgenCmd="%__RepoRootDir%\dotnet.cmd" "%CORE_ROOT%\R2RTest\R2RTest.dll"
 if defined __CompositeBuildMode (
     set __CrossgenCmd=%__CrossgenCmd% --composite
 ) else (
-    set __CrossgenCmd=%__CrossgenCmd% --large-bubble
+    set __CrossgenCmd=%__CrossgenCmd% --large-bubble --crossgen2-parallelism 1
 )
 
 set __CrossgenDir=%__BinDir%
@@ -659,7 +659,7 @@ if defined __DoCrossgen (
     if /i "%__BuildArch%" == "x86" (
         set __CrossgenDir=!__CrossgenDir!\x64
     )
-    set __CrossgenCmd=%__CrossgenCmd% --verify-type-and-field-layout --crossgen2-parallelism 1 --crossgen2-path "!__CrossgenDir!\crossgen2\crossgen2.dll"
+    set __CrossgenCmd=%__CrossgenCmd% --verify-type-and-field-layout --crossgen2-path "!__CrossgenDir!\crossgen2\crossgen2.dll"
 )
 
 echo Running %__CrossgenCmd%
index 9b35b7d..cfd6aad 100755 (executable)
@@ -174,6 +174,8 @@ precompile_coreroot_fx()
 
     if [[ "$__CompositeBuildMode" != 0 ]]; then
         crossgenCmd="$crossgenCmd --composite"
+    else
+        crossgenCmd="$crossgenCmd --crossgen2-parallelism 1"
     fi
 
     local crossgenDir="$__BinDir"
@@ -184,7 +186,7 @@ precompile_coreroot_fx()
     if [[ "$__DoCrossgen" != 0 ]]; then
         crossgenCmd="$crossgenCmd --crossgen --nocrossgen2 --crossgen-path \"$crossgenDir/crossgen\""
     else
-        crossgenCmd="$crossgenCmd --verify-type-and-field-layout --crossgen2-parallelism 1 --crossgen2-path \"$crossgenDir/crossgen2/crossgen2.dll\""
+        crossgenCmd="$crossgenCmd --verify-type-and-field-layout --crossgen2-path \"$crossgenDir/crossgen2/crossgen2.dll\""
     fi
 
     echo "Running $crossgenCmd"
index 587bf6b..5916773 100644 (file)
         </ExcludeList>
     </ItemGroup>
 
-    <!-- Crossgen2 type generator tests currently failing outerloop Windows legs -->
-    <ItemGroup Condition="'$(XunitTestBinBase)' != '' and '$(TestBuildMode)' == 'crossgen2' and '$(RuntimeFlavor)' == 'coreclr' and '$(TargetsWindows)' == 'true'">
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest612/Generated612/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43466</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest613/Generated613/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43466</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest614/Generated614/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43466</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest681/Generated681/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43466</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest682/Generated682/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43466</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest683/Generated683/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43466</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest1/Generated1/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest14/Generated14/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest15/Generated15/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest16/Generated16/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest17/Generated17/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest18/Generated18/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest19/Generated19/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest20/Generated20/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest21/Generated21/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest22/Generated22/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest23/Generated23/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest24/Generated24/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest25/Generated25/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest26/Generated26/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest27/Generated27/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest28/Generated28/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest62/Generated62/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest63/Generated63/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest64/Generated64/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest65/Generated65/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest66/Generated66/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest67/Generated67/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest68/Generated68/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest69/Generated69/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest70/Generated70/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest171/Generated171/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest192/Generated192/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest193/Generated193/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest194/Generated194/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest195/Generated195/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest196/Generated196/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest197/Generated197/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest198/Generated198/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest199/Generated199/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest200/Generated200/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest201/Generated201/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest202/Generated202/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest203/Generated203/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest204/Generated204/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest205/Generated205/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest206/Generated206/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest207/Generated207/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest208/Generated208/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest209/Generated209/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest210/Generated210/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest211/Generated211/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest212/Generated212/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest213/Generated213/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest214/Generated214/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest215/Generated215/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest292/Generated292/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest293/Generated293/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest294/Generated294/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest295/Generated295/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest296/Generated296/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest297/Generated297/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest298/Generated298/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest299/Generated299/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest300/Generated300/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest301/Generated301/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest302/Generated302/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest303/Generated303/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest304/Generated304/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest305/Generated305/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest306/Generated306/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest307/Generated307/*">
-            <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
-        </ExcludeList>
-    </ItemGroup>
-
     <!-- run.proj finds all the *.cmd/*.sh scripts in a test folder and creates corresponding test methods.
          Exclude these scripts to avoid creating such methods for the superpmicollect dependent test projects
          and running them separately from superpmicollect test. These should be excluded regardless of RuntimeFlavor/os/arch-->
         <ExcludeList Include="$(XunitTestBinBase)/readytorun/crossgen2/crossgen2smoke/**">
             <Issue>needs triage</Issue>
         </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/readytorun/crossgen2/crossgen2smoke_donotalwaysusecrossgen2/**">
+            <Issue>needs triage</Issue>
+        </ExcludeList>
         <ExcludeList Include="$(XunitTestBinBase)/readytorun/tests/mainv1/**">
             <Issue>needs triage</Issue>
         </ExcludeList>
index 348b0e1..b0c011e 100644 (file)
@@ -2164,6 +2164,11 @@ internal class Program
 
         TextFileName = EmitTextFileForTesting();
 
+        RunTest("CallMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_NonGenericCaller", HelperILDllTests.CallMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_NonGenericCaller());
+        RunTest("CallMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_GenericCaller", HelperILDllTests.CallMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_GenericCaller());
+        RunTest("CallMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_GenericCreateDelegate", HelperILDllTests.CallMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_GenericCreateDelegate());
+        RunTest("CallGenMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_NonGenericCaller", HelperILDllTests.CallGenMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_NonGenericCaller());
+        RunTest("CallGenMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_GenericCaller", HelperILDllTests.CallGenMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_GenericCaller());
         RunTest("NewString", NewString());
         RunTest("WriteLine", WriteLine());
         RunTest("IsInstanceOf", IsInstanceOf());
@@ -2227,7 +2232,6 @@ internal class Program
         RunTest("TestWithStructureNonBlittableFieldDueToGenerics", TestWithStructureNonBlittableFieldDueToGenerics());
         RunTest("TestSingleElementStructABI", TestSingleElementStructABI());
         RunTest("TestEnumLayoutAlignments", TestEnumLayoutAlignments());
-
         File.Delete(TextFileName);
 
         Console.WriteLine($@"{_passedTests.Count} tests pass:");
index eb44c22..c233cd8 100644 (file)
@@ -1,21 +1,10 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <OutputType>exe</OutputType>
-    <CLRTestKind>BuildAndRun</CLRTestKind>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-    <CLRTestPriority>0</CLRTestPriority>
-
     <!-- ilasm round-trip testing doesn't make sense for this test -->
     <IlasmRoundTripIncompatible>true</IlasmRoundTripIncompatible>
 
     <!-- This is an explicit crossgen test -->
     <AlwaysUseCrossGen2>true</AlwaysUseCrossGen2>
   </PropertyGroup>
-  <ItemGroup>
-    <ProjectReference Include=".\helperdll.csproj" />
-    <ProjectReference Include=".\helperildll.ilproj" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Program.cs" />
-  </ItemGroup>
+  <Import Project="smoketest.targets" />
 </Project>
diff --git a/src/tests/readytorun/crossgen2/crossgen2smoke_donotalwaysusecrossgen2.csproj b/src/tests/readytorun/crossgen2/crossgen2smoke_donotalwaysusecrossgen2.csproj
new file mode 100644 (file)
index 0000000..04b56bc
--- /dev/null
@@ -0,0 +1,3 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <Import Project="smoketest.targets" />
+</Project>
\ No newline at end of file
index 82a4928..79427e8 100644 (file)
@@ -69,3 +69,29 @@ public struct GenericStructForLdtoken<T>
         return inputIntValue;
     }
 }
+
+public class BaseTypeNonGenericMethodActuallyOnBase
+{
+    public string Method()
+    {
+        return "BaseTypeNonGenericMethodActuallyOnBase::Method";
+    }
+
+    public string GenMethod<T>()
+    {
+        return "BaseTypeNonGenericMethodActuallyOnBase::GenMethod<T>";
+    }
+}
+
+public class BaseTypeGenericMethodActuallyOnBase<U>
+{
+    public string Method()
+    {
+        return "BaseTypeGenericMethodActuallyOnBase<U>::Method";
+    }
+
+    public string GenMethod<T>()
+    {
+        return "BaseTypeGenericMethodActuallyOnBase<U>::GenMethod<T>";
+    }
+}
index 752d16c..ed3b732 100644 (file)
      ret
   }
 }
+
+.class auto ansi public beforefieldinit BaseTypeNonGenericMethodActuallyOnBase_ModuleLocal extends [mscorlib]System.Object
+{
+  .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+  { 
+    ldarg.0
+    call instance void [mscorlib]System.Object::.ctor()
+    ret
+  }
+
+  .method public hidebysig instance string Method() cil managed noinlining
+  {
+    ldstr "BaseTypeNonGenericMethodActuallyOnBase::Method"
+    ret
+  }
+}
+
+.class auto ansi public beforefieldinit DerivedTypeGenericMethodActuallyOnBase_ModuleLocal`1<T0> extends BaseTypeNonGenericMethodActuallyOnBase_ModuleLocal
+{
+  .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+  { 
+    ldarg.0
+    call instance void BaseTypeNonGenericMethodActuallyOnBase_ModuleLocal::.ctor()
+    ret
+  }
+}
+
+.class auto ansi public beforefieldinit DerivedTypeGenericMethodActuallyOnBase`1<T0> extends [helperdll]BaseTypeNonGenericMethodActuallyOnBase
+{
+  .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+  { 
+    ldarg.0
+    call instance void [helperdll]BaseTypeNonGenericMethodActuallyOnBase::.ctor()
+    ret
+  }
+}
+
+.class auto ansi public beforefieldinit DerivedTypeNonGenericMethodActuallyOnBase`1<T0> extends class [helperdll]BaseTypeGenericMethodActuallyOnBase<string>
+{
+  .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+  { 
+    ldarg.0
+    call instance void class [helperdll]BaseTypeGenericMethodActuallyOnBase<string>::.ctor()
+    ret
+  }
+}
+
+.class public auto ansi beforefieldinit HelperILDllTests {
+
+    .method static class [mscorlib]System.Func`1<string> GetDelegateMethodFromGenericType<T0>() cil managed noinlining
+    {
+        newobj       instance void class DerivedTypeGenericMethodActuallyOnBase_ModuleLocal`1<!!0>::.ctor()
+        ldftn        instance string class DerivedTypeGenericMethodActuallyOnBase_ModuleLocal`1<!!T0>::Method()
+        newobj       instance void class [mscorlib]System.Func`1<string>::.ctor(object, native int)
+        ret
+    }
+
+    .method static string CallMethodFromGenericType<T0>() cil managed noinlining
+    {
+        newobj       instance void class DerivedTypeGenericMethodActuallyOnBase`1<!!0>::.ctor()
+        callvirt     instance string class DerivedTypeGenericMethodActuallyOnBase`1<!!T0>::Method()
+        ret
+    }
+
+    .method static string CallGenMethodFromGenericType<T0>() cil managed noinlining
+    {
+        newobj       instance void class DerivedTypeGenericMethodActuallyOnBase`1<!!0>::.ctor()
+        callvirt     instance string class DerivedTypeGenericMethodActuallyOnBase`1<!!T0>::GenMethod<!!0>()
+        ret
+    }
+
+    .method public hidebysig static bool CallMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_GenericCreateDelegate() cil managed noinlining
+    {
+        .maxstack  10
+        .locals init (object V_0)
+        call         class [mscorlib]System.Func`1<string> HelperILDllTests::GetDelegateMethodFromGenericType<object>()
+        callvirt     instance !0 class [mscorlib]System.Func`1<string>::Invoke()
+        ldstr        "BaseTypeNonGenericMethodActuallyOnBase::Method"
+        call         bool [mscorlib]System.String::op_Equality(string,string)
+        ret
+    }
+
+
+    .method public hidebysig static bool CallMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_GenericCaller() cil managed noinlining
+    {
+        .maxstack  10
+        .locals init (object V_0)
+        call         string HelperILDllTests::CallMethodFromGenericType<object>()
+        ldstr        "BaseTypeNonGenericMethodActuallyOnBase::Method"
+        call         bool [mscorlib]System.String::op_Equality(string,string)
+        ret
+    }
+
+    .method public hidebysig static bool CallGenMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_GenericCaller() cil managed noinlining
+    {
+        .maxstack  10
+        .locals init (object V_0)
+        call         string HelperILDllTests::CallGenMethodFromGenericType<object>()
+        ldstr        "BaseTypeNonGenericMethodActuallyOnBase::GenMethod<T>"
+        call         bool [mscorlib]System.String::op_Equality(string,string)
+        ret
+    }
+
+    .method public hidebysig static bool CallMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_NonGenericCaller() cil managed noinlining
+    {
+        .maxstack  10
+        .locals init (object V_0)
+        newobj       instance void class DerivedTypeGenericMethodActuallyOnBase`1<object>::.ctor()
+        callvirt     instance string class DerivedTypeGenericMethodActuallyOnBase`1<object>::Method()
+        ldstr        "BaseTypeNonGenericMethodActuallyOnBase::Method"
+        call         bool [mscorlib]System.String::op_Equality(string,string)
+        ret
+    }
+
+    .method public hidebysig static bool CallGenMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_NonGenericCaller() cil managed noinlining
+    {
+        .maxstack  10
+        .locals init (object V_0)
+        newobj       instance void class DerivedTypeGenericMethodActuallyOnBase`1<object>::.ctor()
+        callvirt     instance string class DerivedTypeGenericMethodActuallyOnBase`1<object>::GenMethod<string>()
+        ldstr        "BaseTypeNonGenericMethodActuallyOnBase::GenMethod<T>"
+        call         bool [mscorlib]System.String::op_Equality(string,string)
+        ret
+    }
+}
diff --git a/src/tests/readytorun/crossgen2/smoketest.targets b/src/tests/readytorun/crossgen2/smoketest.targets
new file mode 100644 (file)
index 0000000..085ef5d
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project>
+  <PropertyGroup>
+    <OutputType>exe</OutputType>
+    <CLRTestKind>BuildAndRun</CLRTestKind>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <CLRTestPriority>0</CLRTestPriority>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include=".\helperdll.csproj" />
+    <ProjectReference Include=".\helperildll.ilproj" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+  </ItemGroup>
+</Project>
\ No newline at end of file