art nterp解释器

这段代码展示了AndroidART运行时中调用静态方法的汇编流程,包括从线程缓存获取方法、检查是否需要类初始化、使用快速路径或解释器。如果需要类初始化,会更新方法入口点至相应trampoline。在trampoline中执行类加载和初始化,然后可能将方法代码替换为优化的quickcode。
摘要由CSDN通过智能技术生成
汇编
.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.
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值