2017-02-18 45 views
0

Мы знаем следующее призывающих бесед эта тема, What's the calling convention for the Java code in Linux platform? А также пояснила, что, который используется для передачи методов JNIEnv для JNI в Solaris/linux?

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

Значит ли это, когда мы вызывали функцию JNI, такую ​​как jclass FindClass (JNIEnv * env, const char * name); то значение JNIEnv env будет передано в rdi, а имя передано в rsi, однако, когда мы вызываем общий метод JNI 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 | 
|-------------------------------------------------------| 
+0

В чем проблема, которую вы пытаетесь решить? –

+1

Изучить знания отладки. –

ответ

0

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

E.g. при вызове метода 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); 

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

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

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


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

+0

Очень ценю за ваше столь четкое объяснение, вы так любезны.Однако, как вы когда-либо говорили, «до 6 первых целых аргументов передаются в регистры: rsi, rdx, rcx, r8, r9, rdi» в http://stackoverflow.com/questions/41693637/whats-the-calling-convention -for-the-java-code-in-linux-platform, поскольку Object o является ссылкой на объект не целочисленным, почему он также передается в RCX? Статья openjdk также выражает то же значение, что и шесть Integer ... https: //wiki.openjdk.java.net/display/HotSpot/CallingSequences, я думаю, что у меня есть кое-что непонимание. –

+0

@Jacky В приведенной выше цитате я использовал «целое число» как противоположность «с плавающей запятой». Ссылка на объект (адрес/указатель/сжатый указатель или что-то еще) также является значением, которое подходит для регистров общего назначения (целочисленных). – apangin

+0

много спасибо за прекрасное объяснение. –

 Смежные вопросы

  • Нет связанных вопросов^_^