Skip to content

Commit

Permalink
Update CEEInfo::getAddressOfPInvokeTarget to handle already resolved …
Browse files Browse the repository at this point in the history
…P/Invokes (#82150)

* Update CEEInfo::getAddressOfPInvokeTarget to handle already resolved P/Invokes

* Make sure to use NDirectMethodDesc

* Respond to PR feedback and remove dead GetNativeNDirectTarget logic

* Fix a manual offsetof for NDirectMethodDesc

* Use offsetof directly

* Remove some more dead code

* Fix the JIT/EE transition for getAddressOfPInvokeTarget

* Fix the getAddressOfPInvokeTarget contract
  • Loading branch information
tannergooding authored Feb 15, 2023
1 parent 8ad7113 commit 05f8388
Show file tree
Hide file tree
Showing 12 changed files with 35 additions and 94 deletions.
3 changes: 0 additions & 3 deletions src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1113,9 +1113,6 @@ public IntPtr AddRef()

internal static class StubHelpers
{
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern IntPtr GetNDirectTarget(IntPtr pMD);

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern IntPtr GetDelegateTarget(Delegate pThis);

Expand Down
3 changes: 0 additions & 3 deletions src/coreclr/vm/amd64/asmconstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,6 @@ ASMCONSTANTS_C_ASSERT(OFFSETOF__ThreadExceptionState__m_pCurrentTracker



#define OFFSETOF__NDirectMethodDesc__m_pWriteableData DBG_FRE(0x48, 0x20)
ASMCONSTANTS_C_ASSERT(OFFSETOF__NDirectMethodDesc__m_pWriteableData == offsetof(NDirectMethodDesc, ndirect.m_pWriteableData));

#define OFFSETOF__DelegateObject___methodPtr 0x18
ASMCONSTANT_OFFSETOF_ASSERT(DelegateObject, _methodPtr);

Expand Down
1 change: 0 additions & 1 deletion src/coreclr/vm/corelib.h
Original file line number Diff line number Diff line change
Expand Up @@ -953,7 +953,6 @@ DEFINE_METHOD(BUFFER, MEMCPY_PTRBYTE_ARRBYTE, Memcpy,
DEFINE_METHOD(BUFFER, MEMCPY, Memcpy, SM_PtrByte_PtrByte_Int_RetVoid)

DEFINE_CLASS(STUBHELPERS, StubHelpers, StubHelpers)
DEFINE_METHOD(STUBHELPERS, GET_NDIRECT_TARGET, GetNDirectTarget, SM_IntPtr_RetIntPtr)
DEFINE_METHOD(STUBHELPERS, GET_DELEGATE_TARGET, GetDelegateTarget, SM_Delegate_RetIntPtr)
#ifdef FEATURE_COMINTEROP
DEFINE_METHOD(STUBHELPERS, GET_COM_HR_EXCEPTION_OBJECT, GetCOMHRExceptionObject, SM_Int_IntPtr_Obj_RetException)
Expand Down
11 changes: 2 additions & 9 deletions src/coreclr/vm/dllimport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2102,15 +2102,8 @@ void NDirectStubLinker::DoNDirect(ILCodeStream *pcsEmit, DWORD dwStubFlags, Meth
#endif // FEATURE_COMINTEROP
{
EmitLoadStubContext(pcsEmit, dwStubFlags);
// pcsEmit->EmitCALL(METHOD__STUBHELPERS__GET_NDIRECT_TARGET, 1, 1);

#ifdef _DEBUG // There are five more pointer values for _DEBUG
_ASSERTE(offsetof(NDirectMethodDesc, ndirect.m_pWriteableData) == sizeof(void*) * 8 + 8);
pcsEmit->EmitLDC(TARGET_POINTER_SIZE * 8 + 8); // offsetof(NDirectMethodDesc, ndirect.m_pWriteableData)
#else // _DEBUG
_ASSERTE(offsetof(NDirectMethodDesc, ndirect.m_pWriteableData) == sizeof(void*) * 3 + 8);
pcsEmit->EmitLDC(TARGET_POINTER_SIZE * 3 + 8); // offsetof(NDirectMethodDesc, ndirect.m_pWriteableData)
#endif // _DEBUG

pcsEmit->EmitLDC(offsetof(NDirectMethodDesc, ndirect.m_pWriteableData));
pcsEmit->EmitADD();

pcsEmit->EmitLDIND_I();
Expand Down
1 change: 0 additions & 1 deletion src/coreclr/vm/ecalllist.h
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,6 @@ FCFuncStart(gMngdRefCustomMarshalerFuncs)
FCFuncEnd()

FCFuncStart(gStubHelperFuncs)
FCFuncElement("GetNDirectTarget", StubHelpers::GetNDirectTarget)
FCFuncElement("GetDelegateTarget", StubHelpers::GetDelegateTarget)
FCFuncElement("SetLastError", StubHelpers::SetLastError)
FCFuncElement("ClearLastError", StubHelpers::ClearLastError)
Expand Down
59 changes: 18 additions & 41 deletions src/coreclr/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9840,59 +9840,36 @@ bool CEEInfo::isCompatibleDelegate(
}

/*********************************************************************/
// return address of fixup area for late-bound N/Direct calls.
void* CEEInfo::getAddressOfPInvokeFixup(CORINFO_METHOD_HANDLE method,
void **ppIndirection)
// return address of fixup area for late-bound N/Direct calls.
void CEEInfo::getAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method,
CORINFO_CONST_LOOKUP *pLookup)
{
CONTRACTL {
NOTHROW;
GC_NOTRIGGER;
THROWS;
GC_TRIGGERS;
MODE_PREEMPTIVE;
} CONTRACTL_END;

void * result = NULL;

if (ppIndirection != NULL)
*ppIndirection = NULL;

JIT_TO_EE_TRANSITION_LEAF();

MethodDesc* ftn = GetMethod(method);
_ASSERTE(ftn->IsNDirect());
NDirectMethodDesc *pMD = (NDirectMethodDesc*)ftn;

result = (LPVOID)&(pMD->GetWriteableData()->m_pNDirectTarget);

EE_TO_JIT_TRANSITION_LEAF();
JIT_TO_EE_TRANSITION();

return result;
}
MethodDesc* pMD = GetMethod(method);
_ASSERTE(pMD->IsNDirect());

/*********************************************************************/
// return address of fixup area for late-bound N/Direct calls.
void CEEInfo::getAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method,
CORINFO_CONST_LOOKUP *pLookup)
{
WRAPPER_NO_CONTRACT;
NDirectMethodDesc* pNMD = reinterpret_cast<NDirectMethodDesc*>(pMD);

void* pIndirection;
if (NDirectMethodDesc::TryGetResolvedNDirectTarget(pNMD, &pIndirection))
{
JIT_TO_EE_TRANSITION_LEAF();

MethodDesc* pMD = GetMethod(method);
if (NDirectMethodDesc::TryResolveNDirectTargetForNoGCTransition(pMD, &pIndirection))
{
pLookup->accessType = IAT_VALUE;
pLookup->addr = pIndirection;
return;
}

EE_TO_JIT_TRANSITION_LEAF();
pLookup->accessType = IAT_VALUE;
pLookup->addr = pIndirection;
}
else
{
pLookup->accessType = IAT_PVALUE;
pLookup->addr = (LPVOID)&(pNMD->GetWriteableData()->m_pNDirectTarget);
}

pLookup->accessType = IAT_PVALUE;
pLookup->addr = getAddressOfPInvokeFixup(method, &pIndirection);
_ASSERTE(pIndirection == NULL);
EE_TO_JIT_TRANSITION();
}

/*********************************************************************/
Expand Down
2 changes: 0 additions & 2 deletions src/coreclr/vm/jitinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -476,8 +476,6 @@ class CEEInfo : public ICorJitInfo

public:

void* getAddressOfPInvokeFixup(CORINFO_METHOD_HANDLE method, void **ppIndirection);

bool getTailCallHelpersInternal(
CORINFO_RESOLVED_TOKEN* callToken,
CORINFO_SIG_INFO* sig,
Expand Down
12 changes: 9 additions & 3 deletions src/coreclr/vm/method.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3372,7 +3372,7 @@ void *NDirectMethodDesc::ResolveAndSetNDirectTarget(_In_ NDirectMethodDesc* pMD)

}

BOOL NDirectMethodDesc::TryResolveNDirectTargetForNoGCTransition(_In_ MethodDesc* pMD, _Out_ void** ndirectTarget)
BOOL NDirectMethodDesc::TryGetResolvedNDirectTarget(_In_ NDirectMethodDesc* pMD, _Out_ void** ndirectTarget)
{
CONTRACTL
{
Expand All @@ -3384,11 +3384,17 @@ BOOL NDirectMethodDesc::TryResolveNDirectTargetForNoGCTransition(_In_ MethodDesc
}
CONTRACTL_END

if (!pMD->NDirectTargetIsImportThunk())
{
// This is an early out to handle already resolved targets
*ndirectTarget = pMD->GetNDirectTarget();
return TRUE;
}

if (!pMD->ShouldSuppressGCTransition())
return FALSE;

_ASSERTE(pMD->IsNDirect());
*ndirectTarget = ResolveAndSetNDirectTarget((NDirectMethodDesc*)pMD);
*ndirectTarget = ResolveAndSetNDirectTarget(pMD);
return TRUE;

}
Expand Down
23 changes: 3 additions & 20 deletions src/coreclr/vm/method.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2769,10 +2769,6 @@ class NDirectMethodDesc : public MethodDesc
public:
struct temp1
{
// If we are hosted, stack imbalance MDA is active, or alignment thunks are needed,
// we will intercept m_pNDirectTarget. The true target is saved here.
LPVOID m_pNativeNDirectTarget;

// Information about the entrypoint
PTR_CUTF8 m_pszEntrypointName;

Expand Down Expand Up @@ -2851,8 +2847,9 @@ class NDirectMethodDesc : public MethodDesc
// Resolve the import to the NDirect target and set it on the NDirectMethodDesc.
static void* ResolveAndSetNDirectTarget(_In_ NDirectMethodDesc* pMD);

// Attempt to import the NDirect target if a GC transition is suppressed.
static BOOL TryResolveNDirectTargetForNoGCTransition(_In_ MethodDesc* pMD, _Out_ void** ndirectTarget);
// Attempt to get a resolved NDirect target. This will return true for already resolved
// targets and methods that are resolved at JIT time, such as those marked SuppressGCTransition
static BOOL TryGetResolvedNDirectTarget(_In_ NDirectMethodDesc* pMD, _Out_ void** ndirectTarget);

// Retrieves the cached result of marshaling required computation, or performs the computation
// if the result is not cached yet.
Expand Down Expand Up @@ -3001,20 +2998,6 @@ class NDirectMethodDesc : public MethodDesc
return GetWriteableData()->m_pNDirectTarget;
}

LPVOID GetNativeNDirectTarget()
{
LIMITED_METHOD_CONTRACT;

_ASSERTE(IsNDirect());
_ASSERTE_IMPL(!NDirectTargetIsImportThunk());

LPVOID pNativeNDirectTarget = ndirect.m_pNativeNDirectTarget;
if (pNativeNDirectTarget != NULL)
return pNativeNDirectTarget;

return GetNDirectTarget();
}

VOID SetNDirectTarget(LPVOID pTarget);

#ifndef DACCESS_COMPILE
Expand Down
9 changes: 0 additions & 9 deletions src/coreclr/vm/stubhelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,15 +455,6 @@ FCIMPL0(void, StubHelpers::ClearLastError)
}
FCIMPLEND

FCIMPL1(void*, StubHelpers::GetNDirectTarget, NDirectMethodDesc* pNMD)
{
FCALL_CONTRACT;

FCUnique(0xa2);
return pNMD->GetNDirectTarget();
}
FCIMPLEND

FCIMPL1(void*, StubHelpers::GetDelegateTarget, DelegateObject *pThisUNSAFE)
{
PCODE pEntryPoint = NULL;
Expand Down
1 change: 0 additions & 1 deletion src/coreclr/vm/stubhelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ class StubHelpers

static FCDECL0(void, SetLastError );
static FCDECL0(void, ClearLastError );
static FCDECL1(void*, GetNDirectTarget, NDirectMethodDesc* pNMD);
static FCDECL1(void*, GetDelegateTarget, DelegateObject *pThisUNSAFE);

static FCDECL2(void, ThrowInteropParamException, UINT resID, UINT paramIdx);
Expand Down
4 changes: 3 additions & 1 deletion src/coreclr/vm/stubmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1765,7 +1765,9 @@ BOOL ILStubManager::TraceManager(Thread *thread,
MethodDesc *pMD = (MethodDesc *)arg;
if (pMD->IsNDirect())
{
target = (PCODE)((NDirectMethodDesc *)pMD)->GetNativeNDirectTarget();
NDirectMethodDesc* pNMD = reinterpret_cast<NDirectMethodDesc*>(pMD);
_ASSERTE_IMPL(!pNMD->NDirectTargetIsImportThunk());
target = (PCODE)pNMD->GetNDirectTarget();
LOG((LF_CORDB, LL_INFO10000, "ILSM::TraceManager: Forward P/Invoke case 0x%p\n", target));
trace->InitForUnmanaged(target);
}
Expand Down

0 comments on commit 05f8388

Please sign in to comment.