Skip to content

Commit a4674c3

Browse files
Remove HMFs from JIT helpers (#111034)
* Convert JIT_GetFieldAddr and JIT_GetStaticFieldAddr to C#. These JIT helpers are only used in EnC scenarios so their performance is secondary. * Convert JIT_NewMDArr to C#.
1 parent 33351e6 commit a4674c3

File tree

14 files changed

+106
-120
lines changed

14 files changed

+106
-120
lines changed

src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,20 @@ private static unsafe Array InternalCreateFromArrayType(RuntimeType arrayType, i
3535
return retArray!;
3636
}
3737

38+
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Array_CreateInstanceMDArray")]
39+
private static unsafe partial void CreateInstanceMDArray(nint typeHandle, uint dwNumArgs, void* pArgList, ObjectHandleOnStack retArray);
40+
41+
// implementation of CORINFO_HELP_NEW_MDARR and CORINFO_HELP_NEW_MDARR_RARE.
42+
[StackTraceHidden]
43+
[DebuggerStepThrough]
44+
[DebuggerHidden]
45+
internal static unsafe object CreateInstanceMDArray(nint typeHandle, uint dwNumArgs, void* pArgList)
46+
{
47+
Array? arr = null;
48+
CreateInstanceMDArray(typeHandle, dwNumArgs, pArgList, ObjectHandleOnStack.Create(ref arr));
49+
return arr!;
50+
}
51+
3852
private static unsafe void CopyImpl(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable)
3953
{
4054
if (sourceArray == null)

src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,6 +1658,34 @@ public void GetObjectData(SerializationInfo info, StreamingContext context)
16581658
{
16591659
throw new PlatformNotSupportedException();
16601660
}
1661+
1662+
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeFieldHandle_GetEnCFieldAddr")]
1663+
private static partial void* GetEnCFieldAddr(ObjectHandleOnStack tgt, void* pFD);
1664+
1665+
// implementation of CORINFO_HELP_GETFIELDADDR
1666+
[StackTraceHidden]
1667+
[DebuggerStepThrough]
1668+
[DebuggerHidden]
1669+
internal static unsafe void* GetFieldAddr(object tgt, void* pFD)
1670+
{
1671+
void* addr = GetEnCFieldAddr(ObjectHandleOnStack.Create(ref tgt), pFD);
1672+
if (addr == null)
1673+
throw new NullReferenceException();
1674+
return addr;
1675+
}
1676+
1677+
// implementation of CORINFO_HELP_GETSTATICFIELDADDR
1678+
[StackTraceHidden]
1679+
[DebuggerStepThrough]
1680+
[DebuggerHidden]
1681+
internal static unsafe void* GetStaticFieldAddr(void* pFD)
1682+
{
1683+
object? nullTarget = null;
1684+
void* addr = GetEnCFieldAddr(ObjectHandleOnStack.Create(ref nullTarget), pFD);
1685+
if (addr == null)
1686+
throw new NullReferenceException();
1687+
return addr;
1688+
}
16611689
}
16621690

16631691
public unsafe partial struct ModuleHandle : IEquatable<ModuleHandle>

src/coreclr/classlibnative/bcltype/arraynative.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ static void CheckElementType(TypeHandle elementType)
110110
}
111111
}
112112

