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
3 changes: 2 additions & 1 deletion src/coreclr/vm/amd64/PInvokeStubs.asm
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,11 @@ NESTED_ENTRY VarargPInvokeGenILStub, _TEXT
mov r13, PINVOKE_CALLI_SIGTOKEN_REGISTER

;
; VarargPInvokeStubWorker(TransitionBlock* pTransitionBlock, VASigCookie* pVASigCookie)
; VarargPInvokeStubWorker(TransitionBlock * pTransitionBlock, VASigCookie *pVASigCookie, MethodDesc *pMD)
;
lea rcx, [rsp + __PWTB_TransitionBlock] ; pTransitionBlock*
mov rdx, PINVOKE_CALLI_SIGTOKEN_REGISTER ; pVASigCookie
mov r8, METHODDESC_REGISTER ; pMD
call VarargPInvokeStubWorker

;
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/vm/amd64/pinvokestubs.S
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,11 @@ NESTED_ENTRY VarargPInvokeGenILStub, _TEXT, NoHandler
mov r13, PINVOKE_CALLI_SIGTOKEN_REGISTER

//
// VarargPInvokeStubWorker(TransitionBlock* pTransitionBlock, VASigCookie* pVASigCookie)
// VarargPInvokeStubWorker(TransitionBlock * pTransitionBlock, VASigCookie *pVASigCookie, MethodDesc *pMD)
//
lea rdi, [rsp + __PWTB_TransitionBlock] // pTransitionBlock*
mov rsi, PINVOKE_CALLI_SIGTOKEN_REGISTER // pVASigCookie
mov rdx, METHODDESC_REGISTER // pMD
call C_FUNC(VarargPInvokeStubWorker)

//
Expand Down
13 changes: 3 additions & 10 deletions src/coreclr/vm/ceeload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4197,13 +4197,12 @@ static bool MethodSignatureContainsGenericVariables(SigParser& sp)
//==========================================================================
// Enregisters a VASig.
//==========================================================================
VASigCookie *Module::GetVASigCookie(Signature vaSignature, MethodDesc* pMD, const SigTypeContext* typeContext)
VASigCookie *Module::GetVASigCookie(Signature vaSignature, const SigTypeContext* typeContext)
{
CONTRACT(VASigCookie*)
{
INSTANCE_CHECK;
STANDARD_VM_CHECK;
PRECONDITION(pMD == NULL || pMD->IsPInvoke()); // Only PInvoke methods are embedded in VASig cookies.
POSTCONDITION(CheckPointer(RETVAL));
INJECT_FAULT(COMPlusThrowOM());
}
Expand Down Expand Up @@ -4236,17 +4235,16 @@ VASigCookie *Module::GetVASigCookie(Signature vaSignature, MethodDesc* pMD, cons
#endif
}

VASigCookie *pCookie = GetVASigCookieWorker(this, pLoaderModule, pMD, vaSignature, typeContext);
VASigCookie *pCookie = GetVASigCookieWorker(this, pLoaderModule, vaSignature, typeContext);

RETURN pCookie;
}

