auto unwind()

in cpp/profiler/unwindc/android_500/x86_64/unwinder.h [305:368]


auto unwind(unwind_callback_t __unwind_callback, void* __unwind_data) {
  uintptr_t thread = get_art_thread();
  if ((thread == 0UL)) {
    return true;
  }
  auto runtime = get_runtime_from_thread(thread);
  uintptr_t thread_obj = thread;
  auto runtime_obj = runtime;
  uintptr_t tls = AccessField(thread_obj, 120UL);
  uintptr_t mstack = AccessField(tls, 24UL);
  uint64_t generic_jni_trampoline =
      Read8(AccessField(AccessField(tls, 320UL), 296UL));
  while ((mstack != 0UL)) {
    uint64_t quick_frame = Read8(AccessField(mstack, 16UL));
    quick_frame = quick_frame;
    uint64_t shadow_frame = Read8(AccessField(mstack, 8UL));
    shadow_frame = shadow_frame;
    uintptr_t pc = 0UL;
    uintptr_t kMaxFrames = 1024UL;
    uintptr_t depth = 0UL;
    if ((quick_frame != 0UL)) {
      while (((quick_frame != 0UL) && (depth < kMaxFrames))) {
        uint64_t frameptr = Read8(quick_frame);
        if ((frameptr == 0UL)) {
          break;
        }
        uint64_t frame = frameptr;
        if ((!is_runtime_method(frame))) {
          if ((!__unwind_callback(frame, __unwind_data))) {
            return false;
          }
        }
        auto size = get_frame_size(frameptr, runtime_obj, thread_obj, pc);
        auto return_pc_offset = (size - 8UL);
        uint64_t return_pc_addr = (quick_frame + return_pc_offset);
        uint64_t return_pc = return_pc_addr;
        pc = Read8(return_pc);
        quick_frame = (quick_frame + size);
        depth = (depth + 1UL);
      }
    } else {
      if ((shadow_frame != 0UL)) {
        while (((shadow_frame != 0UL) && (depth < kMaxFrames))) {
          uint64_t frame_obj = shadow_frame;
          uint64_t artmethodptr = Read8(AccessField(frame_obj, 16UL));
          uint64_t artmethod = artmethodptr;
          if ((!is_runtime_method(artmethod))) {
            if ((!__unwind_callback(artmethod, __unwind_data))) {
              return false;
            }
          }
          shadow_frame = Read8(AccessField(frame_obj, 8UL));
          depth = (depth + 1UL);
        }
      }
    }
    uint64_t link = Read8(AccessField(mstack, 0UL));
    if ((link == 0UL)) {
      break;
    }
    mstack = link;
  }
  return true;
}