前言
要想深入地理解 art 虚拟机,那么理解 Java 方法在虚拟机当中是如何执行的是必不可少的一环。
本篇从 Native 函数调用 Java 函数角度来探讨一下 Java 函数在 art 虚拟机当中的执行。(基于 Android 8.1)
一、调用流程
首先,我们用 gdb 将断点打在 art_quick_invoke_stub,观察一下 Native 函数 -> Java 函数的调用栈:
我们可以看到 Native 函数调用 Java 函数最开始是要调用 env->CallBooleanMethod:
(gdb) f 6
#6 0x000000798f46c2d0 in JavaBBinder::onTransact (this=0x79032efa80, code=4, data=..., reply=0x78f55fd1c0, flags=17) at frameworks/base/core/jni/android_util_Binder.cpp:312
312 jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
(gdb) list
307 const int32_t strict_policy_before = thread_state->getStrictModePolicy();
308
309 //printf("Transact from %p to Java code sending: ", this);
310 //data.print();
311 //printf("\n");
312 jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
313 code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
314
315 if (env->ExceptionCheck()) {
316 jthrowable excep = env->ExceptionOccurred();
1、CallBooleanMethod
我们来看一下 CallBooleanMethod 定义:
libnativehelper/include_jni/jni.h
594#define CALL_TYPE_METHOD(_jtype, _jname) \
595 _jtype Call##_jname##Method(jobject obj, jmethodID methodID, ...) \
596 { \
597 _jtype result; \
598 va_list args; \
599 va_start(args, methodID); \
600 result = functions->Call##_jname##MethodV(this, obj, methodID, \
601 args); \
602 va_end(args); \
603 return result; \
604 }
605#define CALL_TYPE_METHODV(_jtype, _jname) \
606 _jtype Call##_jname##MethodV(jobject obj, jmethodID methodID, \
607 va_list args) \
608 { return functions->Call##_jname##MethodV(this, obj, methodID, args); }
609#define CALL_TYPE_METHODA(_jtype, _jname) \
610 _jtype Call##_jname##