Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,7 @@ enum CorInfoHelpFunc
CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT_TRACK_TRANSITIONS, // Transition to preemptive mode and track transitions in reverse P/Invoke prolog.

CORINFO_HELP_GVMLOOKUP_FOR_SLOT, // Resolve a generic virtual method target from this pointer and runtime method handle
CORINFO_HELP_INTERFACELOOKUP_FOR_SLOT, // Resolve a non-generic interface method from this pointer and dispatch cell

CORINFO_HELP_STACK_PROBE, // Probes each page of the allocated stack frame

Expand Down
1 change: 1 addition & 0 deletions src/coreclr/inc/jithelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@
JITHELPER(CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT_TRACK_TRANSITIONS, JIT_ReversePInvokeExitTrackTransitions, CORINFO_HELP_SIG_REG_ONLY)

JITHELPER(CORINFO_HELP_GVMLOOKUP_FOR_SLOT, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
JITHELPER(CORINFO_HELP_INTERFACELOOKUP_FOR_SLOT, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)

#if !defined(TARGET_ARM64) && !defined(TARGET_LOONGARCH64) && !defined(TARGET_RISCV64)
JITHELPER(CORINFO_HELP_STACK_PROBE, JIT_StackProbe, CORINFO_HELP_SIG_REG_ONLY)
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2736,6 +2736,12 @@ GenTree* Compiler::impImportLdvirtftn(GenTree* thisPtr,
impLookupToTree(pResolvedToken, &pCallInfo->codePointerLookup, GTF_ICON_METHOD_HDL, pCallInfo->hMethod);
call = gtNewHelperCallNode(CORINFO_HELP_GVMLOOKUP_FOR_SLOT, TYP_I_IMPL, thisPtr, runtimeMethodHandle);
}
else if (isInterface && IsTargetAbi(CORINFO_NATIVEAOT_ABI))
{
GenTree* dispatchCell =
impLookupToTree(pResolvedToken, &pCallInfo->codePointerLookup, GTF_ICON_GLOBAL_PTR, pCallInfo->hMethod);
call = gtNewHelperCallNode(CORINFO_HELP_INTERFACELOOKUP_FOR_SLOT, TYP_I_IMPL, thisPtr, dispatchCell);
}

#ifdef FEATURE_READYTORUN
else if (opts.IsReadyToRun())
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/jit/importercalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ var_types Compiler::impImportCall(OPCODE opcode,

case CORINFO_VIRTUALCALL_LDVIRTFTN:
{
// Why? This looks like a problem.
if (compIsForInlining())
{
compInlineResult->NoteFatal(InlineObservation::CALLSITE_HAS_CALL_VIA_LDVIRTFTN);
Expand Down Expand Up @@ -425,7 +426,7 @@ var_types Compiler::impImportCall(OPCODE opcode,
addFatPointerCandidate(call->AsCall());
}
#ifdef FEATURE_READYTORUN
if (opts.IsReadyToRun())
if (opts.IsReadyToRun() && !IsTargetAbi(CORINFO_NATIVEAOT_ABI))
{
// Null check is needed for ready to run to handle
// non-virtual <-> virtual changes between versions
Expand Down
4 changes: 0 additions & 4 deletions src/coreclr/nativeaot/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ if(CLR_CMAKE_HOST_UNIX)
add_definitions(-DFEATURE_OBJCMARSHAL)
endif(CLR_CMAKE_TARGET_APPLE)

if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386)
# Allow 16 byte compare-exchange
add_compile_options(-mcx16)
endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386)
endif (CLR_CMAKE_HOST_UNIX)

if(CLR_CMAKE_TARGET_ANDROID)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,78 +11,25 @@ namespace System.Runtime
{
internal static unsafe class CachedInterfaceDispatch
{
[RuntimeExport("RhpCidResolve")]
private static unsafe IntPtr RhpCidResolve(IntPtr callerTransitionBlockParam, IntPtr pCell)
{
IntPtr locationOfThisPointer = callerTransitionBlockParam + TransitionBlock.GetThisOffset();
#pragma warning disable 8500 // address of managed types
object pObject = *(object*)locationOfThisPointer;
#pragma warning restore 8500
IntPtr dispatchResolveTarget = RhpCidResolve_Worker(pObject, pCell);
return dispatchResolveTarget;
}

private static IntPtr RhpCidResolve_Worker(object pObject, IntPtr pCell)
{
DispatchCellInfo cellInfo;

InternalCalls.RhpGetDispatchCellInfo(pCell, out cellInfo);
IntPtr pTargetCode = RhResolveDispatchWorker(pObject, (void*)pCell, ref cellInfo);
if (pTargetCode != IntPtr.Zero)
{
// We don't update the dispatch cell cache if this is IDynamicInterfaceCastable because this
// scenario is by-design dynamic. There is no guarantee that another instance with the same MethodTable
// as the one we just resolved would do the resolution the same way. We will need to ask again.
if (!pObject.GetMethodTable()->IsIDynamicInterfaceCastable)
{
return InternalCalls.RhpUpdateDispatchCellCache(pCell, pTargetCode, pObject.GetMethodTable(), ref cellInfo);
}
else
{
return pTargetCode;
}
}

// "Valid method implementation was not found."
EH.FallbackFailFast(RhFailFastReason.InternalError, null);
return IntPtr.Zero;
}

[RuntimeExport("RhpResolveInterfaceMethod")]
private static IntPtr RhpResolveInterfaceMethod(object pObject, IntPtr pCell)
[RuntimeExport("RhResolveDispatch")]
private static IntPtr RhResolveDispatch(object pObject, EETypePtr interfaceType, ushort slot)
{
if (pObject == null)
{
// Optimizer may perform code motion on dispatch such that it occurs independant of
// null check on "this" pointer. Allow for this case by returning back an invalid pointer.
return IntPtr.Zero;
}

MethodTable* pInstanceType = pObject.GetMethodTable();

// This method is used for the implementation of LOAD_VIRT_FUNCTION and in that case the mapping we want
// may already be in the cache.
IntPtr pTargetCode = InternalCalls.RhpSearchDispatchCellCache(pCell, pInstanceType);
if (pTargetCode == IntPtr.Zero)
IntPtr pTargetCode = DispatchResolve.FindInterfaceMethodImplementationTarget(pObject.GetMethodTable(),
interfaceType.ToPointer(),
slot,
ppGenericContext: null);
if (pTargetCode == IntPtr.Zero && pObject.GetMethodTable()->IsIDynamicInterfaceCastable)
{
// Otherwise call the version of this method that knows how to resolve the method manually.
pTargetCode = RhpCidResolve_Worker(pObject, pCell);
// Dispatch not resolved through normal dispatch map, try using the IDynamicInterfaceCastable
// This will either give us the appropriate result, or throw.
var pfnGetInterfaceImplementation = (delegate*<object, MethodTable*, ushort, IntPtr>)
pObject.GetMethodTable()->GetClasslibFunction(ClassLibFunctionId.IDynamicCastableGetInterfaceImplementation);
pTargetCode = pfnGetInterfaceImplementation(pObject, interfaceType.ToPointer(), slot);
Diagnostics.Debug.Assert(pTargetCode != IntPtr.Zero);
}

return pTargetCode;
}

[RuntimeExport("RhResolveDispatch")]
private static IntPtr RhResolveDispatch(object pObject, EETypePtr interfaceType, ushort slot)
{
DispatchCellInfo cellInfo = default;
cellInfo.CellType = DispatchCellType.InterfaceAndSlot;
cellInfo.InterfaceType = interfaceType;
cellInfo.InterfaceSlot = slot;

return RhResolveDispatchWorker(pObject, null, ref cellInfo);
}

[RuntimeExport("RhResolveDispatchOnType")]
private static IntPtr RhResolveDispatchOnType(EETypePtr instanceType, EETypePtr interfaceType, ushort slot, EETypePtr* pGenericContext)
{
Expand All @@ -97,58 +44,5 @@ private static IntPtr RhResolveDispatchOnType(EETypePtr instanceType, EETypePtr
slot,
(MethodTable**)pGenericContext);
}

private static unsafe IntPtr RhResolveDispatchWorker(object pObject, void* cell, ref DispatchCellInfo cellInfo)
{
// Type of object we're dispatching on.
MethodTable* pInstanceType = pObject.GetMethodTable();

if (cellInfo.CellType == DispatchCellType.InterfaceAndSlot)
{
// Type whose DispatchMap is used. Usually the same as the above but for types which implement IDynamicInterfaceCastable
// we may repeat this process with an alternate type.
MethodTable* pResolvingInstanceType = pInstanceType;

IntPtr pTargetCode = DispatchResolve.FindInterfaceMethodImplementationTarget(pResolvingInstanceType,
cellInfo.InterfaceType.ToPointer(),
cellInfo.InterfaceSlot,
ppGenericContext: null);
if (pTargetCode == IntPtr.Zero && pInstanceType->IsIDynamicInterfaceCastable)
{
// Dispatch not resolved through normal dispatch map, try using the IDynamicInterfaceCastable
// This will either give us the appropriate result, or throw.
var pfnGetInterfaceImplementation = (delegate*<object, MethodTable*, ushort, IntPtr>)
pInstanceType->GetClasslibFunction(ClassLibFunctionId.IDynamicCastableGetInterfaceImplementation);
pTargetCode = pfnGetInterfaceImplementation(pObject, cellInfo.InterfaceType.ToPointer(), cellInfo.InterfaceSlot);
Diagnostics.Debug.Assert(pTargetCode != IntPtr.Zero);
}
return pTargetCode;
}
else if (cellInfo.CellType == DispatchCellType.VTableOffset)
{
// Dereference VTable
return *(IntPtr*)(((byte*)pInstanceType) + cellInfo.VTableOffset);
}
else
{
#if SUPPORTS_NATIVE_METADATA_TYPE_LOADING_AND_SUPPORTS_TOKEN_BASED_DISPATCH_CELLS
// Attempt to convert dispatch cell to non-metadata form if we haven't acquired a cache for this cell yet
if (cellInfo.HasCache == 0)
{
cellInfo = InternalTypeLoaderCalls.ConvertMetadataTokenDispatch(InternalCalls.RhGetModuleFromPointer(cell), cellInfo);
if (cellInfo.CellType != DispatchCellType.MetadataToken)
{
return RhResolveDispatchWorker(pObject, cell, ref cellInfo);
}
}

// If that failed, go down the metadata resolution path
return InternalTypeLoaderCalls.ResolveMetadataTokenDispatch(InternalCalls.RhGetModuleFromPointer(cell), (int)cellInfo.MetadataToken, new IntPtr(pInstanceType));
#else
EH.FallbackFailFast(RhFailFastReason.InternalError, null);
return IntPtr.Zero;
#endif
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,6 @@

namespace System.Runtime
{
internal enum DispatchCellType
{
InterfaceAndSlot = 0x0,
MetadataToken = 0x1,
VTableOffset = 0x2,
}

internal struct DispatchCellInfo
{
public DispatchCellType CellType;
public EETypePtr InterfaceType;
public ushort InterfaceSlot;
public byte HasCache;
public uint MetadataToken;
public uint VTableOffset;
}

// Constants used with RhpGetClasslibFunction, to indicate which classlib function
// we are interested in.
// Note: make sure you change the def in ICodeManager.h if you change this!
Expand Down Expand Up @@ -183,18 +166,6 @@ internal static int RhEndNoGCRegion()
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern unsafe bool RhpEHEnumNext(void* pEHEnum, void* pEHClause);

[RuntimeImport(Redhawk.BaseName, "RhpGetDispatchCellInfo")]
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern unsafe void RhpGetDispatchCellInfo(IntPtr pCell, out DispatchCellInfo newCellInfo);

[RuntimeImport(Redhawk.BaseName, "RhpSearchDispatchCellCache")]
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern unsafe IntPtr RhpSearchDispatchCellCache(IntPtr pCell, MethodTable* pInstanceType);

[RuntimeImport(Redhawk.BaseName, "RhpUpdateDispatchCellCache")]
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern unsafe IntPtr RhpUpdateDispatchCellCache(IntPtr pCell, IntPtr pTargetCode, MethodTable* pInstanceType, ref DispatchCellInfo newCellInfo);

[RuntimeImport(Redhawk.BaseName, "RhpGetClasslibFunctionFromCodeAddress")]
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern unsafe void* RhpGetClasslibFunctionFromCodeAddress(IntPtr address, ClassLibFunctionId id);
Expand Down
9 changes: 0 additions & 9 deletions src/coreclr/nativeaot/Runtime/AsmOffsets.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,6 @@ ASM_SIZEOF( 14, 20, EHEnum)
ASM_OFFSET( 0, 0, gc_alloc_context, alloc_ptr)
ASM_OFFSET( 4, 8, gc_alloc_context, alloc_limit)

#ifdef FEATURE_CACHED_INTERFACE_DISPATCH
ASM_OFFSET( 4, 8, InterfaceDispatchCell, m_pCache)
#ifdef INTERFACE_DISPATCH_CACHE_HAS_CELL_BACKPOINTER
ASM_OFFSET( 8, 0, InterfaceDispatchCache, m_pCell)
#endif
ASM_OFFSET( 10, 20, InterfaceDispatchCache, m_rgEntries)
ASM_SIZEOF( 8, 10, InterfaceDispatchCacheEntry)
#endif

// Undefine macros that are only used in this header for convenience.
#undef ASM_OFFSET
#undef ASM_SIZEOF
Expand Down
1 change: 0 additions & 1 deletion src/coreclr/nativeaot/Runtime/AsmOffsetsVerify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include "TargetPtrs.h"
#include "rhbinder.h"
#include "RuntimeInstance.h"
#include "CachedInterfaceDispatch.h"
#include "shash.h"
#include <minipal/cpufeatures.h>

Expand Down
5 changes: 0 additions & 5 deletions src/coreclr/nativeaot/Runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
set(GC_DIR ../../gc)

set(COMMON_RUNTIME_SOURCES
allocheap.cpp
rhassert.cpp
CachedInterfaceDispatch.cpp
Crst.cpp
DebugHeader.cpp
MethodTable.cpp
Expand All @@ -29,7 +27,6 @@ set(COMMON_RUNTIME_SOURCES
StackFrameIterator.cpp
startup.cpp
stressLog.cpp
SyncClean.cpp
thread.cpp
threadstore.cpp
UniversalTransitionHelpers.cpp
Expand Down Expand Up @@ -207,7 +204,6 @@ list(APPEND RUNTIME_SOURCES_ARCH_ASM
${ARCH_SOURCES_DIR}/MiscStubs.${ASM_SUFFIX}
${ARCH_SOURCES_DIR}/PInvoke.${ASM_SUFFIX}
${ARCH_SOURCES_DIR}/InteropThunksHelpers.${ASM_SUFFIX}
${ARCH_SOURCES_DIR}/StubDispatch.${ASM_SUFFIX}
${ARCH_SOURCES_DIR}/UniversalTransition.${ASM_SUFFIX}
${ARCH_SOURCES_DIR}/WriteBarriers.${ASM_SUFFIX}
)
Expand Down Expand Up @@ -240,7 +236,6 @@ add_compile_definitions($<$<OR:$<CONFIG:Debug>,$<CONFIG:Checked>>:FEATURE_GC_STR
add_definitions(-DFEATURE_NATIVEAOT)
add_definitions(-DVERIFY_HEAP)
add_definitions(-DNATIVEAOT)
add_definitions(-DFEATURE_CACHED_INTERFACE_DISPATCH)
add_definitions(-D_LIB)

# there is a problem with undefined symbols when this is set
Expand Down
Loading