汇编
.L_op_invoke_static: /* 0x71 */
ENTRY nterp_op_invoke_static
EXPORT_PC
// Fast-path which gets the method from thread-local cache.
// Fetch some information from the thread cache.
// Uses rax, rdx, rcx as temporaries.
movq rSELF:THREAD_SELF_OFFSET, %rax
movq rPC, %rdx
salq MACRO_LITERAL(THREAD_INTERPRETER_CACHE_SIZE_SHIFT), %rdx
andq MACRO_LITERAL(THREAD_INTERPRETER_CACHE_SIZE_MASK), %rdx
cmpq THREAD_INTERPRETER_CACHE_OFFSET(%rax, %rdx, 1), rPC
jne 1f
movq __SIZEOF_POINTER__+THREAD_INTERPRETER_CACHE_OFFSET(%rax, %rdx, 1), %rdi
jmp NterpCommonInvokeStatic
1:
//{ RDI, RSI, RDX, RCX } NterpGetMethod(Thread* self, ArtMethod* caller, uint16_t* dex_pc_ptr) 第三个参数PC指针
movq rSELF:THREAD_SELF_OFFSET, %rdi
movq 0(%rsp), %rsi
movq rPC, %rdx
call nterp_get_method
movq %rax, %rdi
jmp NterpCommonInvokeStatic
堆栈
libart.so!NterpGetMethod(art::Thread * self, art::ArtMethod * caller, uint16_t * dex_pc_ptr) (\home\w00456713\code\aosp\android13\art\runtime\interpreter\mterp\nterp.cc:254)
libart.so!nterp_get_method() (\home\w00456713\code\aosp\android13\out\soong\.intermediates\art\runtime\libart_mterp.x86_64ng\gen\mterp_x86_64ng.S:8841)
libart.so!nterp_op_invoke_static() (\home\w00456713\code\aosp\android13\out\soong\.intermediates\art\runtime\libart_mterp.x86_64ng\gen\mterp_x86_64ng.S:4381)
libart.so!art_quick_invoke_static_stub() (\home\w00456713\code\aosp\android13\art\runtime\arch\x86_64\quick_entrypoints_x86_64.S:569)
libart.so!art::ArtMethod::Invoke(art::ArtMethod * this, art::Thread * self, uint32_t * args, uint32_t args_size, art::JValue * result, const char * shorty) (\home\w00456713\code\aosp\android13\art\runtime\art_method.cc:373)
libart.so!art::ClassLinker::InitializeClass(art::ClassLinker * this, art::Thread * self, art::Handle<art::mirror::Class> klass, bool can_init_statics, bool can_init_parents) (\home\w00456713\code\aosp\android13\art\runtime\class_linker.cc:5387)
libart.so!art::ClassLinker::EnsureInitialized(art::ClassLinker * this, art::Thread * self, art::Handle<art::mirror::Class> c, bool can_init_fields, bool can_init_parents) (\home\w00456713\code\aosp\android13\art\runtime\class_linker.cc:5761)
libart.so!art::EnsureInitialized(art::Thread * self, art::ObjPtr<art::mirror::Class> klass) (\home\w00456713\code\aosp\android13\art\runtime\jni\jni_internal.cc:471)
libart.so!art::FindMethodJNI(const art::ScopedObjectAccess & soa, jclass jni_class, const char * name, const char * sig, bool is_static) (\home\w00456713\code\aosp\android13\art\runtime\jni\jni_internal.cc:482)
libart.so!art::FindMethodID<false>(art::ScopedObjectAccess & soa, jclass jni_class, const char * name, const char * sig, bool is_static) (\home\w00456713\code\aosp\android13\art\runtime\jni\jni_internal.cc:387)
libart.so!art::JNI<false>::GetStaticMethodID(JNIEnv * env, jclass java_class, const char * name, const char * sig) (\home\w00456713\code\aosp\android13\art\runtime\jni\jni_internal.cc:1010)
_JNIEnv::GetStaticMethodID(_JNIEnv * this, jclass clazz, const char * name, const char * sig) (\home\w00456713\code\aosp\android13\libnativehelper\include_jni\jni.h:734)
art::InvokeMain(JNIEnv * env, char ** argv) (\home\w00456713\code\aosp\android13\art\dalvikvm\dalvikvm.cc:83)
art::dalvikvm(int argc, char ** argv) (\home\w00456713\code\aosp\android13\art\dalvikvm\dalvikvm.cc:191)
main(int argc, char ** argv) (\home\w00456713\code\aosp\android13\art\dalvikvm\dalvikvm.cc:220)
- artmethod的code如果需要clinit,则更新为art_quick_resolution_trampoline
// Special case if we need an initialization check.
if (NeedsClinitCheckBeforeCall(method) && !method->GetDeclaringClass()->IsVisiblyInitialized()) {
// If we have code but the method needs a class initialization check before calling
// that code, install the resolution stub that will perform the check.
// It will be replaced by the proper entry point by ClassLinker::FixupStaticTrampolines
// after initializing class (see ClassLinker::InitializeClass method).
// Note: this mimics the logic in image_writer.cc that installs the resolution
// stub only if we have compiled code or we can execute nterp, and the method needs a class
// initialization check.
if (aot_code != nullptr || method->IsNative() || CanUseNterp(method)) {
UpdateEntryPoints(method, GetQuickResolutionStub());
} else {
UpdateEntryPoints(method, GetQuickToInterpreterBridge());
}
return;
}
- 在art_quick_resolution_trampoline里面完成class加载,initialize以及artmethod的code更新为quick code
static const void* GetOptimizedCodeFor(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) {
DCHECK(!Runtime::Current()->GetInstrumentation()->InterpretOnly(method));
// In debuggable mode, we can only use AOT code for native methods.
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
const void* aot_code = method->GetOatMethodQuickCode(class_linker->GetImagePointerSize());
if (CanUseAotCode(method, aot_code)) {
return aot_code;
}
}
void ClassLinker::FixupStaticTrampolines(Thread* self, ObjPtr<mirror::Class> klass) {
ScopedAssertNoThreadSuspension sants(__FUNCTION__);
for (size_t method_index = 0; method_index < num_direct_methods; ++method_index) {
ArtMethod* method = klass->GetDirectMethod(method_index, pointer_size);
if (!method->IsStatic()) {
// Only update static methods.
continue;
}
instrumentation->UpdateMethodsCode(method, instrumentation->GetCodeForInvoke(method));
}
// Ignore virtual methods on the iterator.
}