@@ -374,7 +374,7 @@ VOID StubLinkerCPU::X64EmitMovXmmXmm(X86Reg destXmmreg, X86Reg srcXmmReg)
374374 Emit8 (REX_PREFIX_BASE | rex);
375375
376376 Emit16 (0x280F );
377- Emit8 (static_cast <UINT8>(0300 | (destXmmreg << 3 ) | srcXmmReg));
377+ Emit8 (static_cast <UINT8>(0300 | (destXmmreg << 3 ) | srcXmmReg));
378378}
379379
380380// ---------------------------------------------------------------
@@ -852,7 +852,7 @@ static const X86Reg c_argRegs[] = {
852852// and pass it as an extra argument. Thus this stub generator really covers both
853853// - Unboxing, non-instantiating stubs
854854// - Unboxing, method-table-instantiating stubs
855- VOID StubLinkerCPU::EmitUnboxMethodStub (MethodDesc* pUnboxMD)
855+ bool StubLinkerCPU::EmitUnboxMethodStub (MethodDesc* pUnboxMD)
856856{
857857 CONTRACTL
858858 {
@@ -861,25 +861,96 @@ VOID StubLinkerCPU::EmitUnboxMethodStub(MethodDesc* pUnboxMD)
861861 }
862862 CONTRACTL_END;
863863
864- #ifdef FEATURE_INSTANTIATINGSTUB_AS_IL
865- _ASSERTE (!pUnboxMD->RequiresInstMethodTableArg ());
866- #else
867864 if (pUnboxMD->RequiresInstMethodTableArg ())
868865 {
869- EmitInstantiatingMethodStub (pUnboxMD, NULL );
870- return ;
866+ return EmitInstantiatingMethodStub (pUnboxMD, NULL );
871867 }
872- #endif
873868
874869 //
875870 // unboxing a value class simply means adding sizeof(void*) to the THIS pointer
876871 //
877872 X86EmitAddReg (THIS_kREG, sizeof (void *));
878873 EmitTailJumpToMethod (pUnboxMD);
874+ return true ;
875+ }
876+
877+ // The stub generated by this method passes an extra dictionary argument before jumping to
878+ // shared-instantiation generic code.
879+ //
880+ // pMD is either
881+ // * An InstantiatedMethodDesc for a generic method whose code is shared across instantiations.
882+ // In this case, the extra argument is the InstantiatedMethodDesc for the instantiation-specific stub itself.
883+ // or * A MethodDesc for a static method in a generic class whose code is shared across instantiations.
884+ // In this case, the extra argument is the MethodTable pointer of the instantiated type.
885+ // or * A MethodDesc for unboxing stub. In this case, the extra argument is null.
886+ bool StubLinkerCPU::EmitInstantiatingMethodStub (MethodDesc* pMD, void * extra)
887+ {
888+ CONTRACTL
889+ {
890+ STANDARD_VM_CHECK;
891+ PRECONDITION (pMD->RequiresInstArg ());
892+ }
893+ CONTRACTL_END;
894+
895+ #ifdef UNIX_X86_ABI
896+ // Unix x86 ABI requires stack alignment
897+ return false ;
898+ #else // UNIX_X86_ABI
899+ MetaSig msig (pMD);
900+ ArgIterator argit (&msig);
901+
902+ int paramTypeArgOffset = argit.GetParamTypeArgOffset ();
903+
904+ // It's on the stack
905+ if (TransitionBlock::IsStackArgumentOffset (paramTypeArgOffset))
906+ {
907+ // Pop return address into AX
908+ X86EmitPopReg (kEAX );
909+
910+ if (extra != NULL )
911+ {
912+ // Push extra dictionary argument
913+ X86EmitPushImmPtr (extra);
914+ }
915+ else
916+ {
917+ // Push the vtable pointer from "this"
918+ X86EmitIndexPush (THIS_kREG, 0 );
919+ }
920+
921+ // Put return address back
922+ X86EmitPushReg (kEAX );
923+ }
924+ // It's in a register
925+ else
926+ {
927+ X86Reg paramReg = GetX86ArgumentRegisterFromOffset (paramTypeArgOffset - TransitionBlock::GetOffsetOfArgumentRegisters ());
928+
929+ if (extra != NULL )
930+ {
931+ X86EmitRegLoad (paramReg, (UINT_PTR)extra);
932+ }
933+ else
934+ {
935+ // Just extract the vtable pointer from "this"
936+ X86EmitIndexRegLoad (paramReg, THIS_kREG);
937+ }
938+ }
939+
940+ if (extra == NULL )
941+ {
942+ // Unboxing stub case.
943+ X86EmitAddReg (THIS_kREG, sizeof (void *));
944+ }
945+
946+ EmitTailJumpToMethod (pMD);
947+
948+ return true ;
949+ #endif // UNIX_X86_ABI
879950}
880- #endif // TARGET_X86
951+ #endif // TARGET_X86
881952
882- #if defined(FEATURE_SHARE_GENERIC_CODE) && defined(TARGET_AMD64)
953+ #ifdef FEATURE_PORTABLE_SHUFFLE_THUNKS
883954VOID StubLinkerCPU::EmitComputedInstantiatingMethodStub (MethodDesc* pSharedMD, struct ShuffleEntry *pShuffleEntryArray, void * extraArg)
884955{
885956 STANDARD_VM_CONTRACT;
@@ -939,7 +1010,7 @@ VOID StubLinkerCPU::EmitComputedInstantiatingMethodStub(MethodDesc* pSharedMD, s
9391010 EmitTailJumpToMethod (pSharedMD);
9401011 SetTargetMethod (pSharedMD);
9411012}
942- #endif // defined(FEATURE_SHARE_GENERIC_CODE) && defined(TARGET_AMD64)
1013+ #endif // FEATURE_PORTABLE_SHUFFLE_THUNKS
9431014
9441015#ifdef TARGET_AMD64
9451016VOID StubLinkerCPU::EmitLoadMethodAddressIntoAX (MethodDesc *pMD)
@@ -984,76 +1055,6 @@ VOID StubLinkerCPU::EmitTailJumpToMethod(MethodDesc *pMD)
9841055#endif
9851056}
9861057
987- #if defined(FEATURE_SHARE_GENERIC_CODE) && !defined(FEATURE_INSTANTIATINGSTUB_AS_IL) && defined(TARGET_X86)
988- // The stub generated by this method passes an extra dictionary argument before jumping to
989- // shared-instantiation generic code.
990- //
991- // pMD is either
992- // * An InstantiatedMethodDesc for a generic method whose code is shared across instantiations.
993- // In this case, the extra argument is the InstantiatedMethodDesc for the instantiation-specific stub itself.
994- // or * A MethodDesc for a static method in a generic class whose code is shared across instantiations.
995- // In this case, the extra argument is the MethodTable pointer of the instantiated type.
996- // or * A MethodDesc for unboxing stub. In this case, the extra argument is null.
997- VOID StubLinkerCPU::EmitInstantiatingMethodStub (MethodDesc* pMD, void * extra)
998- {
999- CONTRACTL
1000- {
1001- STANDARD_VM_CHECK;
1002- PRECONDITION (pMD->RequiresInstArg ());
1003- }
1004- CONTRACTL_END;
1005-
1006- MetaSig msig (pMD);
1007- ArgIterator argit (&msig);
1008-
1009- int paramTypeArgOffset = argit.GetParamTypeArgOffset ();
1010-
1011- // It's on the stack
1012- if (TransitionBlock::IsStackArgumentOffset (paramTypeArgOffset))
1013- {
1014- // Pop return address into AX
1015- X86EmitPopReg (kEAX );
1016-
1017- if (extra != NULL )
1018- {
1019- // Push extra dictionary argument
1020- X86EmitPushImmPtr (extra);
1021- }
1022- else
1023- {
1024- // Push the vtable pointer from "this"
1025- X86EmitIndexPush (THIS_kREG, 0 );
1026- }
1027-
1028- // Put return address back
1029- X86EmitPushReg (kEAX );
1030- }
1031- // It's in a register
1032- else
1033- {
1034- X86Reg paramReg = GetX86ArgumentRegisterFromOffset (paramTypeArgOffset - TransitionBlock::GetOffsetOfArgumentRegisters ());
1035-
1036- if (extra != NULL )
1037- {
1038- X86EmitRegLoad (paramReg, (UINT_PTR)extra);
1039- }
1040- else
1041- {
1042- // Just extract the vtable pointer from "this"
1043- X86EmitIndexRegLoad (paramReg, THIS_kREG);
1044- }
1045- }
1046-
1047- if (extra == NULL )
1048- {
1049- // Unboxing stub case.
1050- X86EmitAddReg (THIS_kREG, sizeof (void *));
1051- }
1052-
1053- EmitTailJumpToMethod (pMD);
1054- }
1055- #endif // defined(FEATURE_SHARE_GENERIC_CODE) && !defined(FEATURE_INSTANTIATINGSTUB_AS_IL) && defined(TARGET_X86)
1056-
10571058VOID StubLinkerCPU::EmitShuffleThunk (ShuffleEntry *pShuffleEntryArray)
10581059{
10591060 STANDARD_VM_CONTRACT;
0 commit comments