Skip to content

Commit e96eaee

Browse files
Move GetMethodTable to JIT (#105098)
1 parent d0ed3d2 commit e96eaee

File tree

7 files changed

+14
-62
lines changed

7 files changed

+14
-62
lines changed

src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -436,16 +436,8 @@ internal static unsafe bool ObjectHasComponentSize(object obj)
436436
//
437437
// GC.KeepAlive(o);
438438
//
439-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
440439
[Intrinsic]
441-
internal static unsafe MethodTable* GetMethodTable(object obj)
442-
{
443-
// The body of this function will be replaced by the EE with unsafe code
444-
// See getILIntrinsicImplementationForRuntimeHelpers for how this happens.
445-
446-
return (MethodTable*)Unsafe.Add(ref Unsafe.As<byte, IntPtr>(ref obj.GetRawData()), -1);
447-
}
448-
440+
internal static unsafe MethodTable* GetMethodTable(object obj) => GetMethodTable(obj);
449441

450442
[LibraryImport(QCall, EntryPoint = "MethodTable_AreTypesEquivalent")]
451443
[return: MarshalAs(UnmanagedType.Bool)]

src/coreclr/jit/importercalls.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3561,6 +3561,12 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
35613561
break;
35623562
}
35633563

3564+
case NI_System_Runtime_CompilerServices_RuntimeHelpers_GetMethodTable:
3565+
{
3566+
retNode = gtNewMethodTableLookup(impPopStack().val);
3567+
break;
3568+
}
3569+
35643570
case NI_System_Runtime_InteropService_MemoryMarshal_GetArrayDataReference:
35653571
{
35663572
assert(sig->numArgs == 1);
@@ -10410,6 +10416,10 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method)
1041010416
result =
1041110417
NI_System_Runtime_CompilerServices_RuntimeHelpers_IsReferenceOrContainsReferences;
1041210418
}
10419+
else if (strcmp(methodName, "GetMethodTable") == 0)
10420+
{
10421+
result = NI_System_Runtime_CompilerServices_RuntimeHelpers_GetMethodTable;
10422+
}
1041310423
}
1041410424
else if (strcmp(className, "Unsafe") == 0)
1041510425
{

src/coreclr/jit/namedintrinsiclist.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ enum NamedIntrinsic : unsigned short
114114
NI_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray,
115115
NI_System_Runtime_CompilerServices_RuntimeHelpers_IsKnownConstant,
116116
NI_System_Runtime_CompilerServices_RuntimeHelpers_IsReferenceOrContainsReferences,
117+
NI_System_Runtime_CompilerServices_RuntimeHelpers_GetMethodTable,
117118

118119
NI_System_Runtime_InteropService_MemoryMarshal_GetArrayDataReference,
119120

src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,8 @@ internal static unsafe ushort GetElementSize(this Array array)
216216
return array.GetMethodTable()->ComponentSize;
217217
}
218218

219-
internal static unsafe MethodTable* GetMethodTable(this object obj)
220-
=> obj.m_pEEType;
219+
[Intrinsic]
220+
internal static unsafe MethodTable* GetMethodTable(this object obj) => obj.GetMethodTable();
221221

222222
internal static unsafe ref MethodTable* GetMethodTableRef(this object obj)
223223
=> ref obj.m_pEEType;

src/coreclr/tools/Common/TypeSystem/IL/Stubs/RuntimeHelpersIntrinsics.cs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,6 @@ public static MethodIL EmitIL(MethodDesc method)
1919
Debug.Assert(((MetadataType)method.OwningType).Name == "RuntimeHelpers");
2020
string methodName = method.Name;
2121

22-
if (methodName == "GetMethodTable")
23-
{
24-
ILEmitter emit = new ILEmitter();
25-
ILCodeStream codeStream = emit.NewCodeStream();
26-
codeStream.EmitLdArg(0);
27-
codeStream.Emit(ILOpcode.ldflda, emit.NewToken(method.Context.SystemModule.GetKnownType("System.Runtime.CompilerServices", "RawData").GetField("Data")));
28-
codeStream.EmitLdc(-method.Context.Target.PointerSize);
29-
codeStream.Emit(ILOpcode.add);
30-
codeStream.Emit(ILOpcode.ldind_i);
31-
codeStream.Emit(ILOpcode.ret);
32-
return emit.Link(method);
33-
}
34-
3522
// All the methods handled below are per-instantiation generic methods
3623
if (method.Instantiation.Length != 1 || method.IsTypicalMethodDefinition)
3724
return null;

