Может ли 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].

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