diff --git a/src/coreclr/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs index cc951806f2a4ea..72922bde0274b3 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs @@ -400,27 +400,84 @@ internal static Delegate CreateDelegateForDynamicMethod(Type type, object? targe Justification = "The parameter 'methodType' is passed by ref to QCallTypeHandle")] private bool BindToMethodName(object? target, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.AllMethods)] RuntimeType methodType, string method, DelegateBindingFlags flags) { - Delegate d = this; - return BindToMethodName(ObjectHandleOnStack.Create(ref d), ObjectHandleOnStack.Create(ref target), - new QCallTypeHandle(ref methodType), method, flags); + bool ret; + BindToMethodDetails bindToMethodDetails; + + unsafe + { + ret = BindToMethodName(RuntimeHelpers.GetMethodTable(this), (target != null) ? RuntimeHelpers.GetMethodTable(target) : null, + new QCallTypeHandle(ref methodType), method, flags, ObjectHandleOnStack.Create(ref target), out bindToMethodDetails); + } + + if (ret) + { + // Apply the results of the QCall to the delegate instance. + _methodPtr = bindToMethodDetails.methodPtr; + _methodPtrAux = bindToMethodDetails.methodPtrAux; + Unsafe.As(this)._invocationCount = bindToMethodDetails.invocationCount; + if (bindToMethodDetails.loaderAllocatorGCHandle.IsAllocated) + { + _helperObject = bindToMethodDetails.loaderAllocatorGCHandle.Target; + GC.KeepAlive(method); + } + + if (bindToMethodDetails.selfReferentialTarget != 0) + _target = this; + else + _target = target; + } + return ret; + } + + private struct BindToMethodDetails + { + public int selfReferentialTarget; // Whether the delegate's target object is the same as the first argument of the method to bind to. Only meaningful for open instance delegates. + public IntPtr methodPtr; + public IntPtr methodPtrAux; + public IntPtr invocationCount; + public GCHandle loaderAllocatorGCHandle; // The loader allocator needed if the delegate needs to keep it alive } [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Delegate_BindToMethodName", StringMarshalling = StringMarshalling.Utf8)] [return: MarshalAs(UnmanagedType.Bool)] - private static partial bool BindToMethodName(ObjectHandleOnStack d, ObjectHandleOnStack target, QCallTypeHandle methodType, string method, DelegateBindingFlags flags); + private static partial bool BindToMethodName(MethodTable* pDelegateMT, MethodTable *pTargetMT, QCallTypeHandle methodType, string method, DelegateBindingFlags flags, ObjectHandleOnStack targetParameter, out BindToMethodDetails bindToMethodDetails); private bool BindToMethodInfo(object? target, IRuntimeMethodInfo method, RuntimeType methodType, DelegateBindingFlags flags) { - Delegate d = this; - bool ret = BindToMethodInfo(ObjectHandleOnStack.Create(ref d), ObjectHandleOnStack.Create(ref target), - method.Value, new QCallTypeHandle(ref methodType), flags); - GC.KeepAlive(method); + bool ret; + BindToMethodDetails bindToMethodDetails; + + unsafe + { + // Note the use of Unsafe.As on method. This is not a generally safe operation, but we require in CoreCLR that + // all implementors of IRuntimeMethodInfo have the same offset for the m_value field, so this is safe in this context. + ret = BindToMethodInfo(RuntimeHelpers.GetMethodTable(this), (target != null) ? RuntimeHelpers.GetMethodTable(target) : null, + IRuntimeMethodInfo.GetValue(method), new QCallTypeHandle(ref methodType), flags, ObjectHandleOnStack.Create(ref target), out bindToMethodDetails); + } + + if (ret) + { + // Apply the results of the QCall to the delegate instance. + _methodPtr = bindToMethodDetails.methodPtr; + _methodPtrAux = bindToMethodDetails.methodPtrAux; + Unsafe.As(this)._invocationCount = bindToMethodDetails.invocationCount; + if (bindToMethodDetails.loaderAllocatorGCHandle.IsAllocated) + { + _helperObject = bindToMethodDetails.loaderAllocatorGCHandle.Target; + GC.KeepAlive(method); + } + + if (bindToMethodDetails.selfReferentialTarget != 0) + _target = this; + else + _target = target; + } return ret; } [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Delegate_BindToMethodInfo")] [return: MarshalAs(UnmanagedType.Bool)] - private static partial bool BindToMethodInfo(ObjectHandleOnStack d, ObjectHandleOnStack target, RuntimeMethodHandleInternal method, QCallTypeHandle methodType, DelegateBindingFlags flags); + private static partial bool BindToMethodInfo(MethodTable* pDelegateMT, MethodTable *pTargetMT, RuntimeMethodHandleInternal method, QCallTypeHandle methodType, DelegateBindingFlags flags, ObjectHandleOnStack targetParameter, out BindToMethodDetails bindToMethodDetails); private static MulticastDelegate InternalAlloc(RuntimeType type) { @@ -465,12 +522,31 @@ private void DelegateConstruct(object target, IntPtr method) throw new ArgumentNullException(nameof(method)); } - Delegate _this = this; - Construct(ObjectHandleOnStack.Create(ref _this), ObjectHandleOnStack.Create(ref target), method); + BindToMethodDetails bindToMethodDetails; + + unsafe + { + Construct(RuntimeHelpers.GetMethodTable(this), (target != null) ? RuntimeHelpers.GetMethodTable(target) : null, + method, out bindToMethodDetails); + } + + // Apply the results of the QCall to the delegate instance. + _methodPtr = bindToMethodDetails.methodPtr; + _methodPtrAux = bindToMethodDetails.methodPtrAux; + Unsafe.As(this)._invocationCount = bindToMethodDetails.invocationCount; + if (bindToMethodDetails.loaderAllocatorGCHandle.IsAllocated) + { + _helperObject = bindToMethodDetails.loaderAllocatorGCHandle.Target; + } + + if (bindToMethodDetails.selfReferentialTarget != 0) + _target = this; + else + _target = target; } [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Delegate_Construct")] - private static partial void Construct(ObjectHandleOnStack _this, ObjectHandleOnStack target, IntPtr method); + private static partial void Construct(MethodTable* pDelegateMT, MethodTable* pTargetMT, IntPtr method, out BindToMethodDetails bindToMethodDetails); [MethodImpl(MethodImplOptions.InternalCall)] private static extern unsafe void* GetMulticastInvoke(MethodTable* pMT); @@ -525,11 +601,16 @@ private static bool InternalEqualMethodHandles(Delegate left, Delegate right) internal static IntPtr AdjustTarget(object target, IntPtr methodPtr) { - return AdjustTarget(ObjectHandleOnStack.Create(ref target), methodPtr); + unsafe + { + IntPtr result = AdjustTarget(RuntimeHelpers.GetMethodTable(target), methodPtr); + GC.KeepAlive(target); + return result; + } } [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Delegate_AdjustTarget")] - private static partial IntPtr AdjustTarget(ObjectHandleOnStack target, IntPtr methodPtr); + private static partial IntPtr AdjustTarget(MethodTable* targetMT, IntPtr methodPtr); internal void InitializeVirtualCallStub(IntPtr methodPtr) { diff --git a/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.CoreCLR.cs index f9e22594e1a3ad..ea439235fb32ce 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.CoreCLR.cs @@ -23,7 +23,7 @@ public abstract partial class MulticastDelegate : Delegate // 1. Multicast delegate // 2. Unmanaged function pointer // 3. Open virtual delegate - private nint _invocationCount; + internal nint _invocationCount; private bool IsUnmanagedFunctionPtr() { diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs index dc11617d89ed09..42fad545acf345 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs @@ -652,7 +652,7 @@ internal DynamicResolver(DynamicILInfo dynamicILInfo) // We can never ever have two active destroy scouts for the same method. We need to initialize the scout // outside the try/reregister block to avoid possibility of reregistration for finalization with active scout. - scout.m_methodHandle = method._methodHandle.Value; + scout.m_methodHandle = IRuntimeMethodInfo.GetValue(method._methodHandle); } private sealed class DestroyScout @@ -1028,7 +1028,7 @@ public int GetTokenFor(RuntimeMethodHandle method) IRuntimeMethodInfo methodReal = method.GetMethodInfo(); if (methodReal != null) { - RuntimeMethodHandleInternal rmhi = methodReal.Value; + RuntimeMethodHandleInternal rmhi = IRuntimeMethodInfo.GetValue(methodReal); if (!RuntimeMethodHandle.IsDynamicMethod(rmhi)) { RuntimeType type = RuntimeMethodHandle.GetDeclaringType(rmhi); diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.CoreCLR.cs index 77aa9fc4fc77b9..b337fa3dd8d25e 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.CoreCLR.cs @@ -51,7 +51,7 @@ public sealed override Delegate CreateDelegate(Type delegateType, object? target // Compile the method since accessibility checks are done as part of compilation GetMethodDescriptor(); IRuntimeMethodInfo? methodHandle = _methodHandle; - CompileMethod(methodHandle != null ? methodHandle.Value : RuntimeMethodHandleInternal.EmptyHandle); + CompileMethod(methodHandle != null ? IRuntimeMethodInfo.GetValue(methodHandle) : RuntimeMethodHandleInternal.EmptyHandle); GC.KeepAlive(methodHandle); } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeModuleBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeModuleBuilder.cs index 5c5bc5d0e52217..dd094bda0c06dd 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeModuleBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeModuleBuilder.cs @@ -129,7 +129,7 @@ private int GetMemberRefOfMethodInfo(int tr, RuntimeMethodInfo method) Debug.Assert(method != null); RuntimeModuleBuilder thisModule = this; - int result = GetMemberRefOfMethodInfo(new QCallModule(ref thisModule), tr, ((IRuntimeMethodInfo)method).Value); + int result = GetMemberRefOfMethodInfo(new QCallModule(ref thisModule), tr, IRuntimeMethodInfo.GetValue(method)); GC.KeepAlive(method); return result; } @@ -139,7 +139,7 @@ private int GetMemberRefOfMethodInfo(int tr, RuntimeConstructorInfo method) Debug.Assert(method != null); RuntimeModuleBuilder thisModule = this; - int result = GetMemberRefOfMethodInfo(new QCallModule(ref thisModule), tr, ((IRuntimeMethodInfo)method).Value); + int result = GetMemberRefOfMethodInfo(new QCallModule(ref thisModule), tr, IRuntimeMethodInfo.GetValue(method)); GC.KeepAlive(method); return result; } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.CoreCLR.cs index 39da6d248bdd2c..56fb49ec83bb19 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.CoreCLR.cs @@ -66,8 +66,6 @@ internal RuntimeConstructorInfo( #endregion #region NonPublic Methods - RuntimeMethodHandleInternal IRuntimeMethodInfo.Value => new RuntimeMethodHandleInternal(m_handle); - internal override bool CacheEquals(object? o) => o is RuntimeConstructorInfo m && m.m_handle == m_handle && ReferenceEquals(m_declaringType, m.m_declaringType); diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs index 06492be84dfd6b..69f1582a46e9cf 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs @@ -1701,7 +1701,7 @@ private static bool FilterCustomAttributeRecord( RuntimeTypeHandle attributeTypeHandle = attributeType.TypeHandle; bool result = RuntimeMethodHandle.IsCAVisibleFromDecoratedType(new QCallTypeHandle(ref attributeTypeHandle), - ctorWithParameters is not null ? ctorWithParameters.Value : RuntimeMethodHandleInternal.EmptyHandle, + ctorWithParameters is not null ? IRuntimeMethodInfo.GetValue(ctorWithParameters) : RuntimeMethodHandleInternal.EmptyHandle, new QCallTypeHandle(ref parentTypeHandle), new QCallModule(ref decoratedModule)) != Interop.BOOL.FALSE; diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.CoreCLR.cs index f786ba624532fe..770d7a5cdef0c8 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.CoreCLR.cs @@ -69,8 +69,6 @@ internal RuntimeMethodInfo( #endregion #region Private Methods - RuntimeMethodHandleInternal IRuntimeMethodInfo.Value => new RuntimeMethodHandleInternal(m_handle); - private RuntimeType ReflectedTypeInternal => m_reflectedTypeCache.GetRuntimeType(); private ParameterInfo[] FetchNonReturnParameters() => diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs index 584f6cd3e15965..e34f20f5855938 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs @@ -213,7 +213,7 @@ public static unsafe void PrepareMethod(RuntimeMethodHandle method, RuntimeTypeH ReadOnlySpan instantiationHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(instantiation, stackScratch: stackalloc IntPtr[8]); fixed (IntPtr* pInstantiation = instantiationHandles) { - PrepareMethod(methodInfo.Value, pInstantiation, instantiationHandles.Length); + PrepareMethod(IRuntimeMethodInfo.GetValue(methodInfo), pInstantiation, instantiationHandles.Length); GC.KeepAlive(instantiation); GC.KeepAlive(methodInfo); } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs index 5b8da16ac80bf5..2b77e1c139b5b4 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs @@ -217,7 +217,7 @@ private static void PrelinkCore(MethodInfo m) throw new ArgumentException(SR.Argument_MustBeRuntimeMethodInfo, nameof(m)); } - InternalPrelink(((IRuntimeMethodInfo)rmi).Value); + InternalPrelink(IRuntimeMethodInfo.GetValue(rmi)); GC.KeepAlive(rmi); } diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index 7fc5dc96f17b0f..ed87c8de922a0e 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -879,7 +879,7 @@ internal bool ContainsGenericVariables() internal static bool SatisfiesConstraints(RuntimeType paramType, RuntimeType? typeContext, RuntimeMethodInfo? methodContext, RuntimeType toType) { - RuntimeMethodHandleInternal methodContextRaw = ((IRuntimeMethodInfo?)methodContext)?.Value ?? RuntimeMethodHandleInternal.EmptyHandle; + RuntimeMethodHandleInternal methodContextRaw = (methodContext == null) ? RuntimeMethodHandleInternal.EmptyHandle : IRuntimeMethodInfo.GetValue(methodContext); bool result = SatisfiesConstraints(new QCallTypeHandle(ref paramType), new QCallTypeHandle(ref typeContext!), methodContextRaw, new QCallTypeHandle(ref toType)) != Interop.BOOL.FALSE; GC.KeepAlive(methodContext); return result; @@ -959,9 +959,7 @@ public RuntimeMethodInfoStub(RuntimeMethodHandleInternal methodHandleValue, obje private object? m_h; #pragma warning restore CA1823, 414, 169, IDE0044 - private IntPtr m_value; - - RuntimeMethodHandleInternal IRuntimeMethodInfo.Value => new RuntimeMethodHandleInternal(m_value); + internal IntPtr m_value; // implementation of CORINFO_HELP_METHODDESC_TO_STUBRUNTIMEMETHOD [StackTraceHidden] @@ -976,9 +974,10 @@ internal static object FromPtr(IntPtr pMD) internal interface IRuntimeMethodInfo { - RuntimeMethodHandleInternal Value + internal static RuntimeMethodHandleInternal GetValue(IRuntimeMethodInfo method) { - get; + // All implementations of IRuntimeMethodInfo are required to have a m_value field at the same offset as RuntimeMethodInfoStub.m_value. + return new RuntimeMethodHandleInternal(Unsafe.As(method).m_value); } } @@ -1013,7 +1012,7 @@ public void GetObjectData(SerializationInfo info, StreamingContext context) throw new PlatformNotSupportedException(); } - public IntPtr Value => m_value != null ? m_value.Value.Value : IntPtr.Zero; + public IntPtr Value => m_value != null ? IRuntimeMethodInfo.GetValue(m_value).Value : IntPtr.Zero; public override int GetHashCode() { @@ -1068,7 +1067,7 @@ internal bool IsNullHandle() public IntPtr GetFunctionPointer() { - IntPtr ptr = GetFunctionPointer(EnsureNonNullMethodInfo(m_value).Value); + IntPtr ptr = GetFunctionPointer(IRuntimeMethodInfo.GetValue(EnsureNonNullMethodInfo(m_value))); GC.KeepAlive(m_value); return ptr; } @@ -1088,7 +1087,7 @@ internal static partial Interop.BOOL IsCAVisibleFromDecoratedType( internal static MethodAttributes GetAttributes(IRuntimeMethodInfo method) { - MethodAttributes retVal = GetAttributes(method.Value); + MethodAttributes retVal = GetAttributes(IRuntimeMethodInfo.GetValue(method)); GC.KeepAlive(method); return retVal; } @@ -1103,7 +1102,7 @@ internal static string ConstructInstantiation(IRuntimeMethodInfo method, TypeNam { string? name = null; IRuntimeMethodInfo methodInfo = EnsureNonNullMethodInfo(method); - ConstructInstantiation(methodInfo.Value, format, new StringHandleOnStack(ref name)); + ConstructInstantiation(IRuntimeMethodInfo.GetValue(methodInfo), format, new StringHandleOnStack(ref name)); GC.KeepAlive(methodInfo); return name!; } @@ -1120,7 +1119,7 @@ internal static unsafe RuntimeType GetDeclaringType(RuntimeMethodHandleInternal internal static RuntimeType GetDeclaringType(IRuntimeMethodInfo method) { - RuntimeType type = GetDeclaringType(method.Value); + RuntimeType type = GetDeclaringType(IRuntimeMethodInfo.GetValue(method)); GC.KeepAlive(method); return type; } @@ -1132,7 +1131,7 @@ internal static int GetSlot(IRuntimeMethodInfo method) { Debug.Assert(method != null); - int slot = GetSlot(method.Value); + int slot = GetSlot(IRuntimeMethodInfo.GetValue(method)); GC.KeepAlive(method); return slot; } @@ -1144,7 +1143,7 @@ internal static int GetMethodDef(IRuntimeMethodInfo method) { Debug.Assert(method != null); - int token = GetMethodDef(method.Value); + int token = GetMethodDef(IRuntimeMethodInfo.GetValue(method)); GC.KeepAlive(method); return token; } @@ -1154,7 +1153,7 @@ internal static string GetName(RuntimeMethodHandleInternal method) internal static string GetName(IRuntimeMethodInfo method) { - string name = GetName(method.Value); + string name = GetName(IRuntimeMethodInfo.GetValue(method)); GC.KeepAlive(method); return name; } @@ -1237,7 +1236,7 @@ ref obj.GetRawData(), internal static RuntimeType[] GetMethodInstantiationInternal(IRuntimeMethodInfo method) { RuntimeType[]? types = null; - GetMethodInstantiation(EnsureNonNullMethodInfo(method).Value, ObjectHandleOnStack.Create(ref types), Interop.BOOL.TRUE); + GetMethodInstantiation(IRuntimeMethodInfo.GetValue(EnsureNonNullMethodInfo(method)), ObjectHandleOnStack.Create(ref types), Interop.BOOL.TRUE); GC.KeepAlive(method); return types!; } @@ -1252,7 +1251,7 @@ internal static RuntimeType[] GetMethodInstantiationInternal(RuntimeMethodHandle internal static Type[]? GetMethodInstantiationPublic(IRuntimeMethodInfo method) { Type[]? types = null; - GetMethodInstantiation(EnsureNonNullMethodInfo(method).Value, ObjectHandleOnStack.Create(ref types), Interop.BOOL.FALSE); + GetMethodInstantiation(IRuntimeMethodInfo.GetValue(EnsureNonNullMethodInfo(method)), ObjectHandleOnStack.Create(ref types), Interop.BOOL.FALSE); GC.KeepAlive(method); return types; } @@ -1262,7 +1261,7 @@ internal static RuntimeType[] GetMethodInstantiationInternal(RuntimeMethodHandle internal static bool HasMethodInstantiation(IRuntimeMethodInfo method) { - bool fRet = HasMethodInstantiation(method.Value); + bool fRet = HasMethodInstantiation(IRuntimeMethodInfo.GetValue(method)); GC.KeepAlive(method); return fRet; } @@ -1297,7 +1296,7 @@ static RuntimeMethodHandleInternal GetStubIfNeededWorker(RuntimeMethodHandleInte internal static bool IsGenericMethodDefinition(IRuntimeMethodInfo method) { - bool fRet = IsGenericMethodDefinition(method.Value); + bool fRet = IsGenericMethodDefinition(IRuntimeMethodInfo.GetValue(method)); GC.KeepAlive(method); return fRet; } @@ -1312,7 +1311,7 @@ internal static IRuntimeMethodInfo GetTypicalMethodDefinition(IRuntimeMethodInfo { if (!IsTypicalMethodDefinition(method)) { - GetTypicalMethodDefinition(method.Value, ObjectHandleOnStack.Create(ref method)); + GetTypicalMethodDefinition(IRuntimeMethodInfo.GetValue(method), ObjectHandleOnStack.Create(ref method)); GC.KeepAlive(method); } @@ -1322,7 +1321,7 @@ internal static IRuntimeMethodInfo GetTypicalMethodDefinition(IRuntimeMethodInfo [MethodImpl(MethodImplOptions.InternalCall)] private static extern int GetGenericParameterCount(RuntimeMethodHandleInternal method); - internal static int GetGenericParameterCount(IRuntimeMethodInfo method) => GetGenericParameterCount(method.Value); + internal static int GetGenericParameterCount(IRuntimeMethodInfo method) => GetGenericParameterCount(IRuntimeMethodInfo.GetValue(method)); [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeMethodHandle_StripMethodInstantiation")] private static partial void StripMethodInstantiation(RuntimeMethodHandleInternal method, ObjectHandleOnStack outMethod); @@ -1331,7 +1330,7 @@ internal static IRuntimeMethodInfo StripMethodInstantiation(IRuntimeMethodInfo m { IRuntimeMethodInfo strippedMethod = method; - StripMethodInstantiation(method.Value, ObjectHandleOnStack.Create(ref strippedMethod)); + StripMethodInstantiation(IRuntimeMethodInfo.GetValue(method), ObjectHandleOnStack.Create(ref strippedMethod)); GC.KeepAlive(method); return strippedMethod; @@ -1352,7 +1351,7 @@ internal static IRuntimeMethodInfo StripMethodInstantiation(IRuntimeMethodInfo m internal static RuntimeMethodBody? GetMethodBody(IRuntimeMethodInfo method, RuntimeType declaringType) { RuntimeMethodBody? result = null; - GetMethodBody(method.Value, new QCallTypeHandle(ref declaringType), ObjectHandleOnStack.Create(ref result)); + GetMethodBody(IRuntimeMethodInfo.GetValue(method), new QCallTypeHandle(ref declaringType), ObjectHandleOnStack.Create(ref result)); GC.KeepAlive(method); return result; } @@ -2081,7 +2080,7 @@ public Signature( _returnTypeORfieldType = returnType; _managedCallingConventionAndArgIteratorFlags = (int)callingConvention; Debug.Assert((_managedCallingConventionAndArgIteratorFlags & 0xffffff00) == 0); - _pMethod = methodHandle.Value; + _pMethod = IRuntimeMethodInfo.GetValue(methodHandle); _declaringType = RuntimeMethodHandle.GetDeclaringType(_pMethod); Init(null, 0, default, _pMethod); @@ -2091,7 +2090,7 @@ public Signature( public Signature(IRuntimeMethodInfo methodHandle, RuntimeType declaringType) { _declaringType = declaringType; - Init(null, 0, default, methodHandle.Value); + Init(null, 0, default, IRuntimeMethodInfo.GetValue(methodHandle)); GC.KeepAlive(methodHandle); } diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs index a50bed7f6bcafc..849f33fd9afb81 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs @@ -1808,7 +1808,7 @@ internal FieldInfo GetField(RuntimeFieldHandleInternal field) internal static MethodBase? GetMethodBase(RuntimeType? reflectedType, IRuntimeMethodInfo methodHandle) { - MethodBase? retval = GetMethodBase(reflectedType, methodHandle.Value); + MethodBase? retval = GetMethodBase(reflectedType, IRuntimeMethodInfo.GetValue(methodHandle)); GC.KeepAlive(methodHandle); return retval; } @@ -1856,7 +1856,7 @@ internal FieldInfo GetField(RuntimeFieldHandleInternal field) for (int i = 0; i < methodBases.Length; i++) { IRuntimeMethodInfo rmi = (IRuntimeMethodInfo)methodBases[i]; - if (rmi.Value.Value == methodHandle.Value) + if (IRuntimeMethodInfo.GetValue(rmi).Value == methodHandle.Value) loaderAssuredCompatible = true; } diff --git a/src/coreclr/debug/ee/debugger.cpp b/src/coreclr/debug/ee/debugger.cpp index 54bde6c60c6845..074a56f366755e 100644 --- a/src/coreclr/debug/ee/debugger.cpp +++ b/src/coreclr/debug/ee/debugger.cpp @@ -12471,15 +12471,6 @@ HRESULT Debugger::ApplyChangesAndSendResult(DebuggerModule * pDebuggerModule, } else { - // Violation with the following call stack: - // CONTRACT in MethodTableBuilder::InitMethodDesc - // CONTRACT in EEClass::AddMethod - // CONTRACT in EditAndContinueModule::AddMethod - // CONTRACT in EditAndContinueModule::ApplyEditAndContinue - // CONTRACT in EEDbgInterfaceImpl::EnCApplyChanges - // VIOLATED--> CONTRACT in Debugger::ApplyChangesAndSendResult - CONTRACT_VIOLATION(GCViolation); - // Tell the VM to apply the edit hr = g_pEEInterface->EnCApplyChanges( (EditAndContinueModule*)pModule, cbMetadata, pMetadata, cbIL, pIL); diff --git a/src/coreclr/debug/ee/funceval.cpp b/src/coreclr/debug/ee/funceval.cpp index 263beaa911bbfc..7e81734c7f63ef 100644 --- a/src/coreclr/debug/ee/funceval.cpp +++ b/src/coreclr/debug/ee/funceval.cpp @@ -2099,6 +2099,7 @@ void GatherFuncEvalMethodInfo(DebuggerEval *pDE, // if ((pDE->m_evalType != DB_IPCE_FET_NEW_OBJECT) && !pDE->m_md->IsStatic() && pDE->m_md->IsUnboxingStub()) { + GCX_PREEMP(); *ppUnboxedMD = pDE->m_md->GetMethodTable()->GetUnboxedEntryPointMD(pDE->m_md); } @@ -2213,13 +2214,20 @@ void GatherFuncEvalMethodInfo(DebuggerEval *pDE, // Now, find the proper MethodDesc for this interface method based on the object we're invoking the // method on. // - pDE->m_targetCodeAddr = pDE->m_md->GetCallTarget(&objRef, pDE->m_ownerTypeHandle); + { + MethodTable *pMT = objRef->GetMethodTable(); + GCX_PREEMP(); + pDE->m_targetCodeAddr = pDE->m_md->GetCallTarget(&objRef, pMT, pDE->m_ownerTypeHandle); + } GCPROTECT_END(); } else { - pDE->m_targetCodeAddr = pDE->m_md->GetCallTarget(NULL, pDE->m_ownerTypeHandle); + { + GCX_PREEMP(); + pDE->m_targetCodeAddr = pDE->m_md->GetCallTarget(NULL, NULL, pDE->m_ownerTypeHandle); + } } // @@ -3195,7 +3203,10 @@ static void DoNormalFuncEval( DebuggerEval *pDE, // Now that all the args are protected, we can go back and deal with generic args and resolving // all their information. // - ResolveFuncEvalGenericArgInfo(pDE); + { + GCX_PREEMP(); + ResolveFuncEvalGenericArgInfo(pDE); + } // // Grab the signature of the method we're working on and do some error checking. diff --git a/src/coreclr/vm/amd64/cgenamd64.cpp b/src/coreclr/vm/amd64/cgenamd64.cpp index e8380e10983f34..c786fd3259b70b 100644 --- a/src/coreclr/vm/amd64/cgenamd64.cpp +++ b/src/coreclr/vm/amd64/cgenamd64.cpp @@ -24,9 +24,7 @@ #include "clrtocomcall.h" #endif // FEATURE_COMINTEROP -#ifdef FEATURE_PERFMAP #include "perfmap.h" -#endif void UpdateRegDisplayFromCalleeSavedRegisters(REGDISPLAY * pRD, CalleeSavedRegisters * pRegs) { @@ -462,6 +460,7 @@ INT32 rel32UsingJumpStub(INT32 UNALIGNED * pRel32, PCODE target, MethodDesc *pMe { CONTRACTL { + MODE_PREEMPTIVE; THROWS; // Creating a JumpStub could throw OutOfMemory GC_NOTRIGGER; @@ -607,13 +606,9 @@ DWORD GetOffsetAtEndOfFunction(ULONGLONG uImageBase, size_t rxOffset = pStartRX - pStart; \ BYTE * p = pStart; -#ifdef FEATURE_PERFMAP #define BEGIN_DYNAMIC_HELPER_EMIT(size) \ BEGIN_DYNAMIC_HELPER_EMIT_WORKER(size) \ PerfMap::LogStubs(__FUNCTION__, "DynamicHelper", (PCODE)p, size, PerfMapStubType::Individual); -#else -#define BEGIN_DYNAMIC_HELPER_EMIT(size) BEGIN_DYNAMIC_HELPER_EMIT_WORKER(size) -#endif #define END_DYNAMIC_HELPER_EMIT() \ _ASSERTE(pStart + cb == p); \ @@ -647,7 +642,7 @@ void DynamicHelpers::EmitHelperWithArg(BYTE*& p, size_t rxOffset, LoaderAllocato { CONTRACTL { - GC_NOTRIGGER; + STANDARD_VM_CHECK; PRECONDITION(p != NULL && target != NULL); } CONTRACTL_END; @@ -670,6 +665,8 @@ void DynamicHelpers::EmitHelperWithArg(BYTE*& p, size_t rxOffset, LoaderAllocato PCODE DynamicHelpers::CreateHelperWithArg(LoaderAllocator * pAllocator, TADDR arg, PCODE target) { + STANDARD_VM_CONTRACT; + BEGIN_DYNAMIC_HELPER_EMIT(15); EmitHelperWithArg(p, rxOffset, pAllocator, arg, target); @@ -679,6 +676,8 @@ PCODE DynamicHelpers::CreateHelperWithArg(LoaderAllocator * pAllocator, TADDR ar PCODE DynamicHelpers::CreateHelper(LoaderAllocator * pAllocator, TADDR arg, TADDR arg2, PCODE target) { + STANDARD_VM_CONTRACT; + BEGIN_DYNAMIC_HELPER_EMIT(25); #ifdef UNIX_AMD64_ABI @@ -708,6 +707,8 @@ PCODE DynamicHelpers::CreateHelper(LoaderAllocator * pAllocator, TADDR arg, TADD PCODE DynamicHelpers::CreateHelperArgMove(LoaderAllocator * pAllocator, TADDR arg, PCODE target) { + STANDARD_VM_CONTRACT; + BEGIN_DYNAMIC_HELPER_EMIT(18); #ifdef UNIX_AMD64_ABI @@ -737,6 +738,8 @@ PCODE DynamicHelpers::CreateHelperArgMove(LoaderAllocator * pAllocator, TADDR ar PCODE DynamicHelpers::CreateReturn(LoaderAllocator * pAllocator) { + STANDARD_VM_CONTRACT; + BEGIN_DYNAMIC_HELPER_EMIT(1); *p++ = 0xC3; // ret @@ -746,6 +749,8 @@ PCODE DynamicHelpers::CreateReturn(LoaderAllocator * pAllocator) PCODE DynamicHelpers::CreateReturnConst(LoaderAllocator * pAllocator, TADDR arg) { + STANDARD_VM_CONTRACT; + BEGIN_DYNAMIC_HELPER_EMIT(11); SET_UNALIGNED_16(p, 0xB848); // mov rax, XXXXXX @@ -760,6 +765,8 @@ PCODE DynamicHelpers::CreateReturnConst(LoaderAllocator * pAllocator, TADDR arg) PCODE DynamicHelpers::CreateReturnIndirConst(LoaderAllocator * pAllocator, TADDR arg, INT8 offset) { + STANDARD_VM_CONTRACT; + BEGIN_DYNAMIC_HELPER_EMIT((offset != 0) ? 15 : 11); SET_UNALIGNED_16(p, 0xA148); // mov rax, [XXXXXX] @@ -783,6 +790,8 @@ PCODE DynamicHelpers::CreateReturnIndirConst(LoaderAllocator * pAllocator, TADDR PCODE DynamicHelpers::CreateHelperWithTwoArgs(LoaderAllocator * pAllocator, TADDR arg, PCODE target) { + STANDARD_VM_CONTRACT; + BEGIN_DYNAMIC_HELPER_EMIT(15); #ifdef UNIX_AMD64_ABI @@ -803,6 +812,8 @@ PCODE DynamicHelpers::CreateHelperWithTwoArgs(LoaderAllocator * pAllocator, TADD PCODE DynamicHelpers::CreateHelperWithTwoArgs(LoaderAllocator * pAllocator, TADDR arg, TADDR arg2, PCODE target) { + STANDARD_VM_CONTRACT; + BEGIN_DYNAMIC_HELPER_EMIT(25); #ifdef UNIX_AMD64_ABI diff --git a/src/coreclr/vm/arm/stubs.cpp b/src/coreclr/vm/arm/stubs.cpp index 2f0215b21006c0..24eb174ec59904 100644 --- a/src/coreclr/vm/arm/stubs.cpp +++ b/src/coreclr/vm/arm/stubs.cpp @@ -25,9 +25,7 @@ #include "ecall.h" #include "threadsuspend.h" -#ifdef FEATURE_PERFMAP #include "perfmap.h" -#endif // target write barriers EXTERN_C void JIT_WriteBarrier(Object **dst, Object *ref); @@ -1494,13 +1492,9 @@ void MovRegImm(BYTE* p, int reg, TADDR imm) size_t rxOffset = pStartRX - pStart; \ BYTE * p = pStart; -#ifdef FEATURE_PERFMAP #define BEGIN_DYNAMIC_HELPER_EMIT(size) \ BEGIN_DYNAMIC_HELPER_EMIT_WORKER(size) \ PerfMap::LogStubs(__FUNCTION__, "DynamicHelper", (PCODE)p, size, PerfMapStubType::Individual); -#else -#define BEGIN_DYNAMIC_HELPER_EMIT(size) BEGIN_DYNAMIC_HELPER_EMIT_WORKER(size) -#endif #define END_DYNAMIC_HELPER_EMIT() \ diff --git a/src/coreclr/vm/arm64/stubs.cpp b/src/coreclr/vm/arm64/stubs.cpp index 9ee0c4b42377d4..f7274eb0d1ab7d 100644 --- a/src/coreclr/vm/arm64/stubs.cpp +++ b/src/coreclr/vm/arm64/stubs.cpp @@ -13,9 +13,7 @@ #include "ecall.h" #include "writebarriermanager.h" -#ifdef FEATURE_PERFMAP #include "perfmap.h" -#endif #ifndef DACCESS_COMPILE //----------------------------------------------------------------------- @@ -951,13 +949,9 @@ void StubLinkerCPU::EmitCallManagedMethod(MethodDesc *pMD, BOOL fTailCall) size_t rxOffset = pStartRX - pStart; \ BYTE * p = pStart; -#ifdef FEATURE_PERFMAP #define BEGIN_DYNAMIC_HELPER_EMIT(size) \ BEGIN_DYNAMIC_HELPER_EMIT_WORKER(size) \ PerfMap::LogStubs(__FUNCTION__, "DynamicHelper", (PCODE)p, size, PerfMapStubType::Individual); -#else -#define BEGIN_DYNAMIC_HELPER_EMIT(size) BEGIN_DYNAMIC_HELPER_EMIT_WORKER(size) -#endif #define END_DYNAMIC_HELPER_EMIT() \ diff --git a/src/coreclr/vm/assembly.cpp b/src/coreclr/vm/assembly.cpp index 5f2526172d941d..b408cb8ed17154 100644 --- a/src/coreclr/vm/assembly.cpp +++ b/src/coreclr/vm/assembly.cpp @@ -1156,7 +1156,11 @@ static void RunMainInternal(Param* pParam) StrArgArray = *pParam->stringArgs; pParam->pFD->EnsureActive(); - PCODE entryPoint = pParam->pFD->GetSingleCallableAddrOfCode(); + PCODE entryPoint; + { + GCX_PREEMP(); + entryPoint = pParam->pFD->GetSingleCallableAddrOfCode(); + } BOOL hasReturnValue = !pParam->pFD->IsVoid(); PTRARRAYREF* pArgument = (pParam->EntryType == EntryManagedMain) ? &StrArgArray : NULL; @@ -1701,7 +1705,8 @@ void Assembly::AddType( CONTRACTL { THROWS; - GC_TRIGGERS; + GC_NOTRIGGER; + MODE_PREEMPTIVE; INJECT_FAULT(COMPlusThrowOM();); } CONTRACTL_END @@ -1727,7 +1732,8 @@ void Assembly::AddExportedType(mdExportedType cl) CONTRACTL { THROWS; - GC_TRIGGERS; + GC_NOTRIGGER; + MODE_PREEMPTIVE; INJECT_FAULT(COMPlusThrowOM();); } CONTRACTL_END @@ -1991,6 +1997,7 @@ void Assembly::SetError(Exception *ex) SetProfilerNotified(); #ifdef PROFILING_SUPPORTED + GCX_PREEMP(); // Only send errors for non-shared assemblies; other assemblies might be successfully completed // in another app domain later. m_pModule->NotifyProfilerLoadFinished(ex->GetHR()); diff --git a/src/coreclr/vm/assemblynative.cpp b/src/coreclr/vm/assemblynative.cpp index 97ee4dfc6dfbab..f0fe61dcac9a38 100644 --- a/src/coreclr/vm/assemblynative.cpp +++ b/src/coreclr/vm/assemblynative.cpp @@ -1408,7 +1408,6 @@ extern "C" void QCALLTYPE AssemblyNative_ApplyUpdate( _ASSERTE(ilDeltaLength > 0); #ifdef FEATURE_METADATA_UPDATER - GCX_COOP(); { if (CORDebuggerAttached()) { diff --git a/src/coreclr/vm/callhelpers.cpp b/src/coreclr/vm/callhelpers.cpp index 2568a1483d5714..b2160b1ac6bfd3 100644 --- a/src/coreclr/vm/callhelpers.cpp +++ b/src/coreclr/vm/callhelpers.cpp @@ -559,11 +559,17 @@ void CallDefaultConstructor(OBJECTREF ref) GCPROTECT_BEGIN (ref); - MethodDesc *pMD = pMT->GetDefaultConstructor(); + + PCODE methodEntry; + { + GCX_PREEMP(); + MethodDesc *pMD = pMT->GetDefaultConstructor(); + methodEntry = pMD->GetSingleCallableAddrOfCode(); + } UnmanagedCallersOnlyCaller defaultCtorInvoker{METHOD__RUNTIME_HELPERS__CALL_DEFAULT_CONSTRUCTOR}; - defaultCtorInvoker.InvokeThrowing(&ref, pMD->GetSingleCallableAddrOfCode()); + defaultCtorInvoker.InvokeThrowing(&ref, methodEntry); GCPROTECT_END (); } diff --git a/src/coreclr/vm/callhelpers.h b/src/coreclr/vm/callhelpers.h index a91f65078c271c..b5b19b89d61a33 100644 --- a/src/coreclr/vm/callhelpers.h +++ b/src/coreclr/vm/callhelpers.h @@ -104,103 +104,17 @@ class MethodDescCallSite } #endif // _DEBUG - void DefaultInit(OBJECTREF* porProtectedThis) - { - CONTRACTL - { - MODE_ANY; - GC_TRIGGERS; - THROWS; - } - CONTRACTL_END; - -#ifdef _DEBUG - // - // Make sure we are passing in a 'this' if and only if it is required - // - if (m_pMD->IsVtableMethod()) - { - CONSISTENCY_CHECK_MSG(NULL != porProtectedThis, "You did not pass in the 'this' object for a vtable method"); - } - else - { - if (NULL != porProtectedThis) - { - if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_AssertOnUnneededThis)) - { - CONSISTENCY_CHECK_MSG(NULL == porProtectedThis, "You passed in a 'this' object to a non-vtable method."); - } - else - { - LogWeakAssert(); - } - - } - } -#endif // _DEBUG - - m_pCallTarget = m_pMD->GetCallTarget(porProtectedThis); - - m_argIt.ForceSigWalk(); - } - - void DefaultInit(TypeHandle th) - { - CONTRACTL - { - MODE_ANY; - GC_TRIGGERS; - THROWS; - } - CONTRACTL_END; - - m_pCallTarget = m_pMD->GetCallTarget(NULL, th); - - m_argIt.ForceSigWalk(); -} - void CallTargetWorker(const ARG_SLOT *pArguments, ARG_SLOT *pReturnValue, int cbReturnValue); public: - // Used to avoid touching metadata for CoreLib methods. - // instance methods must pass in the 'this' object - // static methods must pass null - MethodDescCallSite(BinderMethodID id, OBJECTREF* porProtectedThis = NULL) : - m_pMD( - CoreLibBinder::GetMethod(id) - ), - m_methodSig(id), - m_argIt(&m_methodSig) - { - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - DefaultInit(porProtectedThis); - } - - // Used to avoid touching metadata for CoreLib methods. - // instance methods must pass in the 'this' object - // static methods must pass null - MethodDescCallSite(BinderMethodID id, OBJECTHANDLE hThis) : - m_pMD( - CoreLibBinder::GetMethod(id) - ), - m_methodSig(id), - m_argIt(&m_methodSig) - { - WRAPPER_NO_CONTRACT; - - DefaultInit((OBJECTREF*)hThis); - } - - // instance methods must pass in the 'this' object - // static methods must pass null - MethodDescCallSite(MethodDesc* pMD, OBJECTREF* porProtectedThis = NULL) : + // + // Only use this constructor if you're certain you know where + // you're going and it cannot be affected by generics/virtual + // dispatch/etc.. + // + MethodDescCallSite(MethodDesc* pMD, PCODE pCallTarget) : m_pMD(pMD), + m_pCallTarget(pCallTarget), m_methodSig(pMD), m_argIt(&m_methodSig) { @@ -208,72 +122,13 @@ class MethodDescCallSite { THROWS; GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - if (porProtectedThis == NULL) - { - // We don't have a "this" pointer - ensure that we have activated the containing module - m_pMD->EnsureActive(); - } - - DefaultInit(porProtectedThis); - } - - // instance methods must pass in the 'this' object - // static methods must pass null - MethodDescCallSite(MethodDesc* pMD, OBJECTHANDLE hThis) : - m_pMD(pMD), - m_methodSig(pMD), - m_argIt(&m_methodSig) - { - WRAPPER_NO_CONTRACT; - - if (hThis == NULL) - { - // We don't have a "this" pointer - ensure that we have activated the containing module - m_pMD->EnsureActive(); - } - - DefaultInit((OBJECTREF*)hThis); - } - - // instance methods must pass in the 'this' object - // static methods must pass null - MethodDescCallSite(MethodDesc* pMD, LPHARDCODEDMETASIG pwzSignature, OBJECTREF* porProtectedThis = NULL) : - m_pMD(pMD), - m_methodSig(pwzSignature), - m_argIt(&m_methodSig) - { - WRAPPER_NO_CONTRACT; - - if (porProtectedThis == NULL) - { - // We don't have a "this" pointer - ensure that we have activated the containing module - m_pMD->EnsureActive(); - } - - DefaultInit(porProtectedThis); - } - - MethodDescCallSite(MethodDesc* pMD, TypeHandle th) : - m_pMD(pMD), - m_methodSig(pMD, th), - m_argIt(&m_methodSig) - { - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; + MODE_ANY; } CONTRACTL_END; - // We don't have a "this" pointer - ensure that we have activated the containing module m_pMD->EnsureActive(); - DefaultInit(th); + m_argIt.ForceSigWalk(); } // @@ -281,10 +136,10 @@ class MethodDescCallSite // you're going and it cannot be affected by generics/virtual // dispatch/etc.. // - MethodDescCallSite(MethodDesc* pMD, PCODE pCallTarget) : + MethodDescCallSite(MethodDesc* pMD, PCODE pCallTarget, TypeHandle th) : m_pMD(pMD), m_pCallTarget(pCallTarget), - m_methodSig(pMD), + m_methodSig(pMD, th), m_argIt(&m_methodSig) { CONTRACTL diff --git a/src/coreclr/vm/ceeload.cpp b/src/coreclr/vm/ceeload.cpp index 76655714601019..83348a5040a495 100644 --- a/src/coreclr/vm/ceeload.cpp +++ b/src/coreclr/vm/ceeload.cpp @@ -214,8 +214,9 @@ void Module::UpdateNewlyAddedTypes() { CONTRACTL { + MODE_PREEMPTIVE; THROWS; - GC_TRIGGERS; + GC_NOTRIGGER; INJECT_FAULT(COMPlusThrowOM();); } CONTRACTL_END @@ -278,7 +279,7 @@ void Module::NotifyProfilerLoadFinished(HRESULT hr) THROWS; GC_TRIGGERS; INJECT_FAULT(COMPlusThrowOM()); - MODE_ANY; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -296,7 +297,6 @@ void Module::NotifyProfilerLoadFinished(HRESULT hr) { BEGIN_PROFILER_CALLBACK(CORProfilerTrackModuleLoads()); { - GCX_PREEMP(); (&g_profControlBlock)->ModuleLoadFinished((ModuleID) this, hr); if (SUCCEEDED(hr)) @@ -640,8 +640,8 @@ void Module::ApplyMetaData() CONTRACTL { THROWS; - GC_TRIGGERS; - MODE_ANY; + GC_NOTRIGGER; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -957,7 +957,7 @@ void Module::SetDynamicRvaField(mdToken token, TADDR blobAddress) { THROWS; GC_NOTRIGGER; - MODE_COOPERATIVE; + MODE_PREEMPTIVE; } CONTRACTL_END; diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp index d9ab0c0c0d5326..96e850b9943279 100644 --- a/src/coreclr/vm/ceemain.cpp +++ b/src/coreclr/vm/ceemain.cpp @@ -194,9 +194,7 @@ #include "profilinghelper.h" #endif // PROFILING_SUPPORTED -#ifdef FEATURE_PERFMAP #include "perfmap.h" -#endif #include "diagnosticserveradapter.h" #include "eventpipeadapter.h" diff --git a/src/coreclr/vm/class.cpp b/src/coreclr/vm/class.cpp index 551c456691954b..66956a029feb41 100644 --- a/src/coreclr/vm/class.cpp +++ b/src/coreclr/vm/class.cpp @@ -322,7 +322,7 @@ HRESULT EEClass::AddField(MethodTable* pMT, mdFieldDef fieldDef, FieldDesc** ppN { THROWS; GC_NOTRIGGER; - MODE_COOPERATIVE; + MODE_PREEMPTIVE; PRECONDITION(pMT != NULL); PRECONDITION(ppNewFD != NULL); } @@ -442,7 +442,7 @@ HRESULT EEClass::AddFieldDesc( { THROWS; GC_NOTRIGGER; - MODE_COOPERATIVE; + MODE_PREEMPTIVE; PRECONDITION(pMT != NULL); PRECONDITION(ppNewFD != NULL); } @@ -508,7 +508,7 @@ HRESULT EEClass::AddMethod(MethodTable* pMT, mdMethodDef methodDef, MethodDesc** { THROWS; GC_NOTRIGGER; - MODE_COOPERATIVE; + MODE_PREEMPTIVE; PRECONDITION(pMT != NULL); PRECONDITION(methodDef != mdTokenNil); } @@ -776,7 +776,7 @@ HRESULT EEClass::AddMethodDesc( { THROWS; GC_NOTRIGGER; - MODE_COOPERATIVE; + MODE_PREEMPTIVE; PRECONDITION(pMT != NULL); PRECONDITION(methodDef != mdTokenNil); PRECONDITION(ppNewMD != NULL); @@ -1709,6 +1709,7 @@ void TypeHandle::NotifyDebuggerUnload() const MethodDesc* MethodTable::GetBoxedEntryPointMD(MethodDesc *pMD) { CONTRACT (MethodDesc *) { + MODE_PREEMPTIVE; THROWS; GC_TRIGGERS; INJECT_FAULT(COMPlusThrowOM();); @@ -1732,6 +1733,7 @@ MethodDesc* MethodTable::GetBoxedEntryPointMD(MethodDesc *pMD) MethodDesc* MethodTable::GetUnboxedEntryPointMD(MethodDesc *pMD) { CONTRACT (MethodDesc *) { + MODE_PREEMPTIVE; THROWS; GC_TRIGGERS; INJECT_FAULT(COMPlusThrowOM();); diff --git a/src/coreclr/vm/classhash.cpp b/src/coreclr/vm/classhash.cpp index 10c73eeff8570a..7c361f8d39c6b7 100644 --- a/src/coreclr/vm/classhash.cpp +++ b/src/coreclr/vm/classhash.cpp @@ -73,8 +73,8 @@ EEClassHashTable *EEClassHashTable::Create(Module *pModule, DWORD dwNumBuckets, CONTRACTL { THROWS; - GC_TRIGGERS; - MODE_ANY; + GC_NOTRIGGER; + MODE_PREEMPTIVE; INJECT_FAULT(COMPlusThrowOM();); PRECONDITION(!FORBIDGC_LOADER_USE_ENABLED()); @@ -676,7 +676,7 @@ BOOL EEClassHashTable::IsNested(ModuleBase *pModule, mdToken token, mdToken *mdE CONTRACTL { if (FORBIDGC_LOADER_USE_ENABLED()) NOTHROW; else THROWS; - if (FORBIDGC_LOADER_USE_ENABLED()) GC_NOTRIGGER; else GC_TRIGGERS; + GC_NOTRIGGER; if (FORBIDGC_LOADER_USE_ENABLED()) FORBID_FAULT; else { INJECT_FAULT(COMPlusThrowOM()); } MODE_ANY; SUPPORTS_DAC; @@ -714,7 +714,7 @@ BOOL EEClassHashTable::IsNested(const NameHandle* pName, mdToken *mdEncloser) CONTRACTL { if (FORBIDGC_LOADER_USE_ENABLED()) NOTHROW; else THROWS; - if (FORBIDGC_LOADER_USE_ENABLED()) GC_NOTRIGGER; else GC_TRIGGERS; + GC_NOTRIGGER; if (FORBIDGC_LOADER_USE_ENABLED()) FORBID_FAULT; else { INJECT_FAULT(COMPlusThrowOM()); } MODE_ANY; SUPPORTS_DAC; diff --git a/src/coreclr/vm/clsload.cpp b/src/coreclr/vm/clsload.cpp index ba86d440ecb2fc..fa7c2442a9cb95 100644 --- a/src/coreclr/vm/clsload.cpp +++ b/src/coreclr/vm/clsload.cpp @@ -584,8 +584,8 @@ VOID ClassLoader::PopulateAvailableClassHashTable(Module* pModule, { INSTANCE_CHECK; THROWS; - GC_TRIGGERS; - MODE_ANY; + GC_NOTRIGGER; + MODE_PREEMPTIVE; INJECT_FAULT(COMPlusThrowOM();); } CONTRACTL_END; @@ -638,8 +638,8 @@ void ClassLoader::LazyPopulateCaseSensitiveHashTablesDontHaveLock() { INSTANCE_CHECK; THROWS; - GC_TRIGGERS; - MODE_ANY; + GC_NOTRIGGER; + MODE_PREEMPTIVE; INJECT_FAULT(COMPlusThrowOM()); } CONTRACTL_END; @@ -655,8 +655,8 @@ void ClassLoader::LazyPopulateCaseSensitiveHashTables() { INSTANCE_CHECK; THROWS; - GC_TRIGGERS; - MODE_ANY; + GC_NOTRIGGER; + MODE_PREEMPTIVE; INJECT_FAULT(COMPlusThrowOM()); } CONTRACTL_END; @@ -3455,8 +3455,8 @@ VOID ClassLoader::AddAvailableClassDontHaveLock(Module *pModule, { INSTANCE_CHECK; THROWS; - GC_TRIGGERS; - MODE_ANY; + GC_NOTRIGGER; + MODE_PREEMPTIVE; INJECT_FAULT(COMPlusThrowOM();); } CONTRACTL_END @@ -3490,8 +3490,8 @@ VOID ClassLoader::AddAvailableClassHaveLock( { INSTANCE_CHECK; THROWS; - GC_TRIGGERS; - MODE_ANY; + GC_NOTRIGGER; + MODE_PREEMPTIVE; INJECT_FAULT(COMPlusThrowOM();); } CONTRACTL_END @@ -3564,8 +3564,8 @@ VOID ClassLoader::AddExportedTypeDontHaveLock(Module *pManifestModule, { INSTANCE_CHECK; THROWS; - GC_TRIGGERS; - MODE_ANY; + GC_NOTRIGGER; + MODE_PREEMPTIVE; INJECT_FAULT(COMPlusThrowOM();); } CONTRACTL_END @@ -3589,8 +3589,8 @@ VOID ClassLoader::AddExportedTypeHaveLock(Module *pManifestModule, { INSTANCE_CHECK; THROWS; - GC_TRIGGERS; - MODE_ANY; + GC_NOTRIGGER; + MODE_PREEMPTIVE; INJECT_FAULT(COMPlusThrowOM();); } CONTRACTL_END diff --git a/src/coreclr/vm/codeman.cpp b/src/coreclr/vm/codeman.cpp index d3a640139b1a2e..e5deacd24049e3 100644 --- a/src/coreclr/vm/codeman.cpp +++ b/src/coreclr/vm/codeman.cpp @@ -41,9 +41,7 @@ #include "../debug/daccess/fntableaccess.h" #endif // HOST_64BIT -#ifdef FEATURE_PERFMAP #include "perfmap.h" -#endif // Default number of jump stubs in a jump stub block #define DEFAULT_JUMPSTUBS_PER_BLOCK 32 @@ -6296,7 +6294,7 @@ PCODE ExecutionManager::jumpStub(MethodDesc* pMD, PCODE target, CONTRACT(PCODE) { THROWS; GC_NOTRIGGER; - MODE_ANY; + MODE_PREEMPTIVE; PRECONDITION(pLoaderAllocator != NULL || pMD != NULL); PRECONDITION(loAddr < hiAddr); POSTCONDITION((RETVAL != NULL) || !throwOnOutOfMemoryWithinRange); @@ -6384,6 +6382,7 @@ PCODE ExecutionManager::getNextJumpStub(MethodDesc* pMD, PCODE target, bool throwOnOutOfMemoryWithinRange) { CONTRACT(PCODE) { + MODE_PREEMPTIVE; THROWS; GC_NOTRIGGER; PRECONDITION(pLoaderAllocator != NULL); @@ -6491,9 +6490,7 @@ PCODE ExecutionManager::getNextJumpStub(MethodDesc* pMD, PCODE target, emitBackToBackJump(jumpStub, jumpStubRW, (void*) target); -#ifdef FEATURE_PERFMAP PerfMap::LogStubs(__FUNCTION__, "emitBackToBackJump", (PCODE)jumpStub, BACK_TO_BACK_JUMP_ALLOCATE_SIZE, PerfMapStubType::IndividualWithinBlock); -#endif // We always add the new jumpstub to the jumpStubCache // diff --git a/src/coreclr/vm/codeman.h b/src/coreclr/vm/codeman.h index 371174c434a9a8..03c82e7280323f 100644 --- a/src/coreclr/vm/codeman.h +++ b/src/coreclr/vm/codeman.h @@ -152,6 +152,12 @@ void ReportStubBlock(void* start, size_t size, StubCodeBlockKind kind); #ifndef FEATURE_PERFMAP inline void ReportStubBlock(void* start, size_t size, StubCodeBlockKind kind) { + CONTRACTL + { + GC_NOTRIGGER; + MODE_PREEMPTIVE; + } + CONTRACTL_END; } #endif diff --git a/src/coreclr/vm/comcallablewrapper.cpp b/src/coreclr/vm/comcallablewrapper.cpp index 6644cc43039567..b7afdcd66cad64 100644 --- a/src/coreclr/vm/comcallablewrapper.cpp +++ b/src/coreclr/vm/comcallablewrapper.cpp @@ -2836,7 +2836,7 @@ namespace { THROWS; GC_NOTRIGGER; - MODE_ANY; + MODE_PREEMPTIVE; INJECT_FAULT(COMPlusThrowOM()); } CONTRACTL_END; diff --git a/src/coreclr/vm/comconnectionpoints.cpp b/src/coreclr/vm/comconnectionpoints.cpp index f4c60e20ea451e..09e2cef87c7196 100644 --- a/src/coreclr/vm/comconnectionpoints.cpp +++ b/src/coreclr/vm/comconnectionpoints.cpp @@ -556,14 +556,24 @@ void ConnectionPoint::InvokeProviderMethod( OBJECTREF pProvider, OBJECTREF pSubs { UnmanagedCallersOnlyCaller invokeConnectionPointProviderMethod(METHOD__STUBHELPERS__INVOKE_CONNECTION_POINT_PROVIDER_METHOD); + PCODE pProvCode; + PCODE pDlgCtorCode; + PCODE pEventMethodCode; + { + GCX_PREEMP(); + pProvCode = pProvMethodDesc->GetSingleCallableAddrOfCode(); + pDlgCtorCode = pDlgCtorMD->GetSingleCallableAddrOfCode(); + pEventMethodCode = pEventMethodDesc->GetMultiCallableAddrOfCode(); + } + // Using GetMultiCallableAddrOfCode() for the event target since it is stored for future invokes. invokeConnectionPointProviderMethod.InvokeThrowing( &pProvider, - pProvMethodDesc->GetSingleCallableAddrOfCode(), + pProvCode, &pDelegate, - pDlgCtorMD->GetSingleCallableAddrOfCode(), + pDlgCtorCode, &pSubscriber, - pEventMethodDesc->GetMultiCallableAddrOfCode()); + pEventMethodCode); } GCPROTECT_END(); } diff --git a/src/coreclr/vm/comdelegate.cpp b/src/coreclr/vm/comdelegate.cpp index ec6d9f4277c91e..3c95b80d1ee633 100644 --- a/src/coreclr/vm/comdelegate.cpp +++ b/src/coreclr/vm/comdelegate.cpp @@ -964,7 +964,7 @@ static PCODE GetVirtualCallStub(MethodDesc *method, TypeHandle scopeType) { THROWS; GC_TRIGGERS; - MODE_ANY; + MODE_PREEMPTIVE; INJECT_FAULT(COMPlusThrowOM()); // from MetaSig::SizeOfArgStack } CONTRACTL_END; @@ -987,8 +987,8 @@ static PCODE GetVirtualCallStub(MethodDesc *method, TypeHandle scopeType) ); } -extern "C" BOOL QCALLTYPE Delegate_BindToMethodName(QCall::ObjectHandleOnStack d, QCall::ObjectHandleOnStack target, - QCall::TypeHandle pMethodType, LPCUTF8 pszMethodName, DelegateBindingFlags flags) +extern "C" BOOL QCALLTYPE Delegate_BindToMethodName(MethodTable* pDelegateMT, MethodTable *pTargetMT, + QCall::TypeHandle pMethodType, LPCUTF8 pszMethodName, DelegateBindingFlags flags, QCall::ObjectHandleOnStack targetParameter, BindToMethodDetails *pBindToMethodDetails) { QCALL_CONTRACT; @@ -996,25 +996,11 @@ extern "C" BOOL QCALLTYPE Delegate_BindToMethodName(QCall::ObjectHandleOnStack d BEGIN_QCALL; - GCX_COOP(); - - struct - { - DELEGATEREF refThis; - OBJECTREF target; - } gc; - - gc.refThis = (DELEGATEREF) d.Get(); - gc.target = target.Get(); - - GCPROTECT_BEGIN(gc); TypeHandle methodType = pMethodType.AsTypeHandle(); - TypeHandle targetType((gc.target != NULL) ? gc.target->GetMethodTable() : NULL); // get the invoke of the delegate - MethodTable * pDelegateType = gc.refThis->GetMethodTable(); - MethodDesc* pInvokeMeth = COMDelegate::FindDelegateInvokeMethod(pDelegateType); + MethodDesc* pInvokeMeth = COMDelegate::FindDelegateInvokeMethod(pDelegateMT); _ASSERTE(pInvokeMeth); // @@ -1070,10 +1056,10 @@ extern "C" BOOL QCALLTYPE Delegate_BindToMethodName(QCall::ObjectHandleOnStack d false /* do not allow code with a shared-code calling convention to be returned */, true /* Ensure that methods on generic interfaces are returned as instantiated method descs */); bool fIsOpenDelegate; - if (!COMDelegate::IsMethodDescCompatible((gc.target == NULL) ? TypeHandle() : gc.target->GetTypeHandle(), + if (!COMDelegate::IsMethodDescCompatible(TypeHandle(pTargetMT), methodType, pCurMethod, - gc.refThis->GetTypeHandle(), + TypeHandle(pDelegateMT), pInvokeMeth, flags, &fIsOpenDelegate)) @@ -1084,11 +1070,13 @@ extern "C" BOOL QCALLTYPE Delegate_BindToMethodName(QCall::ObjectHandleOnStack d // Found the target that matches the signature and satisfies security transparency rules // Initialize the delegate to point to the target method. - COMDelegate::BindToMethod(&gc.refThis, - &gc.target, - pCurMethod, - methodType.GetMethodTable(), - fIsOpenDelegate); + COMDelegate::BindToMethod(pDelegateMT, + pTargetMT, + pCurMethod, + methodType.GetMethodTable(), + fIsOpenDelegate, + targetParameter, + pBindToMethodDetails); pMatchingMethod = pCurMethod; goto done; @@ -1098,15 +1086,14 @@ extern "C" BOOL QCALLTYPE Delegate_BindToMethodName(QCall::ObjectHandleOnStack d done: ; - GCPROTECT_END(); END_QCALL; return (pMatchingMethod != NULL); } -extern "C" BOOL QCALLTYPE Delegate_BindToMethodInfo(QCall::ObjectHandleOnStack d, QCall::ObjectHandleOnStack target, - MethodDesc * method, QCall::TypeHandle pMethodType, DelegateBindingFlags flags) +extern "C" BOOL QCALLTYPE Delegate_BindToMethodInfo(MethodTable* pDelegateMT, MethodTable *pTargetMT, + MethodDesc * method, QCall::TypeHandle pMethodType, DelegateBindingFlags flags, QCall::ObjectHandleOnStack targetParameter, BindToMethodDetails *pBindToMethodDetails) { QCALL_CONTRACT; @@ -1114,62 +1101,49 @@ extern "C" BOOL QCALLTYPE Delegate_BindToMethodInfo(QCall::ObjectHandleOnStack d BEGIN_QCALL; - GCX_COOP(); - - struct - { - DELEGATEREF refThis; - OBJECTREF refFirstArg; - } gc; - - gc.refThis = (DELEGATEREF) d.Get(); - gc.refFirstArg = target.Get(); - - GCPROTECT_BEGIN(gc); - MethodTable *pMethMT = pMethodType.AsTypeHandle().GetMethodTable(); - // Assert to track down VS#458689. - _ASSERTE(gc.refThis != gc.refFirstArg); - // A generic method had better be instantiated (we can't dispatch to an uninstantiated one). if (method->IsGenericMethodDefinition()) COMPlusThrow(kArgumentException, W("Arg_DlgtTargMeth")); // get the invoke of the delegate - MethodTable * pDelegateType = gc.refThis->GetMethodTable(); - MethodDesc* pInvokeMeth = COMDelegate::FindDelegateInvokeMethod(pDelegateType); + MethodDesc* pInvokeMeth = COMDelegate::FindDelegateInvokeMethod(pDelegateMT); _ASSERTE(pInvokeMeth); // See the comment in BindToMethodName - method = - MethodDesc::FindOrCreateAssociatedMethodDesc(method, - pMethMT, - (!method->IsStatic() && pMethMT->IsValueType()), - method->GetMethodInstantiation(), - false /* do not allow code with a shared-code calling convention to be returned */, - true /* Ensure that methods on generic interfaces are returned as instantiated method descs */); - bool fIsOpenDelegate; - if (COMDelegate::IsMethodDescCompatible((gc.refFirstArg == NULL) ? TypeHandle() : gc.refFirstArg->GetTypeHandle(), + + method = MethodDesc::FindOrCreateAssociatedMethodDesc(method, + pMethMT, + (!method->IsStatic() && pMethMT->IsValueType()), + method->GetMethodInstantiation(), + false /* do not allow code with a shared-code calling convention to be returned */, + true /* Ensure that methods on generic interfaces are returned as instantiated method descs */); + + if (COMDelegate::IsMethodDescCompatible(TypeHandle(pTargetMT), TypeHandle(pMethMT), method, - gc.refThis->GetTypeHandle(), + TypeHandle(pDelegateMT), pInvokeMeth, flags, &fIsOpenDelegate)) { // Initialize the delegate to point to the target method. - COMDelegate::BindToMethod(&gc.refThis, - &gc.refFirstArg, + COMDelegate::BindToMethod(pDelegateMT, + pTargetMT, method, pMethMT, - fIsOpenDelegate); + fIsOpenDelegate, + targetParameter, + pBindToMethodDetails); + + result = TRUE; } else + { result = FALSE; - - GCPROTECT_END(); + } END_QCALL; @@ -1179,19 +1153,20 @@ extern "C" BOOL QCALLTYPE Delegate_BindToMethodInfo(QCall::ObjectHandleOnStack d // This method is called (in the late bound case only) once a target method has been decided on. All the consistency checks // (signature matching etc.) have been done at this point, this method will simply initialize the delegate, with any required // wrapping. The delegate returned will be ready for invocation immediately. -void COMDelegate::BindToMethod(DELEGATEREF *pRefThis, - OBJECTREF *pRefFirstArg, +void COMDelegate::BindToMethod(MethodTable* pDelegateMT, + MethodTable *pTargetMT, MethodDesc *pTargetMethod, MethodTable *pExactMethodType, - BOOL fIsOpenDelegate) + BOOL fIsOpenDelegate, + QCall::ObjectHandleOnStack targetParameter, + BindToMethodDetails *pBindToMethodDetails) { CONTRACTL { THROWS; GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(CheckPointer(pRefThis)); - PRECONDITION(CheckPointer(pRefFirstArg, NULL_OK)); + MODE_PREEMPTIVE; + PRECONDITION(CheckPointer(pDelegateMT)); PRECONDITION(CheckPointer(pTargetMethod)); PRECONDITION(CheckPointer(pExactMethodType)); } @@ -1201,19 +1176,16 @@ void COMDelegate::BindToMethod(DELEGATEREF *pRefThis, if (fIsOpenDelegate) { - _ASSERTE(pRefFirstArg == NULL || *pRefFirstArg == NULL); - // Open delegates use themselves as the target (which handily allows their shuffle thunks to locate additional data at // invocation time). - (*pRefThis)->SetTarget(*pRefThis); + pBindToMethodDetails->selfReferentialTarget = TRUE; // We need to shuffle arguments for open delegates since the first argument on the calling side is not meaningful to the // callee. - MethodTable * pDelegateMT = (*pRefThis)->GetMethodTable(); PCODE pEntryPoint = SetupShuffleThunk(pDelegateMT, pTargetMethod); // Indicate that the delegate will jump to the shuffle thunk rather than directly to the target method. - (*pRefThis)->SetMethodPtr(pEntryPoint); + pBindToMethodDetails->methodPtr = pEntryPoint; // Use stub dispatch for all virtuals. // Investigate not using this for non-interface virtuals. @@ -1226,9 +1198,8 @@ void COMDelegate::BindToMethod(DELEGATEREF *pRefThis, // Since this is an open delegate over a virtual method we cannot virtualize the call target now. So the shuffle thunk // needs to jump to another stub (this time provided by the VirtualStubManager) that will virtualize the call at // runtime. - PCODE pTargetCall = GetVirtualCallStub(pTargetMethod, TypeHandle(pExactMethodType)); - (*pRefThis)->SetMethodPtrAux(pTargetCall); - (*pRefThis)->SetInvocationCount((INT_PTR)(void *)pTargetMethod); + pBindToMethodDetails->methodPtrAux = GetVirtualCallStub(pTargetMethod, TypeHandle(pExactMethodType)); + pBindToMethodDetails->invocationCount = (INT_PTR)(void *)pTargetMethod; } else { @@ -1252,12 +1223,12 @@ void COMDelegate::BindToMethod(DELEGATEREF *pRefThis, // Note that it is important to cache pTargetCode in local variable to avoid GC hole. // GetMultiCallableAddrOfCode() can trigger GC. - PCODE pTargetCode = pTargetMethod->GetMultiCallableAddrOfCode(); - (*pRefThis)->SetMethodPtrAux(pTargetCode); + pBindToMethodDetails->methodPtrAux = pTargetMethod->GetMultiCallableAddrOfCode(); } } else { + pBindToMethodDetails->selfReferentialTarget = FALSE; PCODE pTargetCode = (PCODE)NULL; // For virtual methods we can (and should) virtualize the call now (so we don't have to insert a thunk to do so at runtime). @@ -1267,10 +1238,11 @@ void COMDelegate::BindToMethod(DELEGATEREF *pRefThis, // virtualize since we're just going to throw NullRefException at invocation time). // if (pTargetMethod->IsVirtual() - && *pRefFirstArg != NULL - && pTargetMethod->GetMethodTable() != (*pRefFirstArg)->GetMethodTable()) + && pTargetMT != NULL + && pTargetMethod->GetMethodTable() != pTargetMT) { - pTargetCode = pTargetMethod->GetMultiCallableAddrOfVirtualizedCode(pRefFirstArg, pTargetMethod->GetMethodTable()); + // Casting Object** to OBJECTREF* is safe as long as no code attempts to mutate the OBJECTREF through the OBJECTREF* (and we don't, we only use it to read the this pointer/target object) + pTargetCode = pTargetMethod->GetMultiCallableAddrOfVirtualizedCode((OBJECTREF*)targetParameter.GetObjectPointer(), pTargetMT, pTargetMethod->GetMethodTable()); } #ifdef HAS_THISPTR_RETBUF_PRECODE else if (pTargetMethod->IsStatic() && pTargetMethod->HasRetBuffArg() && IsRetBuffPassedAsFirstArg()) @@ -1283,15 +1255,13 @@ void COMDelegate::BindToMethod(DELEGATEREF *pRefThis, pTargetCode = pTargetMethod->GetMultiCallableAddrOfCode(); } _ASSERTE(pTargetCode); - - (*pRefThis)->SetTarget(*pRefFirstArg); - (*pRefThis)->SetMethodPtr(pTargetCode); + pBindToMethodDetails->methodPtr = pTargetCode; } LoaderAllocator *pLoaderAllocator = pTargetMethod->GetLoaderAllocator(); - if (pLoaderAllocator->IsCollectible()) - (*pRefThis)->SetHelperObject(pLoaderAllocator->GetExposedObject()); + // If the loader allocator is not collectible, this will be NULL + pBindToMethodDetails->loaderAllocatorGCHandle = pLoaderAllocator->GetLoaderAllocatorObjectHandle(); } // Marshals a delegate to a unmanaged callback. @@ -1338,6 +1308,7 @@ LPVOID COMDelegate::ConvertToCallback(OBJECTREF pDelegateObj) InteropSyncBlockInfo* pInteropInfo = pSyncBlock->GetInteropInfo(); + GCX_PREEMP(); pUMEntryThunk = pInteropInfo->GetUMEntryThunk(); if (!pUMEntryThunk) @@ -1347,8 +1318,6 @@ LPVOID COMDelegate::ConvertToCallback(OBJECTREF pDelegateObj) if (!pUMThunkMarshInfo) { - GCX_PREEMP(); - pUMThunkMarshInfo = (UMThunkMarshInfo*)(void*)pMT->GetLoaderAllocator()->GetLowFrequencyHeap()->AllocMem(S_SIZE_T(sizeof(DelegateUMThunkMarshInfo))); new (pUMThunkMarshInfo) DelegateUMThunkMarshInfo(pInvokeMeth); @@ -1365,15 +1334,22 @@ LPVOID COMDelegate::ConvertToCallback(OBJECTREF pDelegateObj) _ASSERTE(pUMThunkMarshInfo == pClass->m_pUMThunkMarshInfo); pUMEntryThunk = UMEntryThunkData::CreateUMEntryThunk(); + Holder umHolder; umHolder.Assign(pUMEntryThunk); - // multicast. go thru Invoke - OBJECTHANDLE objhnd = GetAppDomain()->CreateLongWeakHandle(pDelegate); - _ASSERTE(objhnd != NULL); + OBJECTHANDLE objhnd; + PCODE pManagedTargetForDiagnostics; + { + GCX_COOP(); + + // multicast. go thru Invoke + objhnd = GetAppDomain()->CreateLongWeakHandle(pDelegate); + _ASSERTE(objhnd != NULL); - // This target should not ever be used. We are storing it in the thunk for better diagnostics of "call on collected delegate" crashes. - PCODE pManagedTargetForDiagnostics = (pDelegate->GetMethodPtrAux() != (PCODE)NULL) ? pDelegate->GetMethodPtrAux() : pDelegate->GetMethodPtr(); + // This target should not ever be used. We are storing it in the thunk for better diagnostics of "call on collected delegate" crashes. + pManagedTargetForDiagnostics = (pDelegate->GetMethodPtrAux() != (PCODE)NULL) ? pDelegate->GetMethodPtrAux() : pDelegate->GetMethodPtr(); + } // MethodDesc is passed in for profiling to know the method desc of target pUMEntryThunk->LoadTimeInit( @@ -1573,13 +1549,13 @@ extern "C" void QCALLTYPE Delegate_InitializeVirtualCallStub(QCall::ObjectHandle BEGIN_QCALL; - GCX_COOP(); - MethodDesc *pMeth = NonVirtualEntry2MethodDesc((PCODE)method); _ASSERTE(pMeth); _ASSERTE(!pMeth->IsStatic() && pMeth->IsVirtual()); PCODE target = GetVirtualCallStub(pMeth, TypeHandle(pMeth->GetMethodTable())); + GCX_COOP(); + DELEGATEREF refThis = (DELEGATEREF)d.Get(); refThis->SetMethodPtrAux(target); refThis->SetInvocationCount((INT_PTR)(void*)pMeth); @@ -1587,18 +1563,12 @@ extern "C" void QCALLTYPE Delegate_InitializeVirtualCallStub(QCall::ObjectHandle END_QCALL; } -extern "C" PCODE QCALLTYPE Delegate_AdjustTarget(QCall::ObjectHandleOnStack target, PCODE method) +extern "C" PCODE QCALLTYPE Delegate_AdjustTarget(MethodTable* pMTTarg, PCODE method) { QCALL_CONTRACT; BEGIN_QCALL; - GCX_COOP(); - - _ASSERTE(method); - - MethodTable* pMTTarg = target.Get()->GetMethodTable(); - MethodDesc *pMeth = NonVirtualEntry2MethodDesc(method); _ASSERTE(pMeth); _ASSERTE(!pMeth->IsStatic()); @@ -1651,7 +1621,7 @@ uint32_t MethodDescToNumFixedArgs(MethodDesc *pMD) // This is the single constructor for all Delegates. The compiler // doesn't provide an implementation of the Delegate constructor. We // provide that implementation through a QCall call to this method. -extern "C" void QCALLTYPE Delegate_Construct(QCall::ObjectHandleOnStack _this, QCall::ObjectHandleOnStack target, PCODE method) +extern "C" void QCALLTYPE Delegate_Construct(MethodTable* pDelegateMT, MethodTable* pTargetMT, PCODE method, BindToMethodDetails *pBindToMethodDetails) { QCALL_CONTRACT; @@ -1660,23 +1630,15 @@ extern "C" void QCALLTYPE Delegate_Construct(QCall::ObjectHandleOnStack _this, Q _ASSERTE(method != (PCODE)NULL); BEGIN_QCALL; - GCX_COOP(); - - DELEGATEREF refThis = (DELEGATEREF) ObjectToOBJECTREF(_this.Get()); - _ASSERTE(refThis != NULL); - - GCPROTECT_BEGIN(refThis); + _ASSERTE(pDelegateMT != NULL); // Programmers could feed garbage data to DelegateConstruct(). // It's difficult to validate a method code pointer, but at least we'll // try to catch the easy garbage. _ASSERTE(isMemoryReadable(method, 1)); - MethodTable* pMTTarg = NULL; - if (target.Get() != NULL) - pMTTarg = target.Get()->GetMethodTable(); - - MethodTable* pDelMT = refThis->GetMethodTable(); + MethodTable* pMTTarg = pTargetMT; + MethodTable* pDelMT = pDelegateMT; MethodDesc* pMethOrig = NonVirtualEntry2MethodDesc(method); MethodDesc* pMeth = pMethOrig; _ASSERTE(pMeth != NULL); @@ -1705,38 +1667,41 @@ extern "C" void QCALLTYPE Delegate_Construct(QCall::ObjectHandleOnStack _this, Q if (!isStatic) methodArgCount++; // count 'this' - if (pMeth->GetLoaderAllocator()->IsCollectible()) - refThis->SetHelperObject(pMeth->GetLoaderAllocator()->GetExposedObject()); + // If the loader allocator is not collectible, this will be NULL + pBindToMethodDetails->loaderAllocatorGCHandle = pMeth->GetLoaderAllocator()->GetLoaderAllocatorObjectHandle(); // Open delegates. if (invokeArgCount == methodArgCount) { - // set the target - refThis->SetTarget(refThis); + pBindToMethodDetails->selfReferentialTarget = TRUE; // set the shuffle thunk PCODE pEntryPoint = SetupShuffleThunk(pDelMT, pMeth); - refThis->SetMethodPtr(pEntryPoint); + pBindToMethodDetails->methodPtr = pEntryPoint; // set the ptr aux according to what is needed, if virtual need to call make virtual stub dispatch if (!pMeth->IsStatic() && pMeth->IsVirtual() && !pMeth->GetMethodTable()->IsValueType()) { - PCODE pTargetCall = GetVirtualCallStub(pMeth, TypeHandle(pMeth->GetMethodTable())); - refThis->SetMethodPtrAux(pTargetCall); - refThis->SetInvocationCount((INT_PTR)(void *)pMeth); + PCODE pTargetCall; + { + pTargetCall = GetVirtualCallStub(pMeth, TypeHandle(pMeth->GetMethodTable())); + } + pBindToMethodDetails->methodPtrAux = pTargetCall; + pBindToMethodDetails->invocationCount = (INT_PTR)(void *)pMeth; } else { - refThis->SetMethodPtrAux(method); + pBindToMethodDetails->methodPtrAux = method; } } else { + pBindToMethodDetails->selfReferentialTarget = FALSE; MethodTable* pMTMeth = pMeth->GetMethodTable(); if (!pMeth->IsStatic()) { - if (target.Get() == NULL) + if (pTargetMT == NULL) COMPlusThrow(kArgumentException, W("Arg_DlgtNullInst")); if (pMTTarg != NULL) @@ -1776,11 +1741,9 @@ extern "C" void QCALLTYPE Delegate_Construct(QCall::ObjectHandleOnStack _this, Q } #endif // HAS_THISPTR_RETBUF_PRECODE - refThis->SetTarget(target.Get()); - refThis->SetMethodPtr((PCODE)(void *)method); + pBindToMethodDetails->methodPtr = (PCODE)(void *)method; } - GCPROTECT_END(); END_QCALL; } @@ -1968,7 +1931,10 @@ extern "C" void QCALLTYPE Delegate_FindMethodHandle(QCall::ObjectHandleOnStack d GCX_COOP(); MethodDesc* pMD = COMDelegate::GetMethodDesc(d.Get()); - pMD = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMD, TypeHandle(pMD->GetMethodTable()), pMD->GetMethodInstantiation()); + { + GCX_PREEMP(); + pMD = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMD, TypeHandle(pMD->GetMethodTable()), pMD->GetMethodInstantiation()); + } retMethodInfo.Set(pMD->AllocateStubMethodInfo()); END_QCALL; diff --git a/src/coreclr/vm/comdelegate.h b/src/coreclr/vm/comdelegate.h index 03a84fabf9f6da..6aab9af5ca3361 100644 --- a/src/coreclr/vm/comdelegate.h +++ b/src/coreclr/vm/comdelegate.h @@ -26,6 +26,15 @@ enum class ShuffleComputationType }; BOOL GenerateShuffleArrayPortable(MethodDesc* pMethodSrc, MethodDesc *pMethodDst, SArray * pShuffleEntryArray, ShuffleComputationType shuffleType); +struct BindToMethodDetails +{ + BOOL selfReferentialTarget; // Whether the delegate's target object is the same as the first argument of the method to bind to. Only meaningful for open instance delegates. + PCODE methodPtr; + PCODE methodPtrAux; + INT_PTR invocationCount; + OBJECTHANDLE loaderAllocatorGCHandle; // The loader allocator needed if the delegate needs to keep it alive +}; + // This class represents the native methods for the Delegate class class COMDelegate { @@ -78,18 +87,20 @@ class COMDelegate bool *pfIsOpenDelegate); static MethodDesc* GetDelegateCtor(TypeHandle delegateType, MethodDesc *pTargetMethod, DelegateCtorArgs *pCtorData); - static void BindToMethod(DELEGATEREF *pRefThis, - OBJECTREF *pRefFirstArg, + static void BindToMethod(MethodTable* pDelegateMT, + MethodTable *pTargetMT, MethodDesc *pTargetMethod, MethodTable *pExactMethodType, - BOOL fIsOpenDelegate); + BOOL fIsOpenDelegate, + QCall::ObjectHandleOnStack targetParameter, + BindToMethodDetails *pBindToMethodDetails); }; -extern "C" void QCALLTYPE Delegate_Construct(QCall::ObjectHandleOnStack _this, QCall::ObjectHandleOnStack target, PCODE method); +extern "C" void QCALLTYPE Delegate_Construct(MethodTable* pDelegateMT, MethodTable* pTargetMT, PCODE method, BindToMethodDetails *pBindToMethodDetails); extern "C" PCODE QCALLTYPE Delegate_GetMulticastInvokeSlow(MethodTable* pDelegateMT); -extern "C" PCODE QCALLTYPE Delegate_AdjustTarget(QCall::ObjectHandleOnStack target, PCODE method); +extern "C" PCODE QCALLTYPE Delegate_AdjustTarget(MethodTable* pMTTarg, PCODE method); extern "C" void QCALLTYPE Delegate_InitializeVirtualCallStub(QCall::ObjectHandleOnStack d, PCODE method); @@ -106,11 +117,11 @@ enum DelegateBindingFlags DBF_RelaxedSignature = 0x00000040, // Allow relaxed signature matching (co/contra variance) }; -extern "C" BOOL QCALLTYPE Delegate_BindToMethodName(QCall::ObjectHandleOnStack d, QCall::ObjectHandleOnStack target, - QCall::TypeHandle pMethodType, LPCUTF8 pszMethodName, DelegateBindingFlags flags); +extern "C" BOOL QCALLTYPE Delegate_BindToMethodName(MethodTable* pDelegateMT, MethodTable *pTargetMT, + QCall::TypeHandle pMethodType, LPCUTF8 pszMethodName, DelegateBindingFlags flags, QCall::ObjectHandleOnStack targetParameter, BindToMethodDetails *pBindToMethodDetails); -extern "C" BOOL QCALLTYPE Delegate_BindToMethodInfo(QCall::ObjectHandleOnStack d, QCall::ObjectHandleOnStack target, - MethodDesc * method, QCall::TypeHandle pMethodType, DelegateBindingFlags flags); +extern "C" BOOL QCALLTYPE Delegate_BindToMethodInfo(MethodTable* pDelegateMT, MethodTable *pTargetMT, + MethodDesc * method, QCall::TypeHandle pMethodType, DelegateBindingFlags flags, QCall::ObjectHandleOnStack targetParameter, BindToMethodDetails *pBindToMethodDetails); extern "C" void QCALLTYPE Delegate_FindMethodHandle(QCall::ObjectHandleOnStack d, QCall::ObjectHandleOnStack retMethodInfo); diff --git a/src/coreclr/vm/comutilnative.cpp b/src/coreclr/vm/comutilnative.cpp index 640baa44a9c9f0..0bad0ba2ef1869 100644 --- a/src/coreclr/vm/comutilnative.cpp +++ b/src/coreclr/vm/comutilnative.cpp @@ -775,19 +775,23 @@ extern "C" void* QCALLTYPE GCInterface_GetNextFinalizableObject(QCall::ObjectHan BEGIN_QCALL; - GCX_COOP(); - - OBJECTREF target = FinalizerThread::GetNextFinalizableObject(); - - if (target != NULL) + MethodTable *pTargetMT = NULL; { - pObj.Set(target); + GCX_COOP(); - MethodTable* pMT = target->GetMethodTable(); + OBJECTREF target = FinalizerThread::GetNextFinalizableObject(); - funcPtr = pMT->GetRestoredSlot(g_pObjectFinalizerMD->GetSlot()); + if (target != NULL) + { + pObj.Set(target); + + pTargetMT = target->GetMethodTable(); + } } + if (pTargetMT != NULL) + funcPtr = pTargetMT->GetRestoredSlot(g_pObjectFinalizerMD->GetSlot()); + END_QCALL; return (void*)funcPtr; diff --git a/src/coreclr/vm/corhost.cpp b/src/coreclr/vm/corhost.cpp index 64e0e308e9aba4..e7c525050bd8e0 100644 --- a/src/coreclr/vm/corhost.cpp +++ b/src/coreclr/vm/corhost.cpp @@ -430,7 +430,11 @@ HRESULT CorHost2::ExecuteInDefaultAppDomain(LPCWSTR pwzAssemblyPath, UnmanagedCallersOnlyCaller executeInDefaultAppDomain(METHOD__ENVIRONMENT__EXECUTE_IN_DEFAULT_APP_DOMAIN); pMethodMD->EnsureActive(); - PCODE entryPoint = pMethodMD->GetSingleCallableAddrOfCode(); + PCODE entryPoint; + { + GCX_PREEMP(); + entryPoint = pMethodMD->GetSingleCallableAddrOfCode(); + } INT32 retval = executeInDefaultAppDomain.InvokeThrowing_Ret( static_cast(entryPoint), diff --git a/src/coreclr/vm/customattribute.cpp b/src/coreclr/vm/customattribute.cpp index 59c3d87f73b3d2..82fcdbf0941eac 100644 --- a/src/coreclr/vm/customattribute.cpp +++ b/src/coreclr/vm/customattribute.cpp @@ -915,7 +915,14 @@ extern "C" void QCALLTYPE CustomAttribute_CreateCustomAttributeInstance( MethodDesc* pCtorMD = ((REFLECTMETHODREF)pMethod.Get())->GetMethod(); TypeHandle th = ((REFLECTCLASSBASEREF)pCaType.Get())->GetType(); - MethodDescCallSite ctorCallSite(pCtorMD, th); + PCODE pCallTarget; + + { + GCX_PREEMP(); + pCallTarget = pCtorMD->GetSingleCallableAddrOfCode(); + } + + MethodDescCallSite ctorCallSite(pCtorMD, pCallTarget, th); MetaSig* pSig = ctorCallSite.GetMetaSig(); BYTE* pBlob = *ppBlob; diff --git a/src/coreclr/vm/dispatchinfo.cpp b/src/coreclr/vm/dispatchinfo.cpp index 388c4366d2e74d..fe840a99ea99c5 100644 --- a/src/coreclr/vm/dispatchinfo.cpp +++ b/src/coreclr/vm/dispatchinfo.cpp @@ -2514,13 +2514,12 @@ BOOL DispatchInfo::SynchWithManagedView() // Determine if this is the first time we synch. BOOL bFirstSynch = (m_pFirstMemberInfo == NULL); + GCX_PREEMP(); + // This method needs to be synchronized to make sure two threads don't try and // add members at the same time. CrstHolder ch(&m_lock); { - // Make sure we switch to cooperative mode before we start. - GCX_COOP(); - // Go through the list of member info's and find the end. DispatchMemberInfo **ppNextMember = &m_pFirstMemberInfo; while (*ppNextMember) @@ -2529,6 +2528,9 @@ BOOL DispatchInfo::SynchWithManagedView() // Retrieve the member info map. pMemberMap = GetMemberInfoMap(); + // Make sure we switch to cooperative mode before we start. + GCX_COOP(); + for (int cPhase = 0; cPhase < 3; cPhase++) { PTRARRAYREF MemberArrayObj = NULL; @@ -2837,13 +2839,12 @@ ComMTMemberInfoMap *DispatchInfo::GetMemberInfoMap() { THROWS; GC_TRIGGERS; - MODE_COOPERATIVE; + MODE_PREEMPTIVE; INJECT_FAULT(COMPlusThrowOM()); POSTCONDITION(CheckPointer(RETVAL)); } CONTRACT_END; - // Create the member info map. NewHolder pMemberInfoMap (new ComMTMemberInfoMap(m_pMT)); diff --git a/src/coreclr/vm/dllimportcallback.cpp b/src/coreclr/vm/dllimportcallback.cpp index e4cb9206c9160f..5c08f190499e49 100644 --- a/src/coreclr/vm/dllimportcallback.cpp +++ b/src/coreclr/vm/dllimportcallback.cpp @@ -19,9 +19,7 @@ #include "stubgen.h" #include "appdomain.inl" -#ifdef FEATURE_PERFMAP #include "perfmap.h" -#endif class UMEntryThunkFreeList { @@ -122,7 +120,7 @@ UMEntryThunkData *UMEntryThunkCache::GetUMEntryThunk(MethodDesc *pMD) { THROWS; GC_TRIGGERS; - MODE_ANY; + MODE_PREEMPTIVE; PRECONDITION(CheckPointer(pMD)); POSTCONDITION(CheckPointer(RETVAL)); } @@ -270,7 +268,7 @@ UMEntryThunkData* UMEntryThunkData::CreateUMEntryThunk() { THROWS; GC_NOTRIGGER; - MODE_ANY; + MODE_PREEMPTIVE; INJECT_FAULT(COMPlusThrowOM()); POSTCONDITION(CheckPointer(RETVAL)); } @@ -293,9 +291,7 @@ UMEntryThunkData* UMEntryThunkData::CreateUMEntryThunk() #else // !FEATURE_PORTABLE_ENTRYPOINTS pThunk = (UMEntryThunk*)pamTracker->Track(pLoaderAllocator->GetNewStubPrecodeHeap()->AllocStub()); #endif // FEATURE_PORTABLE_ENTRYPOINTS -#ifdef FEATURE_PERFMAP PerfMap::LogStubs(__FUNCTION__, "UMEntryThunk", (PCODE)pThunk, sizeof(UMEntryThunk), PerfMapStubType::IndividualWithinBlock); -#endif pData->m_pUMEntryThunk = pThunk; pThunk->Init(pThunk, dac_cast(pData), NULL, dac_cast(PRECODE_UMENTRY_THUNK)); pamTracker->SuppressRelease(); diff --git a/src/coreclr/vm/encee.cpp b/src/coreclr/vm/encee.cpp index 025df8ac2aa77f..9a8bd30c3e13d3 100644 --- a/src/coreclr/vm/encee.cpp +++ b/src/coreclr/vm/encee.cpp @@ -109,7 +109,7 @@ HRESULT EditAndContinueModule::ApplyEditAndContinue( { THROWS; GC_NOTRIGGER; - MODE_COOPERATIVE; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -340,7 +340,7 @@ HRESULT EditAndContinueModule::UpdateMethod(MethodDesc *pMethod) { THROWS; GC_NOTRIGGER; - MODE_COOPERATIVE; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -417,7 +417,7 @@ HRESULT EditAndContinueModule::AddMethod(mdMethodDef token) { THROWS; GC_NOTRIGGER; - MODE_COOPERATIVE; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -493,7 +493,7 @@ HRESULT EditAndContinueModule::AddField(mdFieldDef token) { THROWS; GC_NOTRIGGER; - MODE_COOPERATIVE; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -1147,7 +1147,7 @@ void EnCFieldDesc::Init(mdFieldDef token, BOOL fIsStatic) { THROWS; GC_NOTRIGGER; - MODE_COOPERATIVE; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -1627,17 +1627,18 @@ void EnCEEClassData::AddField(EnCAddedFieldElement *pAddedField) // If the list is empty, just add this field as the only entry if (*pList == NULL) { - *pList = pAddedField; + VolatileStore(pList, pAddedField); return; } // Otherwise, add this field to the end of the field list - EnCAddedFieldElement *pCur = *pList; - while (pCur->m_next != NULL) + EnCAddedFieldElement *pCur = VolatileLoad(pList); + EnCAddedFieldElement *pNext; + while (pNext = VolatileLoad(&pCur->m_next), pNext != NULL) { - pCur = pCur->m_next; + pCur = pNext; } - pCur->m_next = pAddedField; + VolatileStore(&pCur->m_next, pAddedField); } #endif // #ifndef DACCESS_COMPILE @@ -1831,7 +1832,7 @@ PTR_EnCFieldDesc EncApproxFieldDescIterator::NextEnC() // We're at the start of the instance list. if ( doInst ) { - m_pCurrListElem = m_encClassData->m_pAddedInstanceFields; + m_pCurrListElem = VolatileLoad(&m_encClassData->m_pAddedInstanceFields); } } @@ -1844,7 +1845,7 @@ PTR_EnCFieldDesc EncApproxFieldDescIterator::NextEnC() // We're at the start of the statics list. if ( doStatic ) { - m_pCurrListElem = m_encClassData->m_pAddedStaticFields; + m_pCurrListElem = VolatileLoad(&m_encClassData->m_pAddedStaticFields); } } @@ -1859,7 +1860,7 @@ PTR_EnCFieldDesc EncApproxFieldDescIterator::NextEnC() // Advance the list pointer and return the element m_encFieldsReturned++; PTR_EnCFieldDesc fd = PTR_EnCFieldDesc(PTR_HOST_MEMBER_TADDR(EnCAddedFieldElement, m_pCurrListElem, m_fieldDesc)); - m_pCurrListElem = m_pCurrListElem->m_next; + m_pCurrListElem = VolatileLoad(&m_pCurrListElem->m_next); return fd; } diff --git a/src/coreclr/vm/eventing/eventpipe/ds-rt-coreclr.h b/src/coreclr/vm/eventing/eventpipe/ds-rt-coreclr.h index 67d8e3c54dd6eb..b8ad4bc9585b26 100644 --- a/src/coreclr/vm/eventing/eventpipe/ds-rt-coreclr.h +++ b/src/coreclr/vm/eventing/eventpipe/ds-rt-coreclr.h @@ -15,9 +15,7 @@ #include #include #include -#ifdef FEATURE_PERFMAP #include "perfmap.h" -#endif #undef DS_LOG_ALWAYS_0 #define DS_LOG_ALWAYS_0(msg) STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_ALWAYS, msg "\n") diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp index 46741b04604d01..37ded3c968199f 100644 --- a/src/coreclr/vm/excep.cpp +++ b/src/coreclr/vm/excep.cpp @@ -9556,7 +9556,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowWin32() CONTRACTL { THROWS; - DISABLED(GC_NOTRIGGER); // Must sanitize first pass handling to enable this + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; @@ -9572,7 +9572,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowWin32(HRESULT hr) CONTRACTL { THROWS; - DISABLED(GC_NOTRIGGER); // Must sanitize first pass handling to enable this + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; @@ -9593,7 +9593,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowOM() CONTRACTL { THROWS; - DISABLED(GC_NOTRIGGER); // Must sanitize first pass handling to enable this + GC_NOTRIGGER; CANNOT_TAKE_LOCK; MODE_ANY; SUPPORTS_DAC; @@ -9611,7 +9611,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrow(RuntimeExceptionKind reKind) CONTRACTL { THROWS; - DISABLED(GC_NOTRIGGER); // Must sanitize first pass handling to enable this + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; @@ -9631,7 +9631,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowNonLocalized(RuntimeExceptionKind reKind, CONTRACTL { THROWS; - DISABLED(GC_NOTRIGGER); // Must sanitize first pass handling to enable this + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; @@ -9712,33 +9712,13 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowHR(HRESULT hr) EX_THROW(EEMessageException, (hr)); } - -VOID DECLSPEC_NORETURN RealCOMPlusThrowHR(HRESULT hr, tagGetErrorInfo) -{ - CONTRACTL - { - THROWS; - DISABLED(GC_NOTRIGGER); // Must sanitize first pass handling to enable this - MODE_ANY; - } - CONTRACTL_END; - - // Get an IErrorInfo if one is available. - IErrorInfo *pErrInfo = NULL; - - if (SafeGetErrorInfo(&pErrInfo) != S_OK) - pErrInfo = NULL; - - // Throw the exception. - RealCOMPlusThrowHR(hr, pErrInfo); -} #else // FEATURE_COMINTEROP VOID DECLSPEC_NORETURN RealCOMPlusThrowHR(HRESULT hr) { CONTRACTL { THROWS; - DISABLED(GC_NOTRIGGER); // Must sanitize first pass handling to enable this + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; @@ -9786,7 +9766,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrow(RuntimeExceptionKind reKind, LPCWSTR wsz CONTRACTL { THROWS; - DISABLED(GC_NOTRIGGER); // Must sanitize first pass handling to enable this + GC_NOTRIGGER; MODE_ANY; PRECONDITION(CheckPointer(wszResourceName)); } @@ -9826,7 +9806,7 @@ VOID DECLSPEC_NORETURN ThrowTypeLoadException(LPCWSTR pFullTypeName, CONTRACTL { THROWS; - DISABLED(GC_NOTRIGGER); // Must sanitize first pass handling to enable this + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; @@ -9846,7 +9826,7 @@ VOID DECLSPEC_NORETURN ThrowFieldLayoutError(mdTypeDef cl, // cl CONTRACTL { THROWS; - DISABLED(GC_NOTRIGGER); // Must sanitize first pass handling to enable this + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; @@ -9877,7 +9857,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowArithmetic() CONTRACTL { THROWS; - DISABLED(GC_NOTRIGGER); // Must sanitize first pass handling to enable this + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; @@ -9893,7 +9873,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowArgumentNull(LPCWSTR argName, LPCWSTR wsz CONTRACTL { THROWS; - DISABLED(GC_NOTRIGGER); // Must sanitize first pass handling to enable this + GC_NOTRIGGER; MODE_ANY; PRECONDITION(CheckPointer(wszResourceName)); } @@ -9908,7 +9888,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowArgumentNull(LPCWSTR argName) CONTRACTL { THROWS; - DISABLED(GC_NOTRIGGER); // Must sanitize first pass handling to enable this + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; @@ -9925,7 +9905,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowArgumentOutOfRange(LPCWSTR argName, LPCWS CONTRACTL { THROWS; - DISABLED(GC_NOTRIGGER); // Must sanitize first pass handling to enable this + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; @@ -9941,7 +9921,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowArgumentException(LPCWSTR argName, LPCWST CONTRACTL { THROWS; - DISABLED(GC_NOTRIGGER); // Must sanitize first pass handling to enable this + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; @@ -9966,7 +9946,7 @@ VOID DECLSPEC_NORETURN ThrowTypeLoadException(LPCUTF8 pszNameSpace, CONTRACTL { THROWS; - DISABLED(GC_NOTRIGGER); // Must sanitize first pass handling to enable this + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; @@ -9984,7 +9964,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrow(RuntimeExceptionKind reKind, UINT resID CONTRACTL { THROWS; - DISABLED(GC_NOTRIGGER); // Must sanitize first pass handling to enable this + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; @@ -10024,7 +10004,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowHR(EXCEPINFO *pExcepInfo) CONTRACTL { THROWS; - DISABLED(GC_NOTRIGGER); // Must sanitize first pass handling to enable this + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; diff --git a/src/coreclr/vm/excep.h b/src/coreclr/vm/excep.h index 472782de483d33..04c737390dbe5a 100644 --- a/src/coreclr/vm/excep.h +++ b/src/coreclr/vm/excep.h @@ -239,13 +239,6 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowHR(HRESULT hr, UINT resID, LPCWSTR wszArg #ifdef FEATURE_COMINTEROP -enum tagGetErrorInfo -{ - kGetErrorInfo -}; - -VOID DECLSPEC_NORETURN RealCOMPlusThrowHR(HRESULT hr, tagGetErrorInfo); - //========================================================================== // Throw a runtime exception based on an HResult, check for error info //========================================================================== diff --git a/src/coreclr/vm/fptrstubs.cpp b/src/coreclr/vm/fptrstubs.cpp index cf3f4db379f92b..f0e3a466df6bf0 100644 --- a/src/coreclr/vm/fptrstubs.cpp +++ b/src/coreclr/vm/fptrstubs.cpp @@ -78,6 +78,7 @@ PCODE FuncPtrStubs::GetFuncPtrStub(MethodDesc * pMD, PrecodeType type) { return pPrecode->GetEntryPoint(); } + GCX_PREEMP(); PCODE target = (PCODE)NULL; bool setTargetAfterAddingToHashTable = false; @@ -151,8 +152,6 @@ PCODE FuncPtrStubs::GetFuncPtrStub(MethodDesc * pMD, PrecodeType type) if (setTargetAfterAddingToHashTable) { - GCX_PREEMP(); - _ASSERTE(pMD->IsVersionableWithVtableSlotBackpatch()); PCODE temporaryEntryPoint = pMD->GetTemporaryEntryPoint(); diff --git a/src/coreclr/vm/genericdict.cpp b/src/coreclr/vm/genericdict.cpp index e9d15c0fa6bb63..ce2cfd806363f8 100644 --- a/src/coreclr/vm/genericdict.cpp +++ b/src/coreclr/vm/genericdict.cpp @@ -674,6 +674,7 @@ Dictionary::PopulateEntry( Module * pModule /* = NULL */) { CONTRACTL { + MODE_PREEMPTIVE; THROWS; GC_TRIGGERS; } CONTRACTL_END; diff --git a/src/coreclr/vm/genmeth.cpp b/src/coreclr/vm/genmeth.cpp index be61fb34b33d1c..72fbb73af4e32e 100644 --- a/src/coreclr/vm/genmeth.cpp +++ b/src/coreclr/vm/genmeth.cpp @@ -170,6 +170,7 @@ static MethodDesc * FindTightlyBoundWrappedMethodDesc(MethodDesc * pMD) { CONTRACTL { + MODE_ANY; NOTHROW; GC_NOTRIGGER; PRECONDITION(CheckPointer(pMD)); @@ -401,6 +402,7 @@ InstantiatedMethodDesc::NewInstantiatedMethodDesc(MethodTable *pExactMT, { CONTRACT(InstantiatedMethodDesc*) { + MODE_PREEMPTIVE; THROWS; GC_TRIGGERS; INJECT_FAULT(COMPlusThrowOM();); @@ -596,45 +598,6 @@ InstantiatedMethodDesc::NewInstantiatedMethodDesc(MethodTable *pExactMT, RETURN pNewMD; } - -// Calling this method is equivalent to -// FindOrCreateAssociatedMethodDesc(pCanonicalMD, pExactMT, FALSE, Instantiation(), FALSE, TRUE) -// except that it also creates InstantiatedMethodDescs based on shared class methods. This is -// convenient for interop where, unlike ordinary managed methods, marshaling stubs for say Foo -// and Foo look very different and need separate representation. -InstantiatedMethodDesc* -InstantiatedMethodDesc::FindOrCreateExactClassMethod(MethodTable *pExactMT, - MethodDesc *pCanonicalMD) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(!pExactMT->IsSharedByGenericInstantiations()); - PRECONDITION(pCanonicalMD->IsSharedByGenericInstantiations()); - } - CONTRACTL_END; - - InstantiatedMethodDesc *pInstMD = FindLoadedInstantiatedMethodDesc(pExactMT, - pCanonicalMD->GetMemberDef(), - Instantiation(), - FALSE, - pCanonicalMD->GetMatchingAsyncVariantLookup()); - - if (pInstMD == NULL) - { - // create a new MD if not found - pInstMD = NewInstantiatedMethodDesc(pExactMT, - pCanonicalMD, - pCanonicalMD, - Instantiation(), - FALSE); - } - - return pInstMD; -} - #endif // !DACCESS_COMPILE // N.B. it is not guarantee that the returned InstantiatedMethodDesc is restored. @@ -807,6 +770,7 @@ MethodDesc::FindOrCreateAssociatedMethodDesc(MethodDesc* pDefMD, CONTRACT(MethodDesc*) { THROWS; + if (allowCreate) { MODE_PREEMPTIVE; } else { MODE_ANY; } if (allowCreate) { GC_TRIGGERS; } else { GC_NOTRIGGER; } if (!allowCreate) { SUPPORTS_DAC; } INJECT_FAULT(COMPlusThrowOM();); @@ -1322,6 +1286,7 @@ MethodDesc::FindOrCreateAssociatedMethodDesc(MethodDesc* pDefMD, Instantiation methodInst) { CONTRACTL { + MODE_PREEMPTIVE; THROWS; GC_TRIGGERS; // Because allowCreate is TRUE PRECONDITION(CheckPointer(pMethod)); diff --git a/src/coreclr/vm/i386/cgenx86.cpp b/src/coreclr/vm/i386/cgenx86.cpp index 8068a7ed4f1a70..a729d4064872e4 100644 --- a/src/coreclr/vm/i386/cgenx86.cpp +++ b/src/coreclr/vm/i386/cgenx86.cpp @@ -37,9 +37,7 @@ #include "stublink.inl" -#ifdef FEATURE_PERFMAP #include "perfmap.h" -#endif void UpdateRegDisplayFromCalleeSavedRegisters(REGDISPLAY * pRD, CalleeSavedRegisters * regs) { @@ -565,13 +563,9 @@ void ResumeAtJit(PCONTEXT pContext, LPVOID oldESP) size_t rxOffset = pStartRX - pStart; \ BYTE * p = pStart; -#ifdef FEATURE_PERFMAP #define BEGIN_DYNAMIC_HELPER_EMIT(size) \ BEGIN_DYNAMIC_HELPER_EMIT_WORKER(size) \ PerfMap::LogStubs(__FUNCTION__, "DynamicHelper", (PCODE)p, size, PerfMapStubType::Individual); -#else -#define BEGIN_DYNAMIC_HELPER_EMIT(size) BEGIN_DYNAMIC_HELPER_EMIT_WORKER(size) -#endif #define END_DYNAMIC_HELPER_EMIT() \ _ASSERTE(pStart + cb == p); \ @@ -600,7 +594,7 @@ void DynamicHelpers::EmitHelperWithArg(BYTE*& p, size_t rxOffset, LoaderAllocato { CONTRACTL { - GC_NOTRIGGER; + STANDARD_VM_CHECK; PRECONDITION(p != NULL && target != NULL); } CONTRACTL_END; @@ -618,6 +612,8 @@ void DynamicHelpers::EmitHelperWithArg(BYTE*& p, size_t rxOffset, LoaderAllocato PCODE DynamicHelpers::CreateHelperWithArg(LoaderAllocator * pAllocator, TADDR arg, PCODE target) { + STANDARD_VM_CONTRACT; + BEGIN_DYNAMIC_HELPER_EMIT(10); EmitHelperWithArg(p, rxOffset, pAllocator, arg, target); @@ -627,6 +623,8 @@ PCODE DynamicHelpers::CreateHelperWithArg(LoaderAllocator * pAllocator, TADDR ar PCODE DynamicHelpers::CreateHelper(LoaderAllocator * pAllocator, TADDR arg, TADDR arg2, PCODE target) { + STANDARD_VM_CONTRACT; + BEGIN_DYNAMIC_HELPER_EMIT(15); *p++ = 0xB9; // mov ecx, XXXXXX @@ -646,6 +644,8 @@ PCODE DynamicHelpers::CreateHelper(LoaderAllocator * pAllocator, TADDR arg, TADD PCODE DynamicHelpers::CreateHelperArgMove(LoaderAllocator * pAllocator, TADDR arg, PCODE target) { + STANDARD_VM_CONTRACT; + BEGIN_DYNAMIC_HELPER_EMIT(12); SET_UNALIGNED_16(p, 0xD18B); // mov edx, ecx @@ -664,6 +664,8 @@ PCODE DynamicHelpers::CreateHelperArgMove(LoaderAllocator * pAllocator, TADDR ar PCODE DynamicHelpers::CreateReturn(LoaderAllocator * pAllocator) { + STANDARD_VM_CONTRACT; + BEGIN_DYNAMIC_HELPER_EMIT(1); *p++ = 0xC3; // ret @@ -673,6 +675,8 @@ PCODE DynamicHelpers::CreateReturn(LoaderAllocator * pAllocator) PCODE DynamicHelpers::CreateReturnConst(LoaderAllocator * pAllocator, TADDR arg) { + STANDARD_VM_CONTRACT; + BEGIN_DYNAMIC_HELPER_EMIT(6); *p++ = 0xB8; // mov eax, XXXXXX @@ -686,6 +690,8 @@ PCODE DynamicHelpers::CreateReturnConst(LoaderAllocator * pAllocator, TADDR arg) PCODE DynamicHelpers::CreateReturnIndirConst(LoaderAllocator * pAllocator, TADDR arg, INT8 offset) { + STANDARD_VM_CONTRACT; + BEGIN_DYNAMIC_HELPER_EMIT((offset != 0) ? 9 : 6); *p++ = 0xA1; // mov eax, [XXXXXX] @@ -709,6 +715,8 @@ EXTERN_C VOID DynamicHelperArgsStub(); PCODE DynamicHelpers::CreateHelperWithTwoArgs(LoaderAllocator * pAllocator, TADDR arg, PCODE target) { + STANDARD_VM_CONTRACT; + #ifdef UNIX_X86_ABI BEGIN_DYNAMIC_HELPER_EMIT(18); #else @@ -753,6 +761,8 @@ PCODE DynamicHelpers::CreateHelperWithTwoArgs(LoaderAllocator * pAllocator, TADD PCODE DynamicHelpers::CreateHelperWithTwoArgs(LoaderAllocator * pAllocator, TADDR arg, TADDR arg2, PCODE target) { + STANDARD_VM_CONTRACT; + #ifdef UNIX_X86_ABI BEGIN_DYNAMIC_HELPER_EMIT(23); #else diff --git a/src/coreclr/vm/interpexec.cpp b/src/coreclr/vm/interpexec.cpp index 9ee91d7cb18926..94e7b064f58ca0 100644 --- a/src/coreclr/vm/interpexec.cpp +++ b/src/coreclr/vm/interpexec.cpp @@ -3244,8 +3244,9 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr { // miss, resolve the virtual method and cache it targetMethod = CallWithSEHWrapper( - [&pMD, &pThisArg]() { - return pMD->GetMethodDescOfVirtualizedCode(pThisArg, pMD->GetMethodTable()); + [&pMD, &pThisArg, pObjMT]() { + GCX_PREEMP(); + return pMD->GetMethodDescOfVirtualizedCode(pThisArg, pObjMT, pMD->GetMethodTable()); }); g_InterpDispatchCache.Insert(dispatchToken, pObjMT, targetMethod, (uint16_t)dispatchTokenHash); } @@ -3413,7 +3414,9 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr NULL_CHECK(*pThisArg); targetMethod = CallWithSEHWrapper( [&targetMethod, &pThisArg]() { - return targetMethod->GetMethodDescOfVirtualizedCode(pThisArg, targetMethod->GetMethodTable()); + MethodTable* pMT = (*pThisArg)->GetMethodTable(); + GCX_PREEMP(); + return targetMethod->GetMethodDescOfVirtualizedCode(pThisArg, pMT, targetMethod->GetMethodTable()); }); } else diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index 42b5bc31a938f9..df3cf5351e4882 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -731,9 +731,11 @@ extern "C" PCODE QCALLTYPE ResolveVirtualFunctionPointer(QCall::ObjectHandleOnSt } else { + MethodTable *pMTObjRef = objRef->GetMethodTable(); + GCX_PREEMP(); // This is the new way of resolving a virtual call, including generic virtual methods. // The code is now also used by reflection, remoting etc. - addr = pStaticMD->GetMultiCallableAddrOfVirtualizedCode(&objRef, staticTH); + addr = pStaticMD->GetMultiCallableAddrOfVirtualizedCode(&objRef, pMTObjRef, staticTH); _ASSERTE(addr); } diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index f8fa996f3782aa..02f8aa6df48361 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -52,9 +52,7 @@ #endif // HAVE_GCCOVER #include "debugdebugger.h" -#ifdef FEATURE_PERFMAP #include "perfmap.h" -#endif #ifdef FEATURE_PGO #include "pgo.h" diff --git a/src/coreclr/vm/loongarch64/stubs.cpp b/src/coreclr/vm/loongarch64/stubs.cpp index fc5a820e0aca07..096d160695d435 100644 --- a/src/coreclr/vm/loongarch64/stubs.cpp +++ b/src/coreclr/vm/loongarch64/stubs.cpp @@ -14,9 +14,7 @@ #include "jitinterface.h" #include "ecall.h" -#ifdef FEATURE_PERFMAP #include "perfmap.h" -#endif #ifndef DACCESS_COMPILE //----------------------------------------------------------------------- @@ -961,13 +959,9 @@ void StubLinkerCPU::EmitCallManagedMethod(MethodDesc *pMD, BOOL fTailCall) size_t rxOffset = pStartRX - pStart; \ BYTE * p = pStart; -#ifdef FEATURE_PERFMAP #define BEGIN_DYNAMIC_HELPER_EMIT(size) \ BEGIN_DYNAMIC_HELPER_EMIT_WORKER(size) \ PerfMap::LogStubs(__FUNCTION__, "DynamicHelper", (PCODE)p, size, PerfMapStubType::Individual); -#else -#define BEGIN_DYNAMIC_HELPER_EMIT(size) BEGIN_DYNAMIC_HELPER_EMIT_WORKER(size) -#endif #define END_DYNAMIC_HELPER_EMIT() \ _ASSERTE(pStart + cb == p); \ diff --git a/src/coreclr/vm/method.cpp b/src/coreclr/vm/method.cpp index 6d689fa00a8056..a952aaaf396595 100644 --- a/src/coreclr/vm/method.cpp +++ b/src/coreclr/vm/method.cpp @@ -619,7 +619,7 @@ PCODE MethodDesc::GetMethodEntryPoint() { THROWS; GC_NOTRIGGER; - MODE_ANY; + MODE_PREEMPTIVE; SUPPORTS_DAC; } CONTRACTL_END; @@ -1605,7 +1605,6 @@ MethodDesc *MethodDesc::GetExistingWrappedMethodDesc() { THROWS; GC_NOTRIGGER; - MODE_ANY; } CONTRACTL_END; @@ -1936,10 +1935,11 @@ MethodDescChunk *MethodDescChunk::CreateChunk(LoaderHeap *pHeap, DWORD methodDes // The following resolve virtual dispatch for the given method on the given // object down to an actual address to call, including any // handling of context proxies and other thunking layers. -MethodDesc* MethodDesc::ResolveGenericVirtualMethod(OBJECTREF *orThis) +MethodDesc* MethodDesc::ResolveGenericVirtualMethod(OBJECTREF *orThis, MethodTable* pMTOfThis) { CONTRACT(MethodDesc *) { + MODE_PREEMPTIVE; THROWS; GC_TRIGGERS; @@ -1951,9 +1951,6 @@ MethodDesc* MethodDesc::ResolveGenericVirtualMethod(OBJECTREF *orThis) } CONTRACT_END; - // Method table of target (might be instantiated) - MethodTable *pObjMT = (*orThis)->GetMethodTable(); - // This is the static method descriptor describing the call. // It is not the destination of the call, which we must compute. MethodDesc* pStaticMD = this; @@ -1968,8 +1965,8 @@ MethodDesc* MethodDesc::ResolveGenericVirtualMethod(OBJECTREF *orThis) MethodDesc *pTargetMDBeforeGenericMethodArgs = pStaticMD->IsInterface() ? MethodTable::GetMethodDescForInterfaceMethodAndServer(TypeHandle(pStaticMD->GetMethodTable()), - pStaticMDWithoutGenericMethodArgs,orThis) - : pObjMT->GetMethodDescForSlot(pStaticMDWithoutGenericMethodArgs->GetSlot()); + pStaticMDWithoutGenericMethodArgs,orThis, pMTOfThis) + : pMTOfThis->GetMethodDescForSlot(pStaticMDWithoutGenericMethodArgs->GetSlot()); pTargetMDBeforeGenericMethodArgs->CheckRestore(); @@ -1989,7 +1986,7 @@ MethodDesc* MethodDesc::ResolveGenericVirtualMethod(OBJECTREF *orThis) { pTargetMT = ClassLoader::LoadGenericInstantiationThrowing(pTargetMT->GetModule(), pTargetMT->GetCl(), - pTargetMDBeforeGenericMethodArgs->GetExactClassInstantiation(TypeHandle(pObjMT))).GetMethodTable(); + pTargetMDBeforeGenericMethodArgs->GetExactClassInstantiation(TypeHandle(pMTOfThis))).GetMethodTable(); } RETURN(MethodDesc::FindOrCreateAssociatedMethodDesc( @@ -2034,18 +2031,24 @@ PCODE MethodDesc::GetSingleCallableAddrOfCodeForUnmanagedCallersOnly() } //******************************************************************************* -PCODE MethodDesc::GetSingleCallableAddrOfVirtualizedCode(OBJECTREF *orThis, TypeHandle staticTH) +PCODE MethodDesc::GetSingleCallableAddrOfVirtualizedCode(OBJECTREF *orThis, MethodTable* pMTOfThis, TypeHandle staticTH) { - WRAPPER_NO_CONTRACT; - PRECONDITION(IsVtableMethod()); + CONTRACTL + { + THROWS; // Resolving a generic virtual method can throw + GC_TRIGGERS; + MODE_PREEMPTIVE; + } + CONTRACTL_END; - MethodTable *pObjMT = (*orThis)->GetMethodTable(); + PRECONDITION(IsVtableMethod()); + if (HasMethodInstantiation()) { CheckRestore(); - MethodDesc *pResultMD = ResolveGenericVirtualMethod(orThis); - + MethodDesc *pResultMD = ResolveGenericVirtualMethod(orThis, pMTOfThis); + // If we're remoting this call we can't call directly on the returned // method desc, we need to go through a stub that guarantees we end up // in the remoting handler. The stub we use below is normally just for @@ -2053,23 +2056,24 @@ PCODE MethodDesc::GetSingleCallableAddrOfVirtualizedCode(OBJECTREF *orThis, Type // where we could end up bypassing the remoting system), but it serves // our purpose here (basically pushes our correctly instantiated, // resolved method desc on the stack and calls the remoting code). - + return pResultMD->GetSingleCallableAddrOfCode(); } - + if (IsInterface()) { - MethodDesc * pTargetMD = MethodTable::GetMethodDescForInterfaceMethodAndServer(staticTH,this,orThis); + MethodDesc * pTargetMD = MethodTable::GetMethodDescForInterfaceMethodAndServer(staticTH,this,orThis, pMTOfThis); return pTargetMD->GetSingleCallableAddrOfCode(); } - - return pObjMT->GetRestoredSlot(GetSlot()); + + return pMTOfThis->GetRestoredSlot(GetSlot()); } -MethodDesc* MethodDesc::GetMethodDescOfVirtualizedCode(OBJECTREF *orThis, TypeHandle staticTH) +MethodDesc* MethodDesc::GetMethodDescOfVirtualizedCode(OBJECTREF *orThis, MethodTable* pMTOfThis, TypeHandle staticTH) { CONTRACT(MethodDesc*) { + MODE_PREEMPTIVE; THROWS; GC_TRIGGERS; @@ -2078,8 +2082,6 @@ MethodDesc* MethodDesc::GetMethodDescOfVirtualizedCode(OBJECTREF *orThis, TypeHa POSTCONDITION(RETVAL != NULL); } CONTRACT_END; - // Method table of target (might be instantiated) - MethodTable *pObjMT = (*orThis)->GetMethodTable(); // This is the static method descriptor describing the call. // It is not the destination of the call, which we must compute. @@ -2088,32 +2090,34 @@ MethodDesc* MethodDesc::GetMethodDescOfVirtualizedCode(OBJECTREF *orThis, TypeHa if (pStaticMD->HasMethodInstantiation()) { CheckRestore(); - RETURN(ResolveGenericVirtualMethod(orThis)); + RETURN(ResolveGenericVirtualMethod(orThis, pMTOfThis)); } if (pStaticMD->IsInterface()) { - RETURN(MethodTable::GetMethodDescForInterfaceMethodAndServer(staticTH, pStaticMD, orThis)); + RETURN(MethodTable::GetMethodDescForInterfaceMethodAndServer(staticTH, pStaticMD, orThis, pMTOfThis)); } - RETURN(pObjMT->GetMethodDescForSlot(pStaticMD->GetSlot())); + // Method table of target (might be instantiated) + RETURN(pMTOfThis->GetMethodDescForSlot(pStaticMD->GetSlot())); } //******************************************************************************* // The following resolve virtual dispatch for the given method on the given // object down to an actual address to call, including any // handling of context proxies and other thunking layers. -PCODE MethodDesc::GetMultiCallableAddrOfVirtualizedCode(OBJECTREF *orThis, TypeHandle staticTH) +PCODE MethodDesc::GetMultiCallableAddrOfVirtualizedCode(OBJECTREF *orThis, MethodTable* pMTOfThis, TypeHandle staticTH) { CONTRACT(PCODE) { + MODE_PREEMPTIVE; THROWS; GC_TRIGGERS; POSTCONDITION(RETVAL != NULL); } CONTRACT_END; - MethodDesc *pTargetMD = GetMethodDescOfVirtualizedCode(orThis, staticTH); + MethodDesc *pTargetMD = GetMethodDescOfVirtualizedCode(orThis, pMTOfThis, staticTH); RETURN(pTargetMD->GetMultiCallableAddrOfCode()); } @@ -2135,8 +2139,6 @@ PCODE MethodDesc::GetMultiCallableAddrOfCode(CORINFO_ACCESS_FLAGS accessFlags /* #else if (ret == (PCODE)NULL) { - GCX_COOP(); - // We have to allocate funcptr stub ret = GetLoaderAllocator()->GetFuncPtrStubs()->GetFuncPtrStub(this); } @@ -2296,13 +2298,13 @@ PCODE MethodDesc::TryGetMultiCallableAddrOfCode(CORINFO_ACCESS_FLAGS accessFlags } //******************************************************************************* -PCODE MethodDesc::GetCallTarget(OBJECTREF* pThisObj, TypeHandle ownerType) +PCODE MethodDesc::GetCallTarget(OBJECTREF* pThisObj, MethodTable *pMTThis, TypeHandle ownerType) { CONTRACTL { THROWS; // Resolving a generic virtual method can throw GC_TRIGGERS; - MODE_COOPERATIVE; + MODE_PREEMPTIVE; } CONTRACTL_END @@ -2311,9 +2313,10 @@ PCODE MethodDesc::GetCallTarget(OBJECTREF* pThisObj, TypeHandle ownerType) if (IsVtableMethod() && !GetMethodTable()->IsValueType()) { CONSISTENCY_CHECK(NULL != pThisObj); + _ASSERTE(NULL != pMTThis); if (ownerType.IsNull()) ownerType = GetMethodTable(); - pTarget = GetSingleCallableAddrOfVirtualizedCode(pThisObj, ownerType); + pTarget = GetSingleCallableAddrOfVirtualizedCode(pThisObj, pMTThis, ownerType); } else { @@ -2797,7 +2800,7 @@ PCODE MethodDesc::GetTemporaryEntryPoint() { THROWS; GC_NOTRIGGER; - MODE_ANY; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -2872,7 +2875,7 @@ void MethodDesc::EnsureTemporaryEntryPointCore(AllocMemTracker *pamTracker) { THROWS; GC_NOTRIGGER; - MODE_ANY; + MODE_PREEMPTIVE; } CONTRACTL_END; diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index afb45ad0d4a204..dc3f22c5d327e9 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -1588,7 +1588,7 @@ class MethodDesc // indirect call via slot in this case. PCODE TryGetMultiCallableAddrOfCode(CORINFO_ACCESS_FLAGS accessFlags); - MethodDesc* GetMethodDescOfVirtualizedCode(OBJECTREF *orThis, TypeHandle staticTH); + MethodDesc* GetMethodDescOfVirtualizedCode(OBJECTREF *orThis, MethodTable* pMTOfThis, TypeHandle staticTH); // These return an address after resolving "virtual methods" correctly, including any // handling of context proxies, other thunking layers and also including // instantiation of generic virtual methods if required. @@ -1598,8 +1598,8 @@ class MethodDesc // The code that implements these was taken verbatim from elsewhere in the // codebase, and there may be subtle differences between the two, e.g. with // regard to thunking. - PCODE GetSingleCallableAddrOfVirtualizedCode(OBJECTREF *orThis, TypeHandle staticTH); - PCODE GetMultiCallableAddrOfVirtualizedCode(OBJECTREF *orThis, TypeHandle staticTH); + PCODE GetSingleCallableAddrOfVirtualizedCode(OBJECTREF *orThis, MethodTable* pMTOfThis, TypeHandle staticTH); + PCODE GetMultiCallableAddrOfVirtualizedCode(OBJECTREF *orThis, MethodTable* pMTOfThis, TypeHandle staticTH); #ifndef DACCESS_COMPILE // The current method entrypoint. It is simply the value of the current method slot. @@ -1815,7 +1815,7 @@ class MethodDesc // Given an object and an method descriptor for an instantiation of // a virtualized generic method, get the // corresponding instantiation of the target of a call. - MethodDesc *ResolveGenericVirtualMethod(OBJECTREF *orThis); + MethodDesc *ResolveGenericVirtualMethod(OBJECTREF *orThis, MethodTable* pMTOfThis); #if defined(TARGET_X86) && defined(HAVE_GCCOVER) public: @@ -1832,7 +1832,7 @@ class MethodDesc // but the additional weirdness that class-based-virtual calls (but not interface calls nor calls // on proxies) are resolved to their target. Because of this, many clients of "Call" (see above) // end up doing some resolution for interface calls and/or proxies themselves. - PCODE GetCallTarget(OBJECTREF* pThisObj, TypeHandle ownerType = TypeHandle()); + PCODE GetCallTarget(OBJECTREF* pThisObj, MethodTable *pMTThis, TypeHandle ownerType = TypeHandle()); MethodImpl *GetMethodImpl(); @@ -3932,9 +3932,6 @@ class InstantiatedMethodDesc final : public MethodDesc WORD m_wNumGenericArgs; public: - static InstantiatedMethodDesc *FindOrCreateExactClassMethod(MethodTable *pExactMT, - MethodDesc *pCanonicalMD); - static InstantiatedMethodDesc* FindLoadedInstantiatedMethodDesc(MethodTable *pMT, mdMethodDef methodDef, Instantiation methodInst, diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 8a921b23db537c..5e52b8a29e8c75 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -469,13 +469,13 @@ PTR_MethodTable InterfaceInfo_t::GetApproxMethodTable(Module * pContainingModule //========================================================================================== // get the method desc given the interface method desc /* static */ MethodDesc *MethodTable::GetMethodDescForInterfaceMethodAndServer( - TypeHandle ownerType, MethodDesc *pItfMD, OBJECTREF *pServer) + TypeHandle ownerType, MethodDesc *pItfMD, OBJECTREF *pServer, MethodTable* pServerMT) { CONTRACT(MethodDesc*) { THROWS; GC_TRIGGERS; - MODE_COOPERATIVE; + MODE_PREEMPTIVE; PRECONDITION(CheckPointer(pItfMD)); PRECONDITION(pItfMD->IsInterface()); PRECONDITION(!ownerType.IsNull()); @@ -483,16 +483,18 @@ PTR_MethodTable InterfaceInfo_t::GetApproxMethodTable(Module * pContainingModule POSTCONDITION(CheckPointer(RETVAL)); } CONTRACT_END; - VALIDATEOBJECTREF(*pServer); +#ifdef DEBUG + { + GCX_COOP(); + VALIDATEOBJECTREF(*pServer); + } +#endif #ifdef _DEBUG MethodTable * pItfMT = ownerType.GetMethodTable(); _ASSERTE(pItfMT != NULL); #endif // _DEBUG - MethodTable *pServerMT = (*pServer)->GetMethodTable(); - _ASSERTE(pServerMT != NULL); - #ifdef FEATURE_COMINTEROP if (pServerMT->IsComObjectType() && !pItfMD->HasMethodInstantiation()) { @@ -516,15 +518,19 @@ PTR_MethodTable InterfaceInfo_t::GetApproxMethodTable(Module * pContainingModule && !TypeHandle(pServerMT).CanCastTo(ownerType)) // we need to make sure object doesn't implement this interface in a natural way { TypeHandle implTypeHandle; - OBJECTREF obj = *pServer; + { + GCX_COOP(); - GCPROTECT_BEGIN(obj); - OBJECTREF implTypeRef = DynamicInterfaceCastable::GetInterfaceImplementation(&obj, ownerType); - _ASSERTE(implTypeRef != NULL); + OBJECTREF obj = *pServer; - ReflectClassBaseObject *implTypeObj = ((ReflectClassBaseObject *)OBJECTREFToObject(implTypeRef)); - implTypeHandle = implTypeObj->GetType(); - GCPROTECT_END(); + GCPROTECT_BEGIN(obj); + OBJECTREF implTypeRef = DynamicInterfaceCastable::GetInterfaceImplementation(&obj, ownerType); + _ASSERTE(implTypeRef != NULL); + + ReflectClassBaseObject *implTypeObj = ((ReflectClassBaseObject *)OBJECTREFToObject(implTypeRef)); + implTypeHandle = implTypeObj->GetType(); + GCPROTECT_END(); + } RETURN(implTypeHandle.GetMethodTable()->GetMethodDescForInterfaceMethod(ownerType, pItfMD, TRUE /* throwOnConflict */)); } @@ -542,7 +548,7 @@ MethodDesc *MethodTable::GetMethodDescForComInterfaceMethod(MethodDesc *pItfMD) { THROWS; GC_TRIGGERS; - MODE_COOPERATIVE; + MODE_PREEMPTIVE; PRECONDITION(CheckPointer(pItfMD)); PRECONDITION(pItfMD->IsInterface()); PRECONDITION(IsComObjectType()); @@ -3537,7 +3543,11 @@ BOOL MethodTable::RunClassInitEx(OBJECTREF *pThrowable) MethodTable * pCanonMT = GetCanonicalMethodTable(); // Call the code method without touching MethodDesc if possible - PCODE pCctorCode = pCanonMT->GetRestoredSlot(pCanonMT->GetClassConstructorSlot()); + PCODE pCctorCode; + { + GCX_PREEMP(); + pCctorCode = pCanonMT->GetRestoredSlot(pCanonMT->GetClassConstructorSlot()); + } MethodTable* instantiatingArg = pCanonMT->IsSharedByGenericInstantiations() ? this : nullptr; UnmanagedCallersOnlyCaller caller(METHOD__INITHELPERS__CALLCLASSCONSTRUCTOR); caller.InvokeThrowing(pCctorCode, instantiatingArg); @@ -7750,7 +7760,7 @@ PCODE MethodTable::GetRestoredSlot(DWORD slotNumber) CONTRACTL { THROWS; GC_NOTRIGGER; - MODE_ANY; + MODE_PREEMPTIVE; SUPPORTS_DAC; } CONTRACTL_END; diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index 563cc497ec4d94..41cfc049cd5434 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -2459,7 +2459,7 @@ class MethodTable // // get the method desc given the interface method desc - static MethodDesc *GetMethodDescForInterfaceMethodAndServer(TypeHandle ownerType, MethodDesc *pItfMD, OBJECTREF *pServer); + static MethodDesc *GetMethodDescForInterfaceMethodAndServer(TypeHandle ownerType, MethodDesc *pItfMD, OBJECTREF *pServer, MethodTable* pServerMT); #ifdef FEATURE_COMINTEROP // get the method desc given the interface method desc on a COM implemented server diff --git a/src/coreclr/vm/methodtable.inl b/src/coreclr/vm/methodtable.inl index 5bd6ddf711b680..e6b343e86a2e63 100644 --- a/src/coreclr/vm/methodtable.inl +++ b/src/coreclr/vm/methodtable.inl @@ -407,7 +407,7 @@ inline MethodDesc* MethodTable::GetMethodDescForSlot(DWORD slot) { THROWS; GC_NOTRIGGER; - MODE_ANY; + MODE_PREEMPTIVE; } CONTRACTL_END; diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index fb16290b29e561..586558485195ed 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -675,7 +675,7 @@ MethodTableBuilder::BuildMethodTableThrowException( CONTRACTL { THROWS; - GC_TRIGGERS; + GC_NOTRIGGER; INJECT_FAULT(COMPlusThrowOM();); } CONTRACTL_END @@ -6255,7 +6255,7 @@ MethodTableBuilder::InitMethodDesc( { THROWS; if (fEnC) { GC_NOTRIGGER; } else { GC_TRIGGERS; } - MODE_ANY; + MODE_PREEMPTIVE; } CONTRACTL_END; diff --git a/src/coreclr/vm/methodtablebuilder.h b/src/coreclr/vm/methodtablebuilder.h index fece0cc7c6f83f..d7096697f61d4f 100644 --- a/src/coreclr/vm/methodtablebuilder.h +++ b/src/coreclr/vm/methodtablebuilder.h @@ -2394,8 +2394,8 @@ class MethodTableBuilder CONTRACTL { THROWS; - GC_TRIGGERS; - MODE_ANY; + GC_NOTRIGGER; + MODE_PREEMPTIVE; } CONTRACTL_END; bmtError->resIDWhy = idResWhy; @@ -2416,8 +2416,8 @@ class MethodTableBuilder CONTRACTL { THROWS; - GC_TRIGGERS; - MODE_ANY; + GC_NOTRIGGER; + MODE_PREEMPTIVE; } CONTRACTL_END; bmtError->resIDWhy = idResWhy; diff --git a/src/coreclr/vm/perfmap.cpp b/src/coreclr/vm/perfmap.cpp index 6b11db5d85b585..6755eef8660445 100644 --- a/src/coreclr/vm/perfmap.cpp +++ b/src/coreclr/vm/perfmap.cpp @@ -463,7 +463,7 @@ void PerfMap::LogStubs(const char* stubType, const char* stubOwner, PCODE pCode, CONTRACTL { GC_NOTRIGGER; - MODE_ANY; + MODE_PREEMPTIVE; } CONTRACTL_END; diff --git a/src/coreclr/vm/perfmap.h b/src/coreclr/vm/perfmap.h index 17b1e645bf7efc..6595233416556a 100644 --- a/src/coreclr/vm/perfmap.h +++ b/src/coreclr/vm/perfmap.h @@ -32,6 +32,19 @@ class PerfMap return false; #endif } + +#ifdef FEATURE_INTERPRETER + // Log an interpreter IR bytecode range to the perfmap + static void LogInterpreterMethod(MethodDesc * pMethod, PCODE irAddress, size_t irSize) + { + CONTRACTL{ + NOTHROW; + GC_NOTRIGGER; + MODE_PREEMPTIVE; + } CONTRACTL_END; + } +#endif + static void LogJITCompiledMethod(MethodDesc * pMethod, PCODE pCode, size_t codeSize, PrepareCodeConfig *pConfig) { CONTRACTL @@ -57,7 +70,7 @@ class PerfMap CONTRACTL { GC_NOTRIGGER; - MODE_ANY; + MODE_PREEMPTIVE; } CONTRACTL_END; } diff --git a/src/coreclr/vm/precode.cpp b/src/coreclr/vm/precode.cpp index 6b72dee83957bc..07b6332c30a383 100644 --- a/src/coreclr/vm/precode.cpp +++ b/src/coreclr/vm/precode.cpp @@ -15,9 +15,7 @@ #include #endif // FEATURE_INTERPRETER -#ifdef FEATURE_PERFMAP #include "perfmap.h" -#endif InterleavedLoaderHeapConfig s_stubPrecodeHeapConfig; #ifdef HAS_FIXUP_PRECODE @@ -244,7 +242,7 @@ InterpreterPrecode* Precode::AllocateInterpreterPrecode(PCODE byteCode, { THROWS; GC_NOTRIGGER; - MODE_ANY; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -253,9 +251,7 @@ InterpreterPrecode* Precode::AllocateInterpreterPrecode(PCODE byteCode, FlushCacheForDynamicMappedStub(pPrecode, sizeof(InterpreterPrecode)); -#ifdef FEATURE_PERFMAP PerfMap::LogStubs(__FUNCTION__, "UMEntryThunk", (PCODE)pPrecode, sizeof(InterpreterPrecode), PerfMapStubType::IndividualWithinBlock); -#endif return pPrecode; } #endif // FEATURE_INTERPRETER @@ -268,7 +264,7 @@ Precode* Precode::Allocate(PrecodeType t, MethodDesc* pMD, { THROWS; GC_NOTRIGGER; - MODE_ANY; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -288,9 +284,7 @@ Precode* Precode::Allocate(PrecodeType t, MethodDesc* pMD, // to see the actual final Target (which doesn't require any further synchronization), or we'll hit the memory // barrier in the second portion of the FixupPrecodeThunk and find that the MethodDesc/PrecodeFixupThunk are // properly set. See FixupPrecode::GenerateDataPage for the code to fill in the target. -#ifdef FEATURE_PERFMAP PerfMap::LogStubs(__FUNCTION__, "FixupPrecode", (PCODE)pPrecode, sizeof(FixupPrecode), PerfMapStubType::IndividualWithinBlock); -#endif } #ifdef HAS_THISPTR_RETBUF_PRECODE else if (t == PRECODE_THISPTR_RETBUF) @@ -302,9 +296,7 @@ Precode* Precode::Allocate(PrecodeType t, MethodDesc* pMD, FlushCacheForDynamicMappedStub(pPrecode, sizeof(ThisPtrRetBufPrecode)); -#ifdef FEATURE_PERFMAP PerfMap::LogStubs(__FUNCTION__, "ThisPtrRetBuf", (PCODE)pPrecode, sizeof(ThisPtrRetBufPrecodeData), PerfMapStubType::IndividualWithinBlock); -#endif } #endif // HAS_THISPTR_RETBUF_PRECODE else @@ -315,9 +307,7 @@ Precode* Precode::Allocate(PrecodeType t, MethodDesc* pMD, FlushCacheForDynamicMappedStub(pPrecode, sizeof(StubPrecode)); -#ifdef FEATURE_PERFMAP PerfMap::LogStubs(__FUNCTION__, t == PRECODE_STUB ? "StubPrecode" : "PInvokeImportPrecode", (PCODE)pPrecode, sizeof(StubPrecode), PerfMapStubType::IndividualWithinBlock); -#endif } return pPrecode; diff --git a/src/coreclr/vm/prestub.cpp b/src/coreclr/vm/prestub.cpp index 0121ec3b946bdd..87d4ce4f9ebe54 100644 --- a/src/coreclr/vm/prestub.cpp +++ b/src/coreclr/vm/prestub.cpp @@ -33,9 +33,7 @@ #include "clrtocomcall.h" #endif -#ifdef FEATURE_PERFMAP #include "perfmap.h" -#endif #include "methoddescbackpatchinfo.h" @@ -371,10 +369,8 @@ PCODE MethodDesc::PrepareCode(PrepareCodeConfig* pConfig) pCode = GetPrecompiledCode(pConfig, shouldTier); } -#ifdef FEATURE_PERFMAP if (pCode != (PCODE)NULL) PerfMap::LogPreCompiledMethod(this, pCode); -#endif } if (pConfig->IsForMulticoreJit() && pCode == (PCODE)NULL && pConfig->ReadyToRunRejectedPrecompiledCode()) @@ -910,12 +906,15 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J } #endif // PROFILING_SUPPORTED -#ifdef FEATURE_PERFMAP #if defined(FEATURE_INTERPRETER) if (isInterpreterCode) { +#ifdef FEATURE_PORTABLE_ENTRYPOINTS + InterpByteCodeStart* interpreterCode = (InterpByteCodeStart*)PortableEntryPoint::GetInterpreterData(pCode); +#else InterpreterPrecode* pPrecode = InterpreterPrecode::FromEntryPoint(pCode); InterpByteCodeStart* interpreterCode = (InterpByteCodeStart*)pPrecode->GetData()->ByteCodeAddr; +#endif // !FEATURE_PORTABLE_ENTRYPOINTS PCODE irAddress = PINSTRToPCODE((TADDR)interpreterCode); PerfMap::LogInterpreterMethod(this, irAddress, sizeOfCode); } @@ -925,7 +924,6 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J // Save the JIT'd method information so that perf can resolve JIT'd call frames. PerfMap::LogJITCompiledMethod(this, pCode, sizeOfCode, pConfig); } -#endif // The notification will only occur if someone has registered for this method. DACNotifyCompilationFinished(this, pCode); @@ -2939,14 +2937,16 @@ EXTERN_C PCODE STDCALL ExternalMethodFixupWorker(TransitionBlock * pTransitionBl if (fVirtual) { - GCX_COOP_THREAD_EXISTS(CURRENT_THREAD); - // Get the stub manager for this module VirtualCallStubManager *pMgr = pModule->GetLoaderAllocator()->GetVirtualCallStubManager(); OBJECTREF *protectedObj = pEMFrame->GetThisPtr(); _ASSERTE(protectedObj != NULL); - if (*protectedObj == NULL) { + if (!*protectedObj) { + // NOTE: This is in a preemptive block, but the ! operator + // is safe to use on OBJECTREF even in preemptive mode + // (as long as the OBJECTREF is not on a managed object which + // in this case it is not) COMPlusThrow(kNullReferenceException); } @@ -2985,6 +2985,8 @@ EXTERN_C PCODE STDCALL ExternalMethodFixupWorker(TransitionBlock * pTransitionBl #endif } + GCX_COOP_THREAD_EXISTS(CURRENT_THREAD); + // We lost the race or the R2R image was generated without cached interface dispatch support, simply do the resolution in pure C++ DispatchToken token; if (pMT->IsInterface()) @@ -3010,6 +3012,7 @@ EXTERN_C PCODE STDCALL ExternalMethodFixupWorker(TransitionBlock * pTransitionBl token = pMT->GetLoaderAllocator()->GetDispatchToken(pMT->GetTypeID(), slot); StubCallSite callSite(pIndirection, pEMFrame->GetReturnAddress()); + GCX_COOP_THREAD_EXISTS(CURRENT_THREAD); pCode = pMgr->ResolveWorker(&callSite, protectedObj, token, STUB_CODE_BLOCK_VSD_LOOKUP_STUB); } else @@ -3850,6 +3853,10 @@ extern "C" SIZE_T STDCALL DynamicHelperWorker(TransitionBlock * pTransitionBlock if (objRef == NULL) COMPlusThrow(kNullReferenceException); + MethodTable* pMTObjRef = objRef->GetMethodTable(); + + GCX_PREEMP(); + // Duplicated logic from JIT_VirtualFunctionPointer_Framed if (!pMD->IsVtableMethod()) { @@ -3857,7 +3864,7 @@ extern "C" SIZE_T STDCALL DynamicHelperWorker(TransitionBlock * pTransitionBlock } else { - result = pMD->GetMultiCallableAddrOfVirtualizedCode(&objRef, th); + result = pMD->GetMultiCallableAddrOfVirtualizedCode(&objRef, pMTObjRef, th); } GCPROTECT_END(); diff --git a/src/coreclr/vm/qcall.h b/src/coreclr/vm/qcall.h index a64bf4a2d7836c..96d59421ae50dc 100644 --- a/src/coreclr/vm/qcall.h +++ b/src/coreclr/vm/qcall.h @@ -196,12 +196,24 @@ class QCall { Object** m_ppObject; + bool IsNull() const + { + LIMITED_METHOD_CONTRACT; + return *m_ppObject == NULL; + } + OBJECTREF Get() { LIMITED_METHOD_CONTRACT; return ObjectToOBJECTREF(*m_ppObject); } + Object** GetObjectPointer() const + { + LIMITED_METHOD_CONTRACT; + return m_ppObject; + } + #ifndef DACCESS_COMPILE // // Helpers for returning common managed types from QCall diff --git a/src/coreclr/vm/readytoruninfo.cpp b/src/coreclr/vm/readytoruninfo.cpp index 4d57671a2d9288..1a6743ddffab2c 100644 --- a/src/coreclr/vm/readytoruninfo.cpp +++ b/src/coreclr/vm/readytoruninfo.cpp @@ -20,9 +20,7 @@ #include "ilstubcache.h" #include "sigbuilder.h" -#ifdef FEATURE_PERFMAP #include "perfmap.h" -#endif #ifndef DACCESS_COMPILE extern "C" PCODE g_pMethodWithSlotAndModule; @@ -2542,9 +2540,7 @@ PCODE CreateDynamicHelperPrecode(LoaderAllocator *pAllocator, AllocMemTracker *p FlushCacheForDynamicMappedStub(pPrecode, sizeof(StubPrecode)); -#ifdef FEATURE_PERFMAP PerfMap::LogStubs(__FUNCTION__, "DynamicHelper", (PCODE)pPrecode, size, PerfMapStubType::IndividualWithinBlock); -#endif return ((Precode*)pPrecode)->GetEntryPoint(); } diff --git a/src/coreclr/vm/reflectioninvocation.cpp b/src/coreclr/vm/reflectioninvocation.cpp index ea47eb65a156ce..138ebca1576c1a 100644 --- a/src/coreclr/vm/reflectioninvocation.cpp +++ b/src/coreclr/vm/reflectioninvocation.cpp @@ -443,13 +443,18 @@ extern "C" void QCALLTYPE RuntimeMethodHandle_InvokeMethod( // This is duplicated logic from MethodDesc::GetCallTarget PCODE pTarget; - if (pMeth->IsVtableMethod()) { - pTarget = pMeth->GetSingleCallableAddrOfVirtualizedCode(&gc.target, ownerType); - } - else - { - pTarget = pMeth->GetSingleCallableAddrOfCode(); + if (pMeth->IsVtableMethod()) + { + MethodTable *pMT = gc.target->GetMethodTable(); + GCX_PREEMP(); + pTarget = pMeth->GetSingleCallableAddrOfVirtualizedCode(&gc.target, pMT, ownerType); + } + else + { + GCX_PREEMP(); + pTarget = pMeth->GetSingleCallableAddrOfCode(); + } } callDescrData.pTarget = pTarget; diff --git a/src/coreclr/vm/riscv64/stubs.cpp b/src/coreclr/vm/riscv64/stubs.cpp index 9064d3f844f5fd..10571d08e5ca19 100644 --- a/src/coreclr/vm/riscv64/stubs.cpp +++ b/src/coreclr/vm/riscv64/stubs.cpp @@ -14,9 +14,7 @@ #include "jitinterface.h" #include "ecall.h" -#ifdef FEATURE_PERFMAP #include "perfmap.h" -#endif #ifndef DACCESS_COMPILE //----------------------------------------------------------------------- @@ -1027,13 +1025,9 @@ void StubLinkerCPU::EmitCallManagedMethod(MethodDesc *pMD, BOOL fTailCall) size_t rxOffset = pStartRX - pStart; \ BYTE * p = pStart; -#ifdef FEATURE_PERFMAP #define BEGIN_DYNAMIC_HELPER_EMIT(size) \ BEGIN_DYNAMIC_HELPER_EMIT_WORKER(size) \ PerfMap::LogStubs(__FUNCTION__, "DynamicHelper", (PCODE)p, size, PerfMapStubType::Individual); -#else -#define BEGIN_DYNAMIC_HELPER_EMIT(size) BEGIN_DYNAMIC_HELPER_EMIT_WORKER(size) -#endif #define END_DYNAMIC_HELPER_EMIT() \ _ASSERTE(pStart + cb == p); \ diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 1e1fb0c0222cae..0857ebee305668 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -1947,22 +1947,23 @@ extern "C" MethodDesc* QCALLTYPE RuntimeMethodHandle_GetStubIfNeededSlow(MethodD BEGIN_QCALL; - GCX_COOP(); + TypeHandle* inst = NULL; + DWORD ntypars = 0; + if (pMethod->IsAsyncVariantMethod()) { // do not report async variants to reflection. pMethod = pMethod->GetOrdinaryVariant(/*allowInstParam*/ false); } - + TypeHandle instType = declaringTypeHandle.AsTypeHandle(); - - TypeHandle* inst = NULL; - DWORD ntypars = 0; - + // Construct TypeHandle array for instantiation. - if (methodInstantiation.Get() != NULL) + if (!methodInstantiation.IsNull()) { + GCX_COOP(); + ntypars = ((PTRARRAYREF)methodInstantiation.Get())->GetNumComponents(); size_t size = ntypars * sizeof(TypeHandle); @@ -2037,7 +2038,10 @@ extern "C" void QCALLTYPE RuntimeMethodHandle_GetMethodBody(MethodDesc* pMethod, { MethodDesc* pMethodIL = pMethod; if (pMethod->IsWrapperStub()) + { + GCX_PREEMP(); pMethodIL = pMethod->GetWrappedMethodDesc(); + } pILHeader = pMethodIL->GetILHeader(); } diff --git a/src/coreclr/vm/stublink.cpp b/src/coreclr/vm/stublink.cpp index 695b3542dd6f0b..36450b365f7bea 100644 --- a/src/coreclr/vm/stublink.cpp +++ b/src/coreclr/vm/stublink.cpp @@ -16,9 +16,7 @@ #include "rtlfunctions.h" -#ifdef FEATURE_PERFMAP #include "perfmap.h" -#endif #define S_BYTEPTR(x) S_SIZE_T((SIZE_T)(x)) @@ -563,9 +561,7 @@ Stub *StubLinker::Link(LoaderHeap *pHeap, DWORD flags, const char *stubType) EmitStub(pStub, globalsize, size, pHeap); -#ifdef FEATURE_PERFMAP PerfMap::LogStubs(__FUNCTION__, stubType, pStub->GetEntryPoint(), pStub->GetNumCodeBytes(), PerfMapStubType::Individual); -#endif return pStub.Detach(); } diff --git a/src/coreclr/vm/threads.cpp b/src/coreclr/vm/threads.cpp index b290e205367523..1616335ee6f080 100644 --- a/src/coreclr/vm/threads.cpp +++ b/src/coreclr/vm/threads.cpp @@ -51,9 +51,7 @@ #include #endif -#ifdef FEATURE_PERFMAP #include "perfmap.h" -#endif #include "exinfo.h" @@ -1028,13 +1026,13 @@ void InitThreadManagerPerfMapData() GC_TRIGGERS; } CONTRACTL_END; -#ifdef FEATURE_PERFMAP +#ifndef FEATURE_PORTABLE_HELPERS if (IsWriteBarrierCopyEnabled()) { size_t writeBarrierSize = (BYTE*)JIT_PatchedCodeLast - (BYTE*)JIT_PatchedCodeStart; PerfMap::LogStubs(__FUNCTION__, "JIT_CopiedWriteBarriers", (PCODE)s_barrierCopy, writeBarrierSize, PerfMapStubType::Individual); } -#endif +#endif // !FEATURE_PORTABLE_HELPERS } //--------------------------------------------------------------------------- @@ -6096,7 +6094,7 @@ Frame * Thread::NotifyFrameChainOfExceptionUnwind(Frame* pStartFrame, LPVOID pvL CONTRACTL { NOTHROW; - DISABLED(GC_TRIGGERS); // due to UnwindFrameChain from NOTRIGGER areas + GC_NOTRIGGER; MODE_COOPERATIVE; PRECONDITION(CheckPointer(pStartFrame)); PRECONDITION(CheckPointer(pvLimitSP)); diff --git a/src/coreclr/vm/virtualcallstub.cpp b/src/coreclr/vm/virtualcallstub.cpp index 0b1567592843c8..d5b16a8abfdd31 100644 --- a/src/coreclr/vm/virtualcallstub.cpp +++ b/src/coreclr/vm/virtualcallstub.cpp @@ -98,11 +98,23 @@ struct CachedIndirectionCellBlockListNode BYTE* GenerateDispatchStubCellEntryMethodDesc(LoaderAllocator *pLoaderAllocator, TypeHandle ownerType, MethodDesc *pMD, LCGMethodResolver *pResolver) { + CONTRACTL { + THROWS; + GC_TRIGGERS; + MODE_PREEMPTIVE; + } CONTRACTL_END; + return GenerateDispatchStubCellEntrySlot(pLoaderAllocator, ownerType, pMD->GetSlot(), pResolver); } BYTE* GenerateDispatchStubCellEntrySlot(LoaderAllocator *pLoaderAllocator, TypeHandle ownerType, int methodSlot, LCGMethodResolver *pResolver) { + CONTRACTL { + THROWS; + GC_TRIGGERS; + MODE_PREEMPTIVE; + } CONTRACTL_END; + VirtualCallStubManager * pMgr = pLoaderAllocator->GetVirtualCallStubManager(); DispatchToken token = VirtualCallStubManager::GetTokenFromOwnerAndSlot(ownerType, methodSlot); @@ -992,7 +1004,7 @@ DispatchToken VirtualCallStubManager::GetTokenFromOwnerAndSlot(TypeHandle ownerT { THROWS; GC_TRIGGERS; - MODE_ANY; + MODE_PREEMPTIVE; INJECT_FAULT(COMPlusThrowOM();); } CONTRACTL_END @@ -1015,7 +1027,7 @@ PCODE VirtualCallStubManager::GetCallStub(TypeHandle ownerType, MethodDesc *pMD) CONTRACTL { THROWS; GC_TRIGGERS; - MODE_ANY; + MODE_PREEMPTIVE; PRECONDITION(CheckPointer(pMD)); PRECONDITION(!pMD->IsInterface() || ownerType.GetMethodTable()->HasSameTypeDefAs(pMD->GetMethodTable())); INJECT_FAULT(COMPlusThrowOM();); @@ -1485,7 +1497,12 @@ extern "C" PCODE CID_VirtualOpenDelegateDispatchWorker(TransitionBlock * pTransi GCStress::MaybeTriggerAndProtect(pObj); - DispatchToken token = VirtualCallStubManager::GetTokenFromOwnerAndSlot(TypeHandle(pTargetMD->GetMethodTable()), pTargetMD->GetSlot()); + DispatchToken token; + + { + GCX_PREEMP(); + token = VirtualCallStubManager::GetTokenFromOwnerAndSlot(TypeHandle(pTargetMD->GetMethodTable()), pTargetMD->GetSlot()); + } target = CachedInterfaceDispatchResolveWorker(NULL, protectedObj, token); #if _DEBUG diff --git a/src/coreclr/vm/wasm/browser/callhelpers-interp-to-managed.cpp b/src/coreclr/vm/wasm/browser/callhelpers-interp-to-managed.cpp index 08980a9ddf67e2..dc7af3ffa4ea3a 100644 --- a/src/coreclr/vm/wasm/browser/callhelpers-interp-to-managed.cpp +++ b/src/coreclr/vm/wasm/browser/callhelpers-interp-to-managed.cpp @@ -204,28 +204,28 @@ namespace *((int32_t*)pRet) = (*fptr)(ARG_I32(0), ARG_I32(1)); } - static void CallFunc_I32_I32_S8_I32_I32_RetI32(PCODE pcode, int8_t* pArgs, int8_t* pRet) - { - int32_t (*fptr)(int32_t, int32_t, int32_t, int32_t, int32_t) = (int32_t (*)(int32_t, int32_t, int32_t, int32_t, int32_t))pcode; - *((int32_t*)pRet) = (*fptr)(ARG_I32(0), ARG_I32(1), ARG_IND(2), ARG_I32(3), ARG_I32(4)); - } - static void CallFunc_I32_I32_S8_I32_I32_S8_RetI32(PCODE pcode, int8_t* pArgs, int8_t* pRet) { int32_t (*fptr)(int32_t, int32_t, int32_t, int32_t, int32_t, int32_t) = (int32_t (*)(int32_t, int32_t, int32_t, int32_t, int32_t, int32_t))pcode; *((int32_t*)pRet) = (*fptr)(ARG_I32(0), ARG_I32(1), ARG_IND(2), ARG_I32(3), ARG_I32(4), ARG_IND(5)); } + static void CallFunc_I32_I32_S8_I32_I32_I32_I32_RetI32(PCODE pcode, int8_t* pArgs, int8_t* pRet) + { + int32_t (*fptr)(int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t) = (int32_t (*)(int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t))pcode; + *((int32_t*)pRet) = (*fptr)(ARG_I32(0), ARG_I32(1), ARG_IND(2), ARG_I32(3), ARG_I32(4), ARG_I32(5), ARG_I32(6)); + } + static void CallFunc_I32_I32_I32_RetI32(PCODE pcode, int8_t* pArgs, int8_t* pRet) { int32_t (*fptr)(int32_t, int32_t, int32_t) = (int32_t (*)(int32_t, int32_t, int32_t))pcode; *((int32_t*)pRet) = (*fptr)(ARG_I32(0), ARG_I32(1), ARG_I32(2)); } - static void CallFunc_I32_I32_I32_S8_I32_RetI32(PCODE pcode, int8_t* pArgs, int8_t* pRet) + static void CallFunc_I32_I32_I32_S8_I32_I32_I32_RetI32(PCODE pcode, int8_t* pArgs, int8_t* pRet) { - int32_t (*fptr)(int32_t, int32_t, int32_t, int32_t, int32_t) = (int32_t (*)(int32_t, int32_t, int32_t, int32_t, int32_t))pcode; - *((int32_t*)pRet) = (*fptr)(ARG_I32(0), ARG_I32(1), ARG_I32(2), ARG_IND(3), ARG_I32(4)); + int32_t (*fptr)(int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t) = (int32_t (*)(int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t))pcode; + *((int32_t*)pRet) = (*fptr)(ARG_I32(0), ARG_I32(1), ARG_I32(2), ARG_IND(3), ARG_I32(4), ARG_I32(5), ARG_I32(6)); } static void CallFunc_I32_I32_I32_I32_RetI32(PCODE pcode, int8_t* pArgs, int8_t* pRet) @@ -692,10 +692,10 @@ const StringToWasmSigThunk g_wasmThunks[] = { { "MiiS8i", (void*)&CallFunc_I32_S8_I32_RetI32 }, { "MiiS8iii", (void*)&CallFunc_I32_S8_I32_I32_I32_RetI32 }, { "Miii", (void*)&CallFunc_I32_I32_RetI32 }, - { "MiiiS8ii", (void*)&CallFunc_I32_I32_S8_I32_I32_RetI32 }, { "MiiiS8iiS8", (void*)&CallFunc_I32_I32_S8_I32_I32_S8_RetI32 }, + { "MiiiS8iiii", (void*)&CallFunc_I32_I32_S8_I32_I32_I32_I32_RetI32 }, { "Miiii", (void*)&CallFunc_I32_I32_I32_RetI32 }, - { "MiiiiS8i", (void*)&CallFunc_I32_I32_I32_S8_I32_RetI32 }, + { "MiiiiS8iii", (void*)&CallFunc_I32_I32_I32_S8_I32_I32_I32_RetI32 }, { "Miiiii", (void*)&CallFunc_I32_I32_I32_I32_RetI32 }, { "Miiiiii", (void*)&CallFunc_I32_I32_I32_I32_I32_RetI32 }, { "Miiiiiii", (void*)&CallFunc_I32_I32_I32_I32_I32_I32_RetI32 }, diff --git a/src/coreclr/vm/wasm/browser/callhelpers-reverse.cpp b/src/coreclr/vm/wasm/browser/callhelpers-reverse.cpp index e690a467933715..571bfb64e85cb7 100644 --- a/src/coreclr/vm/wasm/browser/callhelpers-reverse.cpp +++ b/src/coreclr/vm/wasm/browser/callhelpers-reverse.cpp @@ -688,54 +688,6 @@ static void Call_System_Private_CoreLib_System_StubHelpers_StubHelpers_LayoutTyp ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_StubHelpers_StubHelpers_LayoutTypeConvertToUnmanaged_I32_I32_I32_RetVoid, (int8_t*)args, sizeof(args), nullptr, (PCODE)&Call_System_Private_CoreLib_System_StubHelpers_StubHelpers_LayoutTypeConvertToUnmanaged_I32_I32_I32_RetVoid); } -static MethodDesc* MD_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssembly_I32_I32_I32_RetI32 = nullptr; -static int32_t Call_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssembly_I32_I32_I32_RetI32(void * arg0, void * arg1, void * arg2) -{ - int64_t args[3] = { (int64_t)arg0, (int64_t)arg1, (int64_t)arg2 }; - - // Lazy lookup of MethodDesc for the function export scenario. - if (!MD_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssembly_I32_I32_I32_RetI32) - { - LookupUnmanagedCallersOnlyMethodByName("Internal.Runtime.InteropServices.ComponentActivator, System.Private.CoreLib", "LoadAssembly", &MD_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssembly_I32_I32_I32_RetI32); - } - - int32_t result; - ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssembly_I32_I32_I32_RetI32, (int8_t*)args, sizeof(args), (int8_t*)&result, (PCODE)&Call_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssembly_I32_I32_I32_RetI32); - return result; -} - -static MethodDesc* MD_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssemblyAndGetFunctionPointer_I32_I32_I32_I32_I32_I32_RetI32 = nullptr; -static int32_t Call_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssemblyAndGetFunctionPointer_I32_I32_I32_I32_I32_I32_RetI32(void * arg0, void * arg1, void * arg2, void * arg3, void * arg4, void * arg5) -{ - int64_t args[6] = { (int64_t)arg0, (int64_t)arg1, (int64_t)arg2, (int64_t)arg3, (int64_t)arg4, (int64_t)arg5 }; - - // Lazy lookup of MethodDesc for the function export scenario. - if (!MD_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssemblyAndGetFunctionPointer_I32_I32_I32_I32_I32_I32_RetI32) - { - LookupUnmanagedCallersOnlyMethodByName("Internal.Runtime.InteropServices.ComponentActivator, System.Private.CoreLib", "LoadAssemblyAndGetFunctionPointer", &MD_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssemblyAndGetFunctionPointer_I32_I32_I32_I32_I32_I32_RetI32); - } - - int32_t result; - ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssemblyAndGetFunctionPointer_I32_I32_I32_I32_I32_I32_RetI32, (int8_t*)args, sizeof(args), (int8_t*)&result, (PCODE)&Call_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssemblyAndGetFunctionPointer_I32_I32_I32_I32_I32_I32_RetI32); - return result; -} - -static MethodDesc* MD_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssemblyBytes_I32_I32_I32_I32_I32_I32_RetI32 = nullptr; -static int32_t Call_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssemblyBytes_I32_I32_I32_I32_I32_I32_RetI32(void * arg0, void * arg1, void * arg2, void * arg3, void * arg4, void * arg5) -{ - int64_t args[6] = { (int64_t)arg0, (int64_t)arg1, (int64_t)arg2, (int64_t)arg3, (int64_t)arg4, (int64_t)arg5 }; - - // Lazy lookup of MethodDesc for the function export scenario. - if (!MD_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssemblyBytes_I32_I32_I32_I32_I32_I32_RetI32) - { - LookupUnmanagedCallersOnlyMethodByName("Internal.Runtime.InteropServices.ComponentActivator, System.Private.CoreLib", "LoadAssemblyBytes", &MD_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssemblyBytes_I32_I32_I32_I32_I32_I32_RetI32); - } - - int32_t result; - ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssemblyBytes_I32_I32_I32_I32_I32_I32_RetI32, (int8_t*)args, sizeof(args), (int8_t*)&result, (PCODE)&Call_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssemblyBytes_I32_I32_I32_I32_I32_I32_RetI32); - return result; -} - static MethodDesc* MD_System_Private_CoreLib_System_Runtime_InteropServices_NativeLibrary_LoadLibraryCallbackStub_I32_I32_I32_I32_I32_RetI32 = nullptr; static void * Call_System_Private_CoreLib_System_Runtime_InteropServices_NativeLibrary_LoadLibraryCallbackStub_I32_I32_I32_I32_I32_RetI32(void * arg0, void * arg1, int32_t arg2, uint32_t arg3, void * arg4) { @@ -1233,9 +1185,6 @@ const ReverseThunkMapEntry g_ReverseThunks[] = { 3290644746, "IsInterfaceImplemented#5:System.Private.CoreLib:System.Runtime.InteropServices:DynamicInterfaceCastableHelpers", { &MD_System_Private_CoreLib_System_Runtime_InteropServices_DynamicInterfaceCastableHelpers_IsInterfaceImplemented_I32_I32_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Runtime_InteropServices_DynamicInterfaceCastableHelpers_IsInterfaceImplemented_I32_I32_I32_I32_I32_RetVoid } }, { 1577711579, "LayoutTypeConvertToManaged#3:System.Private.CoreLib:System.StubHelpers:StubHelpers", { &MD_System_Private_CoreLib_System_StubHelpers_StubHelpers_LayoutTypeConvertToManaged_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_StubHelpers_StubHelpers_LayoutTypeConvertToManaged_I32_I32_I32_RetVoid } }, { 2780693056, "LayoutTypeConvertToUnmanaged#3:System.Private.CoreLib:System.StubHelpers:StubHelpers", { &MD_System_Private_CoreLib_System_StubHelpers_StubHelpers_LayoutTypeConvertToUnmanaged_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_StubHelpers_StubHelpers_LayoutTypeConvertToUnmanaged_I32_I32_I32_RetVoid } }, - { 3422156547, "LoadAssembly#3:System.Private.CoreLib:Internal.Runtime.InteropServices:ComponentActivator", { &MD_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssembly_I32_I32_I32_RetI32, (void*)&Call_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssembly_I32_I32_I32_RetI32 } }, - { 542185314, "LoadAssemblyAndGetFunctionPointer#6:System.Private.CoreLib:Internal.Runtime.InteropServices:ComponentActivator", { &MD_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssemblyAndGetFunctionPointer_I32_I32_I32_I32_I32_I32_RetI32, (void*)&Call_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssemblyAndGetFunctionPointer_I32_I32_I32_I32_I32_I32_RetI32 } }, - { 3765950975, "LoadAssemblyBytes#6:System.Private.CoreLib:Internal.Runtime.InteropServices:ComponentActivator", { &MD_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssemblyBytes_I32_I32_I32_I32_I32_I32_RetI32, (void*)&Call_System_Private_CoreLib_Internal_Runtime_InteropServices_ComponentActivator_LoadAssemblyBytes_I32_I32_I32_I32_I32_I32_RetI32 } }, { 1086681967, "LoadLibraryCallbackStub#5:System.Private.CoreLib:System.Runtime.InteropServices:NativeLibrary", { &MD_System_Private_CoreLib_System_Runtime_InteropServices_NativeLibrary_LoadLibraryCallbackStub_I32_I32_I32_I32_I32_RetI32, (void*)&Call_System_Private_CoreLib_System_Runtime_InteropServices_NativeLibrary_LoadLibraryCallbackStub_I32_I32_I32_I32_I32_RetI32 } }, { 705270488, "ManagedStartup#2:System.Private.CoreLib:System:StartupHookProvider", { &MD_System_Private_CoreLib_System_StartupHookProvider_ManagedStartup_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_StartupHookProvider_ManagedStartup_I32_I32_RetVoid } }, { 343912841, "NewExternalTypeEntry#2:System.Private.CoreLib:System.Runtime.InteropServices:TypeMapLazyDictionary", { &MD_System_Private_CoreLib_System_Runtime_InteropServices_TypeMapLazyDictionary_NewExternalTypeEntry_I32_I32_RetI32, (void*)&Call_System_Private_CoreLib_System_Runtime_InteropServices_TypeMapLazyDictionary_NewExternalTypeEntry_I32_I32_RetI32 } }, diff --git a/src/tasks/WasmAppBuilder/generate-coreclr-helpers.cmd b/src/tasks/WasmAppBuilder/generate-coreclr-helpers.cmd index 0a6108bf4e77e9..c2a84e7fa6e1c5 100644 --- a/src/tasks/WasmAppBuilder/generate-coreclr-helpers.cmd +++ b/src/tasks/WasmAppBuilder/generate-coreclr-helpers.cmd @@ -81,8 +81,8 @@ echo Scan path: %scan_path% :: Run the generator - invoke directly without building a command string echo Running generator... -echo .\dotnet.cmd build /t:RunGenerator /p:RuntimeFlavor=CoreCLR /p:GeneratorOutputPath=%repo_root%\src\coreclr\vm\wasm\ /p:AssembliesScanPath=%scan_path% src\tasks\WasmAppBuilder\WasmAppBuilder.csproj -.\dotnet.cmd build /t:RunGenerator /p:RuntimeFlavor=CoreCLR /p:GeneratorOutputPath=%repo_root%\src\coreclr\vm\wasm\ /p:AssembliesScanPath=%scan_path% src\tasks\WasmAppBuilder\WasmAppBuilder.csproj +echo .\dotnet.cmd build /t:RunGenerator /p:RuntimeFlavor=CoreCLR /p:GeneratorOutputPath=%repo_root%\src\coreclr\vm\wasm\browser\ /p:AssembliesScanPath=%scan_path% src\tasks\WasmAppBuilder\WasmAppBuilder.csproj +.\dotnet.cmd build /t:RunGenerator /p:RuntimeFlavor=CoreCLR /p:GeneratorOutputPath=%repo_root%\src\coreclr\vm\wasm\browser\ /p:AssembliesScanPath=%scan_path% src\tasks\WasmAppBuilder\WasmAppBuilder.csproj if errorlevel 1 ( echo Generator failed! diff --git a/src/tasks/WasmAppBuilder/generate-coreclr-helpers.sh b/src/tasks/WasmAppBuilder/generate-coreclr-helpers.sh index 8275e93339fb31..4b69007b551326 100755 --- a/src/tasks/WasmAppBuilder/generate-coreclr-helpers.sh +++ b/src/tasks/WasmAppBuilder/generate-coreclr-helpers.sh @@ -71,7 +71,7 @@ echo "Scan path: $scan_path" # Run the generator - invoke directly without building a command string echo "Running generator..." -echo "./dotnet.sh build /t:RunGenerator /p:RuntimeFlavor=CoreCLR /p:GeneratorOutputPath=$repo_root/src/coreclr/vm/wasm/ /p:AssembliesScanPath=$scan_path src/tasks/WasmAppBuilder/WasmAppBuilder.csproj" -./dotnet.sh build /t:RunGenerator /p:RuntimeFlavor=CoreCLR "/p:GeneratorOutputPath=$repo_root/src/coreclr/vm/wasm/" "/p:AssembliesScanPath=$scan_path" src/tasks/WasmAppBuilder/WasmAppBuilder.csproj +echo "./dotnet.sh build /t:RunGenerator /p:RuntimeFlavor=CoreCLR /p:GeneratorOutputPath=$repo_root/src/coreclr/vm/wasm/browser/ /p:AssembliesScanPath=$scan_path src/tasks/WasmAppBuilder/WasmAppBuilder.csproj" +./dotnet.sh build /t:RunGenerator /p:RuntimeFlavor=CoreCLR "/p:GeneratorOutputPath=$repo_root/src/coreclr/vm/wasm/browser/" "/p:AssembliesScanPath=$scan_path" src/tasks/WasmAppBuilder/WasmAppBuilder.csproj echo "Done!"