VASigCookie *Module::GetVASigCookieWorker(Module* pDefiningModule, Module* pLoaderModule, MethodDesc* pMD, Signature vaSignature, const SigTypeContext* typeContext)
VASigCookie *Module::GetVASigCookieWorker(Module* pDefiningModule, Module* pLoaderModule, Signature vaSignature, const SigTypeContext* typeContext)
{
CONTRACT(VASigCookie*)
{
STANDARD_VM_CHECK;
PRECONDITION(pMD == NULL || pMD->IsPInvoke());
POSTCONDITION(CheckPointer(RETVAL));
INJECT_FAULT(COMPlusThrowOM());
}
Expand All @@ -4263,10 +4261,6 @@ VASigCookie *Module::GetVASigCookieWorker(Module* pDefiningModule, Module* pLoad
{
VASigCookie* cookieMaybe = &pBlock->m_cookies[i];

// Check if the cookie targets the same MethodDesc.
if (cookieMaybe->pMethodDesc != pMD)
continue;

// Check if the cookie has the same signature.
if (cookieMaybe->signature.GetRawSig() == vaSignature.GetRawSig())
{
Expand Down Expand Up @@ -4355,7 +4349,6 @@ VASigCookie *Module::GetVASigCookieWorker(Module* pDefiningModule, Module* pLoad
// Now, fill in the new cookie (assuming we had enough memory to create one.)
pCookie->pModule = pDefiningModule;
pCookie->pPInvokeILStub = (PCODE)NULL;
pCookie->pMethodDesc = pMD;
pCookie->sizeOfArgs = sizeOfArgs;
pCookie->signature = vaSignature;
pCookie->pLoaderModule = pLoaderModule;
Expand Down
5 changes: 2 additions & 3 deletions src/coreclr/vm/ceeload.h
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,6 @@ struct VASigCookie
// so please keep this field first
unsigned sizeOfArgs; // size of argument list
Volatile<PCODE> pPInvokeILStub; // will be use if target is PInvoke (tag == 0)
PTR_MethodDesc pMethodDesc; // Only non-null if this is a PInvoke method
PTR_Module pModule;
PTR_Module pLoaderModule;
Signature signature;
Expand Down Expand Up @@ -1398,9 +1397,9 @@ class Module : public ModuleBase
void NotifyEtwLoadFinished(HRESULT hr);

// Enregisters a VASig.
VASigCookie *GetVASigCookie(Signature vaSignature, MethodDesc* pMD, const SigTypeContext* typeContext);
VASigCookie *GetVASigCookie(Signature vaSignature, const SigTypeContext* typeContext);
private:
static VASigCookie *GetVASigCookieWorker(Module* pDefiningModule, Module* pLoaderModule, MethodDesc* pMD, Signature vaSignature, const SigTypeContext* typeContext);
static VASigCookie *GetVASigCookieWorker(Module* pDefiningModule, Module* pLoaderModule, Signature vaSignature, const SigTypeContext* typeContext);

public:
#ifndef DACCESS_COMPILE
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/vm/cgensys.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ enum class CallerGCMode
// Non-CPU-specific helper functions called by the CPU-dependent code
extern "C" PCODE STDCALL PreStubWorker(TransitionBlock * pTransitionBlock, MethodDesc * pMD);

extern "C" void STDCALL VarargPInvokeStubWorker(TransitionBlock* pTransitionBlock, VASigCookie* pVASigCookie);
extern "C" void STDCALL VarargPInvokeStubWorker(TransitionBlock* pTransitionBlock, VASigCookie* pVASigCookie, MethodDesc* pMD);
extern "C" void STDCALL VarargPInvokeStub(void);
extern "C" void STDCALL VarargPInvokeStub_RetBuffArg(void);

Expand Down
18 changes: 11 additions & 7 deletions src/coreclr/vm/dllimport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ static bool IsSharedStubScenario(DWORD dwStubFlags)
return false;
}

if (SF_IsForwardPInvokeStub(dwStubFlags) && !SF_IsCALLIStub(dwStubFlags))
if (SF_IsForwardPInvokeStub(dwStubFlags) && !SF_IsCALLIStub(dwStubFlags) && !SF_IsVarArgStub(dwStubFlags))
{
return false;
}
Expand Down Expand Up @@ -857,9 +857,9 @@ class ILStubState : public StubState
// don't use the secret parameter.
}
else if (SF_IsForwardPInvokeStub(m_dwStubFlags)
&& !SF_IsCALLIStub(m_dwStubFlags))
&& !SF_IsCALLIStub(m_dwStubFlags) && !SF_IsVarArgStub(m_dwStubFlags))
{
// Forward stubs (i.e., PInvokes) don't use the secret parameter
// Regular PInvokes don't use the secret parameter
}
else
{
Expand Down Expand Up @@ -2168,6 +2168,13 @@ void PInvokeStubLinker::DoPInvoke(ILCodeStream *pcsEmit, DWORD dwStubFlags, Meth
pcsEmit->EmitSHR_UN();
#endif // TARGET_64BIT
}
else if (SF_IsVarArgStub(dwStubFlags)) // vararg P/Invoke
{
EmitLoadStubContext(pcsEmit, dwStubFlags);
pcsEmit->EmitLDC(offsetof(PInvokeMethodDesc, m_pPInvokeTarget));
pcsEmit->EmitADD();
pcsEmit->EmitLDIND_I();
}
else // forward P/Invoke
{
_ASSERTE(pMD->IsPInvoke());
Expand Down Expand Up @@ -6088,7 +6095,7 @@ static void GetILStubForCalli(VASigCookie* pVASigCookie, MethodDesc* pMD)
UNINSTALL_MANAGED_EXCEPTION_DISPATCHER;
}

EXTERN_C void STDCALL VarargPInvokeStubWorker(TransitionBlock* pTransitionBlock, VASigCookie* pVASigCookie)
EXTERN_C void STDCALL VarargPInvokeStubWorker(TransitionBlock* pTransitionBlock, VASigCookie *pVASigCookie, MethodDesc *pMD)
{
PreserveLastErrorHolder preserveLastError;

Expand All @@ -6103,9 +6110,6 @@ EXTERN_C void STDCALL VarargPInvokeStubWorker(TransitionBlock* pTransitionBlock,
Thread::ObjectRefFlush(CURRENT_THREAD);
#endif

MethodDesc* pMD = pVASigCookie->pMethodDesc;
_ASSERTE(pMD != NULL);

PrestubMethodFrame frame(pTransitionBlock, pMD);
PrestubMethodFrame * pFrame = &frame;

Expand Down
41 changes: 20 additions & 21 deletions src/coreclr/vm/finalizerthread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,26 @@ OBJECTREF FinalizerThread::GetNextFinalizableObject()
if (fQuitFinalizer)
return NULL;

#ifdef _DEBUG
if (g_pConfig->GetGCStressLevel() > 1)
{
// Throttle finalizing to one item per msec, or so, when running GC stress.
// This is to prevent cases where finalizers rearm themselves and
// do allocations or whatever else that triggers GC under stress.
// As a result couple of such things can occupy finalizer loop continuously
// while rearming and finalizing the same objects, which adds little
// to the coverage, but makes everything else move slower.
// NOTE: under GC stress most allocations of finalizable objects
// would trigger a GC, thus 1 item/msec should not be too slow for
// regular not re-arming finalizables.
GetFinalizerThread()->m_GCOnTransitionsOK = FALSE;
GetFinalizerThread()->EnablePreemptiveGC();
ClrSleepEx(1, false);
GetFinalizerThread()->DisablePreemptiveGC();
GetFinalizerThread()->m_GCOnTransitionsOK = TRUE;
}
#endif //_DEBUG

OBJECTREF obj = ObjectToOBJECTREF(GCHeapUtilities::GetGCHeap()->GetNextFinalizable());
if (obj == NULL)
return NULL;
Expand Down Expand Up @@ -432,27 +452,6 @@ VOID FinalizerThread::FinalizerThreadWorker(void *args)

GetFinalizerThread()->DisablePreemptiveGC();

#ifdef _DEBUG
// <TODO> workaround. make finalization very lazy for gcstress 3 or 4.
// only do finalization if the system is quiescent</TODO>
if (g_pConfig->GetGCStressLevel() > 1)
{
size_t last_gc_count;
DWORD dwSwitchCount = 0;

do
{
last_gc_count = GCHeapUtilities::GetGCHeap()->CollectionCount(0);
GetFinalizerThread()->m_GCOnTransitionsOK = FALSE;
GetFinalizerThread()->EnablePreemptiveGC();
__SwitchToThread (0, ++dwSwitchCount);
GetFinalizerThread()->DisablePreemptiveGC();
// If no GCs happened, then we assume we are quiescent
GetFinalizerThread()->m_GCOnTransitionsOK = TRUE;
} while (GCHeapUtilities::GetGCHeap()->CollectionCount(0) - last_gc_count > 0);
}
#endif //_DEBUG

// we might want to do some extra work on the finalizer thread
// check and do it
if (HaveExtraWorkForFinalizer())
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/vm/i386/asmhelpers.S
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ LOCAL_LABEL(GoCallVarargWorker):
// save pMD
push eax

push eax // pMD
push dword ptr [esi + 4*7] // pVaSigCookie
push esi // pTransitionBlock

Expand Down Expand Up @@ -1087,4 +1088,4 @@ LEAF_ENTRY IL_Rethrow, _TEXT

STUB_EPILOG
ret 4
LEAF_END IL_Rethrow
LEAF_END IL_Rethrow
5 changes: 3 additions & 2 deletions src/coreclr/vm/i386/asmhelpers.asm
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ endif ; FEATURE_EH_FUNCLETS
EXTERN __alloca_probe:PROC
EXTERN _PInvokeImportWorker@4:PROC

EXTERN _VarargPInvokeStubWorker@8:PROC
EXTERN _VarargPInvokeStubWorker@12:PROC
EXTERN _GenericPInvokeCalliStubWorker@12:PROC

EXTERN _PreStubWorker@8:PROC
Expand Down Expand Up @@ -930,10 +930,11 @@ GoCallVarargWorker:
; save pMD
push eax

push eax ; pMD
push dword ptr [esi + 4*7] ; pVaSigCookie
push esi ; pTransitionBlock

call _VarargPInvokeStubWorker@8
call _VarargPInvokeStubWorker@12

; restore pMD
pop eax
Expand Down
22 changes: 16 additions & 6 deletions src/coreclr/vm/ilstubcache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,12 @@ namespace

switch (type)
{
case DynamicMethodDesc::StubCLRToNativeInterop: return "IL_STUB_PInvoke";
case DynamicMethodDesc::StubPInvoke:
case DynamicMethodDesc::StubPInvokeDelegate:
case DynamicMethodDesc::StubPInvokeCalli:
case DynamicMethodDesc::StubPInvokeVarArg: return "IL_STUB_PInvoke";
case DynamicMethodDesc::StubReversePInvoke: return "IL_STUB_ReversePInvoke";
case DynamicMethodDesc::StubCLRToCOMInterop: return "IL_STUB_CLRtoCOM";
case DynamicMethodDesc::StubNativeToCLRInterop: return "IL_STUB_ReversePInvoke";
case DynamicMethodDesc::StubCOMToCLRInterop: return "IL_STUB_COMtoCLR";
case DynamicMethodDesc::StubStructMarshalInterop: return "IL_STUB_StructMarshal";
case DynamicMethodDesc::StubArrayOp: return "IL_STUB_Array";
Expand Down Expand Up @@ -304,19 +307,26 @@ MethodDesc* ILStubCache::CreateNewMethodDesc(LoaderHeap* pCreationHeap, MethodTa
// mark certain types of stub MDs with random flags so ILStubManager recognizes them
if (SF_IsReverseStub(dwStubFlags))
{
pMD->SetILStubType(DynamicMethodDesc::StubNativeToCLRInterop);
pMD->SetILStubType(DynamicMethodDesc::StubReversePInvoke);
}
else
{
if (SF_IsDelegateStub(dwStubFlags))
{
pMD->SetFlags(DynamicMethodDesc::FlagIsDelegate);
pMD->SetILStubType(DynamicMethodDesc::StubPInvokeDelegate);
}
else if (SF_IsCALLIStub(dwStubFlags))
{
pMD->SetFlags(DynamicMethodDesc::FlagIsCALLI);
pMD->SetILStubType(DynamicMethodDesc::StubPInvokeCalli);
}
else if (SF_IsVarArgStub(dwStubFlags))
{
pMD->SetILStubType(DynamicMethodDesc::StubPInvokeVarArg);
}
else
{
pMD->SetILStubType(DynamicMethodDesc::StubPInvoke);
}
pMD->SetILStubType(DynamicMethodDesc::StubCLRToNativeInterop);
}
}

Expand Down
8 changes: 1 addition & 7 deletions src/coreclr/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6166,13 +6166,7 @@ CORINFO_VARARGS_HANDLE CEEInfo::getVarArgsHandle(CORINFO_SIG_INFO *sig,
Instantiation methodInst = Instantiation((TypeHandle*) sig->sigInst.methInst, sig->sigInst.methInstCount);
SigTypeContext typeContext = SigTypeContext(classInst, methodInst);

MethodDesc* pMD = GetMethod(methHnd);
if (pMD != NULL && !pMD->IsPInvoke())
{
pMD = NULL;
}

result = CORINFO_VARARGS_HANDLE(module->GetVASigCookie(Signature(sig->pSig, sig->cbSig), pMD, &typeContext));
result = CORINFO_VARARGS_HANDLE(module->GetVASigCookie(Signature(sig->pSig, sig->cbSig), &typeContext));

EE_TO_JIT_TRANSITION();

Expand Down
10 changes: 8 additions & 2 deletions src/coreclr/vm/method.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2462,14 +2462,20 @@ MethodImpl *MethodDesc::GetMethodImpl()
#ifndef DACCESS_COMPILE

//*******************************************************************************
BOOL MethodDesc::RequiresMDContextArg() const
BOOL MethodDesc::RequiresMDContextArg()
{
LIMITED_METHOD_CONTRACT;

// Interop marshaling is implemented using shared stubs
if (IsCLRToCOMCall())
return TRUE;

// Interop marshalling of vararg needs MethodDesc calling convention
// to support ldftn <PInvoke method with varargs>. It is not possible
// to smugle the MethodDesc* via vararg cookie in this case.
if (IsPInvoke() && IsVarArg())
return TRUE;

return FALSE;
}

Expand Down Expand Up @@ -3497,7 +3503,7 @@ BOOL MethodDesc::HasUnmanagedCallersOnlyAttribute()
{
// Stubs generated for being called from native code are equivalent to
// managed methods marked with UnmanagedCallersOnly.
return AsDynamicMethodDesc()->GetILStubType() == DynamicMethodDesc::StubNativeToCLRInterop;
return AsDynamicMethodDesc()->GetILStubType() == DynamicMethodDesc::StubReversePInvoke;
}

HRESULT hr = GetCustomAttribute(
Expand Down
Loading
Loading