Skip to content

Commit

Permalink
NativeAOT: Add win-x86 support (#99372)
Browse files Browse the repository at this point in the history
  • Loading branch information
filipnavara committed Mar 11, 2024
1 parent d942573 commit 60d73db
Show file tree
Hide file tree
Showing 32 changed files with 749 additions and 406 deletions.
4 changes: 3 additions & 1 deletion eng/Subsets.props
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@

<PropertyGroup>
<!-- CLR NativeAot only builds in a subset of the matrix -->
<NativeAotSupported Condition="('$(TargetOS)' == 'windows' or '$(TargetOS)' == 'linux' or '$(TargetOS)' == 'osx' or '$(TargetOS)' == 'maccatalyst' or '$(TargetOS)' == 'iossimulator' or '$(TargetOS)' == 'ios' or '$(TargetOS)' == 'tvossimulator' or '$(TargetOS)' == 'tvos' or '$(TargetOS)' == 'freebsd') and ('$(TargetArchitecture)' == 'x64' or '$(TargetArchitecture)' == 'arm64' or '$(TargetArchitecture)' == 'arm')">true</NativeAotSupported>
<_NativeAotSupportedOS Condition="'$(TargetOS)' == 'windows' or '$(TargetOS)' == 'linux' or '$(TargetOS)' == 'osx' or '$(TargetOS)' == 'maccatalyst' or '$(TargetOS)' == 'iossimulator' or '$(TargetOS)' == 'ios' or '$(TargetOS)' == 'tvossimulator' or '$(TargetOS)' == 'tvos' or '$(TargetOS)' == 'freebsd'">true</_NativeAotSupportedOS>
<_NativeAotSupportedArch Condition="'$(TargetArchitecture)' == 'x64' or '$(TargetArchitecture)' == 'arm64' or '$(TargetArchitecture)' == 'arm' or ('$(TargetOS)' == 'windows' and '$(TargetArchitecture)' == 'x86')">true</_NativeAotSupportedArch>
<NativeAotSupported Condition="'$(_NativeAotSupportedOS)' == 'true' and $(_NativeAotSupportedArch) == 'true'">true</NativeAotSupported>

<!-- If we're building clr.nativeaotlibs and not building the CLR runtime, compile libraries against NativeAOT CoreLib -->
<UseNativeAotCoreLib Condition="'$(TestNativeAot)' == 'true' or ($(_subset.Contains('+clr.nativeaotlibs+')) and !$(_subset.Contains('+clr.native+')) and !$(_subset.Contains('+clr.runtime+')))">true</UseNativeAotCoreLib>
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ add_subdirectory(tools/aot/jitinterface)

if(NOT CLR_CROSS_COMPONENTS_BUILD)
# NativeAOT only buildable for a subset of CoreCLR-supported configurations
if(CLR_CMAKE_HOST_ARCH_ARM64 OR CLR_CMAKE_HOST_ARCH_AMD64 OR CLR_CMAKE_HOST_ARCH_ARM)
if(CLR_CMAKE_HOST_ARCH_ARM64 OR CLR_CMAKE_HOST_ARCH_AMD64 OR CLR_CMAKE_HOST_ARCH_ARM OR (CLR_CMAKE_HOST_ARCH_I386 AND CLR_CMAKE_HOST_WIN32))
add_subdirectory(nativeaot)
endif()
endif(NOT CLR_CROSS_COMPONENTS_BUILD)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,15 @@ public static void CopyBlock(void* destination, void* source, uint byteCount)
{
throw new PlatformNotSupportedException();
}

/// <summary>
/// Copies bytes from the source address to the destination address.
/// </summary>
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CopyBlock(ref byte destination, ref readonly byte source, uint byteCount)
{
throw new PlatformNotSupportedException();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,6 @@ internal static int RhEndNoGCRegion()
[RuntimeImport(Redhawk.BaseName, "RhpGcSafeZeroMemory")]
internal static extern unsafe ref byte RhpGcSafeZeroMemory(ref byte dmem, nuint size);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
[RuntimeImport(Redhawk.BaseName, "memmove")]
internal static extern unsafe void* memmove(byte* dmem, byte* smem, nuint size);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
[RuntimeImport(Redhawk.BaseName, "RhBulkMoveWithWriteBarrier")]
internal static extern unsafe void RhBulkMoveWithWriteBarrier(ref byte dmem, ref byte smem, nuint size);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,7 @@ public static unsafe object RhBox(MethodTable* pEEType, ref byte data)
}
else
{
fixed (byte* pFields = &result.GetRawData())
fixed (byte* pData = &dataAdjustedForNullable)
InternalCalls.memmove(pFields, pData, pEEType->ValueTypeSize);
Unsafe.CopyBlock(ref result.GetRawData(), ref dataAdjustedForNullable, pEEType->ValueTypeSize);
}

return result;
Expand Down Expand Up @@ -271,9 +269,7 @@ public static unsafe void RhUnbox(object? obj, ref byte data, MethodTable* pUnbo
else
{
// Copy the boxed fields into the new location.
fixed (byte *pData = &data)
fixed (byte* pFields = &fields)
InternalCalls.memmove(pData, pFields, pEEType->ValueTypeSize);
Unsafe.CopyBlock(ref data, ref fields, pEEType->ValueTypeSize);
}
}

Expand Down
68 changes: 65 additions & 3 deletions src/coreclr/nativeaot/Runtime/CommonMacros.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#define STDCALL
#endif

#define REDHAWK_CALLCONV FASTCALL
#define F_CALL_CONV FASTCALL
#define QCALLTYPE

#ifdef _MSC_VER
Expand Down Expand Up @@ -219,6 +219,42 @@ typedef uint8_t CODE_LOCATION;
_Pragma(FCALL_XSTRINGIFY(comment (linker, FCALL_DECL_ALTNAME(FCALL_METHOD_NAME_((__VA_ARGS__)), FCALL_ARGHELPER_STACKSIZE(__VA_ARGS__)))))
#define FCIMPL_RENAME(_rettype, ...) \
_Pragma(FCALL_XSTRINGIFY(comment (linker, FCALL_IMPL_ALTNAME(FCALL_METHOD_NAME_((__VA_ARGS__)), FCALL_ARGHELPER_STACKSIZE(__VA_ARGS__)))))
#define FCIMPL_RENAME_ARGSIZE(_rettype, _method, _argSize) \
_Pragma(FCALL_XSTRINGIFY(comment (linker, FCALL_XSTRINGIFY(/alternatename:_method=@_method##_FCall@_argSize))))

#define FCIMPL1_F(_rettype, _method, a) \
FCIMPL_RENAME_ARGSIZE(_rettype, _method, 4) \
EXTERN_C _rettype F_CALL_CONV _method##_FCall (a) \
{
#define FCIMPL1_D(_rettype, _method, a) \
FCIMPL_RENAME_ARGSIZE(_rettype, _method, 8) \
EXTERN_C _rettype F_CALL_CONV _method##_FCall (a) \
{
#define FCIMPL1_L FCIMPL1_D
#define FCIMPL2_FF(_rettype, _method, a, b) \
FCIMPL_RENAME_ARGSIZE(_rettype, _method, 8) \
EXTERN_C _rettype F_CALL_CONV _method##_FCall (b, a) \
{
#define FCIMPL2_DD(_rettype, _method, a, b) \
FCIMPL_RENAME_ARGSIZE(_rettype, _method, 16) \
EXTERN_C _rettype F_CALL_CONV _method##_FCall (b, a) \
{
#define FCIMPL2_FI(_rettype, _method, a, b) \
FCIMPL_RENAME_ARGSIZE(_rettype, _method, 8) \
EXTERN_C _rettype F_CALL_CONV _method##_FCall (a, b) \
{
#define FCIMPL2_DI(_rettype, _method, a, b) \
FCIMPL_RENAME_ARGSIZE(_rettype, _method, 12) \
EXTERN_C _rettype F_CALL_CONV _method##_FCall (a, b) \
{
#define FCIMPL3_FFF(_rettype, _method, a, b, c) \
FCIMPL_RENAME_ARGSIZE(_rettype, _method, 12) \
EXTERN_C _rettype F_CALL_CONV _method##_FCall (c, b, a) \
{
#define FCIMPL3_DDD(_rettype, _method, a, b, c) \
FCIMPL_RENAME_ARGSIZE(_rettype, _method, 24) \
EXTERN_C _rettype F_CALL_CONV _method##_FCall (c, b, a) \
{

#else

Expand All @@ -228,11 +264,37 @@ typedef uint8_t CODE_LOCATION;
#define FCALL_METHOD_ARGS(dummy, ...) (__VA_ARGS__)
#define FCALL_METHOD_ARGS_(tuple) FCALL_METHOD_ARGS tuple

#define FCIMPL1_F(_rettype, _method, a) \
EXTERN_C _rettype F_CALL_CONV _method (a) \
{
#define FCIMPL1_D(_rettype, _method, a) \
EXTERN_C _rettype F_CALL_CONV _method (a) \
{
#define FCIMPL1_L FCIMPL1_D
#define FCIMPL2_FF(_rettype, _method, a, b) \
EXTERN_C _rettype F_CALL_CONV _method (a, b) \
{
#define FCIMPL2_DD(_rettype, _method, a, b) \
EXTERN_C _rettype F_CALL_CONV _method (a, b) \
{
#define FCIMPL2_FI(_rettype, _method, a, b) \
EXTERN_C _rettype F_CALL_CONV _method (a, b) \
{
#define FCIMPL2_DI(_rettype, _method, a, b) \
EXTERN_C _rettype F_CALL_CONV _method (a, b) \
{
#define FCIMPL3_FFF(_rettype, _method, a, b, c) \
EXTERN_C _rettype F_CALL_CONV _method (a, b, c) \
{
#define FCIMPL3_DDD(_rettype, _method, a, b, c) \
EXTERN_C _rettype F_CALL_CONV _method (a, b, c) \
{

#endif

#define FCDECL_(_rettype, ...) \
FCDECL_RENAME(_rettype, __VA_ARGS__) \
EXTERN_C _rettype REDHAWK_CALLCONV FCALL_METHOD_NAME_((__VA_ARGS__)) FCALL_METHOD_ARGS_((__VA_ARGS__))
EXTERN_C _rettype F_CALL_CONV FCALL_METHOD_NAME_((__VA_ARGS__)) FCALL_METHOD_ARGS_((__VA_ARGS__))
#define FCDECL0(_rettype, _method) FCDECL_(_rettype, _method)
#define FCDECL1(_rettype, _method, a) FCDECL_(_rettype, _method, a)
#define FCDECL2(_rettype, _method, a, b) FCDECL_(_rettype, _method, a, b)
Expand All @@ -242,7 +304,7 @@ typedef uint8_t CODE_LOCATION;

#define FCIMPL_(_rettype, ...) \
FCIMPL_RENAME(_rettype, __VA_ARGS__) \
EXTERN_C _rettype REDHAWK_CALLCONV FCALL_METHOD_NAME_((__VA_ARGS__)) FCALL_METHOD_ARGS_((__VA_ARGS__)) \
EXTERN_C _rettype F_CALL_CONV FCALL_METHOD_NAME_((__VA_ARGS__)) FCALL_METHOD_ARGS_((__VA_ARGS__)) \
{
#define FCIMPL0(_rettype, _method) FCIMPL_(_rettype, _method)
#define FCIMPL1(_rettype, _method, a) FCIMPL_(_rettype, _method, a)
Expand Down
34 changes: 34 additions & 0 deletions src/coreclr/nativeaot/Runtime/EHHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,23 @@ EXTERN_C void* RhpRethrow2 = NULL;
#endif

EXTERN_C CODE_LOCATION RhpAssignRefAVLocation;
#if defined(HOST_X86)
EXTERN_C CODE_LOCATION RhpAssignRefEAXAVLocation;
EXTERN_C CODE_LOCATION RhpAssignRefECXAVLocation;
EXTERN_C CODE_LOCATION RhpAssignRefEBXAVLocation;
EXTERN_C CODE_LOCATION RhpAssignRefESIAVLocation;
EXTERN_C CODE_LOCATION RhpAssignRefEDIAVLocation;
EXTERN_C CODE_LOCATION RhpAssignRefEBPAVLocation;
#endif
EXTERN_C CODE_LOCATION RhpCheckedAssignRefAVLocation;
#if defined(HOST_X86)
EXTERN_C CODE_LOCATION RhpCheckedAssignRefEAXAVLocation;
EXTERN_C CODE_LOCATION RhpCheckedAssignRefECXAVLocation;
EXTERN_C CODE_LOCATION RhpCheckedAssignRefEBXAVLocation;
EXTERN_C CODE_LOCATION RhpCheckedAssignRefESIAVLocation;
EXTERN_C CODE_LOCATION RhpCheckedAssignRefEDIAVLocation;
EXTERN_C CODE_LOCATION RhpCheckedAssignRefEBPAVLocation;
#endif
EXTERN_C CODE_LOCATION RhpCheckedLockCmpXchgAVLocation;
EXTERN_C CODE_LOCATION RhpCheckedXchgAVLocation;
#if !defined(HOST_AMD64) && !defined(HOST_ARM64)
Expand All @@ -335,13 +351,31 @@ static bool InWriteBarrierHelper(uintptr_t faultingIP)
static uintptr_t writeBarrierAVLocations[] =
{
(uintptr_t)&RhpAssignRefAVLocation,
#if defined(HOST_X86)
(uintptr_t)&RhpAssignRefEAXAVLocation,
(uintptr_t)&RhpAssignRefECXAVLocation,
(uintptr_t)&RhpAssignRefEBXAVLocation,
(uintptr_t)&RhpAssignRefESIAVLocation,
(uintptr_t)&RhpAssignRefEDIAVLocation,
(uintptr_t)&RhpAssignRefEBPAVLocation,
#endif
(uintptr_t)&RhpCheckedAssignRefAVLocation,
#if defined(HOST_X86)
(uintptr_t)&RhpCheckedAssignRefEAXAVLocation,
(uintptr_t)&RhpCheckedAssignRefECXAVLocation,
(uintptr_t)&RhpCheckedAssignRefEBXAVLocation,
(uintptr_t)&RhpCheckedAssignRefESIAVLocation,
(uintptr_t)&RhpCheckedAssignRefEDIAVLocation,
(uintptr_t)&RhpCheckedAssignRefEBPAVLocation,
#endif
(uintptr_t)&RhpCheckedLockCmpXchgAVLocation,
(uintptr_t)&RhpCheckedXchgAVLocation,
#if !defined(HOST_AMD64) && !defined(HOST_ARM64)
#if !defined(HOST_X86)
(uintptr_t)&RhpLockCmpXchg8AVLocation,
(uintptr_t)&RhpLockCmpXchg16AVLocation,
(uintptr_t)&RhpLockCmpXchg32AVLocation,
#endif
(uintptr_t)&RhpLockCmpXchg64AVLocation,
#endif
(uintptr_t)&RhpByRefAssignRefAVLocation1,
Expand Down
7 changes: 3 additions & 4 deletions src/coreclr/nativeaot/Runtime/GCHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,12 +418,11 @@ FCIMPL0(int64_t, RhGetTotalAllocatedBytes)
}
FCIMPLEND

FCIMPL2(void, RhEnumerateConfigurationValues, void* configurationContext, ConfigurationValueFunc callback)
EXTERN_C void QCALLTYPE RhEnumerateConfigurationValues(void* configurationContext, ConfigurationValueFunc callback)
{
IGCHeap* pHeap = GCHeapUtilities::GetGCHeap();
pHeap->EnumerateConfigurationValues(configurationContext, callback);
}
FCIMPLEND

GCHeapHardLimitInfo g_gcHeapHardLimitInfo;
bool g_gcHeapHardLimitInfoSpecified = false;
Expand Down Expand Up @@ -563,7 +562,7 @@ static Object* GcAllocInternal(MethodTable* pEEType, uint32_t uFlags, uintptr_t
// numElements - number of array elements
// pTransitionFrame- transition frame to make stack crawlable
// Returns a pointer to the object allocated or NULL on failure.
EXTERN_C void* REDHAWK_CALLCONV RhpGcAlloc(MethodTable* pEEType, uint32_t uFlags, uintptr_t numElements, PInvokeTransitionFrame* pTransitionFrame)
EXTERN_C void* F_CALL_CONV RhpGcAlloc(MethodTable* pEEType, uint32_t uFlags, uintptr_t numElements, PInvokeTransitionFrame* pTransitionFrame)
{
Thread* pThread = ThreadStore::GetCurrentThread();

Expand Down Expand Up @@ -702,7 +701,7 @@ EXTERN_C UInt32_BOOL g_fGcStressStarted;
UInt32_BOOL g_fGcStressStarted = UInt32_FALSE; // UInt32_BOOL because asm code reads it

// static
EXTERN_C void REDHAWK_CALLCONV RhpStressGc()
EXTERN_C void F_CALL_CONV RhpStressGc()
{
// The GarbageCollect operation below may trash the last win32 error. We save the error here so that it can be
// restored after the GC operation;
Expand Down
Loading

0 comments on commit 60d73db

Please sign in to comment.