0

We know the following calling conversation the this thread, What's the calling convention for the Java code in Linux platform? And also it explained that

"You may notice that Java calling convention looks similar to C calling convention but shifted by one argument right. This is done intentionally to avoid extra register shuffling when calling JNI methods (you know, JNI methods have extra JNIEnv* argument prepended to method parameters)."

So does it mean when we called the JNI function such as jclass FindClass(JNIEnv *env, const char *name); then JNIEnv value env would be passed to the rdi, and name passed to rsi, however when we called the general non-JNI Java method such as void printClassName(int Integer1 ,Object obj), then Integer1 is passed to rsi, and obj was passed to the stack as it is not a Integer,it is right?

please correct me if I'm wrong.

|-------------------------------------------------------|
| 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    |
|-------------------------------------------------------|
Community
  • 1
  • 1
YuFeng Shen
  • 1,475
  • 1
  • 17
  • 41

1 Answers1

1

The given table describes how VM calls Java methods.

E.g. when calling Java method void print(int i, Object o) it passes

  • this in RSI (j_rarg0)
  • i in RDX (j_rarg1)
  • o in RCX (j_rarg2) - object references are also passed in general purpose registers.

The calling convention is the same, whether a method is declared native or not. For a native method there will be a native implementation

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

This native function follows the standard platform ABI, that is,

  • env goes to RDI (c_rarg0)
  • this to RSI (c_rarg1)
  • i to RDX (c_rarg2)
  • o to RCX (c_rarg3)

Note that due to a wise choice of j_rargs vs. c_rargs, parameters remained in the same registers.


JNI functions like FindClass have nothing to do with VM calling convention. They must follow the platform ABI. Therefore, the first argument JNIEnv* is passed in RDI on Linux/x64.

apangin
  • 92,924
  • 10
  • 193
  • 247
  • Much appreciate for your so clearly explanation, you are so kindly. However as you ever mentioned "Up to 6 first integer arguments are passed in registers: rsi, rdx, rcx, r8, r9, rdi, " in http://stackoverflow.com/questions/41693637/whats-the-calling-convention-for-the-java-code-in-linux-platform , as the Object o is object reference not the integer , why it also passed in RCX ? The openjdk article also express the same meaning as you saying the the six Integer ...https://wiki.openjdk.java.net/display/HotSpot/CallingSequences, I think I have something misunderstanding. – YuFeng Shen Feb 18 '17 at 17:20
  • @Jacky In the quote above I used "integer" as an opposite to "floating point". An object reference (an address / a pointer / a compressed pointer or whatever) is also a value that fits general purpose (integer) registers. – apangin Feb 18 '17 at 20:47