113-
void QCALLTYPE Array_CreateInstance(QCall::TypeHandle pTypeHnd, INT32 rank, INT32* pLengths, INT32* pLowerBounds, BOOL createFromArrayType, QCall::ObjectHandleOnStack retArray)
113+
extern "C" void QCALLTYPE Array_CreateInstance(QCall::TypeHandle pTypeHnd, INT32 rank, INT32* pLengths, INT32* pLowerBounds, BOOL createFromArrayType, QCall::ObjectHandleOnStack retArray)
114114
{
115115
CONTRACTL {
116116
QCALL_CHECK;
@@ -205,3 +205,20 @@ void QCALLTYPE Array_CreateInstance(QCall::TypeHandle pTypeHnd, INT32 rank, INT3
205205
Done: ;
206206
END_QCALL;
207207
}
208+
209+
extern "C" void QCALLTYPE Array_CreateInstanceMDArray(EnregisteredTypeHandle typeHandle, UINT32 dwNumArgs, INT32* pArgList, QCall::ObjectHandleOnStack retArray)
210+
{
211+
QCALL_CONTRACT;
212+
213+
BEGIN_QCALL;
214+
215+
GCX_COOP();
216+
217+
TypeHandle typeHnd = TypeHandle::FromPtr(typeHandle);
218+
_ASSERTE(typeHnd.IsFullyLoaded());
219+
_ASSERTE(typeHnd.GetMethodTable()->IsArray());
220+
221+
retArray.Set(AllocateArrayEx(typeHnd, pArgList, dwNumArgs));
222+
223+
END_QCALL;
224+
}

src/coreclr/classlibnative/bcltype/arraynative.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ class ArrayNative
2121
static FCDECL1(INT32, GetCorElementTypeOfElementType, ArrayBase* arrayUNSAFE);
2222
};
2323

24-
extern "C" void QCALLTYPE Array_CreateInstance(QCall::TypeHandle pTypeHnd, INT32 rank, INT32* pLengths, INT32* pBounds, BOOL createFromArrayType, QCall::ObjectHandleOnStack retArray);
2524
extern "C" PCODE QCALLTYPE Array_GetElementConstructorEntrypoint(QCall::TypeHandle pArrayTypeHnd);
25+
extern "C" void QCALLTYPE Array_CreateInstance(QCall::TypeHandle pTypeHnd, INT32 rank, INT32* pLengths, INT32* pBounds, BOOL createFromArrayType, QCall::ObjectHandleOnStack retArray);
26+
extern "C" void QCALLTYPE Array_CreateInstanceMDArray(EnregisteredTypeHandle typeHandle, UINT32 dwNumArgs, INT32* pArgList, QCall::ObjectHandleOnStack retArray);
2627

2728
#endif // _ARRAYNATIVE_H_

src/coreclr/inc/jithelpers.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@
8484
DYNAMICJITHELPER(CORINFO_HELP_NEWSFAST_ALIGN8, JIT_New, METHOD__NIL)
8585
JITHELPER(CORINFO_HELP_NEWSFAST_ALIGN8_VC, NULL, METHOD__NIL)
8686
JITHELPER(CORINFO_HELP_NEWSFAST_ALIGN8_FINALIZE, NULL, METHOD__NIL)
87-
JITHELPER(CORINFO_HELP_NEW_MDARR, JIT_NewMDArr,METHOD__NIL)
88-
JITHELPER(CORINFO_HELP_NEW_MDARR_RARE, JIT_NewMDArr,METHOD__NIL)
87+
DYNAMICJITHELPER(CORINFO_HELP_NEW_MDARR, NULL, METHOD__ARRAY__CREATEINSTANCEMDARRAY)
88+
DYNAMICJITHELPER(CORINFO_HELP_NEW_MDARR_RARE, NULL, METHOD__ARRAY__CREATEINSTANCEMDARRAY)
8989
JITHELPER(CORINFO_HELP_NEWARR_1_DIRECT, JIT_NewArr1,METHOD__NIL)
9090
JITHELPER(CORINFO_HELP_NEWARR_1_MAYBEFROZEN, JIT_NewArr1MaybeFrozen,METHOD__NIL)
9191
DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_OBJ, JIT_NewArr1,METHOD__NIL)
@@ -164,9 +164,9 @@
164164

165165
// Accessing fields
166166

167-
JITHELPER(CORINFO_HELP_GETFIELDADDR, JIT_GetFieldAddr,METHOD__NIL)
168-
JITHELPER(CORINFO_HELP_GETSTATICFIELDADDR, JIT_GetStaticFieldAddr,METHOD__NIL)
169-
JITHELPER(CORINFO_HELP_GETSTATICFIELDADDR_TLS, NULL, METHOD__NIL)
167+
DYNAMICJITHELPER(CORINFO_HELP_GETFIELDADDR, NULL, METHOD__FIELD_HANDLE__GETFIELDADDR)
168+
DYNAMICJITHELPER(CORINFO_HELP_GETSTATICFIELDADDR, NULL, METHOD__FIELD_HANDLE__GETSTATICFIELDADDR)
169+
JITHELPER(CORINFO_HELP_GETSTATICFIELDADDR_TLS, NULL, METHOD__NIL)
170170

171171
DYNAMICJITHELPER(CORINFO_HELP_GET_GCSTATIC_BASE, JIT_GetGCStaticBase, METHOD__STATICSHELPERS__GET_GC_STATIC)
172172
DYNAMICJITHELPER(CORINFO_HELP_GET_NONGCSTATIC_BASE, JIT_GetNonGCStaticBase, METHOD__STATICSHELPERS__GET_NONGC_STATIC)

