Компиляция MSIL в машинный код

Обновлен: Ноябрь 2007

Перед запуском промежуточного языка MSIL его необходимо скомпилировать в машинный код для среды CLR для архитектуры конечного компьютера. Платформа .NET Framework предоставляет два способа такого преобразования:

Компиляция с помощью JIT-компилятора

При JIT-компиляции язык MSIL преобразуется в машинный код во время выполнения приложения по требованию, когда загружается и исполняется содержимое сборки. Поскольку среда CLR предоставляет JIT-компилятор для каждой поддерживаемой архитектуры процессора, разработчики могут создавать набор сборок MSIL, которые могут компилироваться с помощью JIT-компилятора и выполняться на разных компьютерах с разной архитектурой. Однако если в управляемом коде вызываются специфические для платформы внутренние API-интерфейсы или библиотеки классов, он будет выполняться только в соответствующей операционной системе.

При JIT-компиляции принимается во внимание, что некоторый код может не вызываться во время выполнения. Вместо того, чтобы расходовать время и память на преобразование всего кода MSIL из переносимого исполняемого (PE) файла в машинный код, код MSIL преобразуется в машинный код по мере необходимости при выполнении и полученный машинный код сохраняется в памяти для доступа при дальнейших вызовах в контексте процесса. Загрузчик создает и присоединяет заглушки к каждому методу в типе, когда тип загружается и инициализируется. При первом вызове метода заглушка передает управление JIT-компилятору, который преобразует MSIL для этого метода в машинный код и заменяет заглушку на созданный машинный код. Последующие вызовы метода, скомпилированного с помощью JIT-компилятора, будут направляться непосредственно к машинному коду.

Создание кода во время установки с помощью NGen.exe

Поскольку JIT-компилятор преобразует код MSIL сборки в машинный код при вызове отдельных методов, определенных в этой сборке, то это обязательно приводит к снижению производительности во время выполнения. В большинстве случаев снижение производительности допустимо. Что более важно, код, созданный JIT-компилятором, будет привязан к процессу, вызвавшему компиляцию. Его нельзя сделать общим для нескольких процессов. Чтобы созданный код можно было использовать в нескольких вызовах приложения или в нескольких процессах, которые совместно используют набор сборок, среда CLR предоставляет режим предварительной компиляции. В таком режиме компиляции для преобразования сборок MSIL в машинный код в стиле JIT-компилятора используется программа Генератор образов в машинном коде (Ngen.exe). Однако, работа Ngen.exe отличается от JIT-компилятора в трех аспектах.

  • Она выполняет преобразование из языка MSIL в машинный код перед выполнением приложения, а не во время.

  • Она компилирует всю сборку, а не отдельные методы.

  • Она сохраняет созданный код в кэше образа машинного кода в виде файла на диске.

Проверка кода

В процессе компиляции кода MSIL в машинный код он должен пройти проверку, только если администратор не установил политику безопасности, разрешающую пропустить проверку. Во время проверки код MSIL и метаданные проверяются, чтобы узнать, является ли код строго типизированным. Это означает, что код может иметь доступ только к авторизованным расположениям в памяти. Строгая типизация помогает изолировать объекты друг от друга и поэтому помогает защитить их от непредумышленного или злонамеренного повреждения. Она также гарантирует надежное применение условий безопасности для кода.

Среда выполнения основывается на истинности следующих утверждений для поддающегося проверке строго типизированного кода:

  • ссылка на тип строго совместима с адресуемым типом;

  • для объекта вызываются только правильно определенные операции;

  • удостоверения являются подлинными.

В процессе проверки кода MSIL делается попытка подтвердить, что код может получать доступ к расположениям в памяти и вызывать методы только через правильно определенные типы. Например, код не должен разрешать доступ к полям объекта так, чтобы можно было выходить за границы расположения в памяти. Кроме того, проверка определяет, правильно ли был создан код MSIL, поскольку неверный код MSIL может приводить к нарушению правил строгой типизации. В процессе проверки передается правильно определенный строго типизированный код. Однако иногда строго типизированный код может не пройти проверку из-за ограничений процесса проверки, а некоторые языки по своей структуре не позволяют создавать поддающийся проверке строго типизированный код. Если в соответствии с политикой безопасности использование строго типизированного кода является обязательным и код не проходит проверку, то при выполнении кода создается исключение.

См. также

Основные понятия

Процесс управляемого выполнения