Есть ли другие цели для компиляции IL

Я почти уверен, что одной из причин компиляции языка высокого уровня в некоторый байт-код является то, что виртуальная машина (Java или.NET) может генерировать машинно-зависимые нативные инструкции.

Это единственная причина? Если бы был какой-то способ (теоретически) генерировать машинно-зависимые инструкции перед выполнением программы (на разных компьютерах), будет ли какая-то цель компилироваться в байт-код? Можем ли мы просто скомпилировать машинный код и выполнить эти инструкции во время выполнения?

Чтобы прояснить это:

Если компилятор может просто генерировать совершенные инструкции для каждого компьютера, нужен ли IL?

3 ответа

Это упрощает компиляторы, потому что теперь мы можем ориентироваться только на один простой язык ассемблера - CIL - вместо четырех или пяти сложных.

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

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

Да, вы можете просто объединить несколько версий кода, по одной для каждой архитектуры, в один файл. Apple сделала это при переходе с PowerPC на Intel. Но получающиеся двоичные файлы часто бывают большими, что не очень хорошо работает для мобильных устройств.

Это увеличивает возможности для оптимизации. Любые оптимизации в компиляторе AOT влияют только на код, который он компилирует. Но оптимизация в JIT ускорит все программы.

JIT также имеет дополнительный источник информации - саму запущенную программу. Наблюдая за тем, как работает программа, JIT может ориентироваться на области кода, которые больше всего в ней нуждаются. Java HotSpot VM широко использует эту технику.

Я думаю, что есть и другие преимущества, но они очевидны.

Сборки CLR содержат IL/MSIL/CIL/ независимо от того, какой термин du jour сейчас используется. То есть сделать аппаратный код и операционную систему независимыми от скомпилированного кода. Пока целевая система поддерживает указанную версию CLR (а код не делает ничего смешного с P/Invoke и т. П.), Сборка должна выполняться в целевой системе. Когда сборка загружена, это JIT'd в машинный код (или вы могли бы ngen это, чтобы произвести специфичный для машины двоичный файл.

Причина наличия переносимых исполняемых файлов должна быть достаточно очевидной (см. Java).

Итак, вы задаетесь вопросом, зачем вообще использовать промежуточный язык?

Байт-код (IL, Java-байт-код, даже p-код VB6) предлагает несколько преимуществ. Это происходит из-за того, что байт-код не сразу компилируется и запускается на целевом процессоре. В случае IL, он как раз вовремя компилируется (JIT) в машинные инструкции по требованию.

Хотя это кажется по своей природе более сложным, чем просто компиляция в нативный код сразу, мы получаем множество полезных функций, таких как отражение, сборка мусора, безопасность типов и обработка исключений.

Вы можете получить эти замечательные управляемые функции без IL с помощью кода JITig C# для собственного кода, но тогда вам придется реализовать эти функции и написать JITer для каждого языка, который вы хотите (C++/CLI, VB.NET и т. Д.),

Кроме того, гораздо проще написать эти управляемые функции для машинного языка, а затем попытаться написать эти функции для языка, который в первую очередь предназначен для использования человеком.

Другие вопросы по тегам