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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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