Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the calling convention for the Java code in Linux platform?

Tags:

java

jvm

We know the calling convention that "first six integer or pointer arguments are passed in registers RDI, RSI, RDX, RCX (R10 in the Linux kernel interface[17]:124), R8, and R9" for the c/c++ code in the Linux platform based on the following article. https://en.wikipedia.org/wiki/X86_calling_conventions#x86-64_calling_conventions

However what's the calling convention for the Java code in Linux platform (suppose the JVM is hotspot)? The following is example, what's registers store the four parameters?

protected void caller( ) {
callee(1,"123", 123,1)
}

protected void callee(int a,String b, Integer c,Object d) {

}
like image 370
YuFeng Shen Avatar asked Jan 17 '17 09:01

YuFeng Shen


People also ask

What calling convention does Linux use?

In Linux, GCC sets the de facto standard for calling conventions. Since GCC version 4.5, the stack must be aligned to a 16-byte boundary when calling a function (previous versions only required a 4-byte alignment).

What calling convention does GCC use?

The calling convention for the gcc compiler on Linux systems should be to pass arguments via the stack. Here I assume the arguments are passed using eax and ebx . I don't think that is right. ret probably expects to pick up a return address from somewhere.

What are different calling conventions?

There are three major calling conventions that are used with the C language on 32-bit x86 processors: STDCALL, CDECL, and FASTCALL. In addition, there is another calling convention typically used with C++: THISCALL. There are other calling conventions as well, including PASCAL and FORTRAN conventions, among others.

What is the purpose of calling convention?

A calling convention governs how functions on a particular architecture and operating system interact. This includes rules about includes how function arguments are placed, where return values go, what registers functions may use, how they may allocate local variables, and so forth.


1 Answers

It is not specified how JVM calls Java methods internally. Various JVM implementations may follow different calling conventions. Here is how it works in HotSpot JVM on Linux x64.

  • A Java method may run in interpreter or it can be JIT-compiled.
  • Interpreted and compiled code use different calling conventions.

1. Interpreter method entry

Each Java method has an entry point into the interpreter. This entry is used to jump from an interpreted method to another interpreted method.

  • All arguments are passed on stack, from bottom to top.
  • rbx contains a pointer to Method* structure - internal metadata of a method being called.
  • r13 holds sender_sp - stack pointer of a caller method. It may differ from rsp + 8 if c2i adapter is used (see below).

More details about interpreter entries in HotSpot source code: templateInterpreter_x86_64.cpp.

2. Compiled entry

A compiled method has its own entry point. Compiled code calls compiled methods via this entry.

  • Up to 6 first integer arguments are passed in registers: rsi, rdx, rcx, r8, r9, rdi. Non-static methods receive this reference as the first argument in rsi.
  • Up to 8 floating point arguments are passed in xmm0 ... xmm7 registers.
  • All other arguments are passed on stack from top to bottom.

This convention is nicely illustrated in assembler_x86.hpp:

    |-------------------------------------------------------|
    | 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    |
    |-------------------------------------------------------|

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).

3. Adapters

Java methods may have two more entry points: c2i and i2c adapters. These adapters are pieces of dynamically generated code that convert compiled calling convention to interpreter layout and vice versa. с2i and i2c entry points are used to call interpreted method from compiled code and compiled method from interpreted code respectively.


P.S. It does not usually matter how JVM calls methods internally, because these are just implementation details opaque to end-user. Moreover, these details may change even in a minor JDK update. However, I know at least one case when the knowledge of Java calling convention may appear useful - when analysing JVM crash dumps.

like image 53
apangin Avatar answered Oct 21 '22 16:10

apangin