Что должна делать JVM при вызове нативного метода?

Каковы обычные шаги, которые среда выполнения JVM должна выполнять при вызове метода Java, объявленного как native?

Как в HotSpot 1.8.0 JVM реализован вызов функции JNI? Какие этапы проверки выполняются (например, необработанные исключения после возврата?), Какая бухгалтерия должна выполнять JVM (например, локальный справочный реестр?) И куда направляется элемент управления после вызова нативного метода Java? Я также был бы признателен, если бы кто-то мог предоставить точку входа или важные методы из нативного кода HotSpot 1.8.0.

Отказ от ответственности: я знаю, что я могу читать код самостоятельно, но предварительное объяснение помогает быстро найти свой путь через код. Кроме того, я нашел этот вопрос полезным для поиска в Google.;)

1 ответ

Решение

Вызов метода JNI из Java довольно дорог по сравнению с простым вызовом функции Си. HotSpot обычно выполняет большинство следующих шагов, чтобы вызвать метод JNI:

  1. Создайте кадр стека.
  2. Переместите аргументы в соответствующий регистр или расположите в стеке в соответствии с ABI.
  3. Обернуть ссылки на объекты в дескрипторы JNI.
  4. получать JNIEnv* а также jclass для статических методов и передать их в качестве дополнительных аргументов.
  5. Проверьте, должен ли позвонить method_entry функция трассировки.
  6. Блокировка монитора объекта, если метод synchronized,
  7. Проверьте, связана ли уже нативная функция. Функция поиска и связывания выполняется лениво.
  8. Переключить нить с in_java в in_native государство.
  9. Вызов родной функции
  10. Проверьте, нужна ли безопасная точка.
  11. Вернуться нить в in_java государство.
  12. Разблокируйте монитор, если заблокирован.
  13. Поставить в известность method_exit,
  14. Разверните результат объекта и сбросьте блок JNI-маркеров.
  15. Обрабатывать JNI-исключения.
  16. Удалите кадр стека.

Исходный код этой процедуры можно найти по адресу SharedRuntime:: generate_native_wrapper.

Как видите, накладные расходы могут быть значительными. Но во многих случаях большинство вышеперечисленных шагов не являются необходимыми. Например, если нативный метод просто выполняет некоторое кодирование / декодирование в байтовом массиве и не выдает никаких исключений, ни он вызывает другие функции JNI. Для этих случаев HotSpot имеет нестандартное (и не известное) соглашение, называемое Critical Nativesобсуждается здесь.

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