Может ли Hotspot устранить проверки границ, когда диапазон индекса ограничен с помощью и?
Рассмотрим следующую функцию:
int foo(int[] indices) {
int[] lookup = new int[256];
fill(lookup); // populate values, not shown
int sum = 0;
for (int i : indices) {
sum += lookup[i & 0xFF]; // array access
}
return sum;
}
Может ли современный HotSpot устранить проверку границ на
lookup[i & 0xFF]
доступ? Этот доступ не может быть за пределами, поскольку
i & 0xFF
находится в диапазоне 0-255, а массив состоит из 256 элементов.
1 ответ
Да, это относительно простая оптимизация, которую HotSpot точно может сделать. Компилятор JIT выводит возможные диапазоны выражений и использует эту информацию для устранения избыточных проверок.
Мы можем убедиться в этом, распечатав ассемблерный код:
-XX:CompileCommand=print,Test::foo
...
0x0000020285b5e230: mov r10d,dword ptr [rcx+r8*4+10h] # load 'i' from indices array
0x0000020285b5e235: and r10d,0ffh # i = i & 0xff
0x0000020285b5e23c: mov r11,qword ptr [rsp+8h] # load 'lookup' into r11
0x0000020285b5e241: add eax,dword ptr [r11+r10*4+10h] # eax += r11[i]
Инструкций по сравнению между загрузкой нет.
i
а также
lookup[i & 0xff]
.