Почему для инструкций JVM * const_n определен только такой диапазон констант? - PullRequest
0 голосов
/ 24 октября 2018

Согласно спецификации JVM существует несколько инструкций, оптимизированных для работы с определенным набором констант.Кто-нибудь может объяснить, почему определяется только этот диапазон констант?

  • iconst_n: push целочисленная константа n, 0 ≤ n ≤ 5
  • lconst_n: push длинная константаn, 0 ≤ n ≤ 1
  • fconst_n: константа push-плавающего n, 0 ≤ n ≤ 2
  • dconst_n: константа push-двойного n, 0 ≤ n ≤ 1

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

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Намерение было упомянуто явно, например, в JVMS, §3.2.Использование констант, локальных переменных и управляющих конструкций :

Виртуальная машина Java часто использует вероятность определенных операндов (int константы -1 , 0 , 1 , 2 , 3 , 4 и 5 в случаеинструкции iconst_ ), сделав эти операнды неявными в коде операции.Поскольку инструкция iconst_0 знает, что она собирается выдвинуть int 0, iconst_0 , ей не нужно хранить операнд, чтобы сообщить ему, какое значение выдавать, и при этом не нужнополучить или расшифровать операнд.Компиляция нажатия 0 как bipush 0 была бы правильной, но это сделало бы скомпилированный код на spin ¹ на один байт длиннее.Простая виртуальная машина также потратила бы дополнительное время на выборку и декодирование явного операнда каждый раз в цикле.Использование неявных операндов делает скомпилированный код более компактным и эффективным.

¹ это пример обсуждаемого кода, то есть цикл for от нуля до ста

Это не единственная оптимизациятакого рода, например, существуют специальные инструкции для доступа к первым локальным переменным в кадре стека.

Эти операции также имеют специальную поддержку в наборе команд.В spin значения передаются в и из локальных переменных с помощью инструкций istore_1 и iload_1 , каждая из которых неявно работает с локальной переменной 1 .

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

Оптимизация для индексов малых переменных оправдана, так как эти индексыприсваивается в порядке возрастания this (если не static), за которыми следуют параметры, за которыми следуют первые локальные переменные.В принципе, компилятор мог бы оптимизировать это дальше, переупорядочив переменные так, чтобы они имели наиболее часто используемые переменные с оптимизированными индексами, но на практике этого не происходит.

Для оптимизирующей JVM, такой как HotSpot, наверняка естьнет никакого преимущества в производительности при использовании этих инструкций, но они по-прежнему делают байт-код немного короче.

0 голосов
/ 24 октября 2018

Может кто-нибудь объяснить, почему определяется только этот диапазон констант?

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

Я предполагаю, что это связано с частотой использования этих констант,

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

...