对照汇编看非常清晰,不过也可以看到它建立了栈帧结构,但它还是没有执行java代码,而是使用callq *rdx进行的,
这也是为什么它叫做stub的原因。
另外上面的栈帧里面内容比较多,[rsp+xx]存放什么内容啊这些比较难记,已经归纳好的结构可以参见代码注释:
// Windowsx86_64平台
//
// 注意c_rarg\d 表示寄存器,method/result表示内存地址[rbp+\d]
//
// c_rarg0: call wrapper address
address
// c_rarg1: result
address
// c_rarg2: result type
BasicType
// c_rarg3: method
Method*
// 48(rbp): (interpreter) entry point
address
// 56(rbp): parameters
intptr_t*
// 64(rbp): parameter size (in words)
int
// 72(rbp): thread
Thread*
//
//
[ return_from_Java
] <--- 这里执行callq调用java方法。压入返回地址,跳转到java方法,也就是说↑上面的部分就是java方法使用的栈帧了
//
[ argument word n
] <--- 循环传递的java方法实参
//
...
// -60 [ argument word 1
]
// -59 [ saved xmm31
] <--- rsp after_call
//
[ saved xmm16-xmm30 ]
// -27 [ saved xmm15
]
//
[ saved xmm7-xmm14
]
// -9 [ saved xmm6
]
// -7 [ saved r15
]
// -6 [ saved r14
]
// -5 [ saved r13
]
// -4 [ saved r12
]
// -3 [ saved rdi
]
// -2 [ saved rsi
]
// -1 [ saved rbx
]
// 0 [ saved rbp
] <--- rbp
// 1 [ return address
] <--- last rbp
// 2 [ call wrapper
] <--- arg0
// 3 [ result
] <--- arg1
// 4 [ result type
] <--- arg2
// 5 [ method
] <--- arg3
// 6 [ entry point
] <--- arg4
// 7 [ parameters
] <--- arg5
// 8 [ parameter size
] <--- arg6
// 9 [ thread
] <--- arg7
这8个arg正是之前传递给函数指针指向的函数的实参:
StubRoutines::call_stub()(
(address)&link,
// (intptr_t*)&(result->_value), // see NOTE above (compiler problem)
result_val_address,
// see NOTE above (compiler problem)
result_type,
method(),
entry_point,
args->parameters(),
args->size_of_parameters(),
CHECK
);