3434
3535#if !defined(DACCESS_COMPILE)
3636
37- #ifdef TARGET_X86
38- static PCODE g_pGenericComCallStubFields = NULL ;
39- static PCODE g_pGenericComCallStub = NULL ;
40- #endif
41-
4237UINT64 FieldCallWorker (Thread *pThread, ComMethodFrame* pFrame);
4338void FieldCallWorkerDebuggerWrapper (Thread *pThread, ComMethodFrame* pFrame);
4439void FieldCallWorkerBody (Thread *pThread, ComMethodFrame* pFrame);
4540
46- // ---------------------------------------------------------
47- // void SetupGenericStubs()
48- //
49- // Throws on failure
50- // ---------------------------------------------------------
51- static void SetupGenericStubs ()
52- {
53- STANDARD_VM_CONTRACT;
54-
55- #ifdef TARGET_X86
56- if ( (g_pGenericComCallStubFields != NULL ) && (g_pGenericComCallStub != NULL ))
57- return ;
58-
59- StubHolder<Stub> candidateCall, candidateFields;
60-
61- // Build each one. If we get a collision on replacement, favor the one that's
62- // already there. (We have lifetime issues with these, because they are used
63- // in every VTable without refcounting, so we don't want them to change
64- // underneath us).
65-
66- // Allocate all three before setting - if an error occurs, we'll free the
67- // memory via holder objects and throw.
68- candidateCall = ComCall::CreateGenericComCallStub (FALSE /* notField*/ );
69- candidateFields = ComCall::CreateGenericComCallStub (TRUE /* Field*/ );
70-
71- if (InterlockedCompareExchangeT<PCODE>(&g_pGenericComCallStub, candidateCall->GetEntryPoint (), 0 ) == 0 )
72- candidateCall.SuppressRelease ();
73-
74- if (InterlockedCompareExchangeT<PCODE>(&g_pGenericComCallStubFields, candidateFields->GetEntryPoint (), 0 ) == 0 )
75- candidateFields.SuppressRelease ();
76- #endif // TARGET_X86
77- }
78-
7941#ifdef PROFILING_SUPPORTED
8042// The sole purpose of this helper is to transition into preemptive mode
8143// and then call the profiler transition callbacks. We can't use the GCX_PREEMP
8244// in a function with SEH (such as COMToCLRWorkerBody()).
83- NOINLINE
45+ static NOINLINE
8446void ProfilerTransitionCallbackHelper (MethodDesc* pMD, Thread* pThread, COR_PRF_TRANSITION_REASON reason)
8547{
8648 CONTRACTL
@@ -108,7 +70,7 @@ void ProfilerTransitionCallbackHelper(MethodDesc* pMD, Thread* pThread, COR_PRF_
10870#endif // PROFILING_SUPPORTED
10971
11072// Disable when calling into managed code from a place that fails via HRESULT
111- extern " C " HRESULT STDCALL StubRareDisableHRWorker (Thread *pThread)
73+ static HRESULT StubRareDisableHRWorker (Thread *pThread)
11274{
11375 STATIC_CONTRACT_NOTHROW;
11476 STATIC_CONTRACT_GC_TRIGGERS;
@@ -241,7 +203,7 @@ inline static void InvokeStub(ComCallMethodDesc *pCMD, PCODE pManagedTarget, OBJ
241203#pragma optimize("t", on) // optimize for speed
242204#endif
243205
244- OBJECTREF COMToCLRGetObjectAndTarget_Delegate (ComCallWrapper * pWrap, PCODE * ppManagedTargetOut)
206+ static OBJECTREF COMToCLRGetObjectAndTarget_Delegate (ComCallWrapper * pWrap, PCODE * ppManagedTargetOut)
245207{
246208 CONTRACTL
247209 {
@@ -260,7 +222,7 @@ OBJECTREF COMToCLRGetObjectAndTarget_Delegate(ComCallWrapper * pWrap, PCODE * pp
260222 return pDelObj->GetTarget ();
261223}
262224
263- FORCEINLINE_NONDEBUG
225+ static FORCEINLINE_NONDEBUG
264226OBJECTREF COMToCLRGetObjectAndTarget_Virtual (ComCallWrapper * pWrap, MethodDesc * pRealMD, ComCallMethodDesc * pCMD, PCODE * ppManagedTargetOut)
265227{
266228 CONTRACTL
@@ -291,7 +253,7 @@ OBJECTREF COMToCLRGetObjectAndTarget_Virtual(ComCallWrapper * pWrap, MethodDesc
291253 return pObject;
292254}
293255
294- FORCEINLINE_NONDEBUG
256+ static FORCEINLINE_NONDEBUG
295257OBJECTREF COMToCLRGetObjectAndTarget_NonVirtual (ComCallWrapper * pWrap, MethodDesc * pRealMD, ComCallMethodDesc * pCMD, PCODE * ppManagedTargetOut)
296258{
297259 CONTRACTL
@@ -308,7 +270,7 @@ OBJECTREF COMToCLRGetObjectAndTarget_NonVirtual(ComCallWrapper * pWrap, MethodDe
308270 return pWrap->GetObjectRef ();
309271}
310272
311- FORCEINLINE_NONDEBUG
273+ static FORCEINLINE_NONDEBUG
312274void COMToCLRInvokeTarget (PCODE pManagedTarget, OBJECTREF pObject, ComCallMethodDesc * pCMD,
313275 ComMethodFrame * pFrame, Thread * pThread, UINT64* pRetValOut)
314276{
@@ -330,7 +292,7 @@ void COMToCLRInvokeTarget(PCODE pManagedTarget, OBJECTREF pObject, ComCallMethod
330292 InvokeStub (pCMD, pManagedTarget, pObject, pFrame, pThread, pRetValOut);
331293}
332294
333- NOINLINE
295+ static NOINLINE
334296void COMToCLRWorkerBody_Rare (Thread * pThread, ComMethodFrame * pFrame, ComCallWrapper * pWrap,
335297 MethodDesc * pRealMD, ComCallMethodDesc * pCMD, DWORD maskedFlags,
336298 UINT64 * pRetValOut)
@@ -381,7 +343,7 @@ void COMToCLRWorkerBody_Rare(Thread * pThread, ComMethodFrame * pFrame, ComCallW
381343
382344
383345// This is the factored out body of COMToCLRWorker.
384- FORCEINLINE_NONDEBUG
346+ static FORCEINLINE_NONDEBUG
385347void COMToCLRWorkerBody (
386348 Thread * pThread,
387349 ComMethodFrame * pFrame,
@@ -456,44 +418,30 @@ void COMToCLRWorkerBody(
456418}
457419
458420// ------------------------------------------------------------------
459- // UINT64 __stdcall COMToCLRWorker(Thread *pThread,
460- // ComMethodFrame* pFrame)
421+ // UINT64 __stdcall COMToCLRWorker(ComMethodFrame* pFrame)
461422// ------------------------------------------------------------------
462- extern " C" UINT64 __stdcall COMToCLRWorker (Thread *pThread, ComMethodFrame* pFrame)
423+ extern " C" UINT64 __stdcall COMToCLRWorker (ComMethodFrame* pFrame)
463424{
464425 CONTRACTL
465426 {
466427 NOTHROW; // Although CSE can be thrown
467428 GC_TRIGGERS;
468- #if defined(TARGET_X86)
469- MODE_COOPERATIVE; // X86 sets up COOP in stublinker-generated stub
470- #else
471429 // This contract is disabled because user code can illegally reenter here through no fault of the
472430 // CLR (i.e. it's a user code bug), so we shouldn't be popping ASSERT dialogs in those cases. Note
473431 // that this reentrancy check is already done by the stublinker-generated stub on x86, so it's OK
474432 // to leave the MODE_ contract enabled on x86.
475433 DISABLED (MODE_PREEMPTIVE);
476- #endif
477434 PRECONDITION (CheckPointer (pFrame));
478- PRECONDITION (CheckPointer (pThread, NULL_OK));
479435 }
480436 CONTRACTL_END;
481437
482438 UINT64 retVal = 0 ;
483439
484440 ComCallMethodDesc* pCMD = pFrame->GetComCallMethodDesc ();
485441
486- #if !defined(TARGET_X86)
487- //
488- // The following code is a transcription of the code that is generated by CreateGenericComCallStub. The
489- // idea is that we needn't really do this work either in static assembly code nor in dynamically
490- // generated code since the benefit/cost ratio is low. There are some minor differences in the below
491- // code, compared to x86.
492- // We must check each time at runtime here because we're using static code.
493- //
494442 HRESULT hr = S_OK;
495443
496- pThread = GetThreadNULLOk ();
444+ Thread* pThread = GetThreadNULLOk ();
497445 if (pThread == NULL )
498446 {
499447 pThread = SetupThreadNoThrow ();
@@ -528,22 +476,18 @@ extern "C" UINT64 __stdcall COMToCLRWorker(Thread *pThread, ComMethodFrame* pFra
528476 // Link frame into the chain.
529477 pFrame->Push (pThread);
530478
531- #endif // !TARGET_X86
532-
533479 _ASSERTE (pThread);
534480
535481 // At this point we should be in preemptive GC mode (regardless of if it happened
536482 // in the stub or in the worker).
537483 _ASSERTE (pThread->PreemptiveGCDisabled ());
538484
539485 {
540- #ifndef TARGET_X86
541486 if (pCMD->IsFieldCall ())
542487 {
543488 retVal = FieldCallWorker (pThread, pFrame);
544489 }
545490 else
546- #endif // !TARGET_X86
547491 {
548492 IUnknown **pip = (IUnknown **)pFrame->GetPointerToArguments ();
549493 IUnknown *pUnk = (IUnknown *)*pip;
@@ -555,12 +499,10 @@ extern "C" UINT64 __stdcall COMToCLRWorker(Thread *pThread, ComMethodFrame* pFra
555499 }
556500 }
557501
558- #ifndef TARGET_X86
559502 // Note: the EH subsystem will handle resetting the frame chain and setting
560503 // the correct GC mode on exception.
561504 pFrame->Pop (pThread);
562505 pThread->EnablePreemptiveGC ();
563- #endif
564506
565507 LOG ((LF_STUBS, LL_INFO1000000, " COMToCLRWorker leave\n " ));
566508
@@ -575,7 +517,6 @@ extern "C" UINT64 __stdcall COMToCLRWorker(Thread *pThread, ComMethodFrame* pFra
575517 }
576518 return retVal;
577519
578- #ifndef TARGET_X86
579520ErrorExit:
580521 if (pThread != NULL && pThread->PreemptiveGCDisabled ())
581522 pThread->EnablePreemptiveGC ();
@@ -604,7 +545,6 @@ extern "C" UINT64 __stdcall COMToCLRWorker(Thread *pThread, ComMethodFrame* pFra
604545 }
605546
606547 return retVal;
607- #endif // TARGET_X86
608548}
609549
610550#if defined(_MSC_VER) && !defined(_DEBUG)
@@ -1314,74 +1254,6 @@ void ComCall::PopulateComCallMethodDesc(ComCallMethodDesc *pCMD, DWORD *pdwStubF
13141254 *pdwStubFlags = dwStubFlags;
13151255}
13161256
1317- #ifdef TARGET_X86
1318- // ---------------------------------------------------------
1319- // Creates the generic ComCall stub.
1320- //
1321- // Throws in case of error.
1322- // ---------------------------------------------------------
1323- /* static*/
1324- Stub* ComCall::CreateGenericComCallStub (BOOL isFieldAccess)
1325- {
1326- CONTRACT (Stub*)
1327- {
1328- STANDARD_VM_CHECK;
1329- POSTCONDITION (CheckPointer (RETVAL));
1330- }
1331- CONTRACT_END;
1332-
1333- CPUSTUBLINKER sl;
1334- CPUSTUBLINKER *psl = &sl;
1335-
1336- // These new CodeLabels are allocated on a
1337- // "throwaway" heap. Do not worry about
1338- // deallocating them if one of the allocations
1339- // ends up throwing an OOM exception.
1340-
1341- CodeLabel* rgRareLabels[] = {
1342- psl->NewCodeLabel (),
1343- psl->NewCodeLabel ()
1344- };
1345-
1346-
1347- CodeLabel* rgRejoinLabels[] = {
1348- psl->NewCodeLabel (),
1349- psl->NewCodeLabel ()
1350- };
1351-
1352- // Pop ComCallMethodDesc* pushed by prestub
1353- psl->X86EmitPopReg (kEAX );
1354-
1355- // emit the initial prolog
1356- // NOTE: Don't profile field accesses yet.
1357- psl->EmitComMethodStubProlog (ComMethodFrame::GetMethodFrameVPtr (),
1358- rgRareLabels,
1359- rgRejoinLabels,
1360- !isFieldAccess);
1361-
1362- // ******* NOTE ********
1363- // We now have a frame on the stack that is unproctected by an SEH handler. If we take an
1364- // SO before getting into the target, we'll have a corrupted frame chain. In EmitComMethodStubProlog
1365- // we probe-by-touch for 4 DWORDS to ensure that can set up the SEH handler before linking in
1366- // the frame. So long as we don't use more than that here (currently 3 DWORDS - for the two args plus
1367- // the return address, we are OK. If we decrement ESP more than an additional DWORD here before
1368- // calling the target, we will need to probe farther.
1369-
1370- psl->X86EmitPushReg (kESI ); // push frame as an ARG
1371- psl->X86EmitPushReg (kEBX ); // push ebx (push current thread as ARG)
1372- LPVOID pTarget = isFieldAccess ? (LPVOID)FieldCallWorker : (LPVOID)COMToCLRWorker;
1373- psl->X86EmitCall (psl->NewExternalCodeLabel (pTarget), 8 );
1374-
1375- // emit the epilog
1376- // NOTE: Don't profile field accesses yet.
1377- psl->EmitSharedComMethodStubEpilog (ComMethodFrame::GetMethodFrameVPtr (), rgRareLabels, rgRejoinLabels,
1378- ComCallMethodDesc::GetOffsetOfReturnThunk (), !isFieldAccess);
1379-
1380- // Process-wide stubs that never unload.
1381- RETURN (psl->Link (SystemDomain::GetGlobalLoaderAllocator ()->GetStubHeap ()));
1382- }
1383- #endif // TARGET_X86
1384-
13851257// ---------------------------------------------------------
13861258// Either creates or retrieves from the cache, a stub to
13871259// invoke ComCall methods. Each call refcounts the returned stub.
@@ -1399,8 +1271,6 @@ PCODE ComCall::GetComCallMethodStub(ComCallMethodDesc *pCMD)
13991271 }
14001272 CONTRACT_END;
14011273
1402- SetupGenericStubs ();
1403-
14041274 // The stub style we return is to a single generic stub for method calls and to
14051275 // a single generic stub for field accesses. The generic stub parameterizes
14061276 // its behavior based on the ComCallMethodDesc.
@@ -1419,13 +1289,7 @@ PCODE ComCall::GetComCallMethodStub(ComCallMethodDesc *pCMD)
14191289 ExecutableWriterHolder<PCODE> addrOfILStubWriterHolder (pCMD->GetAddrOfILStubField (), sizeof (PCODE));
14201290 InterlockedCompareExchangeT<PCODE>(addrOfILStubWriterHolder.GetRW (), pTempILStub, NULL );
14211291
1422- #ifdef TARGET_X86
1423- // Finally, we need to build a stub that represents the entire call. This
1424- // is always generic.
1425- RETURN (pCMD->IsFieldCall () ? g_pGenericComCallStubFields : g_pGenericComCallStub);
1426- #else
14271292 RETURN GetEEFuncEntryPoint (GenericComCallStub);
1428- #endif
14291293}
14301294
14311295// Called both at run-time and by NGEN - generates method stub.
0 commit comments