diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index f6922867abcfee..92bf619351f4e6 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -3173,6 +3173,10 @@ class ICorStaticInfo // Returns lowering info for fields of a RISC-V/LoongArch struct passed in registers according to // hardware floating-point calling convention. virtual void getFpStructLowering(CORINFO_CLASS_HANDLE structHnd, CORINFO_FPSTRUCT_LOWERING* pLowering) = 0; + + // Returns the primitive type for passing/returning a Wasm struct by value, + // or CORINFO_TYPE_UNDEF if passing/returning must be by reference. + virtual CorInfoType getWasmLowering(CORINFO_CLASS_HANDLE structHnd) = 0; }; /***************************************************************************** diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index dcc4865513acf1..d1ef597adafaf5 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -535,6 +535,9 @@ void getFpStructLowering( CORINFO_CLASS_HANDLE structHnd, CORINFO_FPSTRUCT_LOWERING* pLowering) override; +CorInfoType getWasmLowering( + CORINFO_CLASS_HANDLE structHnd) override; + uint32_t getThreadTLSIndex( void** ppIndirection) override; diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index 5f7f639550fb31..110b2b448b7243 100644 --- a/src/coreclr/inc/jiteeversionguid.h +++ b/src/coreclr/inc/jiteeversionguid.h @@ -37,11 +37,11 @@ #include -constexpr GUID JITEEVersionIdentifier = { /* 976a4d6d-d1b2-4096-a3c9-46ddcae71196 */ - 0x976a4d6d, - 0xd1b2, - 0x4096, - {0xa3, 0xc9, 0x46, 0xdd, 0xca, 0xe7, 0x11, 0x96} +constexpr GUID JITEEVersionIdentifier = { /* 27ef98b9-21db-46a5-bb25-1ca4b88ce24c */ + 0x27ef98b9, + 0x21db, + 0x46a5, + {0xbb, 0x25, 0x1c, 0xa4, 0xb8, 0x8c, 0xe2, 0x4c} }; #endif // JIT_EE_VERSIONING_GUID_H diff --git a/src/coreclr/jit/ICorJitInfo_names_generated.h b/src/coreclr/jit/ICorJitInfo_names_generated.h index 2d1ce082f8d53f..47d7bd3bd70025 100644 --- a/src/coreclr/jit/ICorJitInfo_names_generated.h +++ b/src/coreclr/jit/ICorJitInfo_names_generated.h @@ -132,6 +132,7 @@ DEF_CLR_API(getMethodHash) DEF_CLR_API(getSystemVAmd64PassStructInRegisterDescriptor) DEF_CLR_API(getSwiftLowering) DEF_CLR_API(getFpStructLowering) +DEF_CLR_API(getWasmLowering) DEF_CLR_API(getThreadTLSIndex) DEF_CLR_API(getAddrOfCaptureThreadGlobal) DEF_CLR_API(getHelperFtn) diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index b8073df5e97987..4fdbe818df0c9e 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -1262,6 +1262,15 @@ void WrapICorJitInfo::getFpStructLowering( API_LEAVE(getFpStructLowering); } +CorInfoType WrapICorJitInfo::getWasmLowering( + CORINFO_CLASS_HANDLE structHnd) +{ + API_ENTER(getWasmLowering); + CorInfoType temp = wrapHnd->getWasmLowering(structHnd); + API_LEAVE(getWasmLowering); + return temp; +} + uint32_t WrapICorJitInfo::getThreadTLSIndex( void** ppIndirection) { diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 5b338ba948f0b2..359a30190ed833 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -1913,6 +1913,10 @@ void CodeGen::genGenerateMachineCode() printf("generic LOONGARCH64"); #elif defined(TARGET_RISCV64) printf("generic RISCV64"); +#elif defined(TARGET_WASM32) + printf("wasm32"); +#elif defined(TARGET_WASM64) + printf("wasm64"); #else printf("unknown architecture"); #endif diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index bba3971a975759..0e120dae770a7d 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -747,6 +747,36 @@ var_types Compiler::getReturnTypeForStruct(CORINFO_CLASS_HANDLE clsHnd, } assert(structSize > 0); +#if defined(TARGET_WASM) + CorInfoType abiType = info.compCompHnd->getWasmLowering(clsHnd); + + if (abiType == CORINFO_TYPE_UNDEF) + { + howToReturnStruct = SPK_ByReference; + useType = TYP_UNKNOWN; + } + else + { + howToReturnStruct = SPK_ByValue; + useType = JITtype2varType(abiType); + } + + if (wbReturnStruct != nullptr) + { + *wbReturnStruct = howToReturnStruct; + } + + return useType; +#else +#ifdef DEBUG + // Extra query to facilitate wasm replay + if (JitConfig.EnableExtraSuperPmiQueries()) + { + info.compCompHnd->getWasmLowering(clsHnd); + } +#endif // DEBUG +#endif // defined(TARGET_WASM) + #ifdef SWIFT_SUPPORT if (callConv == CorInfoCallConvExtension::Swift) { diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index da9d75735670b0..d8c2875059e048 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -930,6 +930,18 @@ void Compiler::lvaClassifyParameterABI(Classifier& classifier) dsc->lvIsRegArg = numRegisters > 0; dsc->lvIsMultiRegArg = numRegisters > 1; + +#ifdef DEBUG + // Extra query to facilitate wasm replay + if (JitConfig.EnableExtraSuperPmiQueries() && (structLayout != nullptr)) + { + CORINFO_CLASS_HANDLE clsHnd = structLayout->GetClassHandle(); + if (clsHnd != NO_CLASS_HANDLE) + { + info.compCompHnd->getWasmLowering(clsHnd); + } + } +#endif } lvaParameterStackSize = classifier.StackSize(); diff --git a/src/coreclr/jit/targetwasm.cpp b/src/coreclr/jit/targetwasm.cpp index 56f342f3af3886..0787b0ea78a8d2 100644 --- a/src/coreclr/jit/targetwasm.cpp +++ b/src/coreclr/jit/targetwasm.cpp @@ -48,7 +48,21 @@ ABIPassingInformation WasmClassifier::Classify(Compiler* comp, { if (type == TYP_STRUCT) { - NYI_WASM("WasmClassifier::Classify - structs"); + CORINFO_CLASS_HANDLE clsHnd = structLayout->GetClassHandle(); + assert(clsHnd != NO_CLASS_HANDLE); + CorInfoType abiType = comp->info.compCompHnd->getWasmLowering(clsHnd); + bool passByRef = false; + + if (abiType == CORINFO_TYPE_UNDEF) + { + abiType = CORINFO_TYPE_NATIVEINT; + passByRef = true; + } + + var_types type = JITtype2varType(abiType); + regNumber reg = MakeWasmReg(m_localIndex++, genActualType(type)); + ABIPassingSegment seg = ABIPassingSegment::InRegister(reg, 0, genTypeSize(type)); + return ABIPassingInformation::FromSegment(comp, passByRef, seg); } regNumber reg = MakeWasmReg(m_localIndex++, genActualType(type)); diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 85d416c833878b..fb7876ea8f6010 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -3616,6 +3616,12 @@ private void getFpStructLowering(CORINFO_CLASS_STRUCT_* structHnd, ref CORINFO_F } } + private CorInfoType getWasmLowering(CORINFO_CLASS_STRUCT_* structHnd) + { + uint size = getClassSize(structHnd); + return WasmLowering.LowerTypeForWasm(HandleToObject(structHnd), size); + } + private uint getThreadTLSIndex(ref void* ppIndirection) { throw new NotImplementedException("getThreadTLSIndex"); } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index c828a995140997..5c240949aab325 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -148,6 +148,7 @@ static ICorJitInfoCallbacks() s_callbacks.getSystemVAmd64PassStructInRegisterDescriptor = &_getSystemVAmd64PassStructInRegisterDescriptor; s_callbacks.getSwiftLowering = &_getSwiftLowering; s_callbacks.getFpStructLowering = &_getFpStructLowering; + s_callbacks.getWasmLowering = &_getWasmLowering; s_callbacks.getThreadTLSIndex = &_getThreadTLSIndex; s_callbacks.getAddrOfCaptureThreadGlobal = &_getAddrOfCaptureThreadGlobal; s_callbacks.getHelperFtn = &_getHelperFtn; @@ -327,6 +328,7 @@ static ICorJitInfoCallbacks() public delegate* unmanaged getSystemVAmd64PassStructInRegisterDescriptor; public delegate* unmanaged getSwiftLowering; public delegate* unmanaged getFpStructLowering; + public delegate* unmanaged getWasmLowering; public delegate* unmanaged getThreadTLSIndex; public delegate* unmanaged getAddrOfCaptureThreadGlobal; public delegate* unmanaged getHelperFtn; @@ -2271,6 +2273,21 @@ private static void _getFpStructLowering(IntPtr thisHandle, IntPtr* ppException, } } + [UnmanagedCallersOnly] + private static CorInfoType _getWasmLowering(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* structHnd) + { + var _this = GetThis(thisHandle); + try + { + return _this.getWasmLowering(structHnd); + } + catch (Exception ex) + { + *ppException = _this.AllocException(ex); + return default; + } + } + [UnmanagedCallersOnly] private static uint _getThreadTLSIndex(IntPtr thisHandle, IntPtr* ppException, void** ppIndirection) { diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 1212351dbcdb5d..888174cc5e0536 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -298,6 +298,7 @@ FUNCTIONS bool getSystemVAmd64PassStructInRegisterDescriptor(CORINFO_CLASS_HANDLE structHnd, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr); void getSwiftLowering(CORINFO_CLASS_HANDLE structHnd, CORINFO_SWIFT_LOWERING* pLowering); void getFpStructLowering(CORINFO_CLASS_HANDLE structHnd, CORINFO_FPSTRUCT_LOWERING* pLowering); + CorInfoType getWasmLowering(CORINFO_CLASS_HANDLE structHnd); uint32_t getThreadTLSIndex(void **ppIndirection); int32_t * getAddrOfCaptureThreadGlobal(void **ppIndirection); void getHelperFtn (CorInfoHelpFunc ftnNum, CORINFO_CONST_LOOKUP* pNativeEntrypoint, CORINFO_METHOD_HANDLE *pMethod); diff --git a/src/coreclr/tools/Common/JitInterface/WasmLowering.cs b/src/coreclr/tools/Common/JitInterface/WasmLowering.cs new file mode 100644 index 00000000000000..56be0e7a0c5fc4 --- /dev/null +++ b/src/coreclr/tools/Common/JitInterface/WasmLowering.cs @@ -0,0 +1,124 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.InteropServices; +using ILCompiler; +using Internal.TypeSystem; + +namespace Internal.JitInterface +{ + public static class WasmLowering + { + // The Wasm "basic C ABI" passes structs that contain one + // primitive field as that primitive field. + // + // Analyze the type and determine if it should be passed + // as a primitive, and if so, which type. If not, return + // CORINFO_TYPE_UNDEF. + + public static CorInfoType LowerTypeForWasm(TypeDesc type, uint size) + { + if (!type.IsValueType) + { + Debug.Fail("Non-struct types should passed directly in Wasm."); + return CorInfoType.CORINFO_TYPE_UNDEF; + } + + MetadataType mdType = type as MetadataType; + if (mdType.HasImpliedRepeatedFields()) + { + return CorInfoType.CORINFO_TYPE_UNDEF; + } + + switch (size) + { + case 1: + case 2: + case 4: + case 8: + break; + + default: + return CorInfoType.CORINFO_TYPE_UNDEF; + } + + while (true) + { + FieldDesc firstField = null; + int numIntroducedFields = 0; + foreach (FieldDesc field in type.GetFields()) + { + if (!field.IsStatic) + { + firstField ??= field; + numIntroducedFields++; + } + + if (numIntroducedFields > 1) + { + break; + } + } + + if (numIntroducedFields != 1) + { + return CorInfoType.CORINFO_TYPE_UNDEF; + } + + TypeDesc firstFieldElementType = firstField.FieldType; + + if (firstFieldElementType.IsValueType) + { + type = firstFieldElementType; + continue; + } + + return WasmTypeClassification(firstFieldElementType, size); + } + } + + private static CorInfoType WasmTypeClassification(TypeDesc typeDesc, uint size) + { + switch (typeDesc.Category) + { + case TypeFlags.Boolean: + case TypeFlags.Char: + case TypeFlags.SByte: + case TypeFlags.Byte: + case TypeFlags.Int16: + case TypeFlags.UInt16: + case TypeFlags.Int32: + case TypeFlags.UInt32: + return (size > 4) ? CorInfoType.CORINFO_TYPE_LONG : CorInfoType.CORINFO_TYPE_INT; + + case TypeFlags.Int64: + case TypeFlags.UInt64: + return CorInfoType.CORINFO_TYPE_LONG; + + case TypeFlags.Single: + return (size > 4) ? CorInfoType.CORINFO_TYPE_DOUBLE : CorInfoType.CORINFO_TYPE_FLOAT; + case TypeFlags.Double: + return CorInfoType.CORINFO_TYPE_DOUBLE; + + case TypeFlags.Enum: + return WasmTypeClassification(typeDesc.UnderlyingType, size); + + case TypeFlags.IntPtr: + case TypeFlags.UIntPtr: + case TypeFlags.Pointer: + case TypeFlags.FunctionPointer: + case TypeFlags.Class: + case TypeFlags.Interface: + case TypeFlags.Array: + case TypeFlags.SzArray: + case TypeFlags.ByRef: + return CorInfoType.CORINFO_TYPE_NATIVEINT; + + default: + return CorInfoType.CORINFO_TYPE_UNDEF; + } + } + } +} diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj index f54c2c6a2a4fdb..469021cdc411a7 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj @@ -145,6 +145,7 @@ + diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/ILCompiler.RyuJit.csproj b/src/coreclr/tools/aot/ILCompiler.RyuJit/ILCompiler.RyuJit.csproj index 8fa7b6865ae5ca..a8b65555b0a0d3 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/ILCompiler.RyuJit.csproj +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/ILCompiler.RyuJit.csproj @@ -89,6 +89,9 @@ JitInterface\SwiftPhysicalLowering.cs + + JitInterface\WasmLowering.cs + Pgo\TypeSystemEntityOrUnknown.cs diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index a2c772f0199586..9ae1f7fc6743af 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -139,6 +139,7 @@ struct JitInterfaceCallbacks bool (* getSystemVAmd64PassStructInRegisterDescriptor)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE structHnd, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr); void (* getSwiftLowering)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE structHnd, CORINFO_SWIFT_LOWERING* pLowering); void (* getFpStructLowering)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE structHnd, CORINFO_FPSTRUCT_LOWERING* pLowering); + CorInfoType (* getWasmLowering)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE structHnd); uint32_t (* getThreadTLSIndex)(void * thisHandle, CorInfoExceptionClass** ppException, void** ppIndirection); int32_t* (* getAddrOfCaptureThreadGlobal)(void * thisHandle, CorInfoExceptionClass** ppException, void** ppIndirection); void (* getHelperFtn)(void * thisHandle, CorInfoExceptionClass** ppException, CorInfoHelpFunc ftnNum, CORINFO_CONST_LOOKUP* pNativeEntrypoint, CORINFO_METHOD_HANDLE* pMethod); @@ -1441,6 +1442,15 @@ class JitInterfaceWrapper : public ICorJitInfo if (pException != nullptr) throw pException; } + virtual CorInfoType getWasmLowering( + CORINFO_CLASS_HANDLE structHnd) +{ + CorInfoExceptionClass* pException = nullptr; + CorInfoType temp = _callbacks->getWasmLowering(_thisHandle, &pException, structHnd); + if (pException != nullptr) throw pException; + return temp; +} + virtual uint32_t getThreadTLSIndex( void** ppIndirection) { diff --git a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h index 22449f398bdad6..c24c7265c65e3d 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h @@ -127,6 +127,7 @@ LWM(GetStringConfigValue, DWORD, DWORD) LWM(GetSystemVAmd64PassStructInRegisterDescriptor, DWORDLONG, Agnostic_GetSystemVAmd64PassStructInRegisterDescriptor) LWM(GetSwiftLowering, DWORDLONG, Agnostic_GetSwiftLowering) LWM(GetFpStructLowering, DWORDLONG, Agnostic_GetFpStructLowering) +LWM(GetWasmLowering, DWORDLONG, DWORD) LWM(GetTailCallHelpers, Agnostic_GetTailCallHelpers, Agnostic_CORINFO_TAILCALL_HELPERS) LWM(GetAsyncResumptionStub, DWORD, DLDL) LWM(GetContinuationType, Agnostic_GetContinuationTypeIn, DWORDLONG) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index a356862e5a3443..ff15803290a3c3 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -6433,6 +6433,26 @@ void MethodContext::repGetFpStructLowering(CORINFO_CLASS_HANDLE structHnd, CORIN } } +void MethodContext::recGetWasmLowering(CORINFO_CLASS_HANDLE structHnd, CorInfoType value) +{ + if (GetWasmLowering == nullptr) + GetWasmLowering = new LightWeightMap(); + DWORDLONG key = CastHandle(structHnd); + GetWasmLowering->Add(key, (DWORD) value); + DEBUG_REC(dmpGetSwiftLowering(key, valuee)); +} +void MethodContext::dmpGetWasmLowering(DWORDLONG key, DWORD value) +{ + printf("GetWasmLowering key structHnd-%016" PRIX64 ", value %d " PRIX64, key, value); +} +CorInfoType MethodContext::repGetWasmLowering(CORINFO_CLASS_HANDLE structHnd) +{ + DWORDLONG key = CastHandle(structHnd); + DWORD value = LookupByKeyOrMiss(GetWasmLowering, key, ": key %016" PRIX64 "", key); + DEBUG_REP(dmpGetWasmLowering(key, value)); + return (CorInfoType) value; +} + void MethodContext::recGetRelocTypeHint(void* target, CorInfoReloc result) { if (GetRelocTypeHint == nullptr) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index 61bbdff04fb5d6..3a1ba56e11ebd8 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -786,6 +786,10 @@ class MethodContext void dmpGetFpStructLowering(DWORDLONG key, const Agnostic_GetFpStructLowering& value); void repGetFpStructLowering(CORINFO_CLASS_HANDLE structHnd, CORINFO_FPSTRUCT_LOWERING* pLowering); + void recGetWasmLowering(CORINFO_CLASS_HANDLE structHnd, CorInfoType infoType); + void dmpGetWasmLowering(DWORDLONG key, DWORD value); + CorInfoType repGetWasmLowering(CORINFO_CLASS_HANDLE structHnd); + void recGetRelocTypeHint(void* target, CorInfoReloc result); void dmpGetRelocTypeHint(DWORDLONG key, DWORD value); CorInfoReloc repGetRelocTypeHint(void* target); @@ -1209,6 +1213,7 @@ enum mcPackets Packet_GetCookieForInterpreterCalliSig = 232, Packet_GetHelperFtn = 233, Packet_GetContinuationType = 234, + Packet_GetWasmLowering = 235, }; void SetDebugDumpVariables(); diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 34c4cefbaa00f5..8f96d049848f35 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -1454,6 +1454,14 @@ void interceptor_ICJI::getFpStructLowering(CORINFO_CLASS_HANDLE structHnd, CORIN mc->recGetFpStructLowering(structHnd, pLowering); } +CorInfoType interceptor_ICJI::getWasmLowering(CORINFO_CLASS_HANDLE structHnd) +{ + mc->cr->AddCall("getWasmLowering"); + CorInfoType result = original_ICorJitInfo->getWasmLowering(structHnd); + mc->recGetWasmLowering(structHnd, result); + return result; +} + // Stuff on ICorDynamicInfo uint32_t interceptor_ICJI::getThreadTLSIndex(void** ppIndirection) { diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp index 1dd2a9520464ae..05559ea232130e 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -1038,6 +1038,13 @@ void interceptor_ICJI::getFpStructLowering( original_ICorJitInfo->getFpStructLowering(structHnd, pLowering); } +CorInfoType interceptor_ICJI::getWasmLowering( + CORINFO_CLASS_HANDLE structHnd) +{ + mcs->AddCall("getWasmLowering"); + return original_ICorJitInfo->getWasmLowering(structHnd); +} + uint32_t interceptor_ICJI::getThreadTLSIndex( void** ppIndirection) { diff --git a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp index 59f9a7dc4140b8..836b7a3d12bb2b 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -910,6 +910,12 @@ void interceptor_ICJI::getFpStructLowering( original_ICorJitInfo->getFpStructLowering(structHnd, pLowering); } +CorInfoType interceptor_ICJI::getWasmLowering( + CORINFO_CLASS_HANDLE structHnd) +{ + return original_ICorJitInfo->getWasmLowering(structHnd); +} + uint32_t interceptor_ICJI::getThreadTLSIndex( void** ppIndirection) { diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index 4e7c6dc9e8b1a5..398c0f31807566 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -1268,6 +1268,12 @@ void MyICJI::getFpStructLowering(CORINFO_CLASS_HANDLE structHnd, CORINFO_FPSTRUC jitInstance->mc->repGetFpStructLowering(structHnd, pLowering); } +CorInfoType MyICJI::getWasmLowering(CORINFO_CLASS_HANDLE structHnd) +{ + jitInstance->mc->cr->AddCall("getWasmLowering"); + return jitInstance->mc->repGetWasmLowering(structHnd); +} + // Stuff on ICorDynamicInfo uint32_t MyICJI::getThreadTLSIndex(void** ppIndirection) { diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index d4169cb86d69d5..e6d042999a808d 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -2543,6 +2543,123 @@ void CEEInfo::getSwiftLowering(CORINFO_CLASS_HANDLE structHnd, CORINFO_SWIFT_LOW EE_TO_JIT_TRANSITION(); } +CorInfoType CEEInfo::getWasmLowering(CORINFO_CLASS_HANDLE structHnd) +{ + CONTRACTL{ + THROWS; + GC_TRIGGERS; + MODE_PREEMPTIVE; + } CONTRACTL_END; + + CorInfoType wasmAbiType = CORINFO_TYPE_UNDEF; + + JIT_TO_EE_TRANSITION(); + + TypeHandle th(structHnd); + + bool useNativeLayout = false; + MethodTable* pMT = nullptr; + if (!th.IsTypeDesc()) + { + pMT = th.AsMethodTable(); + } + else + { + _ASSERTE(th.IsNativeValueType()); + + useNativeLayout = true; + pMT = th.AsNativeValueType(); + } + + unsigned size = th.GetSize(); + + switch (size) + { + case 1: + case 2: + case 4: + case 8: + wasmAbiType = getWasmLoweringHelper(pMT, size); + break; + default: + break; + } + + EE_TO_JIT_TRANSITION(); + + return wasmAbiType; +} + +CorInfoType CEEInfo::getWasmLoweringHelper(MethodTable* pMT, unsigned originalSize) +{ + _ASSERTE(pMT->IsValueType()); + + if ((pMT->GetNumInstanceFields() != 1) || pMT->GetClass()->IsInlineArray()) + { + return CORINFO_TYPE_UNDEF; + } + + ApproxFieldDescIterator fieldIterator(pMT, ApproxFieldDescIterator::INSTANCE_FIELDS); + FieldDesc *pFD = fieldIterator.Next(); + + if (pFD->GetOffset() != 0) + { + return CORINFO_TYPE_UNDEF; + } + + CorElementType fieldType = pFD->GetFieldType(); + + if (fieldType == ELEMENT_TYPE_VALUETYPE) + { + return getWasmLoweringHelper(pFD->GetApproxFieldTypeHandleThrowing().AsMethodTable(), originalSize); + } + + CorInfoType jitType = CEEInfo::asCorInfoType(fieldType); + + switch (jitType) + { + case CORINFO_TYPE_BOOL: + case CORINFO_TYPE_CHAR: + case CORINFO_TYPE_BYTE: + case CORINFO_TYPE_UBYTE: + case CORINFO_TYPE_SHORT: + case CORINFO_TYPE_USHORT: + case CORINFO_TYPE_INT: + case CORINFO_TYPE_UINT: + jitType = originalSize > 4 ? CORINFO_TYPE_LONG : CORINFO_TYPE_INT; + break; + + case CORINFO_TYPE_LONG: + case CORINFO_TYPE_ULONG: + jitType = CORINFO_TYPE_LONG; + break; + + case CORINFO_TYPE_FLOAT: + // ??? + jitType = originalSize > 4 ? CORINFO_TYPE_DOUBLE : CORINFO_TYPE_FLOAT; + break; + + case CORINFO_TYPE_DOUBLE: + jitType = CORINFO_TYPE_DOUBLE; + break; + + case CORINFO_TYPE_NATIVEINT: + case CORINFO_TYPE_NATIVEUINT: + case CORINFO_TYPE_PTR: + case CORINFO_TYPE_BYREF: + case CORINFO_TYPE_CLASS: + // native int on 32 bit platform in 64 bit struct? + jitType = CORINFO_TYPE_NATIVEINT; + break; + + default: + jitType = CORINFO_TYPE_UNDEF; + break; + } + + return jitType; +} + /*********************************************************************/ unsigned CEEInfo::getClassNumInstanceFields (CORINFO_CLASS_HANDLE clsHnd) { diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 89fa3099cb653b..5ffa766e9506d3 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -342,9 +342,10 @@ class CEEInfo : public ICorJitInfo CORINFO_CLASS_HANDLE elemType ); - CorInfoType getFieldTypeInternal (CORINFO_FIELD_HANDLE field, CORINFO_CLASS_HANDLE* structType = NULL,CORINFO_CLASS_HANDLE owner = NULL); + CorInfoType getWasmLoweringHelper(MethodTable* pMT, unsigned originalSize); + protected: void freeArrayInternal(void* array);