src/coreclr/jit/utils.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1817,7 +1817,6 @@ void HelperCallProperties::init()
18171817
case CORINFO_HELP_MON_ENTER:
18181818
case CORINFO_HELP_MON_EXIT:
18191819
case CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT:
1820-
case CORINFO_HELP_GETFIELDADDR:
18211820
case CORINFO_HELP_JIT_PINVOKE_BEGIN:
18221821
case CORINFO_HELP_JIT_PINVOKE_END:
18231822
noThrow = true;

src/coreclr/vm/corelib.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ DEFINE_METHOD(ARG_ITERATOR, CTOR2, .ctor,
109109
DEFINE_CLASS(ARGUMENT_HANDLE, System, RuntimeArgumentHandle)
110110

111111
DEFINE_CLASS(ARRAY, System, Array)
112+
DEFINE_METHOD(ARRAY, CREATEINSTANCEMDARRAY, CreateInstanceMDArray, SM_IntPtr_UInt_VoidPtr_RetObj)
112113

113114
DEFINE_CLASS(ARRAY_WITH_OFFSET, Interop, ArrayWithOffset)
114115
DEFINE_FIELD(ARRAY_WITH_OFFSET, M_ARRAY, m_array)
@@ -367,6 +368,8 @@ DEFINE_CLASS(FIELD, Reflection, RuntimeFieldInfo)
367368

368369
DEFINE_CLASS(FIELD_HANDLE, System, RuntimeFieldHandle)
369370
DEFINE_FIELD(FIELD_HANDLE, M_FIELD, m_ptr)
371+
DEFINE_METHOD(FIELD_HANDLE, GETFIELDADDR, GetFieldAddr, SM_Obj_VoidPtr_RetVoidPtr)
372+
DEFINE_METHOD(FIELD_HANDLE, GETSTATICFIELDADDR, GetStaticFieldAddr, SM_VoidPtr_RetVoidPtr)
370373

371374
DEFINE_CLASS(I_RT_FIELD_INFO, System, IRuntimeFieldInfo)
372375

src/coreclr/vm/field.cpp

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -474,25 +474,6 @@ void *FieldDesc::GetInstanceAddress(OBJECTREF o)
474474
return (void *) (dac_cast<TADDR>(o->GetData()) + dwOffset);
475475
}
476476

477-
// And here's the equivalent, when you are guaranteed that the enclosing instance of
478-
// the field is in the GC Heap. So if the enclosing instance is a value type, it had
479-
// better be boxed. We ASSERT this.
480-
void *FieldDesc::GetAddressGuaranteedInHeap(void *o)
481-
{
482-
CONTRACTL
483-
{
484-
NOTHROW;
485-
GC_NOTRIGGER;
486-
MODE_COOPERATIVE;
487-
}
488-
CONTRACTL_END;
489-
490-
_ASSERTE(!IsEnCNew());
491-
492-
return ((BYTE*)(o)) + sizeof(Object) + m_dwOffset;
493-
}
494-
495-
496477
DWORD FieldDesc::GetValue32(OBJECTREF o)
497478
{
498479
WRAPPER_NO_CONTRACT;

src/coreclr/vm/field.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ class FieldDesc
285285
SetOffset(FIELD_OFFSET_NEW_ENC);
286286
}
287287

