- Loading...
Patch name: tailc.patch
in native code:
Compile to Interpreted Code Adapter C2I
| No Format | ||
|---|---|---|
| ||
// Before we get into the guts of the C2I adapter, see if we should be here
// at all. We've come from compiled code and are attempting to jump to the
// interpreter, which means the caller made a static call to get here
// (vcalls always get a compiled target if there is one). Check for a
// compiled target. If there is one, we need to patch the caller's call.
|
| No Format | ||
|---|---|---|
| ||
. ..............
. . Caller frame
. . .
. . .
. . argn .
. . arg1 ........
..... ................ .
... . argn+m . . . Created by c2i adapter (m=number of args in regs)
. . arg1 ........
. ..............
. RetAddr . InterpreterFrame (Callee) setup will start with
. . templateInterpreter_x86_32.cpp:
. . generate_normal_entry(bool synchronized)
|
Described by three relevant frames. The function performing the tail call is called self. The tail called function is called callee in the following. The function that has called the tail calling function is called calller.
A code example leading to this situation.
| No Format |
|---|
public static int caller(int a) {
int x = self(a);
return x+1;
}
public static int self(int a) {
return tail call calllee(a);
}
public static int callee(int a) {
return a+1;
}
|
assumption: sibling call (callee less or equal arg space requirement than self)
| No Format |
|---|
self: compiled
callee compiled / interpreted
c
a
l c mov args mov args + c2i entry
l
e
r
i mov args mov args + c2i entry
(works because
of i2c adapter in
caller. on ret
interpreter will
restore sp)
self: interpreted
callee compiled / interpreted
c
a
l c mov args for compiled move args for compiled + c2i entry
l (use old sp)
e
r
i mov args int. mov args int.
(works because
of i2c adapter)
|
interpreter call setup sequence:
| No Format |
|---|
registers:
rsi during bytecode execution holds bcp/bci
rdi
rax
rbx
rcx
rdx
rbp
rsp
|
prepare_invoke(invokevirtual)
state after prepare_invoke
| No Format |
|---|
...............
. RET ADDR . ... interpreter entry [numberretaddrs][tos_state]
............... rbx = method (index or pointer (vfinal))
. PARAM N . rcx = receiver
............... rdx = cpCache Flags
. PARM 1 . rsi = bcp
...............
|
invokevirtual_helper
| No Format |
|---|
...............
. RET ADDR . ... interpreter entry [numberretaddrs][tos_state]
............... rbx = method (oop ?) pointer
. PARAM N . rcx = receiver
............... rdx = cpCache Flags (or garbage if profiles)
. PARM 1 . rsi = rsp stack pointer
............... rax = klass ptr
rbp = base pointer/ dynlink
rsp points to RET ADDR
rdi = garbage
|
invoketailcall
...
Soon to come.