Оптимизация реестра JIT-компилятора Java

Я смотрю на некоторый выходной собственный код компилятора Hotspot VM JIT. Метод, который я анализирую, использует множество локальных переменных. Я ожидал, что это повлияет на распределение регистров и вызовет загрузку/сохранение в память и из памяти. Однако я не вижу никаких инструкций по загрузке/сохранению в нативном коде. В связи с этим у меня есть 2 связанных вопроса.

  1. Я читал, что виртуальная машина Java имеет архитектуру на основе стека, в которой вместо использования регистров в качестве блокнота для вычислений используется стек. Таким образом, компилятор JIT также следует модели на основе стека или модели на основе регистров?

  2. Если JIT основан на регистрах, что делает JIT-компилятор при исчерпании регистров? Использует ли JIT-компилятор какой-либо другой метод для обработки этого случая, или это тот случай, когда я не вижу загрузки/сохранения в память и из памяти просто потому, что у меня недостаточно локальных переменных?


person nave    schedule 09.11.2015    source источник
comment
1) регистры 2) это трудно сказать, не зная, какой у вас процессор (мы можем догадаться) и сколько у вас локальных переменных   -  person Erwin Bolwidt    schedule 09.11.2015
comment
@ErwinBolwidt Хм ... Допустим, есть 32 регистра и более 50 локальных переменных? В основном в регистрах может храниться больше переменных, чем это. Чего я могу ожидать в этом случае? Должен ли я видеть распространение на память?   -  person nave    schedule 09.11.2015
comment
Ассемблер для Java VM, Jasmin, основан на стеке. На машинном уровне все еще есть регистры, но я думаю, что ассемблерный код для java — это уровень абстракции выше этого.   -  person Brady Sheehan    schedule 09.11.2015
comment
@BradySheehan Я не уверен, какая связь между Жасмин и вопросом.   -  person assylias    schedule 09.11.2015


Ответы (1)


Прежде всего, ваш вопрос зависит от используемой вами архитектуры JVM и ЦП.

Я предполагаю, что вы говорите о точке доступа.

Таким образом, компилятор JIT также следует модели на основе стека или модели на основе регистров?

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

Если JIT основан на регистрах, что делает JIT-компилятор при исчерпании регистров?

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

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

Взгляните на вики OpenJDK, там есть несколько страниц о распределении регистров, а также более ранние этапы оптимизации.

person the8472    schedule 09.11.2015
comment
поэтому просто чтобы убедиться, что я правильно понял это, 1) интерпретатор байт-кода использует (виртуальный) стек, но под этим виртуальным стеком он по-прежнему просто перемещает данные в регистры и из них? 2) Под разливом на стек вы имеете в виду память? Так что теоретически я должен увидеть кучу операций загрузки/сохранения в моем коде, если давление в регистрах увеличится до очень высокого уровня, верно? - person nave; 10.11.2015
comment
вы спрашивали о компиляторах JIT, а не об интерпретаторе. - person the8472; 10.11.2015
comment
Есть идеи по второму вопросу о влиянии регистрового давления? Меня действительно смущает то, что в выходном коде jit нет загрузки/сохранения. Итак, я просто хотел бы знать, должен ли я вообще ожидать увидеть какую-либо загрузку/сохранение? Спасибо за ссылку OpenJDK... проверю - person nave; 10.11.2015
comment
да, в конце концов вы увидите инструкции mov/push/pop - person the8472; 10.11.2015
comment
это при условии, что вы на x86. разные архитектуры, разные имена - person the8472; 10.11.2015
comment
HotSpot также может передавать данные в регистры xmm. push/pop не используется для разлива на x86. Предпочтение отдается методам с постоянной глубиной штабеля. - person Rickard; 04.01.2016