288-
BOOL IsCollectible()
288+
BOOL IsCollectible()
289289
{
290290
LIMITED_METHOD_DAC_CONTRACT;
291291

@@ -340,7 +340,6 @@ class FieldDesc
340340
PTR_VOID GetAddress(PTR_VOID o);
341341

342342
PTR_VOID GetAddressNoThrowNoGC(PTR_VOID o);
343-
void* GetAddressGuaranteedInHeap(void *o);
344343

345344
void* GetValuePtr(OBJECTREF o);
346345
VOID SetValuePtr(OBJECTREF o, void* pValue);

src/coreclr/vm/jithelpers.cpp

Lines changed: 0 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -462,78 +462,6 @@ HCIMPLEND
462462

463463
#include <optdefault.h>
464464

465-
466-
//========================================================================
467-
//
468-
// INSTANCE FIELD HELPERS
469-
//
470-
//========================================================================
471-
472-
/*********************************************************************/
473-
// Returns the address of the instance field in the object (This is an interior
474-
// pointer and the caller has to use it appropriately) or a static field.
475-
// obj can be either a reference or a byref
476-
HCIMPL2(void*, JIT_GetFieldAddr_Framed, Object *obj, FieldDesc* pFD)
477-
{
478-
CONTRACTL {
479-
FCALL_CHECK;
480-
PRECONDITION(CheckPointer(pFD));
481-
} CONTRACTL_END;
482-
483-
void * fldAddr = NULL;
484-
OBJECTREF objRef = ObjectToOBJECTREF(obj);
485-
486-
HELPER_METHOD_FRAME_BEGIN_RET_1(objRef);
487-
488-
if (!pFD->IsStatic() && objRef == NULL)
489-
COMPlusThrow(kNullReferenceException);
490-
491-
fldAddr = pFD->GetAddress(OBJECTREFToObject(objRef));
492-
493-
HELPER_METHOD_FRAME_END();
494-
495-
return fldAddr;
496-
}
497-
HCIMPLEND
498-
499-
#include <optsmallperfcritical.h>
500-
HCIMPL2(void*, JIT_GetFieldAddr, Object *obj, FieldDesc* pFD)
501-
{
502-
CONTRACTL {
503-
FCALL_CHECK;
504-
PRECONDITION(CheckPointer(pFD));
505-
} CONTRACTL_END;
506-
507-
if (obj == NULL || pFD->IsEnCNew())
508-
{
509-
ENDFORBIDGC();
510-
return HCCALL2(JIT_GetFieldAddr_Framed, obj, pFD);
511-
}
512-
513-
return pFD->GetAddressGuaranteedInHeap(obj);
514-
}
515-
HCIMPLEND
516-
#include <optdefault.h>
517-
518-
#include <optsmallperfcritical.h>
519-
HCIMPL1(void*, JIT_GetStaticFieldAddr, FieldDesc* pFD)
520-
{
521-
CONTRACTL {
522-
FCALL_CHECK;
523-
PRECONDITION(CheckPointer(pFD));
524-
} CONTRACTL_END;
525-
526-
// [TODO] Only handling EnC for now
527-
_ASSERTE(pFD->IsEnCNew());
528-
529-
{
530-
ENDFORBIDGC();
531-
return HCCALL2(JIT_GetFieldAddr_Framed, NULL, pFD);
532-
}
533-
}
534-
HCIMPLEND
535-
#include <optdefault.h>
536-
537465
// Helper for the managed InitClass implementations
538466
extern "C" void QCALLTYPE InitClassHelper(MethodTable* pMT)
539467
{
@@ -1232,25 +1160,6 @@ HCIMPL2(Object*, JIT_NewArr1MaybeFrozen, CORINFO_CLASS_HANDLE arrayMT, INT_PTR s
12321160
}
12331161
HCIMPLEND
12341162

1235-
/*************************************************************/
1236-
HCIMPL3(Object*, JIT_NewMDArr, CORINFO_CLASS_HANDLE classHnd, unsigned dwNumArgs, INT32 * pArgList)
1237-
{
1238-
FCALL_CONTRACT;
1239-
1240-
OBJECTREF ret = 0;
1241-
HELPER_METHOD_FRAME_BEGIN_RET_1(ret); // Set up a frame
1242-
1243-
TypeHandle typeHnd(classHnd);
1244-
_ASSERTE(typeHnd.IsFullyLoaded());
1245-
_ASSERTE(typeHnd.GetMethodTable()->IsArray());
1246-
1247-
ret = AllocateArrayEx(typeHnd, pArgList, dwNumArgs);
1248-
1249-
HELPER_METHOD_FRAME_END();
1250-
return OBJECTREFToObject(ret);
1251-
}
1252-
HCIMPLEND
1253-
12541163
#include <optdefault.h>
12551164

12561165
//========================================================================

src/coreclr/vm/metasig.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,10 @@ DEFINE_METASIG_T(SM(Int_IntPtr_Obj_RetException, i I j, C(EXCEPTION)))
173173
DEFINE_METASIG_T(SM(Type_CharPtr_RuntimeAssembly_Bool_Bool_RetRuntimeType, P(u) C(ASSEMBLY) F F, C(CLASS)))
174174
DEFINE_METASIG_T(SM(Type_RetIntPtr, C(TYPE), I))
175175
DEFINE_METASIG(SM(RefIntPtr_IntPtr_IntPtr_Int_RetObj, r(I) I I i, j))
176+
DEFINE_METASIG(SM(IntPtr_UInt_VoidPtr_RetObj, I K P(v), j))
176177
DEFINE_METASIG(SM(Obj_IntPtr_RetIntPtr, j I, I))
178+
DEFINE_METASIG(SM(VoidPtr_RetVoidPtr, P(v), P(v)))
179+
DEFINE_METASIG(SM(Obj_VoidPtr_RetVoidPtr, j P(v), P(v)))
177180
DEFINE_METASIG(SM(Obj_IntPtr_RetObj, j I, j))
178181
DEFINE_METASIG(SM(Obj_RefIntPtr_RetVoid, j r(I), v))
179182
DEFINE_METASIG(SM(Obj_IntPtr_RetVoid, j I, v))

src/coreclr/vm/qcallentrypoints.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ static const Entry s_QCall[] =
169169
DllImportEntry(RuntimeFieldHandle_SetValue)
170170
DllImportEntry(RuntimeFieldHandle_GetValueDirect)
171171
DllImportEntry(RuntimeFieldHandle_SetValueDirect)
172+
DllImportEntry(RuntimeFieldHandle_GetEnCFieldAddr)
172173
DllImportEntry(RuntimeFieldHandle_GetRVAFieldInfo)
173174
DllImportEntry(RuntimeFieldHandle_GetFieldDataReference)
174175
DllImportEntry(StackTrace_GetStackFramesInternal)
@@ -217,6 +218,7 @@ static const Entry s_QCall[] =
217218
DllImportEntry(TypeBuilder_DefineCustomAttribute)
218219
DllImportEntry(MdUtf8String_EqualsCaseInsensitive)
219220
DllImportEntry(Array_CreateInstance)
221+
DllImportEntry(Array_CreateInstanceMDArray)
220222
DllImportEntry(Array_GetElementConstructorEntrypoint)
221223
DllImportEntry(AssemblyName_InitializeAssemblySpec)
222224
DllImportEntry(AssemblyNative_GetFullName)

src/coreclr/vm/reflectioninvocation.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,6 +1096,35 @@ FCIMPL1(void*, RuntimeFieldHandle::GetStaticFieldAddress, ReflectFieldObject *pF
10961096
}
10971097
FCIMPLEND
10981098

1099+
// Returns the address of the EnC instance field in the object (This is an interior
1100+
// pointer and the caller has to use it appropriately) or an EnC static field.
1101+
extern "C" void* QCALLTYPE RuntimeFieldHandle_GetEnCFieldAddr(QCall::ObjectHandleOnStack target, FieldDesc* pFD)
1102+
{
1103+
CONTRACTL
1104+
{
1105+
QCALL_CHECK;
1106+
PRECONDITION(pFD != NULL);
1107+
}
1108+
CONTRACTL_END;
1109+
1110+
void* ret = NULL;
1111+
1112+
BEGIN_QCALL;
1113+
1114+
GCX_COOP();
1115+
1116+
// Only handling EnC
1117+
_ASSERTE(pFD->IsEnCNew());
1118+
1119+
// If the field is static, or if the object is non-null, get the address of the field.
1120+
if (pFD->IsStatic() || target.Get() != NULL)
1121+
ret = pFD->GetAddress(OBJECTREFToObject(target.Get()));
1122+
1123+
END_QCALL;
1124+
1125+
return ret;
1126+
}
1127+
10991128
extern "C" BOOL QCALLTYPE RuntimeFieldHandle_GetRVAFieldInfo(FieldDesc* pField, void** address, UINT* size)
11001129
{
11011130
QCALL_CONTRACT;

src/coreclr/vm/runtimehandles.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ extern "C" void QCALLTYPE RuntimeFieldHandle_GetValue(FieldDesc* fieldDesc, QCal
270270
extern "C" void QCALLTYPE RuntimeFieldHandle_SetValue(FieldDesc* fieldDesc, QCall::ObjectHandleOnStack instance, QCall::ObjectHandleOnStack value, QCall::TypeHandle fieldType, QCall::TypeHandle declaringType, BOOL* pIsClassInitialized);
271271
extern "C" void QCALLTYPE RuntimeFieldHandle_GetValueDirect(FieldDesc* fieldDesc, TypedByRef *pTarget, QCall::TypeHandle fieldTypeHandle, QCall::TypeHandle declaringTypeHandle, QCall::ObjectHandleOnStack result);
272272
extern "C" void QCALLTYPE RuntimeFieldHandle_SetValueDirect(FieldDesc* fieldDesc, TypedByRef *pTarget, QCall::ObjectHandleOnStack newValue, QCall::TypeHandle fieldType, QCall::TypeHandle declaringType);
273+
extern "C" void* QCALLTYPE RuntimeFieldHandle_GetEnCFieldAddr(QCall::ObjectHandleOnStack target, FieldDesc* pFD);
273274
extern "C" BOOL QCALLTYPE RuntimeFieldHandle_GetRVAFieldInfo(FieldDesc* pField, void** address, UINT* size);
274275
extern "C" void QCALLTYPE RuntimeFieldHandle_GetFieldDataReference(FieldDesc* pField, QCall::ObjectHandleOnStack instance, QCall::ByteRefOnStack offset);
275276

0 commit comments

Comments
 (0)