Могут ли встроенные собственные методы JVM?

Я написал небольшую статическую функцию JNI длиной всего 5 инструкций. Может ли JVM встроить этот код в тело метода, который его часто вызывает, или он всегда будет генерировать инструкцию call в методе JITed?

Например:

public class SomeClass {
    private static native long func();

    public void doLoop() {
        for(int i = 0; i < 0xFFFFFF; i++) {
             func();
        }
    }  

    public static void main(String[] args) {
        for(int i = 0; i < 0xFFFFFF; i++) {
            doLoop();
        }
    }
}

Может ли JVM встроить код func в doLoop, или он просто скомпилирует его как call func


person en4bz    schedule 22.09.2015    source источник
comment
если это всего лишь 5 инструкций, похоже, что вам действительно нужна встроенная сборка. Я думаю, что jnr может сделать это для x86, но документации немного, и это может быть экспериментальный материал.   -  person the8472    schedule 23.09.2015


Ответы (3)


Нет, JVM в принципе не может.

Реализация собственной функции представляет собой двоичный черный ящик; единственное, что знает JVM, - это адрес точки входа.

Собственный код не управляется виртуальной машиной и не может быть выполнен в контексте метода Java. JVM отличает потоки, находящиеся в состоянии 'in_java', от потоков, находящихся в состоянии 'in_native'. Например, собственные потоки не останавливаются в безопасной точке JVM просто потому, что JVM не может это сделать.

Кроме того, вызов собственного метода - не такая уж простая операция. Для всех аспектов вызова JNI требуется специальная процедура.

person apangin    schedule 22.09.2015

Было бы очень сложно сделать это с полной безопасностью, и у JVM есть масса возможностей, так что почти наверняка нет.

например рассмотрим функцию C, которая заканчивается на

return memcpy(dest, src, count);

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

mov   rdi, dest
mov   rsi, src
mov   edx, count
jmp   memcpy

Скорее, чем

...
call memcpy
ret

Таким образом, JVM должна делать больше, чем просто искать ret инструкции, когда выясняется, можно ли / как встроить часть собственного машинного кода.

Чтобы правильно встроить собственный метод, авторам JVM придется продумать все возможные варианты. Скорее всего, они просто не попытаются.

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


Лучшее предложение: создайте версию своей собственной функции, которая содержит нужный вам цикл, или, если это действительно 5 простых строк (не библиотечные функции или другие вещи, которые расширяются до большого количества asm), просто напишите ее на Java и позвольте JIT -компилятор беспокоиться об этом.

person Peter Cordes    schedule 22.09.2015

Буквально, нативные методы не могут быть встроены.

Однако JVM может заменить как методы Java, так и собственные методы встроенными. например многие из небезопасных методов рассматриваются как внутренние и не платят за JNI.

Таким образом, встроенные собственные методы могут быть эффективно встроены.

person Peter Lawrey    schedule 22.09.2015