Разница между анализируемой инструкцией байт-кода и машинным языком? - PullRequest
3 голосов
/ 19 мая 2009

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

Вопрос об этом абзаце таков: после обработки байт-кода В чем разница между анализируемой инструкцией и машинным языком (или машинным кодом)?

Ответы [ 4 ]

7 голосов
/ 19 мая 2009

JIT отличается от интерпретатора байтового кода.

Рассмотрим следующую функцию C:

int sum() {
   return 5 + 6;
}

Это будет скомпилировано непосредственно машинным кодом. Точные инструкции, скажем, для процессоров x86 и ARM будут другими.

Если бы мы написали базовый интерпретатор байт-кода, он мог бы выглядеть примерно так:

for(;;) {
   switch(*currentInstruction++) {
   case OP_PUSHINT:
      *stack++ = nextInt(currentInstruction);
      break;
   case OP_ADD:
      --stack;
      stack[-1].add(*stack);
      break;
   case OP_RETURN:
      return stack[-1];
   }
}

Это может интерпретировать следующий набор инструкций:

OP_PUSHINT (5)
OP_PUSHINT (6)
OP_ADD
OP_RETURN

Если вы скомпилировали интерпретатор байт-кода как на x86, так и на ARM, то вы сможете запустить один и тот же байт-код без дальнейшей перезаписи интерпретатора.

Если вы написали JIT-компилятор, вам нужно будет выдавать специфические для процессора инструкции (машинный код) для каждого поддерживаемого процессора, тогда как интерпретатор байт-кода полагается на компилятор C ++ для выработки специфических для процессора инструкций.

2 голосов
/ 20 мая 2009

В интерпретаторе байт-кода формат инструкции обычно предназначен для очень быстрого "разбора" с использованием операторов сдвига и маски. Интерпретатор, после «синтаксического анализа» (я предпочитаю «декодирование») инструкции, немедленно обновляет состояние виртуальной машины и затем начинает декодировать следующую инструкцию. Таким образом, после обработки байт-кода в интерпретаторе остаток не остается.

В JIT-компиляторе байты обрабатываются в единицах, превышающих одну инструкцию. Минимальный блок - это базовый блок, но современные JIT преобразуют большие пути в машинный код. Это шаг перевода , а вывод шага перевода представляет собой машинный код. Исходный байт-код может оставаться в памяти, но он не используется для реализации - поэтому нет никакой разницы. (Хотя до сих пор типично, что машинный код для виртуальной машины JITted отличается от машинного кода, генерируемого компилятором собственного кода.)

1 голос
/ 19 мая 2009

В конечном итоге все сводится к машинным инструкциям.

  1. Native App - содержит машинные инструкции, которые выполняются напрямую.
  2. JIT App - байт-код компилируется в машинные инструкции и выполняется.
  3. Переведенное приложение - байт-код транслируется виртуальной машиной, которая является собственным приложением.

Как вы можете сказать, с # 1 у вас меньше всего накладных расходов, а с # 3 у вас больше всего накладных расходов. Таким образом, производительность должна быть самой высокой на # 1 и такой же высокой на # 2 после начальной загрузки компиляции.

1 голос
/ 19 мая 2009

Нет никакой разницы - JIT-компилятор сделан именно для этого - он генерирует машинный код, который выполняется на оборудовании.

...