@@ -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