diff --git a/src/ILCompiler.Compiler/src/Compiler/Compilation.cs b/src/ILCompiler.Compiler/src/Compiler/Compilation.cs index 915b4986eb9..27af2e2ae97 100644 --- a/src/ILCompiler.Compiler/src/Compiler/Compilation.cs +++ b/src/ILCompiler.Compiler/src/Compiler/Compilation.cs @@ -88,6 +88,12 @@ public MethodIL GetMethodIL(MethodDesc method) protected abstract void CompileInternal(string outputFile, ObjectDumper dumper); + public virtual bool CanInline(MethodDesc caller, MethodDesc callee) + { + // No restrictions on inlining by default + return true; + } + public DelegateCreationInfo GetDelegateCtor(TypeDesc delegateType, MethodDesc target, bool followVirtualDispatch) { // If we're creating a delegate to a virtual method that cannot be overriden, devirtualize. diff --git a/src/JitInterface/src/CorInfoImpl.cs b/src/JitInterface/src/CorInfoImpl.cs index 7891e588da6..3d1559d85c9 100644 --- a/src/JitInterface/src/CorInfoImpl.cs +++ b/src/JitInterface/src/CorInfoImpl.cs @@ -12,17 +12,16 @@ using System.Diagnostics; using System.IO; using System.Text; -using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; +using System.Runtime.InteropServices; #if SUPPORT_JIT using Internal.Runtime.CompilerServices; #endif -using Internal.TypeSystem; - using Internal.IL; +using Internal.TypeSystem; using ILCompiler; using ILCompiler.DependencyAnalysis; @@ -820,8 +819,18 @@ private bool getMethodInfo(CORINFO_METHOD_STRUCT_* ftn, ref CORINFO_METHOD_INFO private CorInfoInline canInline(CORINFO_METHOD_STRUCT_* callerHnd, CORINFO_METHOD_STRUCT_* calleeHnd, ref uint pRestrictions) { - // No restrictions on inlining - return CorInfoInline.INLINE_PASS; + MethodDesc callerMethod = HandleToObject(callerHnd); + MethodDesc calleeMethod = HandleToObject(calleeHnd); + if (_compilation.CanInline(callerMethod, calleeMethod)) + { + // No restrictions on inlining + return CorInfoInline.INLINE_PASS; + } + else + { + // Call may not be inlined + return CorInfoInline.INLINE_NEVER; + } } private void reportInliningDecision(CORINFO_METHOD_STRUCT_* inlinerHnd, CORINFO_METHOD_STRUCT_* inlineeHnd, CorInfoInline inlineResult, byte* reason) @@ -914,14 +923,14 @@ private void getMethodVTableOffset(CORINFO_METHOD_STRUCT_* method, ref uint offs return impl != null ? ObjectToHandle(impl) : null; } - private void ComputeLookup(CORINFO_CONTEXT_STRUCT* pContextMethod, object entity, ReadyToRunHelperId helperId, ref CORINFO_LOOKUP lookup) + private void ComputeLookup(ref CORINFO_RESOLVED_TOKEN pResolvedToken, object entity, ReadyToRunHelperId helperId, ref CORINFO_LOOKUP lookup) { if (_compilation.NeedsRuntimeLookup(helperId, entity)) { lookup.lookupKind.needsRuntimeLookup = true; lookup.runtimeLookup.signature = null; - MethodDesc contextMethod = methodFromContext(pContextMethod); + MethodDesc contextMethod = methodFromContext(pResolvedToken.tokenContext); // Do not bother computing the runtime lookup if we are inlining. The JIT is going // to abort the inlining attempt anyway. @@ -992,10 +1001,10 @@ private void expandRawHandleIntrinsic(ref CORINFO_RESOLVED_TOKEN pResolvedToken, switch (method.Name) { case "EETypePtrOf": - ComputeLookup(pResolvedToken.tokenContext, method.Instantiation[0], ReadyToRunHelperId.TypeHandle, ref pResult.lookup); + ComputeLookup(ref pResolvedToken, method.Instantiation[0], ReadyToRunHelperId.TypeHandle, ref pResult.lookup); break; case "DefaultConstructorOf": - ComputeLookup(pResolvedToken.tokenContext, method.Instantiation[0], ReadyToRunHelperId.DefaultConstructor, ref pResult.lookup); + ComputeLookup(ref pResolvedToken, method.Instantiation[0], ReadyToRunHelperId.DefaultConstructor, ref pResult.lookup); break; } } @@ -2940,7 +2949,7 @@ private void embedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool Debug.Assert(pResult.compileTimeHandle != null); - ComputeLookup(pResolvedToken.tokenContext, target, helperId, ref pResult.lookup); + ComputeLookup(ref pResolvedToken, target, helperId, ref pResult.lookup); } private CORINFO_RUNTIME_LOOKUP_KIND GetGenericRuntimeLookupKind(MethodDesc method) @@ -3290,7 +3299,7 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO if (pResult.exactContextNeedsRuntimeLookup) { - ComputeLookup(pResolvedToken.tokenContext, + ComputeLookup(ref pResolvedToken, GetRuntimeDeterminedObjectForToken(ref pResolvedToken), ReadyToRunHelperId.MethodHandle, ref pResult.codePointerOrStubLookup); @@ -3309,7 +3318,7 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO if (pResult.exactContextNeedsRuntimeLookup) { - ComputeLookup(pResolvedToken.tokenContext, + ComputeLookup(ref pResolvedToken, GetRuntimeDeterminedObjectForToken(ref pResolvedToken), ReadyToRunHelperId.VirtualDispatchCell, ref pResult.codePointerOrStubLookup); diff --git a/src/System.Private.Jit/src/Internal/Runtime/JitSupport/JitCompilation.cs b/src/System.Private.Jit/src/Internal/Runtime/JitSupport/JitCompilation.cs index 8232916e82f..9681a04db87 100644 --- a/src/System.Private.Jit/src/Internal/Runtime/JitSupport/JitCompilation.cs +++ b/src/System.Private.Jit/src/Internal/Runtime/JitSupport/JitCompilation.cs @@ -43,6 +43,12 @@ public Compilation(TypeSystemContext context) public NameMangler NameMangler { get { return null; } } + public virtual bool CanInline(MethodDesc caller, MethodDesc callee) + { + // No inlining limits by default + return true; + } + public ObjectNode GetFieldRvaData(FieldDesc field) { // Use the typical field definition in case this is an instantiated generic type