diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index a75171aeda1b0..e72c4bf950c2c 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -15,7 +15,7 @@
]
},
"microsoft.dotnet.xharness.cli": {
- "version": "9.0.0-prerelease.24452.1",
+ "version": "10.0.0-prerelease.24459.1",
"commands": [
"xharness"
]
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 77c06d86deee3..238887c6bd098 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -316,17 +316,17 @@
https://github.com/dotnet/runtime
7cb32e193a55a95c74fc3bd56501b951b48b700f
-
+
https://github.com/dotnet/xharness
- c2215b88cdac5390888de3e6ad301c113f40ed6c
+ df9b6509e6b3976d158e46c23d72d6acd9f0d326
-
+
https://github.com/dotnet/xharness
- c2215b88cdac5390888de3e6ad301c113f40ed6c
+ df9b6509e6b3976d158e46c23d72d6acd9f0d326
-
+
https://github.com/dotnet/xharness
- c2215b88cdac5390888de3e6ad301c113f40ed6c
+ df9b6509e6b3976d158e46c23d72d6acd9f0d326
https://github.com/dotnet/arcade
diff --git a/eng/Versions.props b/eng/Versions.props
index a6407d4ed6c89..44522b33fd4a5 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -180,9 +180,9 @@
1.4.0
17.4.0-preview-20220707-01
- 9.0.0-prerelease.24452.1
- 9.0.0-prerelease.24452.1
- 9.0.0-prerelease.24452.1
+ 10.0.0-prerelease.24459.1
+ 10.0.0-prerelease.24459.1
+ 10.0.0-prerelease.24459.1
9.0.0-alpha.0.24419.1
3.12.0
4.5.0
diff --git a/eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml b/eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml
index a189770cb81be..2ac52ca77eb35 100644
--- a/eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml
+++ b/eng/pipelines/common/templates/runtimes/build-runtime-tests-and-send-to-helix.yml
@@ -70,7 +70,7 @@ steps:
displayName: "AOT compile CoreCLR tests"
target: ${{ coalesce(parameters.llvmAotStepContainer, parameters.container) }}
- ${{ if in(parameters.runtimeVariant, 'llvmfullaot', 'minifullaot') }}:
- - script: $(Build.SourcesDirectory)/src/tests/build$(scriptExt) $(logRootNameArg)MonoAot mono_fullaot ${{ parameters.buildConfig }} ${{ parameters.archType }} /p:RuntimeVariant=${{ parameters.runtimeVariant }} -maxcpucount:2
+ - script: $(Build.SourcesDirectory)/src/tests/build$(scriptExt) $(logRootNameArg)MonoAot mono_fullaot ${{ parameters.buildConfig }} ${{ parameters.archType }} /p:RuntimeVariant=${{ parameters.runtimeVariant }} -maxcpucount:1
displayName: "AOT compile CoreCLR tests"
target: ${{ coalesce(parameters.llvmAotStepContainer, parameters.container) }}
- ${{ if eq(parameters.archType, 'arm64') }}:
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs
index ccd3d9aa9efc5..95bcf0652648a 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs
@@ -115,8 +115,6 @@ public override string? CodeBase
}
}
- internal RuntimeAssembly GetNativeHandle() => this;
-
// If the assembly is copied before it is loaded, the codebase will be set to the
// actual file loaded if copiedName is true. If it is false, then the original code base
// is returned.
@@ -263,7 +261,7 @@ public override Type[] GetExportedTypes()
public override IEnumerable DefinedTypes
{
[RequiresUnreferencedCode("Types might be removed")]
- get => GetManifestModule(GetNativeHandle()).GetDefinedTypes();
+ get => GetManifestModule().GetDefinedTypes();
}
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "AssemblyNative_GetIsCollectible")]
@@ -324,7 +322,7 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont
public override Module ManifestModule =>
// We don't need to return the "external" ModuleBuilder because
// it is meant to be read-only
- GetManifestModule(GetNativeHandle());
+ GetManifestModule();
public override object[] GetCustomAttributes(bool inherit)
{
@@ -586,9 +584,17 @@ private CultureInfo GetLocale()
}
[MethodImpl(MethodImplOptions.InternalCall)]
- private static extern bool FCallIsDynamic(RuntimeAssembly assembly);
+ private static extern bool GetIsDynamic(IntPtr assembly);
- public override bool IsDynamic => FCallIsDynamic(GetNativeHandle());
+ public override bool IsDynamic
+ {
+ get
+ {
+ bool isDynamic = GetIsDynamic(GetUnderlyingNativeHandle());
+ GC.KeepAlive(this); // We directly pass the native handle above - make sure this object stays alive for the call
+ return isDynamic;
+ }
+ }
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "AssemblyNative_GetSimpleName")]
private static partial void GetSimpleName(QCallAssembly assembly, StringHandleOnStack retSimpleName);
@@ -701,8 +707,24 @@ public override Module[] GetLoadedModules(bool getResourceModules)
return GetModulesInternal(false, getResourceModules);
}
+ private RuntimeModule GetManifestModule()
+ {
+ return GetManifestModule(this) ?? GetManifestModuleWorker(this);
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static RuntimeModule GetManifestModuleWorker(RuntimeAssembly assembly)
+ {
+ RuntimeModule? module = null;
+ GetManifestModuleSlow(ObjectHandleOnStack.Create(ref assembly), ObjectHandleOnStack.Create(ref module));
+ return module!;
+ }
+ }
+
[MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern RuntimeModule GetManifestModule(RuntimeAssembly assembly);
+ private static extern RuntimeModule? GetManifestModule(RuntimeAssembly assembly);
+
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "AssemblyHandle_GetManifestModuleSlow")]
+ private static partial void GetManifestModuleSlow(ObjectHandleOnStack assembly, ObjectHandleOnStack module);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern int GetToken(RuntimeAssembly assembly);
@@ -713,7 +735,7 @@ public sealed override Type[] GetForwardedTypes()
List types = new List();
List exceptions = new List();
- MetadataImport scope = GetManifestModule(GetNativeHandle()).MetadataImport;
+ MetadataImport scope = GetManifestModule().MetadataImport;
scope.Enum(MetadataTokenType.ExportedType, 0, out MetadataEnumResult enumResult);
RuntimeAssembly runtimeAssembly = this;
QCallAssembly pAssembly = new QCallAssembly(ref runtimeAssembly);
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 a610a5cbe3eab..2ac866f246fce 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeCustomAttributeData.cs
@@ -82,7 +82,7 @@ internal static IList GetCustomAttributesInternal(RuntimeAs
// No pseudo attributes for RuntimeAssembly
- return GetCustomAttributes((RuntimeModule)target.ManifestModule, RuntimeAssembly.GetToken(target.GetNativeHandle()));
+ return GetCustomAttributes((RuntimeModule)target.ManifestModule, RuntimeAssembly.GetToken(target));
}
internal static IList GetCustomAttributesInternal(RuntimeParameterInfo target)
@@ -1227,7 +1227,7 @@ internal static bool IsDefined(RuntimeAssembly assembly, RuntimeType caType)
Debug.Assert(caType is not null);
// No pseudo attributes for RuntimeAssembly
- return IsCustomAttributeDefined((assembly.ManifestModule as RuntimeModule)!, RuntimeAssembly.GetToken(assembly.GetNativeHandle()), caType);
+ return IsCustomAttributeDefined((assembly.ManifestModule as RuntimeModule)!, RuntimeAssembly.GetToken(assembly), caType);
}
internal static bool IsDefined(RuntimeModule module, RuntimeType caType)
@@ -1388,7 +1388,7 @@ internal static object[] GetCustomAttributes(RuntimeAssembly assembly, RuntimeTy
// No pseudo attributes for RuntimeAssembly
- int assemblyToken = RuntimeAssembly.GetToken(assembly.GetNativeHandle());
+ int assemblyToken = RuntimeAssembly.GetToken(assembly);
return GetCustomAttributes((assembly.ManifestModule as RuntimeModule)!, assemblyToken, 0, caType);
}
diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs
index 3d230536519ce..d78cc1ea86bc1 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs
@@ -306,11 +306,43 @@ internal RuntimeType GetRuntimeType()
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern CorElementType GetCorElementType(RuntimeType type);
+ internal static RuntimeAssembly GetAssembly(RuntimeType type)
+ {
+ return GetAssemblyIfExists(type) ?? GetAssemblyWorker(type);
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static RuntimeAssembly GetAssemblyWorker(RuntimeType type)
+ {
+ RuntimeAssembly? assembly = null;
+ GetAssemblySlow(ObjectHandleOnStack.Create(ref type), ObjectHandleOnStack.Create(ref assembly));
+ return assembly!;
+ }
+ }
+
[MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern RuntimeAssembly GetAssembly(RuntimeType type);
+ private static extern RuntimeAssembly? GetAssemblyIfExists(RuntimeType type);
+
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetAssemblySlow")]
+ private static partial void GetAssemblySlow(ObjectHandleOnStack type, ObjectHandleOnStack assembly);
+
+ internal static RuntimeModule GetModule(RuntimeType type)
+ {
+ return GetModuleIfExists(type) ?? GetModuleWorker(type);
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static RuntimeModule GetModuleWorker(RuntimeType type)
+ {
+ RuntimeModule? module = null;
+ GetModuleSlow(ObjectHandleOnStack.Create(ref type), ObjectHandleOnStack.Create(ref module));
+ return module!;
+ }
+ }
[MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern RuntimeModule GetModule(RuntimeType type);
+ private static extern RuntimeModule? GetModuleIfExists(RuntimeType type);
+
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetModuleSlow")]
+ private static partial void GetModuleSlow(ObjectHandleOnStack type, ObjectHandleOnStack module);
public ModuleHandle GetModuleHandle()
{
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs
index 8fe80e7286858..25fc6ff09ad2a 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs
@@ -31,7 +31,7 @@ public bool WaitCore(int timeoutMs)
return waitResult == WaitHandle.WaitSuccess;
}
- [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "WaitHandle_CorWaitOnePrioritizedNative")]
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "WaitHandle_WaitOnePrioritized")]
private static partial int WaitNative(SafeWaitHandle handle, int timeoutMs);
private void ReleaseCore(int count)
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs
index 486e5a505abeb..08b3ae8944d63 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs
@@ -151,13 +151,24 @@ public static void SpinWait(int iterations)
public static bool Yield() => YieldInternal() != Interop.BOOL.FALSE;
[MethodImpl(MethodImplOptions.NoInlining)]
- private static Thread InitializeCurrentThread() => t_currentThread = GetCurrentThreadNative();
+ private static Thread InitializeCurrentThread()
+ {
+ Thread? thread = null;
+ GetCurrentThread(ObjectHandleOnStack.Create(ref thread));
+ return t_currentThread = thread!;
+ }
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern Thread GetCurrentThreadNative();
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ThreadNative_GetCurrentThread")]
+ private static partial void GetCurrentThread(ObjectHandleOnStack thread);
- [MethodImpl(MethodImplOptions.InternalCall)]
- private extern void Initialize();
+ private void Initialize()
+ {
+ Thread _this = this;
+ Initialize(ObjectHandleOnStack.Create(ref _this));
+ }
+
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ThreadNative_Initialize")]
+ private static partial void Initialize(ObjectHandleOnStack thread);
/// Clean up the thread when it goes away.
~Thread() => InternalFinalize(); // Delegate to the unmanaged portion.
@@ -175,11 +186,7 @@ partial void ThreadNameChanged(string? value)
private static partial void InformThreadNameChange(ThreadHandle t, string? name, int len);
/// Returns true if the thread has been started and is not dead.
- public extern bool IsAlive
- {
- [MethodImpl(MethodImplOptions.InternalCall)]
- get;
- }
+ public bool IsAlive => (ThreadState & (ThreadState.Unstarted | ThreadState.Stopped | ThreadState.Aborted)) == 0;
///
/// Return whether or not this thread is a background thread. Background
@@ -247,10 +254,19 @@ public ThreadPriority Priority
/// Return the thread state as a consistent set of bits. This is more
/// general then IsAlive or IsBackground.
///
- public ThreadState ThreadState => (ThreadState)GetThreadStateNative();
+ public ThreadState ThreadState
+ {
+ get
+ {
+ var state = (ThreadState)GetThreadState(GetNativeHandle());
+ GC.KeepAlive(this);
+ return state;
+ }
+ }
- [MethodImpl(MethodImplOptions.InternalCall)]
- private extern int GetThreadStateNative();
+ [SuppressGCTransition]
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ThreadNative_GetThreadState")]
+ private static partial int GetThreadState(ThreadHandle t);
///
/// An unstarted thread can be marked to indicate that it will host a
@@ -327,6 +343,7 @@ public void DisableComObjectEagerCleanup()
GC.KeepAlive(this);
}
+ [SuppressGCTransition]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ThreadNative_DisableComObjectEagerCleanup")]
private static partial void DisableComObjectEagerCleanup(ThreadHandle t);
#else // !FEATURE_COMINTEROP
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/WaitHandle.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/WaitHandle.CoreCLR.cs
index f1bfe33e8c8bc..a9fc4d8b2a045 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Threading/WaitHandle.CoreCLR.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Threading/WaitHandle.CoreCLR.cs
@@ -8,23 +8,18 @@ namespace System.Threading
{
public abstract partial class WaitHandle
{
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern int WaitOneCore(IntPtr waitHandle, int millisecondsTimeout, bool useTrivialWaits);
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "WaitHandle_WaitOneCore")]
+ private static partial int WaitOneCore(IntPtr waitHandle, int millisecondsTimeout, [MarshalAs(UnmanagedType.Bool)] bool useTrivialWaits);
private static unsafe int WaitMultipleIgnoringSyncContextCore(ReadOnlySpan waitHandles, bool waitAll, int millisecondsTimeout)
- {
- fixed (IntPtr* pWaitHandles = &MemoryMarshal.GetReference(waitHandles))
- {
- return WaitMultipleIgnoringSyncContext(pWaitHandles, waitHandles.Length, waitAll, millisecondsTimeout);
- }
- }
+ => WaitMultipleIgnoringSyncContext(waitHandles, waitHandles.Length, waitAll, millisecondsTimeout);
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern unsafe int WaitMultipleIgnoringSyncContext(IntPtr* waitHandles, int numHandles, bool waitAll, int millisecondsTimeout);
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "WaitHandle_WaitMultipleIgnoringSyncContext")]
+ private static partial int WaitMultipleIgnoringSyncContext(ReadOnlySpan waitHandles, int numHandles, [MarshalAs(UnmanagedType.Bool)] bool waitAll, int millisecondsTimeout);
private static int SignalAndWaitCore(IntPtr waitHandleToSignal, IntPtr waitHandleToWaitOn, int millisecondsTimeout)
{
- int ret = SignalAndWaitNative(waitHandleToSignal, waitHandleToWaitOn, millisecondsTimeout);
+ int ret = SignalAndWait(waitHandleToSignal, waitHandleToWaitOn, millisecondsTimeout);
if (ret == Interop.Errors.ERROR_TOO_MANY_POSTS)
{
@@ -34,7 +29,7 @@ private static int SignalAndWaitCore(IntPtr waitHandleToSignal, IntPtr waitHandl
return ret;
}
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern int SignalAndWaitNative(IntPtr waitHandleToSignal, IntPtr waitHandleToWaitOn, int millisecondsTimeout);
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "WaitHandle_SignalAndWait")]
+ private static partial int SignalAndWait(IntPtr waitHandleToSignal, IntPtr waitHandleToWaitOn, int millisecondsTimeout);
}
}
diff --git a/src/coreclr/debug/daccess/dacdbiimpl.cpp b/src/coreclr/debug/daccess/dacdbiimpl.cpp
index 6309533648bb2..223d675df254a 100644
--- a/src/coreclr/debug/daccess/dacdbiimpl.cpp
+++ b/src/coreclr/debug/daccess/dacdbiimpl.cpp
@@ -5557,6 +5557,8 @@ CorDebugUserState DacDbiInterfaceImpl::GetPartialUserState(VMPTR_Thread vmThread
result |= USER_STOPPED;
}
+ // Don't report Thread::TS_AbortRequested
+
// The interruptible flag is unreliable (see issue 699245)
// The Debugger_SleepWaitJoin is always accurate when it is present, but it is still
// just a band-aid fix to cover some of the race conditions interruptible has.
diff --git a/src/coreclr/debug/daccess/dacimpl.h b/src/coreclr/debug/daccess/dacimpl.h
index 0d3ab3ad7bd18..cec666bc02bc1 100644
--- a/src/coreclr/debug/daccess/dacimpl.h
+++ b/src/coreclr/debug/daccess/dacimpl.h
@@ -1061,7 +1061,7 @@ class ClrDataAccess
virtual HRESULT STDMETHODCALLTYPE GetAppDomainData(CLRDATA_ADDRESS addr, struct DacpAppDomainData *data);
virtual HRESULT STDMETHODCALLTYPE GetAppDomainName(CLRDATA_ADDRESS addr, unsigned int count, _Inout_updates_z_(count) WCHAR *name, unsigned int *pNeeded);
virtual HRESULT STDMETHODCALLTYPE GetAssemblyList(CLRDATA_ADDRESS appDomain, int count, CLRDATA_ADDRESS values[], int *fetched);
- virtual HRESULT STDMETHODCALLTYPE GetAssemblyData(CLRDATA_ADDRESS baseDomainPtr, CLRDATA_ADDRESS assembly, struct DacpAssemblyData *data);
+ virtual HRESULT STDMETHODCALLTYPE GetAssemblyData(CLRDATA_ADDRESS domainPtr, CLRDATA_ADDRESS assembly, struct DacpAssemblyData *data);
virtual HRESULT STDMETHODCALLTYPE GetAssemblyName(CLRDATA_ADDRESS assembly, unsigned int count, _Inout_updates_z_(count) WCHAR *name, unsigned int *pNeeded);
virtual HRESULT STDMETHODCALLTYPE GetThreadData(CLRDATA_ADDRESS thread, struct DacpThreadData *data);
virtual HRESULT STDMETHODCALLTYPE GetThreadFromThinlockID(UINT thinLockId, CLRDATA_ADDRESS *pThread);
diff --git a/src/coreclr/debug/daccess/request.cpp b/src/coreclr/debug/daccess/request.cpp
index 2be13b91e98aa..5e73d02325112 100644
--- a/src/coreclr/debug/daccess/request.cpp
+++ b/src/coreclr/debug/daccess/request.cpp
@@ -2834,19 +2834,17 @@ ClrDataAccess::GetAppDomainData(CLRDATA_ADDRESS addr, struct DacpAppDomainData *
}
else
{
- PTR_BaseDomain pBaseDomain = PTR_BaseDomain(TO_TADDR(addr));
-
ZeroMemory(appdomainData, sizeof(DacpAppDomainData));
- appdomainData->AppDomainPtr = PTR_CDADDR(pBaseDomain);
+ appdomainData->AppDomainPtr = addr;
PTR_LoaderAllocator pLoaderAllocator = SystemDomain::GetGlobalLoaderAllocator();
appdomainData->pHighFrequencyHeap = HOST_CDADDR(pLoaderAllocator->GetHighFrequencyHeap());
appdomainData->pLowFrequencyHeap = HOST_CDADDR(pLoaderAllocator->GetLowFrequencyHeap());
appdomainData->pStubHeap = HOST_CDADDR(pLoaderAllocator->GetStubHeap());
appdomainData->appDomainStage = STAGE_OPEN;
- if (pBaseDomain->IsAppDomain())
+ if (addr != HOST_CDADDR(SystemDomain::System()))
{
- AppDomain * pAppDomain = pBaseDomain->AsAppDomain();
+ PTR_AppDomain pAppDomain = PTR_AppDomain(TO_TADDR(addr));
appdomainData->DomainLocalBlock = 0;
appdomainData->pDomainLocalModules = 0;
@@ -2963,15 +2961,19 @@ ClrDataAccess::GetAssemblyList(CLRDATA_ADDRESS addr, int count, CLRDATA_ADDRESS
SOSDacEnter();
- BaseDomain* pBaseDomain = PTR_BaseDomain(TO_TADDR(addr));
-
- int n=0;
- if (pBaseDomain->IsAppDomain())
+ if (addr == HOST_CDADDR(SystemDomain::System()))
+ {
+ // We shouldn't be asking for the assemblies in SystemDomain
+ hr = E_INVALIDARG;
+ }
+ else
{
- AppDomain::AssemblyIterator i = pBaseDomain->AsAppDomain()->IterateAssembliesEx(
+ PTR_AppDomain pAppDomain = PTR_AppDomain(TO_TADDR(addr));
+ AppDomain::AssemblyIterator i = pAppDomain->IterateAssembliesEx(
(AssemblyIterationFlags)(kIncludeLoading | kIncludeLoaded | kIncludeExecution));
CollectibleAssemblyHolder pDomainAssembly;
+ int n = 0;
if (values)
{
while (i.Next(pDomainAssembly.This()) && (n < count))
@@ -2994,13 +2996,6 @@ ClrDataAccess::GetAssemblyList(CLRDATA_ADDRESS addr, int count, CLRDATA_ADDRESS
if (pNeeded)
*pNeeded = n;
}
- else
- {
- // The only other type of BaseDomain is the SystemDomain, and we shouldn't be asking
- // for the assemblies in it.
- _ASSERTE(false);
- hr = E_INVALIDARG;
- }
SOSDacLeave();
return hr;
@@ -3040,10 +3035,9 @@ ClrDataAccess::GetAppDomainName(CLRDATA_ADDRESS addr, unsigned int count, _Inout
{
SOSDacEnter();
- PTR_BaseDomain pBaseDomain = PTR_BaseDomain(TO_TADDR(addr));
- if (!pBaseDomain->IsAppDomain())
+ if (addr == HOST_CDADDR(SystemDomain::System()))
{
- // Shared domain and SystemDomain don't have this field.
+ // SystemDomain doesn't have this field.
if (pNeeded)
*pNeeded = 1;
if (name)
@@ -3051,8 +3045,7 @@ ClrDataAccess::GetAppDomainName(CLRDATA_ADDRESS addr, unsigned int count, _Inout
}
else
{
- AppDomain* pAppDomain = pBaseDomain->AsAppDomain();
-
+ PTR_AppDomain pAppDomain = PTR_AppDomain(TO_TADDR(addr));
if (!pAppDomain->m_friendlyName.IsEmpty())
{
if (!pAppDomain->m_friendlyName.DacGetUnicode(count, name, pNeeded))
@@ -3103,9 +3096,9 @@ ClrDataAccess::GetAppDomainConfigFile(CLRDATA_ADDRESS appDomain, int count,
}
HRESULT
-ClrDataAccess::GetAssemblyData(CLRDATA_ADDRESS cdBaseDomainPtr, CLRDATA_ADDRESS assembly, struct DacpAssemblyData *assemblyData)
+ClrDataAccess::GetAssemblyData(CLRDATA_ADDRESS domain, CLRDATA_ADDRESS assembly, struct DacpAssemblyData *assemblyData)
{
- if (assembly == (CLRDATA_ADDRESS)NULL && cdBaseDomainPtr == (CLRDATA_ADDRESS)NULL)
+ if (assembly == (CLRDATA_ADDRESS)NULL && domain == (CLRDATA_ADDRESS)NULL)
{
return E_INVALIDARG;
}
@@ -3117,14 +3110,9 @@ ClrDataAccess::GetAssemblyData(CLRDATA_ADDRESS cdBaseDomainPtr, CLRDATA_ADDRESS
// Make sure conditionally-assigned fields like AssemblySecDesc, LoadContext, etc. are zeroed
ZeroMemory(assemblyData, sizeof(DacpAssemblyData));
- // If the specified BaseDomain is an AppDomain, get a pointer to it
- AppDomain * pDomain = NULL;
- if (cdBaseDomainPtr != (CLRDATA_ADDRESS)NULL)
+ if (domain != (CLRDATA_ADDRESS)NULL)
{
- assemblyData->BaseDomainPtr = cdBaseDomainPtr;
- PTR_BaseDomain baseDomain = PTR_BaseDomain(TO_TADDR(cdBaseDomainPtr));
- if( baseDomain->IsAppDomain() )
- pDomain = baseDomain->AsAppDomain();
+ assemblyData->DomainPtr = domain;
}
assemblyData->AssemblyPtr = HOST_CDADDR(pAssembly);
diff --git a/src/coreclr/debug/di/process.cpp b/src/coreclr/debug/di/process.cpp
index aae787486adbc..fffd6df484825 100644
--- a/src/coreclr/debug/di/process.cpp
+++ b/src/coreclr/debug/di/process.cpp
@@ -11157,17 +11157,49 @@ void CordbProcess::HandleSetThreadContextNeeded(DWORD dwThreadId)
LOG((LF_CORDB, LL_INFO10000, "RS HandleSetThreadContextNeeded\n"));
#if defined(TARGET_WINDOWS) && defined(TARGET_AMD64)
- HandleHolder hThread = OpenThread(
- THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_QUERY_INFORMATION | THREAD_SUSPEND_RESUME,
- FALSE, // thread handle is not inheritable.
- dwThreadId);
+ // Before we can read the left side context information, we must:
+ // 1. obtain the thread handle
+ // 2. suspened the thread
+ // 3. read the thread context, and from that read the pointer to the left-side context and the size of the context
+ // 4. then we can perform the actual SetThreadContext operation
+ // 5. lastly, we must resume the thread
+ // For the first step of obtaining the thread handle,
+ // we have previously attempted to use ::OpenThread to get a handle to the thread.
+ // However, there are situations where OpenThread can fail with an Access Denied error.
+ // From https://github.com/dotnet/runtime/issues/107263, the control-c handler in
+ // Windows causes the process to have higher privileges.
+ // We are now using the following approach to access the thread handle, which is the same
+ // approach used by CordbThread::RefreshHandle:
+ // 1. Get the thread handle from the DAC
+ // 2. Duplicate the handle to the current process
+
+ // lookup the CordbThread by thread ID, so that we can access the left-side thread handle
+ CordbThread * pThread = TryLookupOrCreateThreadByVolatileOSId(dwThreadId);
+
+ IDacDbiInterface* pDAC = GetDAC();
+ if (pDAC == NULL)
+ {
+ LOG((LF_CORDB, LL_INFO10000, "RS HandleSetThreadContextNeeded - DAC not initialized\n"));
+ ThrowHR(E_UNEXPECTED);
+ }
- if (hThread == NULL)
+ HANDLE hOutOfProcThread = pDAC->GetThreadHandle(pThread->m_vmThreadToken);
+ if (hOutOfProcThread == NULL)
{
- LOG((LF_CORDB, LL_INFO10000, "RS HandleSetThreadContextNeeded - Unexpected result from OpenThread\n"));
+ LOG((LF_CORDB, LL_INFO10000, "RS HandleSetThreadContextNeeded - Failed to get thread handle\n"));
ThrowHR(E_UNEXPECTED);
}
+ // Duplicate the thread handle to the current process
+ HandleHolder hThread;
+ BOOL fSuccess = DuplicateHandle(UnsafeGetProcessHandle(), hOutOfProcThread, ::GetCurrentProcess(), &hThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
+ if (!fSuccess)
+ {
+ LOG((LF_CORDB, LL_INFO10000, "RS HandleSetThreadContextNeeded - Unexpected result from DuplicateHandle\n"));
+ ThrowHR(HRESULT_FROM_GetLastError());
+ }
+
+ // Suspend the thread and so that we can read the thread context.
DWORD previousSuspendCount = ::SuspendThread(hThread);
if (previousSuspendCount == (DWORD)-1)
{
@@ -11178,12 +11210,22 @@ void CordbProcess::HandleSetThreadContextNeeded(DWORD dwThreadId)
DT_CONTEXT context = { 0 };
context.ContextFlags = CONTEXT_FULL;
- HRESULT hr = GetDataTarget()->GetThreadContext(dwThreadId, CONTEXT_FULL, sizeof(DT_CONTEXT), reinterpret_cast (&context));
- IfFailThrow(hr);
+ // we originally used GetDataTarget()->GetThreadContext, but
+ // the implementation uses ShimLocalDataTarget::GetThreadContext which
+ // depends on OpenThread which might fail with an Access Denied error (see note above)
+ BOOL success = ::GetThreadContext(hThread, (CONTEXT*)(&context));
+ if (!success)
+ {
+ LOG((LF_CORDB, LL_INFO10000, "RS HandleSetThreadContextNeeded - Unexpected result from GetThreadContext\n"));
+ ThrowHR(HRESULT_FROM_GetLastError());
+ }
+ // Read the pointer to the left-side context and the size of the context from the thread context.
TADDR lsContextAddr = (TADDR)context.Rcx;
DWORD contextSize = (DWORD)context.Rdx;
+ // Read the expected Rip and Rsp from the thread context. This is used to
+ // validate the context read from the left-side.
TADDR expectedRip = (TADDR)context.R8;
TADDR expectedRsp = (TADDR)context.R9;
@@ -11198,7 +11240,7 @@ void CordbProcess::HandleSetThreadContextNeeded(DWORD dwThreadId)
PCONTEXT pContext = (PCONTEXT)_alloca(contextSize);
ULONG32 cbRead;
- hr = GetDataTarget()->ReadVirtual(lsContextAddr, reinterpret_cast(pContext), contextSize, &cbRead);
+ HRESULT hr = GetDataTarget()->ReadVirtual(lsContextAddr, reinterpret_cast(pContext), contextSize, &cbRead);
if (FAILED(hr))
{
_ASSERTE(!"ReadVirtual failed");
@@ -11232,7 +11274,7 @@ void CordbProcess::HandleSetThreadContextNeeded(DWORD dwThreadId)
// The initialize call should fail but return contextSize
contextSize = 0;
DWORD contextFlags = pContext->ContextFlags;
- BOOL success = InitializeContext(NULL, contextFlags, NULL, &contextSize);
+ success = InitializeContext(NULL, contextFlags, NULL, &contextSize);
if(success || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
@@ -11276,6 +11318,7 @@ void CordbProcess::HandleSetThreadContextNeeded(DWORD dwThreadId)
DWORD lastError = 0;
+ // Perform the actual SetThreadContext operation.
success = ::SetThreadContext(hThread, pFrameContext);
if (!success)
{
@@ -11285,6 +11328,7 @@ void CordbProcess::HandleSetThreadContextNeeded(DWORD dwThreadId)
LOG((LF_CORDB, LL_INFO10000, "RS HandleSetThreadContextNeeded - Set Thread Context Completed: Success=%d GetLastError=%d hr=0x%X\n", success, lastError, HRESULT_FROM_WIN32(lastError)));
_ASSERTE(success);
+ // Now that we have completed the SetThreadContext, resume the thread
DWORD suspendCount = ::ResumeThread(hThread);
if (suspendCount == (DWORD)-1)
{
diff --git a/src/coreclr/dlls/mscorrc/mscorrc.rc b/src/coreclr/dlls/mscorrc/mscorrc.rc
index 927b287844df7..1d58a0681b584 100644
--- a/src/coreclr/dlls/mscorrc/mscorrc.rc
+++ b/src/coreclr/dlls/mscorrc/mscorrc.rc
@@ -467,7 +467,6 @@ BEGIN
IDS_EE_INVALID_CA "Invalid custom attribute provided."
- IDS_EE_THREAD_CANNOT_GET "Unable to retrieve thread information."
IDS_EE_THREAD_ABORT_WHILE_SUSPEND "Thread is suspended; attempting to abort."
IDS_EE_NOVARIANTRETURN "PInvoke restriction: cannot return variants."
diff --git a/src/coreclr/dlls/mscorrc/resource.h b/src/coreclr/dlls/mscorrc/resource.h
index 09bf78dfb93c4..964cb7128325d 100644
--- a/src/coreclr/dlls/mscorrc/resource.h
+++ b/src/coreclr/dlls/mscorrc/resource.h
@@ -232,7 +232,6 @@
#define IDS_EE_INVALID_CA 0x1a10
-#define IDS_EE_THREAD_CANNOT_GET 0x1a15
#define IDS_EE_THREAD_ABORT_WHILE_SUSPEND 0x1a1c
#define IDS_EE_NOVARIANTRETURN 0x1a1d
diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h
index 566d1ecb769a4..bf57e9ea28073 100644
--- a/src/coreclr/inc/corinfo.h
+++ b/src/coreclr/inc/corinfo.h
@@ -930,7 +930,6 @@ struct PatchpointInfo;
// Cookie types consumed by the code generator (these are opaque values
// not inspected by the code generator):
-typedef struct CORINFO_ASSEMBLY_STRUCT_* CORINFO_ASSEMBLY_HANDLE;
typedef struct CORINFO_MODULE_STRUCT_* CORINFO_MODULE_HANDLE;
typedef struct CORINFO_DEPENDENCY_STRUCT_* CORINFO_DEPENDENCY_HANDLE;
typedef struct CORINFO_CLASS_STRUCT_* CORINFO_CLASS_HANDLE;
@@ -2321,18 +2320,9 @@ class ICorStaticInfo
CORINFO_CLASS_HANDLE cls
) = 0;
- virtual CORINFO_MODULE_HANDLE getClassModule (
- CORINFO_CLASS_HANDLE cls
- ) = 0;
-
- // Returns the assembly that contains the module "mod".
- virtual CORINFO_ASSEMBLY_HANDLE getModuleAssembly (
- CORINFO_MODULE_HANDLE mod
- ) = 0;
-
- // Returns the name of the assembly "assem".
- virtual const char* getAssemblyName (
- CORINFO_ASSEMBLY_HANDLE assem
+ // Returns the assembly name of the class "cls", or nullptr if there is none.
+ virtual const char* getClassAssemblyName (
+ CORINFO_CLASS_HANDLE cls
) = 0;
// Allocate and delete process-lifetime objects. Should only be
diff --git a/src/coreclr/inc/dacprivate.h b/src/coreclr/inc/dacprivate.h
index 305029634406c..62821f71395af 100644
--- a/src/coreclr/inc/dacprivate.h
+++ b/src/coreclr/inc/dacprivate.h
@@ -425,11 +425,11 @@ enum DacpAppDomainDataStage {
STAGE_CLOSED
};
-// Information about a BaseDomain (AppDomain, SharedDomain or SystemDomain).
+// Information about an AppDomain or SystemDomain.
// For types other than AppDomain, some fields (like dwID, DomainLocalBlock, etc.) will be 0/null.
struct MSLAYOUT DacpAppDomainData
{
- // The pointer to the BaseDomain (not necessarily an AppDomain).
+ // The pointer to the AppDomain or SystemDomain.
// It's useful to keep this around in the structure
CLRDATA_ADDRESS AppDomainPtr = 0;
CLRDATA_ADDRESS AppSecDesc = 0;
@@ -455,7 +455,7 @@ struct MSLAYOUT DacpAssemblyData
CLRDATA_ADDRESS AssemblyPtr = 0; //useful to have
CLRDATA_ADDRESS ClassLoader = 0;
CLRDATA_ADDRESS ParentDomain = 0;
- CLRDATA_ADDRESS BaseDomainPtr = 0;
+ CLRDATA_ADDRESS DomainPtr = 0;
CLRDATA_ADDRESS AssemblySecDesc = 0;
BOOL isDynamic = FALSE;
UINT ModuleCount = FALSE;
@@ -463,9 +463,9 @@ struct MSLAYOUT DacpAssemblyData
BOOL isDomainNeutral = FALSE; // Always false, preserved for backward compatibility
DWORD dwLocationFlags = 0;
- HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr, CLRDATA_ADDRESS baseDomainPtr)
+ HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr, CLRDATA_ADDRESS domainPtr)
{
- return sos->GetAssemblyData(baseDomainPtr, addr, this);
+ return sos->GetAssemblyData(domainPtr, addr, this);
}
HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
diff --git a/src/coreclr/inc/eventtracebase.h b/src/coreclr/inc/eventtracebase.h
index 316104f649a1d..38868fe528f79 100644
--- a/src/coreclr/inc/eventtracebase.h
+++ b/src/coreclr/inc/eventtracebase.h
@@ -689,7 +689,6 @@ class Module;
class Assembly;
class MethodDesc;
class MethodTable;
-class BaseDomain;
class AppDomain;
class SString;
class CrawlFrame;
@@ -750,12 +749,11 @@ namespace ETW
#ifdef FEATURE_EVENT_TRACE
static VOID SendThreadRundownEvent();
static VOID SendGCRundownEvent();
- static VOID IterateDomain(BaseDomain *pDomain, DWORD enumerationOptions);
- static VOID IterateAppDomain(AppDomain * pAppDomain, DWORD enumerationOptions);
+ static VOID IterateAppDomain(DWORD enumerationOptions);
static VOID IterateCollectibleLoaderAllocator(AssemblyLoaderAllocator *pLoaderAllocator, DWORD enumerationOptions);
static VOID IterateAssembly(Assembly *pAssembly, DWORD enumerationOptions);
static VOID IterateModule(Module *pModule, DWORD enumerationOptions);
- static VOID EnumerationHelper(Module *moduleFilter, BaseDomain *domainFilter, DWORD enumerationOptions);
+ static VOID EnumerationHelper(Module *moduleFilter, DWORD enumerationOptions);
static DWORD GetEnumerationOptionsFromRuntimeKeywords();
public:
typedef union _EnumerationStructs
@@ -839,7 +837,7 @@ namespace ETW
static VOID SendModuleEvent(Module *pModule, DWORD dwEventOptions, BOOL bFireDomainModuleEvents=FALSE);
static ULONG SendModuleRange(_In_ Module *pModule, _In_ DWORD dwEventOptions);
static VOID SendAssemblyEvent(Assembly *pAssembly, DWORD dwEventOptions);
- static VOID SendDomainEvent(BaseDomain *pBaseDomain, DWORD dwEventOptions, LPCWSTR wszFriendlyName=NULL);
+ static VOID SendDomainEvent(DWORD dwEventOptions, LPCWSTR wszFriendlyName=NULL);
public:
typedef union _LoaderStructs
{
@@ -877,23 +875,23 @@ namespace ETW
}LoaderStructs;
- static VOID DomainLoadReal(BaseDomain *pDomain, _In_opt_ LPWSTR wszFriendlyName=NULL);
+ static VOID DomainLoadReal(_In_opt_ LPWSTR wszFriendlyName=NULL);
- static VOID DomainLoad(BaseDomain *pDomain, _In_opt_ LPWSTR wszFriendlyName = NULL)
+ static VOID DomainLoad(_In_opt_ LPWSTR wszFriendlyName = NULL)
{
if (ETW_PROVIDER_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER))
{
- DomainLoadReal(pDomain, wszFriendlyName);
+ DomainLoadReal(wszFriendlyName);
}
}
- static VOID DomainUnload(AppDomain *pDomain);
+ static VOID DomainUnload();
static VOID CollectibleLoaderAllocatorUnload(AssemblyLoaderAllocator *pLoaderAllocator);
static VOID ModuleLoad(Module *pModule, LONG liReportedSharedModule);
#else
public:
- static VOID DomainLoad(BaseDomain *pDomain, _In_opt_ LPWSTR wszFriendlyName=NULL) {};
- static VOID DomainUnload(AppDomain *pDomain) {};
+ static VOID DomainLoad(_In_opt_ LPWSTR wszFriendlyName=NULL) {};
+ static VOID DomainUnload() {};
static VOID CollectibleLoaderAllocatorUnload(AssemblyLoaderAllocator *pLoaderAllocator) {};
static VOID ModuleLoad(Module *pModule, LONG liReportedSharedModule) {};
#endif // FEATURE_EVENT_TRACE
@@ -904,7 +902,7 @@ namespace ETW
{
friend class ETW::EnumerationLog;
#ifdef FEATURE_EVENT_TRACE
- static VOID SendEventsForJitMethods(BaseDomain *pDomainFilter, LoaderAllocator *pLoaderAllocatorFilter, DWORD dwEventOptions);
+ static VOID SendEventsForJitMethods(BOOL getCodeVersionIds, LoaderAllocator *pLoaderAllocatorFilter, DWORD dwEventOptions);
static VOID SendEventsForJitMethodsHelper(
LoaderAllocator *pLoaderAllocatorFilter,
DWORD dwEventOptions,
diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h
index bbaf43a6ee0ce..ffc4659cb9fb8 100644
--- a/src/coreclr/inc/icorjitinfoimpl_generated.h
+++ b/src/coreclr/inc/icorjitinfoimpl_generated.h
@@ -193,15 +193,9 @@ bool isValueClass(
uint32_t getClassAttribs(
CORINFO_CLASS_HANDLE cls) override;
-CORINFO_MODULE_HANDLE getClassModule(
+const char* getClassAssemblyName(
CORINFO_CLASS_HANDLE cls) override;
-CORINFO_ASSEMBLY_HANDLE getModuleAssembly(
- CORINFO_MODULE_HANDLE mod) override;
-
-const char* getAssemblyName(
- CORINFO_ASSEMBLY_HANDLE assem) override;
-
void* LongLifetimeMalloc(
size_t sz) override;
diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h
index 6aef89b2afd76..bce13e8aabcc3 100644
--- a/src/coreclr/inc/jiteeversionguid.h
+++ b/src/coreclr/inc/jiteeversionguid.h
@@ -43,11 +43,11 @@ typedef const GUID *LPCGUID;
#define GUID_DEFINED
#endif // !GUID_DEFINED
-constexpr GUID JITEEVersionIdentifier = { /* 7f7fd340-4779-455a-8046-628f3cd8c3c7 */
- 0x7f7fd340,
- 0x4779,
- 0x455a,
- {0x80, 0x46, 0x62, 0x8f, 0x3c, 0xd8, 0xc3, 0xc7}
+constexpr GUID JITEEVersionIdentifier = { /* b75a5475-ff22-4078-9551-2024ce03d383 */
+ 0xb75a5475,
+ 0xff22,
+ 0x4078,
+ {0x95, 0x51, 0x20, 0x24, 0xce, 0x03, 0xd3, 0x83}
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/coreclr/jit/ICorJitInfo_names_generated.h b/src/coreclr/jit/ICorJitInfo_names_generated.h
index 2d3865018d1de..15665a14b69ba 100644
--- a/src/coreclr/jit/ICorJitInfo_names_generated.h
+++ b/src/coreclr/jit/ICorJitInfo_names_generated.h
@@ -45,9 +45,7 @@ DEF_CLR_API(getTypeInstantiationArgument)
DEF_CLR_API(printClassName)
DEF_CLR_API(isValueClass)
DEF_CLR_API(getClassAttribs)
-DEF_CLR_API(getClassModule)
-DEF_CLR_API(getModuleAssembly)
-DEF_CLR_API(getAssemblyName)
+DEF_CLR_API(getClassAssemblyName)
DEF_CLR_API(LongLifetimeMalloc)
DEF_CLR_API(LongLifetimeFree)
DEF_CLR_API(getIsClassInitedFlagAddress)
diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp
index ff3270192dc5f..f45110fe0caba 100644
--- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp
+++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp
@@ -416,30 +416,12 @@ uint32_t WrapICorJitInfo::getClassAttribs(
return temp;
}
-CORINFO_MODULE_HANDLE WrapICorJitInfo::getClassModule(
+const char* WrapICorJitInfo::getClassAssemblyName(
CORINFO_CLASS_HANDLE cls)
{
- API_ENTER(getClassModule);
- CORINFO_MODULE_HANDLE temp = wrapHnd->getClassModule(cls);
- API_LEAVE(getClassModule);
- return temp;
-}
-
-CORINFO_ASSEMBLY_HANDLE WrapICorJitInfo::getModuleAssembly(
- CORINFO_MODULE_HANDLE mod)
-{
- API_ENTER(getModuleAssembly);
- CORINFO_ASSEMBLY_HANDLE temp = wrapHnd->getModuleAssembly(mod);
- API_LEAVE(getModuleAssembly);
- return temp;
-}
-
-const char* WrapICorJitInfo::getAssemblyName(
- CORINFO_ASSEMBLY_HANDLE assem)
-{
- API_ENTER(getAssemblyName);
- const char* temp = wrapHnd->getAssemblyName(assem);
- API_LEAVE(getAssemblyName);
+ API_ENTER(getClassAssemblyName);
+ const char* temp = wrapHnd->getClassAssemblyName(cls);
+ API_LEAVE(getClassAssemblyName);
return temp;
}
diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp
index 3f28580aba68a..2b9425e6fe502 100644
--- a/src/coreclr/jit/compiler.cpp
+++ b/src/coreclr/jit/compiler.cpp
@@ -2586,8 +2586,7 @@ void Compiler::compInitOptions(JitFlags* jitFlags)
// We have an exclusion list. See if this method is in an assembly that is on the list.
// Note that we check this for every method, since we might inline across modules, and
// if the inlinee module is on the list, we don't want to use the altjit for it.
- const char* methodAssemblyName = info.compCompHnd->getAssemblyName(
- info.compCompHnd->getModuleAssembly(info.compCompHnd->getClassModule(info.compClassHnd)));
+ const char* methodAssemblyName = eeGetClassAssemblyName(info.compClassHnd);
if (s_pAltJitExcludeAssembliesList->IsInList(methodAssemblyName))
{
opts.altJit = false;
@@ -2614,8 +2613,7 @@ void Compiler::compInitOptions(JitFlags* jitFlags)
bool assemblyInIncludeList = true; // assume we'll dump, if there's not an include list (or it's empty).
if (s_pJitDisasmIncludeAssembliesList != nullptr && !s_pJitDisasmIncludeAssembliesList->IsEmpty())
{
- const char* assemblyName = info.compCompHnd->getAssemblyName(
- info.compCompHnd->getModuleAssembly(info.compCompHnd->getClassModule(info.compClassHnd)));
+ const char* assemblyName = eeGetClassAssemblyName(info.compClassHnd);
if (!s_pJitDisasmIncludeAssembliesList->IsInList(assemblyName))
{
// We have a list, and the current assembly is not in it, so we won't dump.
@@ -5238,11 +5236,12 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
m_pLowering->FinalizeOutgoingArgSpace();
// We can not add any new tracked variables after this point.
- lvaTrackedFixed = true;
+ lvaTrackedFixed = true;
+ const unsigned numBlocksBeforeLSRA = fgBBcount;
// Now that lowering is completed we can proceed to perform register allocation
//
- auto linearScanPhase = [this]() {
+ auto linearScanPhase = [this] {
m_pLinearScan->doLinearScan();
};
DoPhase(this, PHASE_LINEAR_SCAN, linearScanPhase);
@@ -5252,8 +5251,25 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
if (opts.OptimizationEnabled())
{
- // LSRA and stack level setting can modify the flowgraph.
- // Now that it won't change, run post-layout optimizations.
+ // LSRA may introduce new blocks. If it does, rerun layout.
+ if ((fgBBcount != numBlocksBeforeLSRA) && JitConfig.JitDoReversePostOrderLayout())
+ {
+ auto lateLayoutPhase = [this] {
+ fgDoReversePostOrderLayout();
+ fgMoveColdBlocks();
+ return PhaseStatus::MODIFIED_EVERYTHING;
+ };
+
+ DoPhase(this, PHASE_OPTIMIZE_LAYOUT, lateLayoutPhase);
+
+ if (fgFirstColdBlock != nullptr)
+ {
+ fgFirstColdBlock = nullptr;
+ DoPhase(this, PHASE_DETERMINE_FIRST_COLD_BLOCK, &Compiler::fgDetermineFirstColdBlock);
+ }
+ }
+
+ // Now that the flowgraph is finalized, run post-layout optimizations.
DoPhase(this, PHASE_OPTIMIZE_POST_LAYOUT, &Compiler::optOptimizePostLayout);
}
@@ -6335,39 +6351,29 @@ int Compiler::compCompile(CORINFO_MODULE_HANDLE classPtr,
#ifdef DEBUG
if (JitConfig.EnableExtraSuperPmiQueries())
{
- // This call to getClassModule/getModuleAssembly/getAssemblyName fails in crossgen2 due to these
- // APIs being unimplemented. So disable this extra info for pre-jit mode. See
- // https://github.com/dotnet/runtime/issues/48888.
- //
- // Ditto for some of the class name queries for generic params.
- //
- if (!compileFlags->IsSet(JitFlags::JIT_FLAG_PREJIT))
- {
- // Get the assembly name, to aid finding any particular SuperPMI method context function
- (void)info.compCompHnd->getAssemblyName(
- info.compCompHnd->getModuleAssembly(info.compCompHnd->getClassModule(info.compClassHnd)));
+ // Get the assembly name, to aid finding any particular SuperPMI method context function
+ (void)eeGetClassAssemblyName(info.compClassHnd);
- // Fetch class names for the method's generic parameters.
- //
- CORINFO_SIG_INFO sig;
- info.compCompHnd->getMethodSig(info.compMethodHnd, &sig, nullptr);
+ // Fetch class names for the method's generic parameters.
+ //
+ CORINFO_SIG_INFO sig;
+ info.compCompHnd->getMethodSig(info.compMethodHnd, &sig, nullptr);
- const unsigned classInst = sig.sigInst.classInstCount;
- if (classInst > 0)
+ const unsigned classInst = sig.sigInst.classInstCount;
+ if (classInst > 0)
+ {
+ for (unsigned i = 0; i < classInst; i++)
{
- for (unsigned i = 0; i < classInst; i++)
- {
- eeGetClassName(sig.sigInst.classInst[i]);
- }
+ eeGetClassName(sig.sigInst.classInst[i]);
}
+ }
- const unsigned methodInst = sig.sigInst.methInstCount;
- if (methodInst > 0)
+ const unsigned methodInst = sig.sigInst.methInstCount;
+ if (methodInst > 0)
+ {
+ for (unsigned i = 0; i < methodInst; i++)
{
- for (unsigned i = 0; i < methodInst; i++)
- {
- eeGetClassName(sig.sigInst.methInst[i]);
- }
+ eeGetClassName(sig.sigInst.methInst[i]);
}
}
}
@@ -9221,8 +9227,7 @@ void JitTimer::PrintCsvMethodStats(Compiler* comp)
}
else
{
- const char* methodAssemblyName = comp->info.compCompHnd->getAssemblyName(
- comp->info.compCompHnd->getModuleAssembly(comp->info.compCompHnd->getClassModule(comp->info.compClassHnd)));
+ const char* methodAssemblyName = comp->eeGetClassAssemblyName(comp->info.compClassHnd);
fprintf(s_csvFile, "\"%s\",", methodAssemblyName);
}
fprintf(s_csvFile, "%u,", comp->info.compILCodeSize);
diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h
index 6fe0555691bd8..a23a650a805f2 100644
--- a/src/coreclr/jit/compiler.h
+++ b/src/coreclr/jit/compiler.h
@@ -5316,6 +5316,8 @@ class Compiler
unsigned xcptnIndex,
bool putInTryRegion);
+ BasicBlock* fgNewBBatTryRegionEnd(BBKinds jumpKind, unsigned tryIndex);
+
void fgInsertBBbefore(BasicBlock* insertBeforeBlk, BasicBlock* newBlk);
void fgInsertBBafter(BasicBlock* insertAfterBlk, BasicBlock* newBlk);
void fgUnlinkBlock(BasicBlock* block);
@@ -8335,6 +8337,8 @@ class Compiler
void eePrintObjectDescription(const char* prefix, CORINFO_OBJECT_HANDLE handle);
const char* eeGetShortClassName(CORINFO_CLASS_HANDLE clsHnd);
+ const char* eeGetClassAssemblyName(CORINFO_CLASS_HANDLE clsHnd);
+
#if defined(DEBUG)
unsigned eeTryGetClassSize(CORINFO_CLASS_HANDLE clsHnd);
#endif
diff --git a/src/coreclr/jit/eeinterface.cpp b/src/coreclr/jit/eeinterface.cpp
index fb07912ebf7d9..7ac73a22d27e0 100644
--- a/src/coreclr/jit/eeinterface.cpp
+++ b/src/coreclr/jit/eeinterface.cpp
@@ -596,6 +596,27 @@ const char* Compiler::eeGetShortClassName(CORINFO_CLASS_HANDLE clsHnd)
return printer.GetBuffer();
}
+//------------------------------------------------------------------------
+// eeGetClassAssemblyName:
+// Get the assembly name of a type.
+// If missing information (in SPMI), then return a placeholder string.
+//
+// Parameters:
+// clsHnd - the handle of the class
+//
+// Return value:
+// The name string.
+//
+const char* Compiler::eeGetClassAssemblyName(CORINFO_CLASS_HANDLE clsHnd)
+{
+ const char* assemblyName = "";
+ eeRunFunctorWithSPMIErrorTrap([&]() {
+ assemblyName = info.compCompHnd->getClassAssemblyName(clsHnd);
+ });
+
+ return assemblyName != nullptr ? assemblyName : "";
+}
+
void Compiler::eePrintObjectDescription(const char* prefix, CORINFO_OBJECT_HANDLE handle)
{
const size_t maxStrSize = 64;
diff --git a/src/coreclr/jit/emitarm.cpp b/src/coreclr/jit/emitarm.cpp
index fd0a27f61818e..902399f58e4fe 100644
--- a/src/coreclr/jit/emitarm.cpp
+++ b/src/coreclr/jit/emitarm.cpp
@@ -3914,10 +3914,7 @@ void emitter::emitIns_S_R(instruction ins, emitAttr attr, regNumber reg1, int va
{
regNumber rsvdReg = codeGen->rsGetRsvdReg();
emitIns_genStackOffset(rsvdReg, varx, offs, /* isFloatUsage */ true, &baseRegUsed);
-
- // Ensure the baseReg calculated is correct.
- assert(baseRegUsed == reg2);
- emitIns_R_R(INS_add, EA_4BYTE, rsvdReg, reg2);
+ emitIns_R_R(INS_add, EA_4BYTE, rsvdReg, baseRegUsed);
emitIns_R_R_I(ins, attr, reg1, rsvdReg, 0);
return;
}
diff --git a/src/coreclr/jit/fgbasic.cpp b/src/coreclr/jit/fgbasic.cpp
index f8e7ead56b323..774e456f5e761 100644
--- a/src/coreclr/jit/fgbasic.cpp
+++ b/src/coreclr/jit/fgbasic.cpp
@@ -6723,6 +6723,39 @@ BasicBlock* Compiler::fgNewBBinRegionWorker(BBKinds jumpKind,
return newBlk;
}
+//-----------------------------------------------------------------------------
+// fgNewBBatTryRegionEnd: Creates and inserts a new block at the end of the specified
+// try region, updating the try end pointers in the EH table as necessary.
+//
+// Arguments:
+// jumpKind - The jump kind of the new block
+// tryIndex - The index of the try region to insert the new block in
+//
+// Returns:
+// The new block
+//
+BasicBlock* Compiler::fgNewBBatTryRegionEnd(BBKinds jumpKind, unsigned tryIndex)
+{
+ BasicBlock* const oldTryLast = ehGetDsc(tryIndex)->ebdTryLast;
+ BasicBlock* const newBlock = fgNewBBafter(jumpKind, oldTryLast, /* extendRegion */ false);
+ newBlock->setTryIndex(tryIndex);
+ newBlock->clearHndIndex();
+
+ // Update this try region's (and all parent try regions') last block pointer
+ //
+ for (unsigned XTnum = tryIndex; XTnum < compHndBBtabCount; XTnum++)
+ {
+ EHblkDsc* const HBtab = ehGetDsc(XTnum);
+ if (HBtab->ebdTryLast == oldTryLast)
+ {
+ assert((XTnum == tryIndex) || (ehGetDsc(tryIndex)->ebdEnclosingTryIndex != EHblkDsc::NO_ENCLOSING_INDEX));
+ fgSetTryEnd(HBtab, newBlock);
+ }
+ }
+
+ return newBlock;
+}
+
//------------------------------------------------------------------------
// fgUseThrowHelperBlocks: Determinate does compiler use throw helper blocks.
//
diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp
index a74bb3651c88f..6b96564af8668 100644
--- a/src/coreclr/jit/lowerarmarch.cpp
+++ b/src/coreclr/jit/lowerarmarch.cpp
@@ -4050,47 +4050,49 @@ GenTree* Lowering::LowerHWIntrinsicCndSel(GenTreeHWIntrinsic* cndSelNode)
GenTree* nestedOp1 = nestedCndSel->Op(1);
GenTree* nestedOp2 = nestedCndSel->Op(2);
assert(varTypeIsMask(nestedOp1));
- assert(nestedOp2->OperIsHWIntrinsic());
- NamedIntrinsic nestedOp2Id = nestedOp2->AsHWIntrinsic()->GetHWIntrinsicId();
-
- // If the nested op uses Pg/Z, then inactive lanes will result in zeros, so can only transform if
- // op3 is all zeros. Such a Csel operation is absorbed into the instruction when emitted. Skip this optimisation
- // when the nestedOp is a reduce operation.
-
- if (nestedOp1->IsMaskAllBitsSet() && !HWIntrinsicInfo::IsReduceOperation(nestedOp2Id) &&
- (!HWIntrinsicInfo::IsZeroingMaskedOperation(nestedOp2Id) || op3->IsVectorZero()))
+ if (nestedOp2->OperIsHWIntrinsic())
{
- GenTree* nestedOp2 = nestedCndSel->Op(2);
- GenTree* nestedOp3 = nestedCndSel->Op(3);
+ NamedIntrinsic nestedOp2Id = nestedOp2->AsHWIntrinsic()->GetHWIntrinsicId();
- JITDUMP("lowering nested ConditionalSelect HWIntrinisic (before):\n");
- DISPTREERANGE(BlockRange(), cndSelNode);
- JITDUMP("\n");
+ // If the nested op uses Pg/Z, then inactive lanes will result in zeros, so can only transform if
+ // op3 is all zeros. Such a Csel operation is absorbed into the instruction when emitted. Skip this
+ // optimisation when the nestedOp is a reduce operation.
- // Transform:
- //
- // CndSel(mask, CndSel(AllTrue, embeddedMask(trueValOp2), trueValOp3), op3) to
- // CndSel(mask, embedded(trueValOp2), op3)
- //
- cndSelNode->Op(2) = nestedCndSel->Op(2);
- if (nestedOp3->IsMaskZero())
- {
- BlockRange().Remove(nestedOp3);
- }
- else
+ if (nestedOp1->IsMaskAllBitsSet() && !HWIntrinsicInfo::IsReduceOperation(nestedOp2Id) &&
+ (!HWIntrinsicInfo::IsZeroingMaskedOperation(nestedOp2Id) || op3->IsVectorZero()))
{
- nestedOp3->SetUnusedValue();
- }
+ GenTree* nestedOp2 = nestedCndSel->Op(2);
+ GenTree* nestedOp3 = nestedCndSel->Op(3);
+
+ JITDUMP("lowering nested ConditionalSelect HWIntrinisic (before):\n");
+ DISPTREERANGE(BlockRange(), cndSelNode);
+ JITDUMP("\n");
+
+ // Transform:
+ //
+ // CndSel(mask, CndSel(AllTrue, embeddedMask(trueValOp2), trueValOp3), op3) to
+ // CndSel(mask, embedded(trueValOp2), op3)
+ //
+ cndSelNode->Op(2) = nestedCndSel->Op(2);
+ if (nestedOp3->IsMaskZero())
+ {
+ BlockRange().Remove(nestedOp3);
+ }
+ else
+ {
+ nestedOp3->SetUnusedValue();
+ }
- BlockRange().Remove(nestedOp1);
- BlockRange().Remove(nestedCndSel);
+ BlockRange().Remove(nestedOp1);
+ BlockRange().Remove(nestedCndSel);
- JITDUMP("lowering nested ConditionalSelect HWIntrinisic (after):\n");
- DISPTREERANGE(BlockRange(), cndSelNode);
- JITDUMP("\n");
+ JITDUMP("lowering nested ConditionalSelect HWIntrinisic (after):\n");
+ DISPTREERANGE(BlockRange(), cndSelNode);
+ JITDUMP("\n");
- return cndSelNode;
+ return cndSelNode;
+ }
}
}
else if (op1->IsMaskAllBitsSet())
diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp
index 763a28989b3a8..3f603fa0c221b 100644
--- a/src/coreclr/jit/lsra.cpp
+++ b/src/coreclr/jit/lsra.cpp
@@ -9789,10 +9789,26 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
if (location[targetReg] == REG_NA)
{
#ifdef TARGET_ARM
- regNumber sourceReg = (regNumber)source[targetReg];
- Interval* interval = sourceIntervals[sourceReg];
+ // For Arm, check two things:
+ // 1. If sourceReg relates to DOUBLE interval, then make sure
+ // the second half of targetReg is not participating in the resolution.
+ // 2. On the contrary, if targetReg is second half of a DOUBLE interval,
+ // then make sure the first half is not participating in the resolution.
+ // Only when both these conditions are met, can we safely assume
+ // that sourceReg can be moved to targetReg.
+ regNumber sourceReg = (regNumber)source[targetReg];
+ Interval* interval = sourceIntervals[sourceReg];
+ Interval* otherTargetInterval = nullptr;
+ regNumber otherHalfTargetReg = REG_NA;
+ if (genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg))
+ {
+ otherHalfTargetReg = REG_PREV(targetReg);
+ otherTargetInterval = sourceIntervals[otherHalfTargetReg];
+ }
+
if (interval->registerType == TYP_DOUBLE)
{
+ // Condition 1 above.
// For ARM32, make sure that both of the float halves of the double register are available.
assert(genIsValidDoubleReg(targetReg));
regNumber anotherHalfRegNum = REG_NEXT(targetReg);
@@ -9801,11 +9817,22 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
targetRegsReady.AddRegNumInMask(targetReg);
}
}
+ else if ((otherTargetInterval != nullptr) && (otherTargetInterval->registerType == TYP_DOUBLE))
+ {
+ // Condition 2 above.
+ assert(otherHalfTargetReg != REG_NA);
+ if (location[otherHalfTargetReg] == REG_NA)
+ {
+ targetRegsReady.AddRegNumInMask(targetReg);
+ }
+ }
else
-#endif // TARGET_ARM
{
targetRegsReady.AddRegNumInMask(targetReg);
}
+#else
+ targetRegsReady.AddRegNumInMask(targetReg);
+#endif
}
}
@@ -10019,6 +10046,13 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
{
compiler->codeGen->regSet.rsSetRegsModified(genRegMask(tempReg) DEBUGARG(true));
#ifdef TARGET_ARM
+ Interval* otherTargetInterval = nullptr;
+ regNumber otherHalfTargetReg = REG_NA;
+ if (genIsValidFloatReg(targetReg) && !genIsValidDoubleReg(targetReg))
+ {
+ otherHalfTargetReg = REG_PREV(targetReg);
+ otherTargetInterval = sourceIntervals[otherHalfTargetReg];
+ }
if (sourceIntervals[fromReg]->registerType == TYP_DOUBLE)
{
assert(genIsValidDoubleReg(targetReg));
@@ -10027,8 +10061,15 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
addResolutionForDouble(block, insertionPoint, sourceIntervals, location, tempReg, targetReg,
resolveType DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock));
}
+ else if (otherTargetInterval != nullptr)
+ {
+ assert(otherHalfTargetReg != REG_NA);
+ assert(otherTargetInterval->registerType == TYP_DOUBLE);
+
+ addResolutionForDouble(block, insertionPoint, sourceIntervals, location, tempReg,
+ otherHalfTargetReg, resolveType DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock));
+ }
else
-#endif // TARGET_ARM
{
assert(sourceIntervals[targetReg] != nullptr);
@@ -10037,6 +10078,14 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
DEBUG_ARG(resolveTypeName[resolveType]));
location[targetReg] = (regNumberSmall)tempReg;
}
+#else
+ assert(sourceIntervals[targetReg] != nullptr);
+
+ addResolution(block, insertionPoint, sourceIntervals[targetReg], tempReg,
+ targetReg DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock)
+ DEBUG_ARG(resolveTypeName[resolveType]));
+ location[targetReg] = (regNumberSmall)tempReg;
+#endif // TARGET_ARM
targetRegsReady |= targetRegMask;
}
}
diff --git a/src/coreclr/jit/optimizer.cpp b/src/coreclr/jit/optimizer.cpp
index 27aedb6eb9af2..f9880026eab26 100644
--- a/src/coreclr/jit/optimizer.cpp
+++ b/src/coreclr/jit/optimizer.cpp
@@ -2891,16 +2891,10 @@ bool Compiler::optCreatePreheader(FlowGraphNaturalLoop* loop)
}
}
- BasicBlock* insertBefore = loop->GetLexicallyTopMostBlock();
- if (!BasicBlock::sameEHRegion(insertBefore, header))
- {
- insertBefore = header;
- }
-
- BasicBlock* preheader = fgNewBBbefore(BBJ_ALWAYS, insertBefore, false);
+ BasicBlock* preheader = fgNewBBbefore(BBJ_ALWAYS, header, false);
preheader->SetFlags(BBF_INTERNAL);
fgSetEHRegionForNewPreheaderOrExit(preheader);
- preheader->bbCodeOffs = insertBefore->bbCodeOffs;
+ preheader->bbCodeOffs = header->bbCodeOffs;
JITDUMP("Created new preheader " FMT_BB " for " FMT_LP "\n", preheader->bbNum, loop->GetIndex());
@@ -3003,21 +2997,11 @@ bool Compiler::optCanonicalizeExit(FlowGraphNaturalLoop* loop, BasicBlock* exit)
{
// Branches to a BBJ_CALLFINALLY _must_ come from inside its associated
// try region, and when we have callfinally thunks the BBJ_CALLFINALLY
- // is outside it. First try to see if the lexically bottom most block
- // is part of the try; if so, inserting after that is a good choice.
+ // is outside it. Thus, insert newExit at the end of the finally's
+ // try region.
BasicBlock* finallyBlock = exit->GetTarget();
assert(finallyBlock->hasHndIndex());
- BasicBlock* bottom = loop->GetLexicallyBottomMostBlock();
- if (bottom->hasTryIndex() && (bottom->getTryIndex() == finallyBlock->getHndIndex()) && !bottom->hasHndIndex())
- {
- newExit = fgNewBBafter(BBJ_ALWAYS, bottom, true);
- }
- else
- {
- // Otherwise just do the heavy-handed thing and insert it anywhere in the right region.
- newExit = fgNewBBinRegion(BBJ_ALWAYS, finallyBlock->bbHndIndex, 0, nullptr, /* putInFilter */ false,
- /* runRarely */ false, /* insertAtEnd */ true);
- }
+ newExit = fgNewBBatTryRegionEnd(BBJ_ALWAYS, finallyBlock->getHndIndex());
}
else
{
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs
index 7db11a8204177..4b0967e372bbc 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs
@@ -120,6 +120,32 @@ public static unsafe Array NewMultiDimArray(RuntimeTypeHandle typeHandleForArray
return Array.NewMultiDimArray(typeHandleForArrayType.ToMethodTable(), pImmutableLengths, lengths.Length);
}
+ public static unsafe void SetArrayValue(Array array, int[] indices, object value)
+ {
+ MethodTable* elementMT = array.ElementMethodTable;
+
+ if (elementMT->IsPointer || elementMT->IsFunctionPointer)
+ {
+ Debug.Assert(value.GetMethodTable()->ValueTypeSize == IntPtr.Size);
+ elementMT = value.GetMethodTable();
+ }
+
+ if (elementMT->IsValueType)
+ {
+ Debug.Assert(value.GetMethodTable()->IsValueType && elementMT->ValueTypeSize == value.GetMethodTable()->ValueTypeSize);
+ nint flattenedIndex = array.GetFlattenedIndex(indices);
+ ref byte element = ref Unsafe.AddByteOffset(ref MemoryMarshal.GetArrayDataReference(array), (nuint)flattenedIndex * array.ElementSize);
+ RuntimeImports.RhUnbox(value, ref element, elementMT);
+ }
+ else
+ {
+ RuntimeImports.RhCheckArrayStore(array, value);
+ nint flattenedIndex = array.GetFlattenedIndex(indices);
+ ref object element = ref Unsafe.Add(ref Unsafe.As(ref MemoryMarshal.GetArrayDataReference(array)), flattenedIndex);
+ element = value;
+ }
+ }
+
public static IntPtr GetAllocateObjectHelperForType(RuntimeTypeHandle type)
{
return RuntimeImports.RhGetRuntimeHelperForType(type.ToMethodTable(), RuntimeHelperKind.AllocateObject);
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs
index 58378b92a9c5f..faa4d51e93532 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs
@@ -727,7 +727,7 @@ private unsafe nint GetFlattenedIndex(int rawIndex)
return rawIndex;
}
- private unsafe nint GetFlattenedIndex(ReadOnlySpan indices)
+ internal unsafe nint GetFlattenedIndex(ReadOnlySpan indices)
{
// Checked by the caller
Debug.Assert(indices.Length == Rank);
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeArrayTypeInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeArrayTypeInfo.cs
index ab9fd61a3587e..1f2f374b2436e 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeArrayTypeInfo.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeArrayTypeInfo.cs
@@ -213,7 +213,7 @@ internal sealed override IEnumerable SyntheticMethods
for (int i = 0; i < rank; i++)
indices[i] = (int)(args[i]);
object value = args[rank];
- array.SetValue(value, indices);
+ RuntimeAugments.SetArrayValue(array, indices, value);
return null;
}
);
diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
index 987bbc6508f13..d766ded60142e 100644
--- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
+++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
@@ -2092,12 +2092,17 @@ private uint getClassAttribsInternal(TypeDesc type)
return (uint)result;
}
- private CORINFO_MODULE_STRUCT_* getClassModule(CORINFO_CLASS_STRUCT_* cls)
- { throw new NotImplementedException("getClassModule"); }
- private CORINFO_ASSEMBLY_STRUCT_* getModuleAssembly(CORINFO_MODULE_STRUCT_* mod)
- { throw new NotImplementedException("getModuleAssembly"); }
- private byte* getAssemblyName(CORINFO_ASSEMBLY_STRUCT_* assem)
- { throw new NotImplementedException("getAssemblyName"); }
+ private byte* getClassAssemblyName(CORINFO_CLASS_STRUCT_* cls)
+ {
+ TypeDesc type = HandleToObject(cls);
+
+ if (type is MetadataType mdType)
+ {
+ return (byte*)GetPin(StringToUTF8(mdType.Module.Assembly.GetName().Name));
+ }
+
+ return null;
+ }
#pragma warning disable CA1822 // Mark members as static
private void* LongLifetimeMalloc(UIntPtr sz)
diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs
index 9213d42aba327..26291e015b428 100644
--- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs
+++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs
@@ -614,42 +614,12 @@ private static uint _getClassAttribs(IntPtr thisHandle, IntPtr* ppException, COR
}
[UnmanagedCallersOnly]
- private static CORINFO_MODULE_STRUCT_* _getClassModule(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls)
+ private static byte* _getClassAssemblyName(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls)
{
var _this = GetThis(thisHandle);
try
{
- return _this.getClassModule(cls);
- }
- catch (Exception ex)
- {
- *ppException = _this.AllocException(ex);
- return default;
- }
- }
-
- [UnmanagedCallersOnly]
- private static CORINFO_ASSEMBLY_STRUCT_* _getModuleAssembly(IntPtr thisHandle, IntPtr* ppException, CORINFO_MODULE_STRUCT_* mod)
- {
- var _this = GetThis(thisHandle);
- try
- {
- return _this.getModuleAssembly(mod);
- }
- catch (Exception ex)
- {
- *ppException = _this.AllocException(ex);
- return default;
- }
- }
-
- [UnmanagedCallersOnly]
- private static byte* _getAssemblyName(IntPtr thisHandle, IntPtr* ppException, CORINFO_ASSEMBLY_STRUCT_* assem)
- {
- var _this = GetThis(thisHandle);
- try
- {
- return _this.getAssemblyName(assem);
+ return _this.getClassAssemblyName(cls);
}
catch (Exception ex)
{
@@ -2623,7 +2593,7 @@ private static uint _getJitFlags(IntPtr thisHandle, IntPtr* ppException, CORJIT_
private static IntPtr GetUnmanagedCallbacks()
{
- void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 177);
+ void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 175);
callbacks[0] = (delegate* unmanaged)&_isIntrinsic;
callbacks[1] = (delegate* unmanaged)&_notifyMethodInfoUsage;
@@ -2666,142 +2636,140 @@ private static IntPtr GetUnmanagedCallbacks()
callbacks[38] = (delegate* unmanaged)&_printClassName;
callbacks[39] = (delegate* unmanaged)&_isValueClass;
callbacks[40] = (delegate* unmanaged)&_getClassAttribs;
- callbacks[41] = (delegate* unmanaged)&_getClassModule;
- callbacks[42] = (delegate* unmanaged)&_getModuleAssembly;
- callbacks[43] = (delegate* unmanaged)&_getAssemblyName;
- callbacks[44] = (delegate* unmanaged)&_LongLifetimeMalloc;
- callbacks[45] = (delegate* unmanaged)&_LongLifetimeFree;
- callbacks[46] = (delegate* unmanaged)&_getIsClassInitedFlagAddress;
- callbacks[47] = (delegate* unmanaged)&_getClassThreadStaticDynamicInfo;
- callbacks[48] = (delegate* unmanaged)&_getClassStaticDynamicInfo;
- callbacks[49] = (delegate* unmanaged)&_getStaticBaseAddress;
- callbacks[50] = (delegate* unmanaged)&_getClassSize;
- callbacks[51] = (delegate* unmanaged)&_getHeapClassSize;
- callbacks[52] = (delegate* unmanaged)&_canAllocateOnStack;
- callbacks[53] = (delegate* unmanaged)&_getClassAlignmentRequirement;
- callbacks[54] = (delegate* unmanaged)&_getClassGClayout;
- callbacks[55] = (delegate* unmanaged)&_getClassNumInstanceFields;
- callbacks[56] = (delegate* unmanaged)&_getFieldInClass;
- callbacks[57] = (delegate* unmanaged)&_getTypeLayout;
- callbacks[58] = (delegate* unmanaged)&_checkMethodModifier;
- callbacks[59] = (delegate* unmanaged)&_getNewHelper;
- callbacks[60] = (delegate* unmanaged)&_getNewArrHelper;
- callbacks[61] = (delegate* unmanaged)&_getCastingHelper;
- callbacks[62] = (delegate* unmanaged)&_getSharedCCtorHelper;
- callbacks[63] = (delegate* unmanaged)&_getTypeForBox;
- callbacks[64] = (delegate* unmanaged)&_getTypeForBoxOnStack;
- callbacks[65] = (delegate* unmanaged)&_getBoxHelper;
- callbacks[66] = (delegate* unmanaged)&_getUnBoxHelper;
- callbacks[67] = (delegate* unmanaged)&_getRuntimeTypePointer;
- callbacks[68] = (delegate* unmanaged)&_isObjectImmutable;
- callbacks[69] = (delegate* unmanaged)&_getStringChar;
- callbacks[70] = (delegate* unmanaged)&_getObjectType;
- callbacks[71] = (delegate* unmanaged)&_getReadyToRunHelper;
- callbacks[72] = (delegate* unmanaged)&_getReadyToRunDelegateCtorHelper;
- callbacks[73] = (delegate* unmanaged)&_initClass;
- callbacks[74] = (delegate* unmanaged)&_classMustBeLoadedBeforeCodeIsRun;
- callbacks[75] = (delegate* unmanaged)&_getBuiltinClass;
- callbacks[76] = (delegate* unmanaged)&_getTypeForPrimitiveValueClass;
- callbacks[77] = (delegate* unmanaged)&_getTypeForPrimitiveNumericClass;
- callbacks[78] = (delegate* unmanaged)&_canCast;
- callbacks[79] = (delegate* unmanaged)&_compareTypesForCast;
- callbacks[80] = (delegate* unmanaged)&_compareTypesForEquality;
- callbacks[81] = (delegate* unmanaged)&_isMoreSpecificType;
- callbacks[82] = (delegate* unmanaged)&_isExactType;
- callbacks[83] = (delegate* unmanaged)&_isGenericType;
- callbacks[84] = (delegate* unmanaged)&_isNullableType;
- callbacks[85] = (delegate* unmanaged)&_isEnum;
- callbacks[86] = (delegate* unmanaged)&_getParentType;
- callbacks[87] = (delegate* unmanaged)&_getChildType;
- callbacks[88] = (delegate* unmanaged)&_isSDArray;
- callbacks[89] = (delegate* unmanaged)&_getArrayRank;
- callbacks[90] = (delegate* unmanaged)&_getArrayIntrinsicID;
- callbacks[91] = (delegate* unmanaged)&_getArrayInitializationData;
- callbacks[92] = (delegate* unmanaged)&_canAccessClass;
- callbacks[93] = (delegate* unmanaged)&_printFieldName;
- callbacks[94] = (delegate* unmanaged)&_getFieldClass;
- callbacks[95] = (delegate* unmanaged)&_getFieldType;
- callbacks[96] = (delegate* unmanaged)&_getFieldOffset;
- callbacks[97] = (delegate* unmanaged)&_getFieldInfo;
- callbacks[98] = (delegate* unmanaged)&_getThreadLocalFieldInfo;
- callbacks[99] = (delegate* unmanaged)&_getThreadLocalStaticBlocksInfo;
- callbacks[100] = (delegate* unmanaged)&_getThreadLocalStaticInfo_NativeAOT;
- callbacks[101] = (delegate* unmanaged)&_isFieldStatic;
- callbacks[102] = (delegate* unmanaged)&_getArrayOrStringLength;
- callbacks[103] = (delegate* unmanaged)&_getBoundaries;
- callbacks[104] = (delegate* unmanaged)&_setBoundaries;
- callbacks[105] = (delegate* unmanaged)&_getVars;
- callbacks[106] = (delegate* unmanaged)&_setVars;
- callbacks[107] = (delegate* unmanaged)&_reportRichMappings;
- callbacks[108] = (delegate* unmanaged)&_reportMetadata;
- callbacks[109] = (delegate* unmanaged)&_allocateArray;
- callbacks[110] = (delegate* unmanaged)&_freeArray;
- callbacks[111] = (delegate* unmanaged)&_getArgNext;
- callbacks[112] = (delegate* unmanaged)&_getArgType;
- callbacks[113] = (delegate* unmanaged)&_getExactClasses;
- callbacks[114] = (delegate* unmanaged)&_getArgClass;
- callbacks[115] = (delegate* unmanaged)&_getHFAType;
- callbacks[116] = (delegate* unmanaged)&_runWithErrorTrap;
- callbacks[117] = (delegate* unmanaged)&_runWithSPMIErrorTrap;
- callbacks[118] = (delegate* unmanaged)&_getEEInfo;
- callbacks[119] = (delegate* unmanaged)&_getJitTimeLogFilename;
- callbacks[120] = (delegate* unmanaged)&_getMethodDefFromMethod;
- callbacks[121] = (delegate* unmanaged)&_printMethodName;
- callbacks[122] = (delegate* unmanaged)&_getMethodNameFromMetadata;
- callbacks[123] = (delegate* unmanaged)&_getMethodHash;
- callbacks[124] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor;
- callbacks[125] = (delegate* unmanaged)&_getSwiftLowering;
- callbacks[126] = (delegate* unmanaged)&_getFpStructLowering;
- callbacks[127] = (delegate* unmanaged)&_getThreadTLSIndex;
- callbacks[128] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal;
- callbacks[129] = (delegate* unmanaged)&_getHelperFtn;
- callbacks[130] = (delegate* unmanaged)&_getFunctionEntryPoint;
- callbacks[131] = (delegate* unmanaged)&_getFunctionFixedEntryPoint;
- callbacks[132] = (delegate* unmanaged)&_getMethodSync;
- callbacks[133] = (delegate* unmanaged)&_getLazyStringLiteralHelper;
- callbacks[134] = (delegate* unmanaged)&_embedModuleHandle;
- callbacks[135] = (delegate* unmanaged)&_embedClassHandle;
- callbacks[136] = (delegate* unmanaged)&_embedMethodHandle;
- callbacks[137] = (delegate* unmanaged)&_embedFieldHandle;
- callbacks[138] = (delegate* unmanaged)&_embedGenericHandle;
- callbacks[139] = (delegate* unmanaged)&_getLocationOfThisType;
- callbacks[140] = (delegate* unmanaged)&_getAddressOfPInvokeTarget;
- callbacks[141] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig;
- callbacks[142] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig;
- callbacks[143] = (delegate* unmanaged)&_getJustMyCodeHandle;
- callbacks[144] = (delegate* unmanaged)&_GetProfilingHandle;
- callbacks[145] = (delegate* unmanaged)&_getCallInfo;
- callbacks[146] = (delegate* unmanaged)&_getStaticFieldContent;
- callbacks[147] = (delegate* unmanaged)&_getObjectContent;
- callbacks[148] = (delegate* unmanaged)&_getStaticFieldCurrentClass;
- callbacks[149] = (delegate* unmanaged)&_getVarArgsHandle;
- callbacks[150] = (delegate* unmanaged)&_canGetVarArgsHandle;
- callbacks[151] = (delegate* unmanaged)&_constructStringLiteral;
- callbacks[152] = (delegate* unmanaged)&_emptyStringLiteral;
- callbacks[153] = (delegate* unmanaged)&_getFieldThreadLocalStoreID;
- callbacks[154] = (delegate* unmanaged)&_GetDelegateCtor;
- callbacks[155] = (delegate* unmanaged)&_MethodCompileComplete;
- callbacks[156] = (delegate* unmanaged)&_getTailCallHelpers;
- callbacks[157] = (delegate* unmanaged)&_convertPInvokeCalliToCall;
- callbacks[158] = (delegate* unmanaged)&_notifyInstructionSetUsage;
- callbacks[159] = (delegate* unmanaged)&_updateEntryPointForTailCall;
- callbacks[160] = (delegate* unmanaged)&_allocMem;
- callbacks[161] = (delegate* unmanaged)&_reserveUnwindInfo;
- callbacks[162] = (delegate* unmanaged)&_allocUnwindInfo;
- callbacks[163] = (delegate* unmanaged)&_allocGCInfo;
- callbacks[164] = (delegate* unmanaged)&_setEHcount;
- callbacks[165] = (delegate* unmanaged)&_setEHinfo;
- callbacks[166] = (delegate* unmanaged)&_logMsg;
- callbacks[167] = (delegate* unmanaged)&_doAssert;
- callbacks[168] = (delegate* unmanaged)&_reportFatalError;
- callbacks[169] = (delegate* unmanaged)&_getPgoInstrumentationResults;
- callbacks[170] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema;
- callbacks[171] = (delegate* unmanaged)&_recordCallSite;
- callbacks[172] = (delegate* unmanaged)&_recordRelocation;
- callbacks[173] = (delegate* unmanaged)&_getRelocTypeHint;
- callbacks[174] = (delegate* unmanaged)&_getExpectedTargetArchitecture;
- callbacks[175] = (delegate* unmanaged)&_getJitFlags;
- callbacks[176] = (delegate* unmanaged)&_getSpecialCopyHelper;
+ callbacks[41] = (delegate* unmanaged)&_getClassAssemblyName;
+ callbacks[42] = (delegate* unmanaged)&_LongLifetimeMalloc;
+ callbacks[43] = (delegate* unmanaged)&_LongLifetimeFree;
+ callbacks[44] = (delegate* unmanaged)&_getIsClassInitedFlagAddress;
+ callbacks[45] = (delegate* unmanaged)&_getClassThreadStaticDynamicInfo;
+ callbacks[46] = (delegate* unmanaged)&_getClassStaticDynamicInfo;
+ callbacks[47] = (delegate* unmanaged)&_getStaticBaseAddress;
+ callbacks[48] = (delegate* unmanaged)&_getClassSize;
+ callbacks[49] = (delegate* unmanaged)&_getHeapClassSize;
+ callbacks[50] = (delegate* unmanaged)&_canAllocateOnStack;
+ callbacks[51] = (delegate* unmanaged)&_getClassAlignmentRequirement;
+ callbacks[52] = (delegate* unmanaged)&_getClassGClayout;
+ callbacks[53] = (delegate* unmanaged)&_getClassNumInstanceFields;
+ callbacks[54] = (delegate* unmanaged)&_getFieldInClass;
+ callbacks[55] = (delegate* unmanaged)&_getTypeLayout;
+ callbacks[56] = (delegate* unmanaged)&_checkMethodModifier;
+ callbacks[57] = (delegate* unmanaged)&_getNewHelper;
+ callbacks[58] = (delegate* unmanaged)&_getNewArrHelper;
+ callbacks[59] = (delegate* unmanaged)&_getCastingHelper;
+ callbacks[60] = (delegate* unmanaged)&_getSharedCCtorHelper;
+ callbacks[61] = (delegate* unmanaged)&_getTypeForBox;
+ callbacks[62] = (delegate* unmanaged)&_getTypeForBoxOnStack;
+ callbacks[63] = (delegate* unmanaged)&_getBoxHelper;
+ callbacks[64] = (delegate* unmanaged)&_getUnBoxHelper;
+ callbacks[65] = (delegate* unmanaged)&_getRuntimeTypePointer;
+ callbacks[66] = (delegate* unmanaged)&_isObjectImmutable;
+ callbacks[67] = (delegate* unmanaged)&_getStringChar;
+ callbacks[68] = (delegate* unmanaged)&_getObjectType;
+ callbacks[69] = (delegate* unmanaged)&_getReadyToRunHelper;
+ callbacks[70] = (delegate* unmanaged)&_getReadyToRunDelegateCtorHelper;
+ callbacks[71] = (delegate* unmanaged)&_initClass;
+ callbacks[72] = (delegate* unmanaged)&_classMustBeLoadedBeforeCodeIsRun;
+ callbacks[73] = (delegate* unmanaged)&_getBuiltinClass;
+ callbacks[74] = (delegate* unmanaged)&_getTypeForPrimitiveValueClass;
+ callbacks[75] = (delegate* unmanaged)&_getTypeForPrimitiveNumericClass;
+ callbacks[76] = (delegate* unmanaged)&_canCast;
+ callbacks[77] = (delegate* unmanaged)&_compareTypesForCast;
+ callbacks[78] = (delegate* unmanaged)&_compareTypesForEquality;
+ callbacks[79] = (delegate* unmanaged)&_isMoreSpecificType;
+ callbacks[80] = (delegate* unmanaged)&_isExactType;
+ callbacks[81] = (delegate* unmanaged)&_isGenericType;
+ callbacks[82] = (delegate* unmanaged)&_isNullableType;
+ callbacks[83] = (delegate* unmanaged)&_isEnum;
+ callbacks[84] = (delegate* unmanaged)&_getParentType;
+ callbacks[85] = (delegate* unmanaged)&_getChildType;
+ callbacks[86] = (delegate* unmanaged)&_isSDArray;
+ callbacks[87] = (delegate* unmanaged)&_getArrayRank;
+ callbacks[88] = (delegate* unmanaged)&_getArrayIntrinsicID;
+ callbacks[89] = (delegate* unmanaged)&_getArrayInitializationData;
+ callbacks[90] = (delegate* unmanaged)&_canAccessClass;
+ callbacks[91] = (delegate* unmanaged)&_printFieldName;
+ callbacks[92] = (delegate* unmanaged)&_getFieldClass;
+ callbacks[93] = (delegate* unmanaged)&_getFieldType;
+ callbacks[94] = (delegate* unmanaged)&_getFieldOffset;
+ callbacks[95] = (delegate* unmanaged)&_getFieldInfo;
+ callbacks[96] = (delegate* unmanaged)&_getThreadLocalFieldInfo;
+ callbacks[97] = (delegate* unmanaged)&_getThreadLocalStaticBlocksInfo;
+ callbacks[98] = (delegate* unmanaged)&_getThreadLocalStaticInfo_NativeAOT;
+ callbacks[99] = (delegate* unmanaged)&_isFieldStatic;
+ callbacks[100] = (delegate* unmanaged)&_getArrayOrStringLength;
+ callbacks[101] = (delegate* unmanaged)&_getBoundaries;
+ callbacks[102] = (delegate* unmanaged)&_setBoundaries;
+ callbacks[103] = (delegate* unmanaged)&_getVars;
+ callbacks[104] = (delegate* unmanaged)&_setVars;
+ callbacks[105] = (delegate* unmanaged)&_reportRichMappings;
+ callbacks[106] = (delegate* unmanaged)&_reportMetadata;
+ callbacks[107] = (delegate* unmanaged)&_allocateArray;
+ callbacks[108] = (delegate* unmanaged)&_freeArray;
+ callbacks[109] = (delegate* unmanaged)&_getArgNext;
+ callbacks[110] = (delegate* unmanaged)&_getArgType;
+ callbacks[111] = (delegate* unmanaged)&_getExactClasses;
+ callbacks[112] = (delegate* unmanaged)&_getArgClass;
+ callbacks[113] = (delegate* unmanaged)&_getHFAType;
+ callbacks[114] = (delegate* unmanaged)&_runWithErrorTrap;
+ callbacks[115] = (delegate* unmanaged)&_runWithSPMIErrorTrap;
+ callbacks[116] = (delegate* unmanaged)&_getEEInfo;
+ callbacks[117] = (delegate* unmanaged)&_getJitTimeLogFilename;
+ callbacks[118] = (delegate* unmanaged)&_getMethodDefFromMethod;
+ callbacks[119] = (delegate* unmanaged)&_printMethodName;
+ callbacks[120] = (delegate* unmanaged)&_getMethodNameFromMetadata;
+ callbacks[121] = (delegate* unmanaged)&_getMethodHash;
+ callbacks[122] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor;
+ callbacks[123] = (delegate* unmanaged)&_getSwiftLowering;
+ callbacks[124] = (delegate* unmanaged)&_getFpStructLowering;
+ callbacks[125] = (delegate* unmanaged)&_getThreadTLSIndex;
+ callbacks[126] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal;
+ callbacks[127] = (delegate* unmanaged)&_getHelperFtn;
+ callbacks[128] = (delegate* unmanaged)&_getFunctionEntryPoint;
+ callbacks[129] = (delegate* unmanaged)&_getFunctionFixedEntryPoint;
+ callbacks[130] = (delegate* unmanaged