Какой регистр раньше передавал 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.