Какой регистр раньше передавал JNIEnv для методов JNI в солярисе /linux?

Мы знаем следующий разговор о вызовах в этой теме: Каковы соглашения о вызовах для кода Java на платформе Linux? А также это объяснило, что

"Вы можете заметить, что соглашение о вызовах Java похоже на соглашение о вызовах C, но смещено на один аргумент вправо. Это сделано намеренно, чтобы избежать дополнительной перестановки регистров при вызове методов JNI (вы знаете, у методов JNI есть дополнительный аргумент JNIEnv*, добавленный к параметрам метода) ".

Так значит ли это, когда мы вызывали функцию JNI, такую ​​как jclass FindClass(JNIEnv *env, const char *name); тогда значение JNIEnv env будет передано в rdi, а имя передано rsi, однако, когда мы вызвали общий не Java-метод Java, такой как void printClassName(int Integer1,Object obj), тогда Integer1 будет передан rsi, а obj был передается в стек, поскольку это не целое число, это правильно?

Пожалуйста, поправьте меня, если я ошибаюсь.

|-------------------------------------------------------|
| c_rarg0   c_rarg1  c_rarg2 c_rarg3 c_rarg4 c_rarg5    |
|-------------------------------------------------------|
| rcx       rdx      r8      r9      rdi*    rsi*       | windows (* not a c_rarg)
| rdi       rsi      rdx     rcx     r8      r9         | solaris/linux
|-------------------------------------------------------|
| j_rarg5   j_rarg0  j_rarg1 j_rarg2 j_rarg3 j_rarg4    |
|-------------------------------------------------------|

1 ответ

Решение

Данная таблица описывает, как VM вызывает методы Java.

Например, при вызове метода Java void print(int i, Object o) это проходит

  • this в RSI (j_rarg0)
  • i в RDX (j_rarg1)
  • o в RCX (j_rarg2) - ссылки на объекты также передаются в регистрах общего назначения.

Соглашение о вызовах одинаково, независимо от того, объявлен ли метод native или нет. Для нативного метода будет нативная реализация

void Java_ClassName_print(JNIEnv* env, jobject this, jint i, jobject o);

Эта нативная функция соответствует стандартной платформе ABI, то есть

  • env идет к RDI (c_rarg0)
  • this в RSI (c_rarg1)
  • i в RDX (c_rarg2)
  • o в RCX (c_rarg3)

Обратите внимание, что из-за мудрого выбора j_rargs против c_rargsпараметры остались в тех же регистрах.


JNI функционирует как FindClass не имеет ничего общего с соглашением о вызовах виртуальных машин. Они должны следовать за платформой ABI. Поэтому первый аргумент JNIEnv* передается в RDI в Linux/x64.

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