From 87a84c860ea046e29efa2e8efd7f74794b2723d7 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Mon, 7 Oct 2019 21:44:47 +0200 Subject: [PATCH] Fix crossgen2 for methods with StackCrawlMark (dotnet/coreclr#27050) * Fix crossgen2 for methods with StackCrawlMark Methods using StackCrawlMark (like Assembly.GetExecutingAssembly) require that the method is not inlined. Such methods are marked by System.Security.DynamicSecurityMethod attribute. This change adds proper handling of such methods, mimicking exactly what old crossgen does. Commit migrated from https://github.com/dotnet/coreclr/commit/98c2d5ff70059d115fe38bc6c19956a721e33558 --- .../crossgen2/Common/JitInterface/CorInfoImpl.cs | 7 ++++ .../TypeSystem/CodeGen/MethodDelegator.CodeGen.cs | 8 ++++ .../TypeSystem/CodeGen/MethodDesc.CodeGen.cs | 30 ++++++++++++++ .../crossgen2/Common/TypeSystem/Ecma/EcmaMethod.cs | 46 ++++++++++++++-------- .../Compiler/ReadyToRunCodegenCompilation.cs | 7 ++++ 5 files changed, 81 insertions(+), 17 deletions(-) diff --git a/src/coreclr/src/tools/crossgen2/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/src/tools/crossgen2/Common/JitInterface/CorInfoImpl.cs index fc9c9d7..68db43c 100644 --- a/src/coreclr/src/tools/crossgen2/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/src/tools/crossgen2/Common/JitInterface/CorInfoImpl.cs @@ -661,6 +661,13 @@ namespace Internal.JitInterface result |= CorInfoFlag.CORINFO_FLG_PINVOKE; } +#if READYTORUN + if (method.RequireSecObject) + { + result |= CorInfoFlag.CORINFO_FLG_DONT_INLINE_CALLER; + } +#endif + if (method.IsAggressiveOptimization) { result |= CorInfoFlag.CORINFO_FLG_AGGRESSIVE_OPT; diff --git a/src/coreclr/src/tools/crossgen2/Common/TypeSystem/CodeGen/MethodDelegator.CodeGen.cs b/src/coreclr/src/tools/crossgen2/Common/TypeSystem/CodeGen/MethodDelegator.CodeGen.cs index 45a04ab..7091ea8 100644 --- a/src/coreclr/src/tools/crossgen2/Common/TypeSystem/CodeGen/MethodDelegator.CodeGen.cs +++ b/src/coreclr/src/tools/crossgen2/Common/TypeSystem/CodeGen/MethodDelegator.CodeGen.cs @@ -38,6 +38,14 @@ namespace Internal.TypeSystem } } + public override bool RequireSecObject + { + get + { + return _wrappedMethod.RequireSecObject; + } + } + public override bool IsNoOptimization { get diff --git a/src/coreclr/src/tools/crossgen2/Common/TypeSystem/CodeGen/MethodDesc.CodeGen.cs b/src/coreclr/src/tools/crossgen2/Common/TypeSystem/CodeGen/MethodDesc.CodeGen.cs index ab1c408..5884f1d 100644 --- a/src/coreclr/src/tools/crossgen2/Common/TypeSystem/CodeGen/MethodDesc.CodeGen.cs +++ b/src/coreclr/src/tools/crossgen2/Common/TypeSystem/CodeGen/MethodDesc.CodeGen.cs @@ -58,6 +58,20 @@ namespace Internal.TypeSystem } /// + /// Gets a value indicating whether this method was marked with the + /// System.Security.DynamicSecurityMethod attribute. For such methods + /// runtime needs to be able to find their caller, their caller's caller + /// or the method itself on the call stack using stack walking. + /// + public virtual bool RequireSecObject + { + get + { + return false; + } + } + + /// /// Gets a value specifying whether this method should not be optimized. /// public virtual bool IsNoOptimization @@ -168,6 +182,14 @@ namespace Internal.TypeSystem } } + public override bool RequireSecObject + { + get + { + return _methodDef.RequireSecObject; + } + } + public override bool IsNoOptimization { get @@ -252,6 +274,14 @@ namespace Internal.TypeSystem } } + public override bool RequireSecObject + { + get + { + return _typicalMethodDef.RequireSecObject; + } + } + public override bool IsNoOptimization { get diff --git a/src/coreclr/src/tools/crossgen2/Common/TypeSystem/Ecma/EcmaMethod.cs b/src/coreclr/src/tools/crossgen2/Common/TypeSystem/Ecma/EcmaMethod.cs index 225711b..7b21872 100644 --- a/src/coreclr/src/tools/crossgen2/Common/TypeSystem/Ecma/EcmaMethod.cs +++ b/src/coreclr/src/tools/crossgen2/Common/TypeSystem/Ecma/EcmaMethod.cs @@ -14,23 +14,24 @@ namespace Internal.TypeSystem.Ecma { private static class MethodFlags { - public const int BasicMetadataCache = 0x0001; - public const int Virtual = 0x0002; - public const int NewSlot = 0x0004; - public const int Abstract = 0x0008; - public const int Final = 0x0010; - public const int NoInlining = 0x0020; - public const int AggressiveInlining = 0x0040; - public const int RuntimeImplemented = 0x0080; - public const int InternalCall = 0x0100; - public const int Synchronized = 0x0200; - public const int AggressiveOptimization = 0x0400; - public const int NoOptimization = 0x0800; - - public const int AttributeMetadataCache = 0x1000; - public const int Intrinsic = 0x2000; - public const int NativeCallable = 0x4000; - public const int RuntimeExport = 0x8000; + public const int BasicMetadataCache = 0x00001; + public const int Virtual = 0x00002; + public const int NewSlot = 0x00004; + public const int Abstract = 0x00008; + public const int Final = 0x00010; + public const int NoInlining = 0x00020; + public const int AggressiveInlining = 0x00040; + public const int RuntimeImplemented = 0x00080; + public const int InternalCall = 0x00100; + public const int Synchronized = 0x00200; + public const int AggressiveOptimization = 0x00400; + public const int NoOptimization = 0x00800; + public const int RequireSecObject = 0x01000; + + public const int AttributeMetadataCache = 0x02000; + public const int Intrinsic = 0x04000; + public const int NativeCallable = 0x08000; + public const int RuntimeExport = 0x10000; }; private EcmaType _type; @@ -143,6 +144,9 @@ namespace Internal.TypeSystem.Ecma if ((methodAttributes & MethodAttributes.Final) != 0) flags |= MethodFlags.Final; + if ((methodAttributes & MethodAttributes.RequireSecObject) != 0) + flags |= MethodFlags.RequireSecObject; + if ((methodImplAttributes & MethodImplAttributes.NoInlining) != 0) flags |= MethodFlags.NoInlining; @@ -266,6 +270,14 @@ namespace Internal.TypeSystem.Ecma } } + public override bool RequireSecObject + { + get + { + return (GetMethodFlags(MethodFlags.BasicMetadataCache | MethodFlags.RequireSecObject) & MethodFlags.RequireSecObject) != 0; + } + } + public override bool IsAggressiveOptimization { get diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs index eb5e6b3..e0d30de 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs @@ -63,6 +63,13 @@ namespace ILCompiler public bool CanInline(MethodDesc caller, MethodDesc callee) { + // Check to see if the method requires a security object. This means they call demand and + // shouldn't be inlined. + if (callee.RequireSecObject) + { + return false; + } + return NodeFactory.CompilationModuleGroup.CanInline(caller, callee); } -- 2.7.4