src/coreclr/vm/corelib.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,6 @@ DEFINE_METHOD(RTFIELD, GET_FIELDHANDLE, GetFieldHandle,
632632

633633
DEFINE_CLASS(RUNTIME_HELPERS, CompilerServices, RuntimeHelpers)
634634
DEFINE_METHOD(RUNTIME_HELPERS, IS_BITWISE_EQUATABLE, IsBitwiseEquatable, NoSig)
635-
DEFINE_METHOD(RUNTIME_HELPERS, GET_METHOD_TABLE, GetMethodTable, NoSig)
636635
DEFINE_METHOD(RUNTIME_HELPERS, GET_RAW_DATA, GetRawData, NoSig)
637636
DEFINE_METHOD(RUNTIME_HELPERS, GET_UNINITIALIZED_OBJECT, GetUninitializedObject, SM_Type_RetObj)
638637
DEFINE_METHOD(RUNTIME_HELPERS, ENUM_EQUALS, EnumEquals, NoSig)

src/coreclr/vm/jitinterface.cpp

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7332,43 +7332,6 @@ bool getILIntrinsicImplementationForRuntimeHelpers(MethodDesc * ftn,
73327332
return true;
73337333
}
73347334

7335-
if (tk == CoreLibBinder::GetMethod(METHOD__RUNTIME_HELPERS__GET_METHOD_TABLE)->GetMemberDef())
7336-
{
7337-
mdToken tokRawData = CoreLibBinder::GetField(FIELD__RAW_DATA__DATA)->GetMemberDef();
7338-
7339-
// In the CLR, an object is laid out as follows.
7340-
// [ object_header || MethodTable* (64-bit pointer) || instance_data ]
7341-
// ^ ^-- ref <theObj>.firstField points here
7342-
// `-- <theObj> reference (type O) points here
7343-
//
7344-
// So essentially what we want to do is to turn an object reference (type O) into a
7345-
// native int&, then dereference it to get the MethodTable*. (Essentially, an object
7346-
// reference is a MethodTable**.) Per ECMA-335, Sec. III.1.5, we can add
7347-
// (but not subtract) a & and an int32 to produce a &. So we'll get a reference to
7348-
// <theObj>.firstField (type &), then back up one pointer length to get a value of
7349-
// essentially type (MethodTable*)&. Both of these are legal GC-trackable references
7350-
// to <theObj>, regardless of <theObj>'s actual length.
7351-
7352-
static BYTE ilcode[] = { CEE_LDARG_0, // stack contains [ O ] = <theObj>
7353-
CEE_LDFLDA,0,0,0,0, // stack contains [ & ] = ref <theObj>.firstField
7354-
CEE_LDC_I4_S,(BYTE)(-TARGET_POINTER_SIZE), // stack contains [ &, int32 ] = -IntPtr.Size
7355-
CEE_ADD, // stack contains [ & ] = ref <theObj>.methodTablePtr
7356-
CEE_LDIND_I, // stack contains [ native int ] = <theObj>.methodTablePtr
7357-
CEE_RET };
7358-
7359-
ilcode[2] = (BYTE)(tokRawData);
7360-
ilcode[3] = (BYTE)(tokRawData >> 8);
7361-
ilcode[4] = (BYTE)(tokRawData >> 16);
7362-
ilcode[5] = (BYTE)(tokRawData >> 24);
7363-
7364-
methInfo->ILCode = const_cast<BYTE*>(ilcode);
7365-
methInfo->ILCodeSize = sizeof(ilcode);
7366-
methInfo->maxStack = 2;
7367-
methInfo->EHcount = 0;
7368-
methInfo->options = (CorInfoOptions)0;
7369-
return true;
7370-
}
7371-
73727335
if (tk == CoreLibBinder::GetMethod(METHOD__RUNTIME_HELPERS__ENUM_EQUALS)->GetMemberDef())
73737336
{
73747337
// Normally we would follow the above pattern and unconditionally replace the IL,

0 commit comments

Comments
 (0)