CLR / Fastcall: как типы больших значений внутренне передаются вызываемым функциям? - PullRequest
3 голосов
/ 07 ноября 2011

Просто из любопытства: типы значений обычно копируются, и JIT-компилятор, похоже, использует соглашение вызовов Fastcall от Microsoft при вызове метода.Это помещает первые несколько аргументов в регистры для быстрого доступа.Но как типы больших значений (т.е. больше, чем размер регистра или ширина стека) передаются вызываемой функции?


В этом отрывке книги говорится, что:

В коде CLR используется соглашение о вызовах fastcall для Windows.Это позволяет вызывающей стороне предоставить первые два аргумента (включая this в случае методов экземпляра) в регистрах ECX и EDX аппарата.

1 Ответ

4 голосов
/ 07 ноября 2011

Это __clrcall, действительно похоже на __fastcall. Два регистра используются джиттером x86 (ecx, edx). Четыре регистра по джиттеру x64 (ecx, edx, r8, r9), такие же, как и в собственном соглашении о вызовах x64. Типы больших значений, такие как десятичные и большие структуры, передаются путем резервирования пространства в стеке вызывающего, копирования значения в него и передачи указателя на эту копию. Вызываемый объект копирует его снова в свой собственный кадр стека.

Это дорого, поэтому Microsoft рекомендует, чтобы структура не превышала 16 байт. Преднамеренная передача структуры с помощью ref во избежание копирования - это обходной путь, обычно также выполняемый в C и C ++. За счет разыменования дополнительного указателя.

...