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 ea1d1ed65a2dac..b27d21da100350 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs @@ -494,27 +494,82 @@ 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; + _extraData = bindToMethodDetails.extraData; + if (bindToMethodDetails.loaderAllocatorGCHandle.IsAllocated) + { + _helperObject = bindToMethodDetails.loaderAllocatorGCHandle.Target; + GC.KeepAlive(methodType); + } + + 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 extraData; + 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 + { + 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; + _extraData = bindToMethodDetails.extraData; + 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 Delegate InternalAlloc(RuntimeType type) { @@ -562,12 +617,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; + _extraData = bindToMethodDetails.extraData; + 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); @@ -805,11 +879,16 @@ private static Wrapper[] DeleteFromInvocationList(ReadOnlySpan invocati 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/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 b6cd7f8b458621..0c28e5e7b9ebe2 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 1b7134247e61c5..81b0dff3c61034 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 IntPtr GetNativeCodeInternal(IRuntimeMethodInfo method) { - IntPtr value = GetNativeCode(method.Value); + IntPtr value = GetNativeCode(IRuntimeMethodInfo.GetValue(method)); GC.KeepAlive(method); return value; } @@ -1307,7 +1306,7 @@ internal static IntPtr GetNativeCodeInternal(IRuntimeMethodInfo method) internal static bool IsGenericMethodDefinition(IRuntimeMethodInfo method) { - bool fRet = IsGenericMethodDefinition(method.Value); + bool fRet = IsGenericMethodDefinition(IRuntimeMethodInfo.GetValue(method)); GC.KeepAlive(method); return fRet; } @@ -1322,7 +1321,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); } @@ -1332,7 +1331,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); @@ -1341,7 +1340,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; @@ -1362,7 +1361,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; } @@ -2091,7 +2090,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); @@ -2101,7 +2100,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 28b67b722794cc..385586e0b04817 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/hosts/corerun/CMakeLists.txt b/src/coreclr/hosts/corerun/CMakeLists.txt index a4f9237fa7c95a..4e480bdc187a61 100644 --- a/src/coreclr/hosts/corerun/CMakeLists.txt +++ b/src/coreclr/hosts/corerun/CMakeLists.txt @@ -122,11 +122,14 @@ else() # required because clang only recognizes well-known linker # names (lld/bfd/gold/etc.) by short name. get_filename_component(_wasi_sdk_bin "${CMAKE_C_COMPILER}" DIRECTORY) + set(_wasi_http_world_wit + "${CLR_DIR}/../libraries/System.Net.Http/src/System/Net/Http/WasiHttpHandler/WasiHttpWorld_component_type.wit") target_link_options(corerun PRIVATE "-fuse-ld=${_wasi_sdk_bin}/wasm-component-ld" -Wl,-z,stack-size=8388608 -Wl,--initial-memory=134217728 - -Wl,--max-memory=4294967296) + -Wl,--max-memory=4294967296 + "-Wl,--component-type,${_wasi_http_world_wit}") endif() if (CORERUN_IN_BROWSER) 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 9078e0af64b0b6..330974dbb9ede1 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(); + } #ifdef FEATURE_PORTABLE_ENTRYPOINTS // The entry point is invoked from R2R-compiled code (Environment.CallEntryPoint performs an // indirect call through this address), so it must resolve to real code (native R2R or a @@ -1704,7 +1708,8 @@ void Assembly::AddType( CONTRACTL { THROWS; - GC_TRIGGERS; + GC_NOTRIGGER; + MODE_PREEMPTIVE; INJECT_FAULT(COMPlusThrowOM();); } CONTRACTL_END @@ -1730,7 +1735,8 @@ void Assembly::AddExportedType(mdExportedType cl) CONTRACTL { THROWS; - GC_TRIGGERS; + GC_NOTRIGGER; + MODE_PREEMPTIVE; INJECT_FAULT(COMPlusThrowOM();); } CONTRACTL_END @@ -1994,6 +2000,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 45c1532c74fb09..1cb14f390c6507 100644 --- a/src/coreclr/vm/callhelpers.cpp +++ b/src/coreclr/vm/callhelpers.cpp @@ -568,11 +568,16 @@ void CallDefaultConstructor(OBJECTREF ref) GCPROTECT_BEGIN (ref); - MethodDesc *pMD = pMT->GetDefaultConstructor(); + + PCODE ctorCode; + { + GCX_PREEMP(); + MethodDesc *pMD = pMT->GetDefaultConstructor(); + ctorCode = pMD->GetSingleCallableAddrOfCode(); + } UnmanagedCallersOnlyCaller defaultCtorInvoker{METHOD__RUNTIME_HELPERS__CALL_DEFAULT_CONSTRUCTOR}; - PCODE ctorCode = pMD->GetSingleCallableAddrOfCode(); #ifdef FEATURE_PORTABLE_ENTRYPOINTS // CallDefaultConstructor invokes the ctor via the function pointer, so its portable entrypoint // must resolve to real code if possible. 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 7d7e9e40d1692f..72f6987316ebd0 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)) @@ -641,8 +641,8 @@ void Module::ApplyMetaData() CONTRACTL { THROWS; - GC_TRIGGERS; - MODE_ANY; + GC_NOTRIGGER; + MODE_PREEMPTIVE; } CONTRACTL_END; @@ -959,7 +959,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 57e76f0cf1bf45..c3258d39098825 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 a9e7eb3c486ae9..8997781757cc75 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 @@ -6239,7 +6237,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); @@ -6327,6 +6325,7 @@ PCODE ExecutionManager::getNextJumpStub(MethodDesc* pMD, PCODE target, bool throwOnOutOfMemoryWithinRange) { CONTRACT(PCODE) { + MODE_PREEMPTIVE; THROWS; GC_NOTRIGGER; PRECONDITION(pLoaderAllocator != NULL); @@ -6434,9 +6433,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 c96fecef5d105e..787b448aa27922 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 91e19a289925b6..603689ad1474a9 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 ec13d9199f6f66..78ec59161e6879 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 1c596f4e7d2de2..f33fcf994e1cfb 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,8 +1198,7 @@ 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); + pBindToMethodDetails->methodPtrAux = GetVirtualCallStub(pTargetMethod, TypeHandle(pExactMethodType)); } else { @@ -1251,12 +1222,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). @@ -1266,10 +1237,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()) @@ -1282,18 +1254,15 @@ void COMDelegate::BindToMethod(DELEGATEREF *pRefThis, pTargetCode = pTargetMethod->GetMultiCallableAddrOfCode(); } _ASSERTE(pTargetCode); - - (*pRefThis)->SetTarget(*pRefFirstArg); - (*pRefThis)->SetMethodPtr(pTargetCode); + pBindToMethodDetails->methodPtr = pTargetCode; } - (*pRefThis)->SetExtraData((INT_PTR)pTargetMethod); + pBindToMethodDetails->extraData = (INT_PTR)pTargetMethod; LoaderAllocator *pLoaderAllocator = pTargetMethod->GetLoaderAllocator(); - _ASSERTE((*pRefThis)->GetHelperObject() == NULL); - 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. @@ -1340,6 +1309,7 @@ LPVOID COMDelegate::ConvertToCallback(OBJECTREF pDelegateObj) InteropSyncBlockInfo* pInteropInfo = pSyncBlock->GetInteropInfo(); + GCX_PREEMP(); pUMEntryThunk = pInteropInfo->GetUMEntryThunk(); if (!pUMEntryThunk) @@ -1349,8 +1319,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); @@ -1367,15 +1335,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(); - // 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(); + // 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. + pManagedTargetForDiagnostics = (pDelegate->GetMethodPtrAux() != (PCODE)NULL) ? pDelegate->GetMethodPtrAux() : pDelegate->GetMethodPtr(); + } // MethodDesc is passed in for profiling to know the method desc of target pUMEntryThunk->LoadTimeInit( @@ -1575,13 +1550,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->SetExtraData((INT_PTR)(void*)pMeth); @@ -1589,18 +1564,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()); @@ -1653,7 +1622,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; @@ -1662,23 +1631,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); @@ -1707,38 +1668,40 @@ extern "C" void QCALLTYPE Delegate_Construct(QCall::ObjectHandleOnStack _this, Q if (!isStatic) methodArgCount++; // count 'this' - _ASSERTE(refThis->GetHelperObject() == NULL); - 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); + PCODE pTargetCall; + { + pTargetCall = GetVirtualCallStub(pMeth, TypeHandle(pMeth->GetMethodTable())); + } + pBindToMethodDetails->methodPtrAux = pTargetCall; } 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) @@ -1778,13 +1741,11 @@ 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; } - refThis->SetExtraData((INT_PTR)pMeth); + pBindToMethodDetails->extraData = (INT_PTR)pMeth; - GCPROTECT_END(); END_QCALL; } @@ -1970,10 +1931,10 @@ extern "C" void QCALLTYPE Delegate_CreateMethodInfo(MethodDesc* methodDesc, QCal BEGIN_QCALL; - GCX_COOP(); - MethodDesc* pMD = methodDesc; pMD = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMD, TypeHandle(pMD->GetMethodTable()), pMD->GetMethodInstantiation()); + + GCX_COOP(); retMethodInfo.Set(pMD->AllocateStubMethodInfo()); END_QCALL; diff --git a/src/coreclr/vm/comdelegate.h b/src/coreclr/vm/comdelegate.h index 102d157d3782f7..263027c2bbc789 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 extraData; + 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 { @@ -79,18 +88,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); @@ -107,11 +118,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_CreateMethodInfo(MethodDesc* methodDesc, QCall::ObjectHandleOnStack retMethodInfo); diff --git a/src/coreclr/vm/comutilnative.cpp b/src/coreclr/vm/comutilnative.cpp index 85b0ec6fabd68d..cc60554cf4cbf7 100644 --- a/src/coreclr/vm/comutilnative.cpp +++ b/src/coreclr/vm/comutilnative.cpp @@ -775,18 +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(); + + OBJECTREF target = FinalizerThread::GetNextFinalizableObject(); - MethodTable* pMT = target->GetMethodTable(); + if (target != NULL) + { + pObj.Set(target); - funcPtr = pMT->GetRestoredSlot(g_pObjectFinalizerMD->GetSlot()); + pTargetMT = target->GetMethodTable(); + } + } + if (pTargetMT != NULL) + { + funcPtr = pTargetMT->GetRestoredSlot(g_pObjectFinalizerMD->GetSlot()); #ifdef FEATURE_PORTABLE_ENTRYPOINTS // RunFinalizers invokes the finalizer via the function pointer, so its portable entrypoint must // resolve to real code if possible. 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 8e9c2761c40f70..d0f35b8bbdb3ba 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 2b3d0c84d5ebd5..73cb3a15cfc6b7 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 678b2a089fbbf6..c6b267c184db0d 100644 --- a/src/coreclr/vm/interpexec.cpp +++ b/src/coreclr/vm/interpexec.cpp @@ -3235,8 +3235,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); } @@ -3402,7 +3403,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 e66b5a6aebc298..8ceb8647a238f0 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 1eab4d07217835..5bb833b15d8527 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 34aae34dc52420..57d5e6726bc84e 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -1595,7 +1595,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. @@ -1605,8 +1605,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. @@ -1822,7 +1822,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: @@ -1839,7 +1839,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(); @@ -3939,9 +3939,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 652729a8755543..49dba0b1f7ee46 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()); @@ -3567,7 +3573,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; #ifdef FEATURE_PORTABLE_ENTRYPOINTS @@ -7924,7 +7934,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 ba51bfaa9ae311..ad90c8b130abb5 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -2482,7 +2482,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 c9984deef79a1b..ca229d3e0056df 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 @@ -6266,7 +6266,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 5e9eb120000e67..4c00e438941de2 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); @@ -2950,14 +2948,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); } @@ -2996,6 +2996,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()) @@ -3021,6 +3023,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 @@ -3861,6 +3864,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()) { @@ -3868,7 +3875,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 30f7bc42853377..f6c82585f80948 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); @@ -2064,7 +2065,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 a5a8458135d362..86965ccd3314d9 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" @@ -1041,13 +1039,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 } //--------------------------------------------------------------------------- @@ -6109,7 +6107,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 d0d194b260f4b9..1139d8a286d64d 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/coreclr/vm/wasm/wasi/callhelpers-interp-to-managed.cpp b/src/coreclr/vm/wasm/wasi/callhelpers-interp-to-managed.cpp index 6359b4d3ede92a..0033e59ea2469e 100644 --- a/src/coreclr/vm/wasm/wasi/callhelpers-interp-to-managed.cpp +++ b/src/coreclr/vm/wasm/wasi/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) @@ -668,10 +668,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/wasi/callhelpers-pinvoke.cpp b/src/coreclr/vm/wasm/wasi/callhelpers-pinvoke.cpp index 5e23ab70e7bd98..5e0f6af613063f 100644 --- a/src/coreclr/vm/wasm/wasi/callhelpers-pinvoke.cpp +++ b/src/coreclr/vm/wasm/wasi/callhelpers-pinvoke.cpp @@ -11,6 +11,7 @@ #include extern "C" { + uint32_t CompressionNative_CompressBound (uint32_t); uint32_t CompressionNative_Crc32 (uint32_t, void *, int32_t); int32_t CompressionNative_Deflate (void *, int32_t); int32_t CompressionNative_DeflateEnd (void *); @@ -119,7 +120,7 @@ extern "C" { int64_t SystemNative_GetSystemTimeAsTicks (); void * SystemNative_GetTimeZoneData (void *, void *); int64_t SystemNative_GetTimestamp (); - int32_t SystemNative_GetWasiSocketDescriptor (void *, void *); + int32_t SystemNative_GetWasiSocketDescriptor (void *, void *, void *); int32_t SystemNative_IsMemfdSupported (); int32_t SystemNative_LChflags (void *, uint32_t); int32_t SystemNative_LChflagsCanSetHiddenFlag (); @@ -196,14 +197,57 @@ extern "C" { int32_t SystemNative_TryGetIPPacketInformation (void *, int32_t, void *); int32_t SystemNative_UTimensat (void *, void *); int32_t SystemNative_Unlink (void *); + int32_t SystemNative_WasiSubscribeSocketPollable (int32_t, int32_t); int32_t SystemNative_Write (void *, void *, int32_t); int32_t SystemNative_WriteToNonblocking (void *, void *, int32_t); int64_t SystemNative_WriteV (void *, void *, int32_t); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[constructor]outgoing-request"))) extern int32_t WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_constructor_5D_outgoing_request (int32_t); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[method]fields.entries"))) extern void WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_fields_entries (int32_t, void *); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[method]future-incoming-response.get"))) extern void WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_future_incoming_response_get (int32_t, void *); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[method]future-incoming-response.subscribe"))) extern int32_t WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_future_incoming_response_subscribe (int32_t); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[method]incoming-body.stream"))) extern void WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_incoming_body_stream (int32_t, void *); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[method]incoming-response.consume"))) extern void WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_incoming_response_consume (int32_t, void *); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[method]incoming-response.headers"))) extern int32_t WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_incoming_response_headers (int32_t); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[method]incoming-response.status"))) extern int32_t WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_incoming_response_status (int32_t); + __attribute__((import_module("wasi:io/streams@0.2.8"),import_name("[method]input-stream.read"))) extern void WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_streams_40_0_2_8_23__5B_method_5D_input_stream_read (int32_t, int64_t, void *); + __attribute__((import_module("wasi:io/streams@0.2.8"),import_name("[method]input-stream.subscribe"))) extern int32_t WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_streams_40_0_2_8_23__5B_method_5D_input_stream_subscribe (int32_t); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[method]outgoing-body.write"))) extern void WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_outgoing_body_write (int32_t, void *); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[method]outgoing-request.body"))) extern void WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_outgoing_request_body (int32_t, void *); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[method]outgoing-request.set-authority"))) extern int32_t WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_outgoing_request_set_authority (int32_t, int32_t, void *, int32_t); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[method]outgoing-request.set-method"))) extern int32_t WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_outgoing_request_set_method (int32_t, int32_t, void *, int32_t); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[method]outgoing-request.set-path-with-query"))) extern int32_t WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_outgoing_request_set_path_with_query (int32_t, int32_t, void *, int32_t); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[method]outgoing-request.set-scheme"))) extern int32_t WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_outgoing_request_set_scheme (int32_t, int32_t, int32_t, void *, int32_t); + __attribute__((import_module("wasi:io/streams@0.2.8"),import_name("[method]output-stream.check-write"))) extern void WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_streams_40_0_2_8_23__5B_method_5D_output_stream_check_write (int32_t, void *); + __attribute__((import_module("wasi:io/streams@0.2.8"),import_name("[method]output-stream.flush"))) extern void WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_streams_40_0_2_8_23__5B_method_5D_output_stream_flush (int32_t, void *); + __attribute__((import_module("wasi:io/streams@0.2.8"),import_name("[method]output-stream.subscribe"))) extern int32_t WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_streams_40_0_2_8_23__5B_method_5D_output_stream_subscribe (int32_t); + __attribute__((import_module("wasi:io/streams@0.2.8"),import_name("[method]output-stream.write"))) extern void WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_streams_40_0_2_8_23__5B_method_5D_output_stream_write (int32_t, void *, int32_t, void *); + __attribute__((import_module("wasi:io/error@0.2.8"),import_name("[resource-drop]error"))) extern void WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_error_40_0_2_8_23__5B_resource_drop_5D_error (int32_t); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[resource-drop]fields"))) extern void WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_resource_drop_5D_fields (int32_t); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[resource-drop]future-incoming-response"))) extern void WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_resource_drop_5D_future_incoming_response (int32_t); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[resource-drop]future-trailers"))) extern void WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_resource_drop_5D_future_trailers (int32_t); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[resource-drop]incoming-body"))) extern void WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_resource_drop_5D_incoming_body (int32_t); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[resource-drop]incoming-response"))) extern void WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_resource_drop_5D_incoming_response (int32_t); + __attribute__((import_module("wasi:io/streams@0.2.8"),import_name("[resource-drop]input-stream"))) extern void WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_streams_40_0_2_8_23__5B_resource_drop_5D_input_stream (int32_t); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[resource-drop]outgoing-body"))) extern void WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_resource_drop_5D_outgoing_body (int32_t); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[resource-drop]outgoing-request"))) extern void WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_resource_drop_5D_outgoing_request (int32_t); + __attribute__((import_module("wasi:io/streams@0.2.8"),import_name("[resource-drop]output-stream"))) extern void WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_streams_40_0_2_8_23__5B_resource_drop_5D_output_stream (int32_t); + __attribute__((import_module("wasi:io/poll@0.2.8"),import_name("[resource-drop]pollable"))) extern void WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_poll_40_0_2_8_23__5B_resource_drop_5D_pollable (int32_t); __attribute__((import_module("wasi:io/poll@0.2.8"),import_name("[resource-drop]pollable"))) extern void WasiPollWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_poll_40_0_2_8_23__5B_resource_drop_5D_pollable (int32_t); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[resource-drop]request-options"))) extern void WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_resource_drop_5D_request_options (int32_t); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[static]fields.from-list"))) extern void WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_static_5D_fields_from_list (void *, int32_t, void *); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[static]incoming-body.finish"))) extern int32_t WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_static_5D_incoming_body_finish (int32_t); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("[static]outgoing-body.finish"))) extern void WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_static_5D_outgoing_body_finish (int32_t, int32_t, int32_t, void *); + __attribute__((import_module("wasi:http/outgoing-handler@0.2.8"),import_name("handle"))) extern void WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_outgoing_handler_40_0_2_8_23_handle (int32_t, int32_t, int32_t, void *); + __attribute__((import_module("wasi:http/types@0.2.8"),import_name("http-error-code"))) extern void WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23_http_error_code (int32_t, void *); + __attribute__((import_module("wasi:clocks/monotonic-clock@0.2.8"),import_name("now"))) extern int64_t WasiHttpWorld_wit_Imports_wasi_clocks_v0_2_8_23_wasi_3A_clocks_2F_monotonic_clock_40_0_2_8_23_now (); __attribute__((import_module("wasi:clocks/monotonic-clock@0.2.8"),import_name("now"))) extern int64_t WasiPollWorld_wit_Imports_wasi_clocks_v0_2_8_23_wasi_3A_clocks_2F_monotonic_clock_40_0_2_8_23_now (); + __attribute__((import_module("wasi:io/poll@0.2.8"),import_name("poll"))) extern void WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_poll_40_0_2_8_23_poll (void *, int32_t, void *); __attribute__((import_module("wasi:io/poll@0.2.8"),import_name("poll"))) extern void WasiPollWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_poll_40_0_2_8_23_poll (void *, int32_t, void *); + __attribute__((import_module("wasi:clocks/monotonic-clock@0.2.8"),import_name("resolution"))) extern int64_t WasiHttpWorld_wit_Imports_wasi_clocks_v0_2_8_23_wasi_3A_clocks_2F_monotonic_clock_40_0_2_8_23_resolution (); __attribute__((import_module("wasi:clocks/monotonic-clock@0.2.8"),import_name("resolution"))) extern int64_t WasiPollWorld_wit_Imports_wasi_clocks_v0_2_8_23_wasi_3A_clocks_2F_monotonic_clock_40_0_2_8_23_resolution (); + __attribute__((import_module("wasi:clocks/monotonic-clock@0.2.8"),import_name("subscribe-duration"))) extern int32_t WasiHttpWorld_wit_Imports_wasi_clocks_v0_2_8_23_wasi_3A_clocks_2F_monotonic_clock_40_0_2_8_23_subscribe_duration (int64_t); __attribute__((import_module("wasi:clocks/monotonic-clock@0.2.8"),import_name("subscribe-duration"))) extern int32_t WasiPollWorld_wit_Imports_wasi_clocks_v0_2_8_23_wasi_3A_clocks_2F_monotonic_clock_40_0_2_8_23_subscribe_duration (int64_t); + __attribute__((import_module("wasi:clocks/monotonic-clock@0.2.8"),import_name("subscribe-instant"))) extern int32_t WasiHttpWorld_wit_Imports_wasi_clocks_v0_2_8_23_wasi_3A_clocks_2F_monotonic_clock_40_0_2_8_23_subscribe_instant (int64_t); __attribute__((import_module("wasi:clocks/monotonic-clock@0.2.8"),import_name("subscribe-instant"))) extern int32_t WasiPollWorld_wit_Imports_wasi_clocks_v0_2_8_23_wasi_3A_clocks_2F_monotonic_clock_40_0_2_8_23_subscribe_instant (int64_t); } // extern "C" @@ -245,6 +289,7 @@ static const Entry s_libSystem_Globalization_Native [] = { }; static const Entry s_libSystem_IO_Compression_Native [] = { + DllImportEntry(CompressionNative_CompressBound) // System.IO.Compression DllImportEntry(CompressionNative_Crc32) // System.IO.Compression DllImportEntry(CompressionNative_Deflate) // System.IO.Compression DllImportEntry(CompressionNative_DeflateEnd) // System.IO.Compression @@ -297,7 +342,7 @@ static const Entry s_libSystem_Native [] = { DllImportEntry(SystemNative_GetCpuUtilization) // System.Private.CoreLib DllImportEntry(SystemNative_GetCwd) // System.Private.CoreLib DllImportEntry(SystemNative_GetDefaultSearchOrderPseudoHandle) // System.Private.CoreLib - DllImportEntry(SystemNative_GetErrNo) // System.Private.CoreLib + DllImportEntry(SystemNative_GetErrNo) // System.Net.NameResolution, System.Private.CoreLib DllImportEntry(SystemNative_GetHostEntryForName) // System.Net.NameResolution DllImportEntry(SystemNative_GetHostName) // System.Net.NameResolution DllImportEntry(SystemNative_GetIPv4Address) // System.Net.Primitives, System.Net.Sockets @@ -399,21 +444,76 @@ static const Entry s_libSystem_Native [] = { DllImportEntry(SystemNative_TryGetIPPacketInformation) // System.Net.Sockets DllImportEntry(SystemNative_UTimensat) // System.Private.CoreLib DllImportEntry(SystemNative_Unlink) // System.IO.MemoryMappedFiles, System.Private.CoreLib + DllImportEntry(SystemNative_WasiSubscribeSocketPollable) // System.Net.Sockets DllImportEntry(SystemNative_Write) // System.Console, System.Net.Sockets, System.Private.CoreLib DllImportEntry(SystemNative_WriteToNonblocking) // System.Private.CoreLib DllImportEntry(SystemNative_WriteV) // System.Private.CoreLib }; +static const Entry s_libSystem_Native_Browser [] = { +}; + +static const Entry s_libSystem_Runtime_InteropServices_JavaScript_Native [] = { +}; + static const Entry s_wasi_3A_clocks_2F_monotonic_clock_40_0_2_8 [] = { - { "now", (void*)&WasiPollWorld_wit_Imports_wasi_clocks_v0_2_8_23_wasi_3A_clocks_2F_monotonic_clock_40_0_2_8_23_now }, // System.Private.CoreLib - { "resolution", (void*)&WasiPollWorld_wit_Imports_wasi_clocks_v0_2_8_23_wasi_3A_clocks_2F_monotonic_clock_40_0_2_8_23_resolution }, // System.Private.CoreLib - { "subscribe-duration", (void*)&WasiPollWorld_wit_Imports_wasi_clocks_v0_2_8_23_wasi_3A_clocks_2F_monotonic_clock_40_0_2_8_23_subscribe_duration }, // System.Private.CoreLib - { "subscribe-instant", (void*)&WasiPollWorld_wit_Imports_wasi_clocks_v0_2_8_23_wasi_3A_clocks_2F_monotonic_clock_40_0_2_8_23_subscribe_instant }, // System.Private.CoreLib + { "now", (void*)&WasiHttpWorld_wit_Imports_wasi_clocks_v0_2_8_23_wasi_3A_clocks_2F_monotonic_clock_40_0_2_8_23_now }, // System.Net.Http, System.Private.CoreLib + { "resolution", (void*)&WasiHttpWorld_wit_Imports_wasi_clocks_v0_2_8_23_wasi_3A_clocks_2F_monotonic_clock_40_0_2_8_23_resolution }, // System.Net.Http, System.Private.CoreLib + { "subscribe-duration", (void*)&WasiHttpWorld_wit_Imports_wasi_clocks_v0_2_8_23_wasi_3A_clocks_2F_monotonic_clock_40_0_2_8_23_subscribe_duration }, // System.Net.Http, System.Private.CoreLib + { "subscribe-instant", (void*)&WasiHttpWorld_wit_Imports_wasi_clocks_v0_2_8_23_wasi_3A_clocks_2F_monotonic_clock_40_0_2_8_23_subscribe_instant }, // System.Net.Http, System.Private.CoreLib +}; + +static const Entry s_wasi_3A_http_2F_outgoing_handler_40_0_2_8 [] = { + { "handle", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_outgoing_handler_40_0_2_8_23_handle }, // System.Net.Http +}; + +static const Entry s_wasi_3A_http_2F_types_40_0_2_8 [] = { + { "[constructor]outgoing-request", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_constructor_5D_outgoing_request }, // System.Net.Http + { "[method]fields.entries", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_fields_entries }, // System.Net.Http + { "[method]future-incoming-response.get", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_future_incoming_response_get }, // System.Net.Http + { "[method]future-incoming-response.subscribe", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_future_incoming_response_subscribe }, // System.Net.Http + { "[method]incoming-body.stream", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_incoming_body_stream }, // System.Net.Http + { "[method]incoming-response.consume", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_incoming_response_consume }, // System.Net.Http + { "[method]incoming-response.headers", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_incoming_response_headers }, // System.Net.Http + { "[method]incoming-response.status", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_incoming_response_status }, // System.Net.Http + { "[method]outgoing-body.write", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_outgoing_body_write }, // System.Net.Http + { "[method]outgoing-request.body", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_outgoing_request_body }, // System.Net.Http + { "[method]outgoing-request.set-authority", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_outgoing_request_set_authority }, // System.Net.Http + { "[method]outgoing-request.set-method", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_outgoing_request_set_method }, // System.Net.Http + { "[method]outgoing-request.set-path-with-query", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_outgoing_request_set_path_with_query }, // System.Net.Http + { "[method]outgoing-request.set-scheme", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_method_5D_outgoing_request_set_scheme }, // System.Net.Http + { "[resource-drop]fields", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_resource_drop_5D_fields }, // System.Net.Http + { "[resource-drop]future-incoming-response", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_resource_drop_5D_future_incoming_response }, // System.Net.Http + { "[resource-drop]future-trailers", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_resource_drop_5D_future_trailers }, // System.Net.Http + { "[resource-drop]incoming-body", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_resource_drop_5D_incoming_body }, // System.Net.Http + { "[resource-drop]incoming-response", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_resource_drop_5D_incoming_response }, // System.Net.Http + { "[resource-drop]outgoing-body", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_resource_drop_5D_outgoing_body }, // System.Net.Http + { "[resource-drop]outgoing-request", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_resource_drop_5D_outgoing_request }, // System.Net.Http + { "[resource-drop]request-options", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_resource_drop_5D_request_options }, // System.Net.Http + { "[static]fields.from-list", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_static_5D_fields_from_list }, // System.Net.Http + { "[static]incoming-body.finish", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_static_5D_incoming_body_finish }, // System.Net.Http + { "[static]outgoing-body.finish", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23__5B_static_5D_outgoing_body_finish }, // System.Net.Http + { "http-error-code", (void*)&WasiHttpWorld_wit_Imports_wasi_http_v0_2_8_23_wasi_3A_http_2F_types_40_0_2_8_23_http_error_code }, // System.Net.Http +}; + +static const Entry s_wasi_3A_io_2F_error_40_0_2_8 [] = { + { "[resource-drop]error", (void*)&WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_error_40_0_2_8_23__5B_resource_drop_5D_error }, // System.Net.Http }; static const Entry s_wasi_3A_io_2F_poll_40_0_2_8 [] = { - { "[resource-drop]pollable", (void*)&WasiPollWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_poll_40_0_2_8_23__5B_resource_drop_5D_pollable }, // System.Private.CoreLib - { "poll", (void*)&WasiPollWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_poll_40_0_2_8_23_poll }, // System.Private.CoreLib + { "[resource-drop]pollable", (void*)&WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_poll_40_0_2_8_23__5B_resource_drop_5D_pollable }, // System.Net.Http, System.Private.CoreLib + { "poll", (void*)&WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_poll_40_0_2_8_23_poll }, // System.Net.Http, System.Private.CoreLib +}; + +static const Entry s_wasi_3A_io_2F_streams_40_0_2_8 [] = { + { "[method]input-stream.read", (void*)&WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_streams_40_0_2_8_23__5B_method_5D_input_stream_read }, // System.Net.Http + { "[method]input-stream.subscribe", (void*)&WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_streams_40_0_2_8_23__5B_method_5D_input_stream_subscribe }, // System.Net.Http + { "[method]output-stream.check-write", (void*)&WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_streams_40_0_2_8_23__5B_method_5D_output_stream_check_write }, // System.Net.Http + { "[method]output-stream.flush", (void*)&WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_streams_40_0_2_8_23__5B_method_5D_output_stream_flush }, // System.Net.Http + { "[method]output-stream.subscribe", (void*)&WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_streams_40_0_2_8_23__5B_method_5D_output_stream_subscribe }, // System.Net.Http + { "[method]output-stream.write", (void*)&WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_streams_40_0_2_8_23__5B_method_5D_output_stream_write }, // System.Net.Http + { "[resource-drop]input-stream", (void*)&WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_streams_40_0_2_8_23__5B_resource_drop_5D_input_stream }, // System.Net.Http + { "[resource-drop]output-stream", (void*)&WasiHttpWorld_wit_Imports_wasi_io_v0_2_8_23_wasi_3A_io_2F_streams_40_0_2_8_23__5B_resource_drop_5D_output_stream }, // System.Net.Http }; typedef struct PInvokeTable { @@ -424,10 +524,16 @@ typedef struct PInvokeTable { static PInvokeTable s_PInvokeTables[] = { {"libSystem.Globalization.Native", s_libSystem_Globalization_Native, 34}, - {"libSystem.IO.Compression.Native", s_libSystem_IO_Compression_Native, 8}, - {"libSystem.Native", s_libSystem_Native, 146}, + {"libSystem.IO.Compression.Native", s_libSystem_IO_Compression_Native, 9}, + {"libSystem.Native", s_libSystem_Native, 147}, + {"libSystem.Native.Browser", s_libSystem_Native_Browser, 0}, + {"libSystem.Runtime.InteropServices.JavaScript.Native", s_libSystem_Runtime_InteropServices_JavaScript_Native, 0}, {"wasi:clocks/monotonic-clock@0.2.8", s_wasi_3A_clocks_2F_monotonic_clock_40_0_2_8, 4}, - {"wasi:io/poll@0.2.8", s_wasi_3A_io_2F_poll_40_0_2_8, 2} + {"wasi:http/outgoing-handler@0.2.8", s_wasi_3A_http_2F_outgoing_handler_40_0_2_8, 1}, + {"wasi:http/types@0.2.8", s_wasi_3A_http_2F_types_40_0_2_8, 26}, + {"wasi:io/error@0.2.8", s_wasi_3A_io_2F_error_40_0_2_8, 1}, + {"wasi:io/poll@0.2.8", s_wasi_3A_io_2F_poll_40_0_2_8, 2}, + {"wasi:io/streams@0.2.8", s_wasi_3A_io_2F_streams_40_0_2_8, 8} }; const size_t s_PInvokeTablesCount = sizeof(s_PInvokeTables) / sizeof(s_PInvokeTables[0]); diff --git a/src/tasks/WasmAppBuilder/generate-coreclr-helpers.cmd b/src/tasks/WasmAppBuilder/generate-coreclr-helpers.cmd index 0a6108bf4e77e9..3cf780d5c5659c 100644 --- a/src/tasks/WasmAppBuilder/generate-coreclr-helpers.cmd +++ b/src/tasks/WasmAppBuilder/generate-coreclr-helpers.cmd @@ -3,7 +3,12 @@ setlocal enabledelayedexpansion :: Default configuration set "configuration=Debug" -set "scan_path_override=" +set "browser_scan_path_override=" +set "wasi_scan_path_override=" + +:: Get the repo root (script is in src/tasks/WasmAppBuilder). +:: This must be computed before argument parsing, because SHIFT also shifts %0. +for %%I in ("%~dp0..\..\..") do set "repo_root=%%~fI" set "usage=Usage: %~nx0 [options]" set "usage=!usage!^ @@ -14,7 +19,9 @@ Options:^ -c, --configuration ^ Build configuration (default: Debug)^ - -s, --scan-path ^ Override the default scan path^ + -s, --scan-path ^ Override the default browser scan path^ + + -w, --wasi-scan-path ^ Override the default wasi scan path^ -h, --help Show this help message" @@ -24,6 +31,8 @@ if /i "%~1"=="-c" goto :set_configuration if /i "%~1"=="--configuration" goto :set_configuration if /i "%~1"=="-s" goto :set_scan_path if /i "%~1"=="--scan-path" goto :set_scan_path +if /i "%~1"=="-w" goto :set_wasi_scan_path +if /i "%~1"=="--wasi-scan-path" goto :set_wasi_scan_path if /i "%~1"=="-h" goto :show_help if /i "%~1"=="--help" goto :show_help @@ -38,7 +47,13 @@ shift goto :parse_args :set_scan_path -set scan_path_override=%~2 +set browser_scan_path_override=%~2 +shift +shift +goto :parse_args + +:set_wasi_scan_path +set wasi_scan_path_override=%~2 shift shift goto :parse_args @@ -55,38 +70,53 @@ if /i not "%configuration%"=="Debug" if /i not "%configuration%"=="Release" if / exit /b 1 ) -:: Get the repo root (script is in src/tasks/WasmAppBuilder) -set script_dir=%~dp0 -pushd "%script_dir%..\..\..\" -set repo_root=%CD% -popd - echo Configuration: %configuration% echo Repo root: %repo_root% -if not "%scan_path_override%"=="" ( - set scan_path=%scan_path_override% +cd /d "%repo_root%" + +:: Resolve scan paths (allow overrides). +if not "%browser_scan_path_override%"=="" ( + set browser_scan_path=%browser_scan_path_override% ) else ( - set scan_path=%repo_root%\artifacts\bin\testhost\net11.0-browser-%configuration%-wasm\shared\Microsoft.NETCore.App\11.0.0\ + set browser_scan_path=%repo_root%\artifacts\bin\testhost\net11.0-browser-%configuration%-wasm\shared\Microsoft.NETCore.App\11.0.0\ ) +if not "%wasi_scan_path_override%"=="" ( + set wasi_scan_path=%wasi_scan_path_override% +) else ( + set wasi_scan_path=%repo_root%\artifacts\bin\testhost\net11.0-wasi-%configuration%-wasm\shared\Microsoft.NETCore.App\11.0.0\ +) + +call :run_generator browser "%browser_scan_path%" "%repo_root%\src\coreclr\vm\wasm\browser\" +if errorlevel 1 exit /b 1 + +call :run_generator wasi "%wasi_scan_path%" "%repo_root%\src\coreclr\vm\wasm\wasi\" +if errorlevel 1 exit /b 1 + +echo Done! +exit /b 0 + +:: run_generator +:run_generator +set "target_os=%~1" +set "scan_path=%~2" +set "output_dir=%~3" + if not exist "%scan_path%" ( - echo Error: Scan path does not exist: %scan_path% - echo Please build the runtime first using: .\build.cmd clr+libs -os browser -c %configuration% + echo Error: Scan path for %target_os% does not exist: %scan_path% + echo Please build the runtime first using: .\build.cmd clr+libs -os %target_os% -c %configuration% exit /b 1 ) -cd /d "%repo_root%" -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 [%target_os%] Scan path: %scan_path% +echo [%target_os%] Output path: %output_dir% +echo Running generator for %target_os%... +echo dotnet.cmd build /t:RunGenerator /p:RuntimeFlavor=CoreCLR /p:TargetOS=%target_os% /p:GeneratorOutputPath=%output_dir% /p:AssembliesScanPath=%scan_path% src\tasks\WasmAppBuilder\WasmAppBuilder.csproj +call .\dotnet.cmd build /t:RunGenerator /p:RuntimeFlavor=CoreCLR /p:TargetOS=%target_os% /p:GeneratorOutputPath=%output_dir% /p:AssembliesScanPath=%scan_path% src\tasks\WasmAppBuilder\WasmAppBuilder.csproj if errorlevel 1 ( - echo Generator failed! + echo Generator failed for %target_os%! exit /b 1 ) - -echo Done! \ No newline at end of file +exit /b 0 diff --git a/src/tasks/WasmAppBuilder/generate-coreclr-helpers.md b/src/tasks/WasmAppBuilder/generate-coreclr-helpers.md new file mode 100644 index 00000000000000..4cc261bffc9ed8 --- /dev/null +++ b/src/tasks/WasmAppBuilder/generate-coreclr-helpers.md @@ -0,0 +1,77 @@ +# Generating CoreCLR WebAssembly call helpers + +The `generate-coreclr-helpers.cmd` (Windows) and `generate-coreclr-helpers.sh` (Linux/macOS) +scripts in this directory regenerate the checked-in CoreCLR call-helper source files used by the +WebAssembly runtime. They run the `RunGenerator` target in +[`WasmAppBuilder.csproj`](./WasmAppBuilder.csproj), which invokes the +`ManagedToNativeGenerator` MSBuild task to scan the managed framework assemblies and emit the +native P/Invoke, reverse-P/Invoke, and interpreter-to-managed call helpers. + +The scripts generate **both** WebAssembly variations: + +| Target OS | Output directory | Default scan path (testhost) | +|-----------|---------------------------------|------------------------------| +| `browser` | `src/coreclr/vm/wasm/browser/` | `artifacts/bin/testhost/net11.0-browser--wasm/shared/Microsoft.NETCore.App/11.0.0/` | +| `wasi` | `src/coreclr/vm/wasm/wasi/` | `artifacts/bin/testhost/net11.0-wasi--wasm/shared/Microsoft.NETCore.App/11.0.0/` | + +Each run emits three files into the output directory: + +- `callhelpers-pinvoke.cpp` +- `callhelpers-reverse.cpp` +- `callhelpers-interp-to-managed.cpp` + +## What needs to be built first + +The generator scans the **managed framework assemblies** in the `testhost` folder produced by a +`clr+libs` build. Because the scripts generate both the `browser` and `wasi` variations, you must +build **both** WebAssembly flavors before running them. The first build of either flavor also +downloads and provisions the Emscripten SDK (emsdk) automatically. + +From the repository root: + +**Windows:** +```cmd +.\build.cmd clr+libs -os browser -c Debug +.\build.cmd clr+libs -os wasi -c Debug +``` + +**Linux/macOS:** +```bash +./build.sh clr+libs -os browser -c Debug +./build.sh clr+libs -os wasi -c Debug +``` + +Notes: + +- Use a matching `-c ` for the configuration you intend to pass to the + generator script (the script derives the scan path from the configuration name). +- The `WasmAppBuilder` task itself is built on demand by the generator script (the `RunGenerator` + target depends on `Build`), so you do not need to build it separately. +- If a required `testhost` scan path is missing, the script stops and prints the exact + `build` command needed to produce it. + +## Running the generator + +Once both flavors are built, run the script from anywhere (it resolves the repo root itself): + +**Windows:** +```cmd +src\tasks\WasmAppBuilder\generate-coreclr-helpers.cmd -c Debug +``` + +**Linux/macOS:** +```bash +src/tasks/WasmAppBuilder/generate-coreclr-helpers.sh -c Debug +``` + +### Options + +| Option | Description | +|--------|-------------| +| `-c`, `--configuration ` | Build configuration (default: `Debug`). Determines the default scan paths. | +| `-s`, `--scan-path ` | Override the default **browser** scan path. | +| `-w`, `--wasi-scan-path ` | Override the default **wasi** scan path. | +| `-h`, `--help` | Show usage. | + +After running, review and commit any changes to the generated files under +`src/coreclr/vm/wasm/browser/` and `src/coreclr/vm/wasm/wasi/`. diff --git a/src/tasks/WasmAppBuilder/generate-coreclr-helpers.sh b/src/tasks/WasmAppBuilder/generate-coreclr-helpers.sh index 8275e93339fb31..917b737b0a83a6 100755 --- a/src/tasks/WasmAppBuilder/generate-coreclr-helpers.sh +++ b/src/tasks/WasmAppBuilder/generate-coreclr-helpers.sh @@ -4,14 +4,16 @@ set -euo pipefail # Default configuration configuration="Debug" -scan_path_override="" +browser_scan_path_override="" +wasi_scan_path_override="" usage="Usage: $0 [options] Options: -c, --configuration Build configuration (default: Debug) - -s, --scan-path Override the default scan path - -h, --help Show this help message" + -s, --scan-path Override the default browser scan path + -w, --wasi-scan-path Override the default wasi scan path + -h, --help Show this help message" # Parse arguments while [[ $# -gt 0 ]]; do @@ -21,7 +23,11 @@ while [[ $# -gt 0 ]]; do shift 2 ;; -s|--scan-path) - scan_path_override="$2" + browser_scan_path_override="$2" + shift 2 + ;; + -w|--wasi-scan-path) + wasi_scan_path_override="$2" shift 2 ;; -h|--help) @@ -54,24 +60,42 @@ repo_root="$(cd "$script_dir/../../.." && pwd)" echo "Configuration: $configuration" echo "Repo root: $repo_root" -if [[ -n "$scan_path_override" ]]; then - scan_path="$scan_path_override" +cd "$repo_root" + +# Run the generator for a given target OS. +# Arguments: +run_generator() { + local target_os="$1" + local scan_path="$2" + local output_dir="$3" + + if [[ ! -d "$scan_path" ]]; then + echo "Error: Scan path for $target_os does not exist: $scan_path" + echo "Please build the runtime first using: ./build.sh clr+libs -os $target_os -c $configuration" + exit 1 + fi + + echo "[$target_os] Scan path: $scan_path" + echo "[$target_os] Output path: $output_dir" + echo "Running generator for $target_os..." + echo "./dotnet.sh build /t:RunGenerator /p:RuntimeFlavor=CoreCLR /p:TargetOS=$target_os /p:GeneratorOutputPath=$output_dir /p:AssembliesScanPath=$scan_path src/tasks/WasmAppBuilder/WasmAppBuilder.csproj" + ./dotnet.sh build /t:RunGenerator /p:RuntimeFlavor=CoreCLR "/p:TargetOS=$target_os" "/p:GeneratorOutputPath=$output_dir" "/p:AssembliesScanPath=$scan_path" src/tasks/WasmAppBuilder/WasmAppBuilder.csproj +} + +# Resolve scan paths (allow overrides). +if [[ -n "$browser_scan_path_override" ]]; then + browser_scan_path="$browser_scan_path_override" else - scan_path="$repo_root/artifacts/bin/testhost/net11.0-browser-$configuration-wasm/shared/Microsoft.NETCore.App/11.0.0/" + browser_scan_path="$repo_root/artifacts/bin/testhost/net11.0-browser-$configuration-wasm/shared/Microsoft.NETCore.App/11.0.0/" fi -if [[ ! -d "$scan_path" ]]; then - echo "Error: Scan path does not exist: $scan_path" - echo "Please build the runtime first using: ./build.sh clr+libs -os browser -c $configuration" - exit 1 +if [[ -n "$wasi_scan_path_override" ]]; then + wasi_scan_path="$wasi_scan_path_override" +else + wasi_scan_path="$repo_root/artifacts/bin/testhost/net11.0-wasi-$configuration-wasm/shared/Microsoft.NETCore.App/11.0.0/" fi -cd "$repo_root" -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 +run_generator "browser" "$browser_scan_path" "$repo_root/src/coreclr/vm/wasm/browser/" +run_generator "wasi" "$wasi_scan_path" "$repo_root/src/coreclr/vm/wasm/wasi/" echo "Done!" diff --git a/src/tests/Common/CLRTest.Execute.Bash.targets b/src/tests/Common/CLRTest.Execute.Bash.targets index be824d9285214a..4372e8bd12f269 100644 --- a/src/tests/Common/CLRTest.Execute.Bash.targets +++ b/src/tests/Common/CLRTest.Execute.Bash.targets @@ -280,7 +280,7 @@ fi block below and the matching block in corerun.cpp. wasmtime is expected to already be on PATH (provisioned via wasi-provisioning.targets or installed manually). --> - wasmtime run -W exceptions=y --dir "$PWD::/" --dir "$CORE_ROOT::/core" --env CORE_ROOT=/core --env DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true --env DOTNET_WASI_PRINT_EXIT_CODE=1 "$CORE_ROOT/corerun" $(CoreRunArgs) ${__DotEnvArg} + wasmtime run -W exceptions=y -S http --dir "$PWD::/" --dir "$CORE_ROOT::/core" --env CORE_ROOT=/core --env DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true --env DOTNET_WASI_PRINT_EXIT_CODE=1 "$CORE_ROOT/corerun" $(CoreRunArgs) ${__DotEnvArg} "$CORE_ROOT/watchdog" $_WatcherTimeoutMins