1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
https://liuxiaofei.com.cn/blog/call_stub-jvm-java%E8%B0%83%E7%94%A8%E7%9A%84%E5%85%A5%E5%8F%A3/
call_stub–JVM Java
Content:
call_helper
call_stub
call_stub
--------
JavaCalls::call_helper() at javaCalls.cpp:393 0x7ffff70f3600
os::os_exception_wrapper() at os_linux.cpp:5,104 0x7ffff7372b40
JavaCalls::call() at javaCalls.cpp:307 0x7ffff70f2fe6
InstanceKlass::call_class_initializer_impl() at instanceKlass.cpp:1,193 0x7ffff7088edf
InstanceKlass::call_class_initializer() at instanceKlass.cpp:1,161 0x7ffff7088c6d
InstanceKlass::initialize_impl() at instanceKlass.cpp:897 0x7ffff7087a40
InstanceKlass::initialize() at instanceKlass.cpp:557 0x7ffff7085f3e
InstanceKlass::initialize_impl() at instanceKlass.cpp:840 0x7ffff70874d7
InstanceKlass::initialize() at instanceKlass.cpp:557 0x7ffff7085f3e
initialize_class() at thread.cpp:983 0x7ffff74c5244
Threads::create_vm() at thread.cpp:3,497 0x7ffff74cc7df
JNI_CreateJavaVM() at jni.cpp:5,166 0x7ffff7134f13
call_helper
-----------------------------------------------
void JavaCalls::call_helper(JavaValue* result, methodHandle* m, JavaCallArguments* args, TRAPS) {
//JVM
OOP-Klass
Java
-
Handle
OOP
Klass
//Handle
()
->,
method()
method->
methodOop
methodHandle method = *m;
JavaThread* thread = (JavaThread*)THREAD;
assert(thread->is_Java_thread(), "must be called by a java thread");
assert(method.not_null(), "must have a method to call");
assert(!SafepointSynchronize::is_at_safepoint(), "call to Java code during VM operation");
assert(!thread->handle_area()->no_handle_mark_active(), "cannot call out to Java here");
CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
// Verify the arguments
if (CheckJNICalls) {
args->verify(method, result->get_type(), thread);
}
else debug_only(args->verify(method, result->get_type(), thread));
// Ignore call if method is empty
if (method->is_empty_method()) {
assert(result->get_type() == T_VOID, "an empty method must return a void value");
return;
}
#ifdef ASSERT
{ InstanceKlass* holder = method->method_holder();
// A klass might not be initialized since JavaCall's might be used during the executing of
// the . For example, a Thread.start might start executing on an object that is
// not fully initialized! (bad Java programming style)
assert(holder->is_linked(), "rewritting must have taken place");
}
#endif
assert(!thread->is_Compiler_thread(), "cannot compile from the compiler");
if (CompilationPolicy::must_be_compiled(method)) {
CompileBroker::compile_method(method, InvocationEntryBci,
CompilationPolicy::policy()->initial_compile_level(),
methodHandle(), 0, "must_be_compiled", CHECK);
}
//
method
entry_point,entry_point
Java
,
method
//
entry_point
//entry_point
method
,
method
entry_point
// Since the call stub sets up like the interpreter we call the from_interpreted_entry
// so we can go compiled via a i2c. Otherwise initial entry method will always
// run interpreted.
address entry_point = method->from_interpreted_entry();
if (JvmtiExport::can_post_interpreter_events() && thread->is_interp_only_mode()) {
entry_point = method->interpreter_entry();
}
// Figure out if the result value is an oop or not (Note: This is a different value
// than result_type. result_type will be T_INT of oops. (it is about size)
BasicType result_type = runtime_type_from(result);
bool oop_result_flag = (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY);
// NOTE: if we move the computation of the result_val_address inside
// the call to call_stub, the optimizer produces wrong code.
intptr_t* result_val_address = (intptr_t*)(result->get_value_addr());
.call_stub–JVM Java
.txt 1/1/2020 8:16 AM
Page 1 of 5