Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "instrumentation.h"
     18 
     19 #include <sstream>
     20 
     21 #include "arch/context.h"
     22 #include "art_method-inl.h"
     23 #include "atomic.h"
     24 #include "class_linker.h"
     25 #include "debugger.h"
     26 #include "dex_file-inl.h"
     27 #include "entrypoints/quick/quick_entrypoints.h"
     28 #include "entrypoints/quick/quick_alloc_entrypoints.h"
     29 #include "entrypoints/runtime_asm_entrypoints.h"
     30 #include "gc_root-inl.h"
     31 #include "interpreter/interpreter.h"
     32 #include "jit/jit.h"
     33 #include "jit/jit_code_cache.h"
     34 #include "mirror/class-inl.h"
     35 #include "mirror/dex_cache.h"
     36 #include "mirror/object_array-inl.h"
     37 #include "mirror/object-inl.h"
     38 #include "nth_caller_visitor.h"
     39 #include "oat_quick_method_header.h"
     40 #include "thread.h"
     41 #include "thread_list.h"
     42 
     43 namespace art {
     44 namespace instrumentation {
     45 
     46 constexpr bool kVerboseInstrumentation = false;
     47 
     48 // Instrumentation works on non-inlined frames by updating returned PCs
     49 // of compiled frames.
     50 static constexpr StackVisitor::StackWalkKind kInstrumentationStackWalk =
     51     StackVisitor::StackWalkKind::kSkipInlinedFrames;
     52 
     53 class InstallStubsClassVisitor : public ClassVisitor {
     54  public:
     55   explicit InstallStubsClassVisitor(Instrumentation* instrumentation)
     56       : instrumentation_(instrumentation) {}
     57 
     58   bool operator()(ObjPtr<mirror::Class> klass) OVERRIDE REQUIRES(Locks::mutator_lock_) {
     59     instrumentation_->InstallStubsForClass(klass.Ptr());
     60     return true;  // we visit all classes.
     61   }
     62 
     63  private:
     64   Instrumentation* const instrumentation_;
     65 };
     66 
     67 
     68 Instrumentation::Instrumentation()
     69     : instrumentation_stubs_installed_(false),
     70       entry_exit_stubs_installed_(false),
     71       interpreter_stubs_installed_(false),
     72       interpret_only_(false),
     73       forced_interpret_only_(false),
     74       have_method_entry_listeners_(false),
     75       have_method_exit_listeners_(false),
     76       have_method_unwind_listeners_(false),
     77       have_dex_pc_listeners_(false),
     78       have_field_read_listeners_(false),
     79       have_field_write_listeners_(false),
     80       have_exception_caught_listeners_(false),
     81       have_branch_listeners_(false),
     82       have_invoke_virtual_or_interface_listeners_(false),
     83       deoptimized_methods_lock_("deoptimized methods lock", kDeoptimizedMethodsLock),
     84       deoptimization_enabled_(false),
     85       interpreter_handler_table_(kMainHandlerTable),
     86       quick_alloc_entry_points_instrumentation_counter_(0),
     87       alloc_entrypoints_instrumented_(false) {
     88 }
     89 
     90 void Instrumentation::InstallStubsForClass(mirror::Class* klass) {
     91   if (!klass->IsResolved()) {
     92     // We need the class to be resolved to install/uninstall stubs. Otherwise its methods
     93     // could not be initialized or linked with regards to class inheritance.
     94   } else if (klass->IsErroneousResolved()) {
     95     // We can't execute code in a erroneous class: do nothing.
     96   } else {
     97     for (ArtMethod& method : klass->GetMethods(kRuntimePointerSize)) {
     98       InstallStubsForMethod(&method);
     99     }
    100   }
    101 }
    102 
    103 static void UpdateEntrypoints(ArtMethod* method, const void* quick_code)
    104     REQUIRES_SHARED(Locks::mutator_lock_) {
    105   method->SetEntryPointFromQuickCompiledCode(quick_code);
    106 }
    107 
    108 bool Instrumentation::NeedDebugVersionFor(ArtMethod* method) const REQUIRES_SHARED(Locks::mutator_lock_) {
    109   return Dbg::IsDebuggerActive() &&
    110          Runtime::Current()->IsJavaDebuggable() &&
    111          !method->IsNative() &&
    112          !method->IsProxyMethod();
    113 }
    114 
    115 void Instrumentation::InstallStubsForMethod(ArtMethod* method) {
    116   if (!method->IsInvokable() || method->IsProxyMethod()) {
    117     // Do not change stubs for these methods.
    118     return;
    119   }
    120   // Don't stub Proxy.<init>. Note that the Proxy class itself is not a proxy class.
    121   if (method->IsConstructor() &&
    122       method->GetDeclaringClass()->DescriptorEquals("Ljava/lang/reflect/Proxy;")) {
    123     return;
    124   }
    125   const void* new_quick_code;
    126   bool uninstall = !entry_exit_stubs_installed_ && !interpreter_stubs_installed_;
    127   Runtime* const runtime = Runtime::Current();
    128   ClassLinker* const class_linker = runtime->GetClassLinker();
    129   bool is_class_initialized = method->GetDeclaringClass()->IsInitialized();
    130   if (uninstall) {
    131     if ((forced_interpret_only_ || IsDeoptimized(method)) && !method->IsNative()) {
    132       new_quick_code = GetQuickToInterpreterBridge();
    133     } else if (is_class_initialized || !method->IsStatic() || method->IsConstructor()) {
    134       if (NeedDebugVersionFor(method)) {
    135         new_quick_code = GetQuickToInterpreterBridge();
    136       } else {
    137         new_quick_code = class_linker->GetQuickOatCodeFor(method);
    138       }
    139     } else {
    140       new_quick_code = GetQuickResolutionStub();
    141     }
    142   } else {  // !uninstall
    143     if ((interpreter_stubs_installed_ || forced_interpret_only_ || IsDeoptimized(method)) &&
    144         !method->IsNative()) {
    145       new_quick_code = GetQuickToInterpreterBridge();
    146     } else {
    147       // Do not overwrite resolution trampoline. When the trampoline initializes the method's
    148       // class, all its static methods code will be set to the instrumentation entry point.
    149       // For more details, see ClassLinker::FixupStaticTrampolines.
    150       if (is_class_initialized || !method->IsStatic() || method->IsConstructor()) {
    151         if (NeedDebugVersionFor(method)) {
    152           // Oat code should not be used. Don't install instrumentation stub and
    153           // use interpreter for instrumentation.
    154           new_quick_code = GetQuickToInterpreterBridge();
    155         } else if (entry_exit_stubs_installed_) {
    156           new_quick_code = GetQuickInstrumentationEntryPoint();
    157         } else {
    158           new_quick_code = class_linker->GetQuickOatCodeFor(method);
    159         }
    160       } else {
    161         new_quick_code = GetQuickResolutionStub();
    162       }
    163     }
    164   }
    165   UpdateEntrypoints(method, new_quick_code);
    166 }
    167 
    168 // Places the instrumentation exit pc as the return PC for every quick frame. This also allows
    169 // deoptimization of quick frames to interpreter frames.
    170 // Since we may already have done this previously, we need to push new instrumentation frame before
    171 // existing instrumentation frames.
    172 static void InstrumentationInstallStack(Thread* thread, void* arg)
    173     REQUIRES_SHARED(Locks::mutator_lock_) {
    174   struct InstallStackVisitor FINAL : public StackVisitor {
    175     InstallStackVisitor(Thread* thread_in, Context* context, uintptr_t instrumentation_exit_pc)
    176         : StackVisitor(thread_in, context, kInstrumentationStackWalk),
    177           instrumentation_stack_(thread_in->GetInstrumentationStack()),
    178           instrumentation_exit_pc_(instrumentation_exit_pc),
    179           reached_existing_instrumentation_frames_(false), instrumentation_stack_depth_(0),
    180           last_return_pc_(0) {
    181     }
    182 
    183     bool VisitFrame() OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
    184       ArtMethod* m = GetMethod();
    185       if (m == nullptr) {
    186         if (kVerboseInstrumentation) {
    187           LOG(INFO) << "  Skipping upcall. Frame " << GetFrameId();
    188         }
    189         last_return_pc_ = 0;
    190         return true;  // Ignore upcalls.
    191       }
    192       if (GetCurrentQuickFrame() == nullptr) {
    193         bool interpreter_frame = true;
    194         InstrumentationStackFrame instrumentation_frame(GetThisObject(), m, 0, GetFrameId(),
    195                                                         interpreter_frame);
    196         if (kVerboseInstrumentation) {
    197           LOG(INFO) << "Pushing shadow frame " << instrumentation_frame.Dump();
    198         }
    199         shadow_stack_.push_back(instrumentation_frame);
    200         return true;  // Continue.
    201       }
    202       uintptr_t return_pc = GetReturnPc();
    203       if (m->IsRuntimeMethod()) {
    204         if (return_pc == instrumentation_exit_pc_) {
    205           if (kVerboseInstrumentation) {
    206             LOG(INFO) << "  Handling quick to interpreter transition. Frame " << GetFrameId();
    207           }
    208           CHECK_LT(instrumentation_stack_depth_, instrumentation_stack_->size());
    209           const InstrumentationStackFrame& frame =
    210               instrumentation_stack_->at(instrumentation_stack_depth_);
    211           CHECK(frame.interpreter_entry_);
    212           // This is an interpreter frame so method enter event must have been reported. However we
    213           // need to push a DEX pc into the dex_pcs_ list to match size of instrumentation stack.
    214           // Since we won't report method entry here, we can safely push any DEX pc.
    215           dex_pcs_.push_back(0);
    216           last_return_pc_ = frame.return_pc_;
    217           ++instrumentation_stack_depth_;
    218           return true;
    219         } else {
    220           if (kVerboseInstrumentation) {
    221             LOG(INFO) << "  Skipping runtime method. Frame " << GetFrameId();
    222           }
    223           last_return_pc_ = GetReturnPc();
    224           return true;  // Ignore unresolved methods since they will be instrumented after resolution.
    225         }
    226       }
    227       if (kVerboseInstrumentation) {
    228         LOG(INFO) << "  Installing exit stub in " << DescribeLocation();
    229       }
    230       if (return_pc == instrumentation_exit_pc_) {
    231         // We've reached a frame which has already been installed with instrumentation exit stub.
    232         // We should have already installed instrumentation on previous frames.
    233         reached_existing_instrumentation_frames_ = true;
    234 
    235         CHECK_LT(instrumentation_stack_depth_, instrumentation_stack_->size());
    236         const InstrumentationStackFrame& frame =
    237             instrumentation_stack_->at(instrumentation_stack_depth_);
    238         CHECK_EQ(m, frame.method_) << "Expected " << ArtMethod::PrettyMethod(m)
    239                                    << ", Found " << ArtMethod::PrettyMethod(frame.method_);
    240         return_pc = frame.return_pc_;
    241         if (kVerboseInstrumentation) {
    242           LOG(INFO) << "Ignoring already instrumented " << frame.Dump();
    243         }
    244       } else {
    245         CHECK_NE(return_pc, 0U);
    246         CHECK(!reached_existing_instrumentation_frames_);
    247         InstrumentationStackFrame instrumentation_frame(GetThisObject(), m, return_pc, GetFrameId(),
    248                                                         false);
    249         if (kVerboseInstrumentation) {
    250           LOG(INFO) << "Pushing frame " << instrumentation_frame.Dump();
    251         }
    252 
    253         // Insert frame at the right position so we do not corrupt the instrumentation stack.
    254         // Instrumentation stack frames are in descending frame id order.
    255         auto it = instrumentation_stack_->begin();
    256         for (auto end = instrumentation_stack_->end(); it != end; ++it) {
    257           const InstrumentationStackFrame& current = *it;
    258           if (instrumentation_frame.frame_id_ >= current.frame_id_) {
    259             break;
    260           }
    261         }
    262         instrumentation_stack_->insert(it, instrumentation_frame);
    263         SetReturnPc(instrumentation_exit_pc_);
    264       }
    265       dex_pcs_.push_back((GetCurrentOatQuickMethodHeader() == nullptr)
    266           ? DexFile::kDexNoIndex
    267           : GetCurrentOatQuickMethodHeader()->ToDexPc(m, last_return_pc_));
    268       last_return_pc_ = return_pc;
    269       ++instrumentation_stack_depth_;
    270       return true;  // Continue.
    271     }
    272     std::deque<InstrumentationStackFrame>* const instrumentation_stack_;
    273     std::vector<InstrumentationStackFrame> shadow_stack_;
    274     std::vector<uint32_t> dex_pcs_;
    275     const uintptr_t instrumentation_exit_pc_;
    276     bool reached_existing_instrumentation_frames_;
    277     size_t instrumentation_stack_depth_;
    278     uintptr_t last_return_pc_;
    279   };
    280   if (kVerboseInstrumentation) {
    281     std::string thread_name;
    282     thread->GetThreadName(thread_name);
    283     LOG(INFO) << "Installing exit stubs in " << thread_name;
    284   }
    285 
    286   Instrumentation* instrumentation = reinterpret_cast<Instrumentation*>(arg);
    287   std::unique_ptr<Context> context(Context::Create());
    288   uintptr_t instrumentation_exit_pc = reinterpret_cast<uintptr_t>(GetQuickInstrumentationExitPc());
    289   InstallStackVisitor visitor(thread, context.get(), instrumentation_exit_pc);
    290   visitor.WalkStack(true);
    291   CHECK_EQ(visitor.dex_pcs_.size(), thread->GetInstrumentationStack()->size());
    292 
    293   if (instrumentation->ShouldNotifyMethodEnterExitEvents()) {
    294     // Create method enter events for all methods currently on the thread's stack. We only do this
    295     // if no debugger is attached to prevent from posting events twice.
    296     auto ssi = visitor.shadow_stack_.rbegin();
    297     for (auto isi = thread->GetInstrumentationStack()->rbegin(),
    298         end = thread->GetInstrumentationStack()->rend(); isi != end; ++isi) {
    299       while (ssi != visitor.shadow_stack_.rend() && (*ssi).frame_id_ < (*isi).frame_id_) {
    300         instrumentation->MethodEnterEvent(thread, (*ssi).this_object_, (*ssi).method_, 0);
    301         ++ssi;
    302       }
    303       uint32_t dex_pc = visitor.dex_pcs_.back();
    304       visitor.dex_pcs_.pop_back();
    305       if (!isi->interpreter_entry_) {
    306         instrumentation->MethodEnterEvent(thread, (*isi).this_object_, (*isi).method_, dex_pc);
    307       }
    308     }
    309   }
    310   thread->VerifyStack();
    311 }
    312 
    313 void Instrumentation::InstrumentThreadStack(Thread* thread) {
    314   instrumentation_stubs_installed_ = true;
    315   InstrumentationInstallStack(thread, this);
    316 }
    317 
    318 // Removes the instrumentation exit pc as the return PC for every quick frame.
    319 static void InstrumentationRestoreStack(Thread* thread, void* arg)
    320     REQUIRES(Locks::mutator_lock_) {
    321   Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
    322 
    323   struct RestoreStackVisitor FINAL : public StackVisitor {
    324     RestoreStackVisitor(Thread* thread_in, uintptr_t instrumentation_exit_pc,
    325                         Instrumentation* instrumentation)
    326         : StackVisitor(thread_in, nullptr, kInstrumentationStackWalk),
    327           thread_(thread_in),
    328           instrumentation_exit_pc_(instrumentation_exit_pc),
    329           instrumentation_(instrumentation),
    330           instrumentation_stack_(thread_in->GetInstrumentationStack()),
    331           frames_removed_(0) {}
    332 
    333     bool VisitFrame() OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
    334       if (instrumentation_stack_->size() == 0) {
    335         return false;  // Stop.
    336       }
    337       ArtMethod* m = GetMethod();
    338       if (GetCurrentQuickFrame() == nullptr) {
    339         if (kVerboseInstrumentation) {
    340           LOG(INFO) << "  Ignoring a shadow frame. Frame " << GetFrameId()
    341               << " Method=" << ArtMethod::PrettyMethod(m);
    342         }
    343         return true;  // Ignore shadow frames.
    344       }
    345       if (m == nullptr) {
    346         if (kVerboseInstrumentation) {
    347           LOG(INFO) << "  Skipping upcall. Frame " << GetFrameId();
    348         }
    349         return true;  // Ignore upcalls.
    350       }
    351       bool removed_stub = false;
    352       // TODO: make this search more efficient?
    353       const size_t frameId = GetFrameId();
    354       for (const InstrumentationStackFrame& instrumentation_frame : *instrumentation_stack_) {
    355         if (instrumentation_frame.frame_id_ == frameId) {
    356           if (kVerboseInstrumentation) {
    357             LOG(INFO) << "  Removing exit stub in " << DescribeLocation();
    358           }
    359           if (instrumentation_frame.interpreter_entry_) {
    360             CHECK(m == Runtime::Current()->GetCalleeSaveMethod(Runtime::kSaveRefsAndArgs));
    361           } else {
    362             CHECK(m == instrumentation_frame.method_) << ArtMethod::PrettyMethod(m);
    363           }
    364           SetReturnPc(instrumentation_frame.return_pc_);
    365           if (instrumentation_->ShouldNotifyMethodEnterExitEvents()) {
    366             // Create the method exit events. As the methods didn't really exit the result is 0.
    367             // We only do this if no debugger is attached to prevent from posting events twice.
    368             instrumentation_->MethodExitEvent(thread_, instrumentation_frame.this_object_, m,
    369                                               GetDexPc(), JValue());
    370           }
    371           frames_removed_++;
    372           removed_stub = true;
    373           break;
    374         }
    375       }
    376       if (!removed_stub) {
    377         if (kVerboseInstrumentation) {
    378           LOG(INFO) << "  No exit stub in " << DescribeLocation();
    379         }
    380       }
    381       return true;  // Continue.
    382     }
    383     Thread* const thread_;
    384     const uintptr_t instrumentation_exit_pc_;
    385     Instrumentation* const instrumentation_;
    386     std::deque<instrumentation::InstrumentationStackFrame>* const instrumentation_stack_;
    387     size_t frames_removed_;
    388   };
    389   if (kVerboseInstrumentation) {
    390     std::string thread_name;
    391     thread->GetThreadName(thread_name);
    392     LOG(INFO) << "Removing exit stubs in " << thread_name;
    393   }
    394   std::deque<instrumentation::InstrumentationStackFrame>* stack = thread->GetInstrumentationStack();
    395   if (stack->size() > 0) {
    396     Instrumentation* instrumentation = reinterpret_cast<Instrumentation*>(arg);
    397     uintptr_t instrumentation_exit_pc =
    398         reinterpret_cast<uintptr_t>(GetQuickInstrumentationExitPc());
    399     RestoreStackVisitor visitor(thread, instrumentation_exit_pc, instrumentation);
    400     visitor.WalkStack(true);
    401     CHECK_EQ(visitor.frames_removed_, stack->size());
    402     while (stack->size() > 0) {
    403       stack->pop_front();
    404     }
    405   }
    406 }
    407 
    408 static bool HasEvent(Instrumentation::InstrumentationEvent expected, uint32_t events) {
    409   return (events & expected) != 0;
    410 }
    411 
    412 static void PotentiallyAddListenerTo(Instrumentation::InstrumentationEvent event,
    413                                      uint32_t events,
    414                                      std::list<InstrumentationListener*>& list,
    415                                      InstrumentationListener* listener,
    416                                      bool* has_listener)
    417     REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::classlinker_classes_lock_) {
    418   Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
    419   if (!HasEvent(event, events)) {
    420     return;
    421   }
    422   // If there is a free slot in the list, we insert the listener in that slot.
    423   // Otherwise we add it to the end of the list.
    424   auto it = std::find(list.begin(), list.end(), nullptr);
    425   if (it != list.end()) {
    426     *it = listener;
    427   } else {
    428     list.push_back(listener);
    429   }
    430   *has_listener = true;
    431 }
    432 
    433 void Instrumentation::AddListener(InstrumentationListener* listener, uint32_t events) {
    434   Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
    435   PotentiallyAddListenerTo(kMethodEntered,
    436                            events,
    437                            method_entry_listeners_,
    438                            listener,
    439                            &have_method_entry_listeners_);
    440   PotentiallyAddListenerTo(kMethodExited,
    441                            events,
    442                            method_exit_listeners_,
    443                            listener,
    444                            &have_method_exit_listeners_);
    445   PotentiallyAddListenerTo(kMethodUnwind,
    446                            events,
    447                            method_unwind_listeners_,
    448                            listener,
    449                            &have_method_unwind_listeners_);
    450   PotentiallyAddListenerTo(kBranch,
    451                            events,
    452                            branch_listeners_,
    453                            listener,
    454                            &have_branch_listeners_);
    455   PotentiallyAddListenerTo(kInvokeVirtualOrInterface,
    456                            events,
    457                            invoke_virtual_or_interface_listeners_,
    458                            listener,
    459                            &have_invoke_virtual_or_interface_listeners_);
    460   PotentiallyAddListenerTo(kDexPcMoved,
    461                            events,
    462                            dex_pc_listeners_,
    463                            listener,
    464                            &have_dex_pc_listeners_);
    465   PotentiallyAddListenerTo(kFieldRead,
    466                            events,
    467                            field_read_listeners_,
    468                            listener,
    469                            &have_field_read_listeners_);
    470   PotentiallyAddListenerTo(kFieldWritten,
    471                            events,
    472                            field_write_listeners_,
    473                            listener,
    474                            &have_field_write_listeners_);
    475   PotentiallyAddListenerTo(kExceptionCaught,
    476                            events,
    477                            exception_caught_listeners_,
    478                            listener,
    479                            &have_exception_caught_listeners_);
    480   UpdateInterpreterHandlerTable();
    481 }
    482 
    483 static void PotentiallyRemoveListenerFrom(Instrumentation::InstrumentationEvent event,
    484                                           uint32_t events,
    485                                           std::list<InstrumentationListener*>& list,
    486                                           InstrumentationListener* listener,
    487                                           bool* has_listener)
    488     REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::classlinker_classes_lock_) {
    489   Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
    490   if (!HasEvent(event, events)) {
    491     return;
    492   }
    493   auto it = std::find(list.begin(), list.end(), listener);
    494   if (it != list.end()) {
    495     // Just update the entry, do not remove from the list. Removing entries in the list
    496     // is unsafe when mutators are iterating over it.
    497     *it = nullptr;
    498   }
    499 
    500   // Check if the list contains any non-null listener, and update 'has_listener'.
    501   for (InstrumentationListener* l : list) {
    502     if (l != nullptr) {
    503       *has_listener = true;
    504       return;
    505     }
    506   }
    507   *has_listener = false;
    508 }
    509 
    510 void Instrumentation::RemoveListener(InstrumentationListener* listener, uint32_t events) {
    511   Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
    512   PotentiallyRemoveListenerFrom(kMethodEntered,
    513                                 events,
    514                                 method_entry_listeners_,
    515                                 listener,
    516                                 &have_method_entry_listeners_);
    517   PotentiallyRemoveListenerFrom(kMethodExited,
    518                                 events,
    519                                 method_exit_listeners_,
    520                                 listener,
    521                                 &have_method_exit_listeners_);
    522   PotentiallyRemoveListenerFrom(kMethodUnwind,
    523                                 events,
    524                                 method_unwind_listeners_,
    525                                 listener,
    526                                 &have_method_unwind_listeners_);
    527   PotentiallyRemoveListenerFrom(kBranch,
    528                                 events,
    529                                 branch_listeners_,
    530                                 listener,
    531                                 &have_branch_listeners_);
    532   PotentiallyRemoveListenerFrom(kInvokeVirtualOrInterface,
    533                                 events,
    534                                 invoke_virtual_or_interface_listeners_,
    535                                 listener,
    536                                 &have_invoke_virtual_or_interface_listeners_);
    537   PotentiallyRemoveListenerFrom(kDexPcMoved,
    538                                 events,
    539                                 dex_pc_listeners_,
    540                                 listener,
    541                                 &have_dex_pc_listeners_);
    542   PotentiallyRemoveListenerFrom(kFieldRead,
    543                                 events,
    544                                 field_read_listeners_,
    545                                 listener,
    546                                 &have_field_read_listeners_);
    547   PotentiallyRemoveListenerFrom(kFieldWritten,
    548                                 events,
    549                                 field_write_listeners_,
    550                                 listener,
    551                                 &have_field_write_listeners_);
    552   PotentiallyRemoveListenerFrom(kExceptionCaught,
    553                                 events,
    554                                 exception_caught_listeners_,
    555                                 listener,
    556                                 &have_exception_caught_listeners_);
    557   UpdateInterpreterHandlerTable();
    558 }
    559 
    560 Instrumentation::InstrumentationLevel Instrumentation::GetCurrentInstrumentationLevel() const {
    561   if (interpreter_stubs_installed_) {
    562     return InstrumentationLevel::kInstrumentWithInterpreter;
    563   } else if (entry_exit_stubs_installed_) {
    564     return InstrumentationLevel::kInstrumentWithInstrumentationStubs;
    565   } else {
    566     return InstrumentationLevel::kInstrumentNothing;
    567   }
    568 }
    569 
    570 bool Instrumentation::RequiresInstrumentationInstallation(InstrumentationLevel new_level) const {
    571   // We need to reinstall instrumentation if we go to a different level.
    572   return GetCurrentInstrumentationLevel() != new_level;
    573 }
    574 
    575 void Instrumentation::ConfigureStubs(const char* key, InstrumentationLevel desired_level) {
    576   // Store the instrumentation level for this key or remove it.
    577   if (desired_level == InstrumentationLevel::kInstrumentNothing) {
    578     // The client no longer needs instrumentation.
    579     requested_instrumentation_levels_.erase(key);
    580   } else {
    581     // The client needs instrumentation.
    582     requested_instrumentation_levels_.Overwrite(key, desired_level);
    583   }
    584 
    585   // Look for the highest required instrumentation level.
    586   InstrumentationLevel requested_level = InstrumentationLevel::kInstrumentNothing;
    587   for (const auto& v : requested_instrumentation_levels_) {
    588     requested_level = std::max(requested_level, v.second);
    589   }
    590 
    591   interpret_only_ = (requested_level == InstrumentationLevel::kInstrumentWithInterpreter) ||
    592                     forced_interpret_only_;
    593 
    594   if (!RequiresInstrumentationInstallation(requested_level)) {
    595     // We're already set.
    596     return;
    597   }
    598   Thread* const self = Thread::Current();
    599   Runtime* runtime = Runtime::Current();
    600   Locks::mutator_lock_->AssertExclusiveHeld(self);
    601   Locks::thread_list_lock_->AssertNotHeld(self);
    602   if (requested_level > InstrumentationLevel::kInstrumentNothing) {
    603     if (requested_level == InstrumentationLevel::kInstrumentWithInterpreter) {
    604       interpreter_stubs_installed_ = true;
    605       entry_exit_stubs_installed_ = true;
    606     } else {
    607       CHECK_EQ(requested_level, InstrumentationLevel::kInstrumentWithInstrumentationStubs);
    608       entry_exit_stubs_installed_ = true;
    609       interpreter_stubs_installed_ = false;
    610     }
    611     InstallStubsClassVisitor visitor(this);
    612     runtime->GetClassLinker()->VisitClasses(&visitor);
    613     instrumentation_stubs_installed_ = true;
    614     MutexLock mu(self, *Locks::thread_list_lock_);
    615     runtime->GetThreadList()->ForEach(InstrumentationInstallStack, this);
    616   } else {
    617     interpreter_stubs_installed_ = false;
    618     entry_exit_stubs_installed_ = false;
    619     InstallStubsClassVisitor visitor(this);
    620     runtime->GetClassLinker()->VisitClasses(&visitor);
    621     // Restore stack only if there is no method currently deoptimized.
    622     bool empty;
    623     {
    624       ReaderMutexLock mu(self, deoptimized_methods_lock_);
    625       empty = IsDeoptimizedMethodsEmpty();  // Avoid lock violation.
    626     }
    627     if (empty) {
    628       MutexLock mu(self, *Locks::thread_list_lock_);
    629       Runtime::Current()->GetThreadList()->ForEach(InstrumentationRestoreStack, this);
    630       // Only do this after restoring, as walking the stack when restoring will see
    631       // the instrumentation exit pc.
    632       instrumentation_stubs_installed_ = false;
    633     }
    634   }
    635 }
    636 
    637 static void ResetQuickAllocEntryPointsForThread(Thread* thread, void* arg ATTRIBUTE_UNUSED) {
    638   thread->ResetQuickAllocEntryPointsForThread(kUseReadBarrier && thread->GetIsGcMarking());
    639 }
    640 
    641 void Instrumentation::SetEntrypointsInstrumented(bool instrumented) {
    642   Thread* self = Thread::Current();
    643   Runtime* runtime = Runtime::Current();
    644   Locks::mutator_lock_->AssertNotHeld(self);
    645   Locks::instrument_entrypoints_lock_->AssertHeld(self);
    646   if (runtime->IsStarted()) {
    647     ScopedSuspendAll ssa(__FUNCTION__);
    648     MutexLock mu(self, *Locks::runtime_shutdown_lock_);
    649     SetQuickAllocEntryPointsInstrumented(instrumented);
    650     ResetQuickAllocEntryPoints();
    651     alloc_entrypoints_instrumented_ = instrumented;
    652   } else {
    653     MutexLock mu(self, *Locks::runtime_shutdown_lock_);
    654     SetQuickAllocEntryPointsInstrumented(instrumented);
    655 
    656     // Note: ResetQuickAllocEntryPoints only works when the runtime is started. Manually run the
    657     //       update for just this thread.
    658     // Note: self may be null. One of those paths is setting instrumentation in the Heap
    659     //       constructor for gcstress mode.
    660     if (self != nullptr) {
    661       ResetQuickAllocEntryPointsForThread(self, nullptr);
    662     }
    663 
    664     alloc_entrypoints_instrumented_ = instrumented;
    665   }
    666 }
    667 
    668 void Instrumentation::InstrumentQuickAllocEntryPoints() {
    669   MutexLock mu(Thread::Current(), *Locks::instrument_entrypoints_lock_);
    670   InstrumentQuickAllocEntryPointsLocked();
    671 }
    672 
    673 void Instrumentation::UninstrumentQuickAllocEntryPoints() {
    674   MutexLock mu(Thread::Current(), *Locks::instrument_entrypoints_lock_);
    675   UninstrumentQuickAllocEntryPointsLocked();
    676 }
    677 
    678 void Instrumentation::InstrumentQuickAllocEntryPointsLocked() {
    679   Locks::instrument_entrypoints_lock_->AssertHeld(Thread::Current());
    680   if (quick_alloc_entry_points_instrumentation_counter_ == 0) {
    681     SetEntrypointsInstrumented(true);
    682   }
    683   ++quick_alloc_entry_points_instrumentation_counter_;
    684 }
    685 
    686 void Instrumentation::UninstrumentQuickAllocEntryPointsLocked() {
    687   Locks::instrument_entrypoints_lock_->AssertHeld(Thread::Current());
    688   CHECK_GT(quick_alloc_entry_points_instrumentation_counter_, 0U);
    689   --quick_alloc_entry_points_instrumentation_counter_;
    690   if (quick_alloc_entry_points_instrumentation_counter_ == 0) {
    691     SetEntrypointsInstrumented(false);
    692   }
    693 }
    694 
    695 void Instrumentation::ResetQuickAllocEntryPoints() {
    696   Runtime* runtime = Runtime::Current();
    697   if (runtime->IsStarted()) {
    698     MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
    699     runtime->GetThreadList()->ForEach(ResetQuickAllocEntryPointsForThread, nullptr);
    700   }
    701 }
    702 
    703 void Instrumentation::UpdateMethodsCodeImpl(ArtMethod* method, const void* quick_code) {
    704   const void* new_quick_code;
    705   if (LIKELY(!instrumentation_stubs_installed_)) {
    706     new_quick_code = quick_code;
    707   } else {
    708     if ((interpreter_stubs_installed_ || IsDeoptimized(method)) && !method->IsNative()) {
    709       new_quick_code = GetQuickToInterpreterBridge();
    710     } else {
    711       ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
    712       if (class_linker->IsQuickResolutionStub(quick_code) ||
    713           class_linker->IsQuickToInterpreterBridge(quick_code)) {
    714         new_quick_code = quick_code;
    715       } else if (entry_exit_stubs_installed_) {
    716         new_quick_code = GetQuickInstrumentationEntryPoint();
    717       } else {
    718         new_quick_code = quick_code;
    719       }
    720     }
    721   }
    722   UpdateEntrypoints(method, new_quick_code);
    723 }
    724 
    725 void Instrumentation::UpdateMethodsCode(ArtMethod* method, const void* quick_code) {
    726   DCHECK(method->GetDeclaringClass()->IsResolved());
    727   UpdateMethodsCodeImpl(method, quick_code);
    728 }
    729 
    730 void Instrumentation::UpdateMethodsCodeForJavaDebuggable(ArtMethod* method,
    731                                                          const void* quick_code) {
    732   // When the runtime is set to Java debuggable, we may update the entry points of
    733   // all methods of a class to the interpreter bridge. A method's declaring class
    734   // might not be in resolved state yet in that case, so we bypass the DCHECK in
    735   // UpdateMethodsCode.
    736   UpdateMethodsCodeImpl(method, quick_code);
    737 }
    738 
    739 bool Instrumentation::AddDeoptimizedMethod(ArtMethod* method) {
    740   if (IsDeoptimizedMethod(method)) {
    741     // Already in the map. Return.
    742     return false;
    743   }
    744   // Not found. Add it.
    745   deoptimized_methods_.insert(method);
    746   return true;
    747 }
    748 
    749 bool Instrumentation::IsDeoptimizedMethod(ArtMethod* method) {
    750   return deoptimized_methods_.find(method) != deoptimized_methods_.end();
    751 }
    752 
    753 ArtMethod* Instrumentation::BeginDeoptimizedMethod() {
    754   if (deoptimized_methods_.empty()) {
    755     // Empty.
    756     return nullptr;
    757   }
    758   return *deoptimized_methods_.begin();
    759 }
    760 
    761 bool Instrumentation::RemoveDeoptimizedMethod(ArtMethod* method) {
    762   auto it = deoptimized_methods_.find(method);
    763   if (it == deoptimized_methods_.end()) {
    764     return false;
    765   }
    766   deoptimized_methods_.erase(it);
    767   return true;
    768 }
    769 
    770 bool Instrumentation::IsDeoptimizedMethodsEmpty() const {
    771   return deoptimized_methods_.empty();
    772 }
    773 
    774 void Instrumentation::Deoptimize(ArtMethod* method) {
    775   CHECK(!method->IsNative());
    776   CHECK(!method->IsProxyMethod());
    777   CHECK(method->IsInvokable());
    778 
    779   Thread* self = Thread::Current();
    780   {
    781     WriterMutexLock mu(self, deoptimized_methods_lock_);
    782     bool has_not_been_deoptimized = AddDeoptimizedMethod(method);
    783     CHECK(has_not_been_deoptimized) << "Method " << ArtMethod::PrettyMethod(method)
    784         << " is already deoptimized";
    785   }
    786   if (!interpreter_stubs_installed_) {
    787     UpdateEntrypoints(method, GetQuickInstrumentationEntryPoint());
    788 
    789     // Install instrumentation exit stub and instrumentation frames. We may already have installed
    790     // these previously so it will only cover the newly created frames.
    791     instrumentation_stubs_installed_ = true;
    792     MutexLock mu(self, *Locks::thread_list_lock_);
    793     Runtime::Current()->GetThreadList()->ForEach(InstrumentationInstallStack, this);
    794   }
    795 }
    796 
    797 void Instrumentation::Undeoptimize(ArtMethod* method) {
    798   CHECK(!method->IsNative());
    799   CHECK(!method->IsProxyMethod());
    800   CHECK(method->IsInvokable());
    801 
    802   Thread* self = Thread::Current();
    803   bool empty;
    804   {
    805     WriterMutexLock mu(self, deoptimized_methods_lock_);
    806     bool found_and_erased = RemoveDeoptimizedMethod(method);
    807     CHECK(found_and_erased) << "Method " << ArtMethod::PrettyMethod(method)
    808         << " is not deoptimized";
    809     empty = IsDeoptimizedMethodsEmpty();
    810   }
    811 
    812   // Restore code and possibly stack only if we did not deoptimize everything.
    813   if (!interpreter_stubs_installed_) {
    814     // Restore its code or resolution trampoline.
    815     ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
    816     if (method->IsStatic() && !method->IsConstructor() &&
    817         !method->GetDeclaringClass()->IsInitialized()) {
    818       UpdateEntrypoints(method, GetQuickResolutionStub());
    819     } else {
    820       const void* quick_code = NeedDebugVersionFor(method)
    821           ? GetQuickToInterpreterBridge()
    822           : class_linker->GetQuickOatCodeFor(method);
    823       UpdateEntrypoints(method, quick_code);
    824     }
    825 
    826     // If there is no deoptimized method left, we can restore the stack of each thread.
    827     if (empty) {
    828       MutexLock mu(self, *Locks::thread_list_lock_);
    829       Runtime::Current()->GetThreadList()->ForEach(InstrumentationRestoreStack, this);
    830       instrumentation_stubs_installed_ = false;
    831     }
    832   }
    833 }
    834 
    835 bool Instrumentation::IsDeoptimized(ArtMethod* method) {
    836   DCHECK(method != nullptr);
    837   ReaderMutexLock mu(Thread::Current(), deoptimized_methods_lock_);
    838   return IsDeoptimizedMethod(method);
    839 }
    840 
    841 void Instrumentation::EnableDeoptimization() {
    842   ReaderMutexLock mu(Thread::Current(), deoptimized_methods_lock_);
    843   CHECK(IsDeoptimizedMethodsEmpty());
    844   CHECK_EQ(deoptimization_enabled_, false);
    845   deoptimization_enabled_ = true;
    846 }
    847 
    848 void Instrumentation::DisableDeoptimization(const char* key) {
    849   CHECK_EQ(deoptimization_enabled_, true);
    850   // If we deoptimized everything, undo it.
    851   InstrumentationLevel level = GetCurrentInstrumentationLevel();
    852   if (level == InstrumentationLevel::kInstrumentWithInterpreter) {
    853     UndeoptimizeEverything(key);
    854   }
    855   // Undeoptimized selected methods.
    856   while (true) {
    857     ArtMethod* method;
    858     {
    859       ReaderMutexLock mu(Thread::Current(), deoptimized_methods_lock_);
    860       if (IsDeoptimizedMethodsEmpty()) {
    861         break;
    862       }
    863       method = BeginDeoptimizedMethod();
    864       CHECK(method != nullptr);
    865     }
    866     Undeoptimize(method);
    867   }
    868   deoptimization_enabled_ = false;
    869 }
    870 
    871 // Indicates if instrumentation should notify method enter/exit events to the listeners.
    872 bool Instrumentation::ShouldNotifyMethodEnterExitEvents() const {
    873   if (!HasMethodEntryListeners() && !HasMethodExitListeners()) {
    874     return false;
    875   }
    876   return !deoptimization_enabled_ && !interpreter_stubs_installed_;
    877 }
    878 
    879 void Instrumentation::DeoptimizeEverything(const char* key) {
    880   CHECK(deoptimization_enabled_);
    881   ConfigureStubs(key, InstrumentationLevel::kInstrumentWithInterpreter);
    882 }
    883 
    884 void Instrumentation::UndeoptimizeEverything(const char* key) {
    885   CHECK(interpreter_stubs_installed_);
    886   CHECK(deoptimization_enabled_);
    887   ConfigureStubs(key, InstrumentationLevel::kInstrumentNothing);
    888 }
    889 
    890 void Instrumentation::EnableMethodTracing(const char* key, bool needs_interpreter) {
    891   InstrumentationLevel level;
    892   if (needs_interpreter) {
    893     level = InstrumentationLevel::kInstrumentWithInterpreter;
    894   } else {
    895     level = InstrumentationLevel::kInstrumentWithInstrumentationStubs;
    896   }
    897   ConfigureStubs(key, level);
    898 }
    899 
    900 void Instrumentation::DisableMethodTracing(const char* key) {
    901   ConfigureStubs(key, InstrumentationLevel::kInstrumentNothing);
    902 }
    903 
    904 const void* Instrumentation::GetQuickCodeFor(ArtMethod* method, PointerSize pointer_size) const {
    905   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
    906   if (LIKELY(!instrumentation_stubs_installed_)) {
    907     const void* code = method->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size);
    908     DCHECK(code != nullptr);
    909     if (LIKELY(!class_linker->IsQuickResolutionStub(code) &&
    910                !class_linker->IsQuickToInterpreterBridge(code)) &&
    911                !class_linker->IsQuickResolutionStub(code) &&
    912                !class_linker->IsQuickToInterpreterBridge(code)) {
    913       return code;
    914     }
    915   }
    916   return class_linker->GetQuickOatCodeFor(method);
    917 }
    918 
    919 void Instrumentation::MethodEnterEventImpl(Thread* thread, mirror::Object* this_object,
    920                                            ArtMethod* method,
    921                                            uint32_t dex_pc) const {
    922   if (HasMethodEntryListeners()) {
    923     for (InstrumentationListener* listener : method_entry_listeners_) {
    924       if (listener != nullptr) {
    925         listener->MethodEntered(thread, this_object, method, dex_pc);
    926       }
    927     }
    928   }
    929 }
    930 
    931 void Instrumentation::MethodExitEventImpl(Thread* thread, mirror::Object* this_object,
    932                                           ArtMethod* method,
    933                                           uint32_t dex_pc, const JValue& return_value) const {
    934   if (HasMethodExitListeners()) {
    935     for (InstrumentationListener* listener : method_exit_listeners_) {
    936       if (listener != nullptr) {
    937         listener->MethodExited(thread, this_object, method, dex_pc, return_value);
    938       }
    939     }
    940   }
    941 }
    942 
    943 void Instrumentation::MethodUnwindEvent(Thread* thread, mirror::Object* this_object,
    944                                         ArtMethod* method,
    945                                         uint32_t dex_pc) const {
    946   if (HasMethodUnwindListeners()) {
    947     for (InstrumentationListener* listener : method_unwind_listeners_) {
    948       if (listener != nullptr) {
    949         listener->MethodUnwind(thread, this_object, method, dex_pc);
    950       }
    951     }
    952   }
    953 }
    954 
    955 void Instrumentation::DexPcMovedEventImpl(Thread* thread, mirror::Object* this_object,
    956                                           ArtMethod* method,
    957                                           uint32_t dex_pc) const {
    958   for (InstrumentationListener* listener : dex_pc_listeners_) {
    959     if (listener != nullptr) {
    960       listener->DexPcMoved(thread, this_object, method, dex_pc);
    961     }
    962   }
    963 }
    964 
    965 void Instrumentation::BranchImpl(Thread* thread,
    966                                  ArtMethod* method,
    967                                  uint32_t dex_pc,
    968                                  int32_t offset) const {
    969   for (InstrumentationListener* listener : branch_listeners_) {
    970     if (listener != nullptr) {
    971       listener->Branch(thread, method, dex_pc, offset);
    972     }
    973   }
    974 }
    975 
    976 void Instrumentation::InvokeVirtualOrInterfaceImpl(Thread* thread,
    977                                                    mirror::Object* this_object,
    978                                                    ArtMethod* caller,
    979                                                    uint32_t dex_pc,
    980                                                    ArtMethod* callee) const {
    981   // We cannot have thread suspension since that would cause the this_object parameter to
    982   // potentially become a dangling pointer. An alternative could be to put it in a handle instead.
    983   ScopedAssertNoThreadSuspension ants(__FUNCTION__);
    984   for (InstrumentationListener* listener : invoke_virtual_or_interface_listeners_) {
    985     if (listener != nullptr) {
    986       listener->InvokeVirtualOrInterface(thread, this_object, caller, dex_pc, callee);
    987     }
    988   }
    989 }
    990 
    991 void Instrumentation::FieldReadEventImpl(Thread* thread, mirror::Object* this_object,
    992                                          ArtMethod* method, uint32_t dex_pc,
    993                                          ArtField* field) const {
    994   for (InstrumentationListener* listener : field_read_listeners_) {
    995     if (listener != nullptr) {
    996       listener->FieldRead(thread, this_object, method, dex_pc, field);
    997     }
    998   }
    999 }
   1000 
   1001 void Instrumentation::FieldWriteEventImpl(Thread* thread, mirror::Object* this_object,
   1002                                          ArtMethod* method, uint32_t dex_pc,
   1003                                          ArtField* field, const JValue& field_value) const {
   1004   for (InstrumentationListener* listener : field_write_listeners_) {
   1005     if (listener != nullptr) {
   1006       listener->FieldWritten(thread, this_object, method, dex_pc, field, field_value);
   1007     }
   1008   }
   1009 }
   1010 
   1011 void Instrumentation::ExceptionCaughtEvent(Thread* thread,
   1012                                            mirror::Throwable* exception_object) const {
   1013   Thread* self = Thread::Current();
   1014   StackHandleScope<1> hs(self);
   1015   Handle<mirror::Throwable> h_exception(hs.NewHandle(exception_object));
   1016   if (HasExceptionCaughtListeners()) {
   1017     DCHECK_EQ(thread->GetException(), h_exception.Get());
   1018     thread->ClearException();
   1019     for (InstrumentationListener* listener : exception_caught_listeners_) {
   1020       if (listener != nullptr) {
   1021         listener->ExceptionCaught(thread, h_exception.Get());
   1022       }
   1023     }
   1024     thread->SetException(h_exception.Get());
   1025   }
   1026 }
   1027 
   1028 // Computes a frame ID by ignoring inlined frames.
   1029 size_t Instrumentation::ComputeFrameId(Thread* self,
   1030                                        size_t frame_depth,
   1031                                        size_t inlined_frames_before_frame) {
   1032   CHECK_GE(frame_depth, inlined_frames_before_frame);
   1033   size_t no_inline_depth = frame_depth - inlined_frames_before_frame;
   1034   return StackVisitor::ComputeNumFrames(self, kInstrumentationStackWalk) - no_inline_depth;
   1035 }
   1036 
   1037 static void CheckStackDepth(Thread* self, const InstrumentationStackFrame& instrumentation_frame,
   1038                             int delta)
   1039     REQUIRES_SHARED(Locks::mutator_lock_) {
   1040   size_t frame_id = StackVisitor::ComputeNumFrames(self, kInstrumentationStackWalk) + delta;
   1041   if (frame_id != instrumentation_frame.frame_id_) {
   1042     LOG(ERROR) << "Expected frame_id=" << frame_id << " but found "
   1043         << instrumentation_frame.frame_id_;
   1044     StackVisitor::DescribeStack(self);
   1045     CHECK_EQ(frame_id, instrumentation_frame.frame_id_);
   1046   }
   1047 }
   1048 
   1049 void Instrumentation::PushInstrumentationStackFrame(Thread* self, mirror::Object* this_object,
   1050                                                     ArtMethod* method,
   1051                                                     uintptr_t lr, bool interpreter_entry) {
   1052   // We have a callee-save frame meaning this value is guaranteed to never be 0.
   1053   size_t frame_id = StackVisitor::ComputeNumFrames(self, kInstrumentationStackWalk);
   1054   std::deque<instrumentation::InstrumentationStackFrame>* stack = self->GetInstrumentationStack();
   1055   if (kVerboseInstrumentation) {
   1056     LOG(INFO) << "Entering " << ArtMethod::PrettyMethod(method) << " from PC "
   1057               << reinterpret_cast<void*>(lr);
   1058   }
   1059   instrumentation::InstrumentationStackFrame instrumentation_frame(this_object, method, lr,
   1060                                                                    frame_id, interpreter_entry);
   1061   stack->push_front(instrumentation_frame);
   1062 
   1063   if (!interpreter_entry) {
   1064     MethodEnterEvent(self, this_object, method, 0);
   1065   }
   1066 }
   1067 
   1068 TwoWordReturn Instrumentation::PopInstrumentationStackFrame(Thread* self, uintptr_t* return_pc,
   1069                                                             uint64_t gpr_result,
   1070                                                             uint64_t fpr_result) {
   1071   // Do the pop.
   1072   std::deque<instrumentation::InstrumentationStackFrame>* stack = self->GetInstrumentationStack();
   1073   CHECK_GT(stack->size(), 0U);
   1074   InstrumentationStackFrame instrumentation_frame = stack->front();
   1075   stack->pop_front();
   1076 
   1077   // Set return PC and check the sanity of the stack.
   1078   *return_pc = instrumentation_frame.return_pc_;
   1079   CheckStackDepth(self, instrumentation_frame, 0);
   1080   self->VerifyStack();
   1081 
   1082   ArtMethod* method = instrumentation_frame.method_;
   1083   uint32_t length;
   1084   const PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
   1085   char return_shorty = method->GetInterfaceMethodIfProxy(pointer_size)->GetShorty(&length)[0];
   1086   JValue return_value;
   1087   if (return_shorty == 'V') {
   1088     return_value.SetJ(0);
   1089   } else if (return_shorty == 'F' || return_shorty == 'D') {
   1090     return_value.SetJ(fpr_result);
   1091   } else {
   1092     return_value.SetJ(gpr_result);
   1093   }
   1094   // TODO: improve the dex pc information here, requires knowledge of current PC as opposed to
   1095   //       return_pc.
   1096   uint32_t dex_pc = DexFile::kDexNoIndex;
   1097   mirror::Object* this_object = instrumentation_frame.this_object_;
   1098   if (!instrumentation_frame.interpreter_entry_) {
   1099     MethodExitEvent(self, this_object, instrumentation_frame.method_, dex_pc, return_value);
   1100   }
   1101 
   1102   // Deoptimize if the caller needs to continue execution in the interpreter. Do nothing if we get
   1103   // back to an upcall.
   1104   NthCallerVisitor visitor(self, 1, true);
   1105   visitor.WalkStack(true);
   1106   bool deoptimize = (visitor.caller != nullptr) &&
   1107                     (interpreter_stubs_installed_ || IsDeoptimized(visitor.caller) ||
   1108                     Dbg::IsForcedInterpreterNeededForUpcall(self, visitor.caller));
   1109   if (deoptimize && Runtime::Current()->IsAsyncDeoptimizeable(*return_pc)) {
   1110     if (kVerboseInstrumentation) {
   1111       LOG(INFO) << "Deoptimizing "
   1112                 << visitor.caller->PrettyMethod()
   1113                 << " by returning from "
   1114                 << method->PrettyMethod()
   1115                 << " with result "
   1116                 << std::hex << return_value.GetJ() << std::dec
   1117                 << " in "
   1118                 << *self;
   1119     }
   1120     self->PushDeoptimizationContext(return_value,
   1121                                     return_shorty == 'L',
   1122                                     false /* from_code */,
   1123                                     nullptr /* no pending exception */);
   1124     return GetTwoWordSuccessValue(*return_pc,
   1125                                   reinterpret_cast<uintptr_t>(GetQuickDeoptimizationEntryPoint()));
   1126   } else {
   1127     if (deoptimize && !Runtime::Current()->IsAsyncDeoptimizeable(*return_pc)) {
   1128       LOG(WARNING) << "Got a deoptimization request on un-deoptimizable " << method->PrettyMethod()
   1129                    << " at PC " << reinterpret_cast<void*>(*return_pc);
   1130     }
   1131     if (kVerboseInstrumentation) {
   1132       LOG(INFO) << "Returning from " << method->PrettyMethod()
   1133                 << " to PC " << reinterpret_cast<void*>(*return_pc);
   1134     }
   1135     return GetTwoWordSuccessValue(0, *return_pc);
   1136   }
   1137 }
   1138 
   1139 uintptr_t Instrumentation::PopMethodForUnwind(Thread* self, bool is_deoptimization) const {
   1140   // Do the pop.
   1141   std::deque<instrumentation::InstrumentationStackFrame>* stack = self->GetInstrumentationStack();
   1142   CHECK_GT(stack->size(), 0U);
   1143   InstrumentationStackFrame instrumentation_frame = stack->front();
   1144   // TODO: bring back CheckStackDepth(self, instrumentation_frame, 2);
   1145   stack->pop_front();
   1146 
   1147   ArtMethod* method = instrumentation_frame.method_;
   1148   if (is_deoptimization) {
   1149     if (kVerboseInstrumentation) {
   1150       LOG(INFO) << "Popping for deoptimization " << ArtMethod::PrettyMethod(method);
   1151     }
   1152   } else {
   1153     if (kVerboseInstrumentation) {
   1154       LOG(INFO) << "Popping for unwind " << ArtMethod::PrettyMethod(method);
   1155     }
   1156 
   1157     // Notify listeners of method unwind.
   1158     // TODO: improve the dex pc information here, requires knowledge of current PC as opposed to
   1159     //       return_pc.
   1160     uint32_t dex_pc = DexFile::kDexNoIndex;
   1161     MethodUnwindEvent(self, instrumentation_frame.this_object_, method, dex_pc);
   1162   }
   1163   return instrumentation_frame.return_pc_;
   1164 }
   1165 
   1166 std::string InstrumentationStackFrame::Dump() const {
   1167   std::ostringstream os;
   1168   os << "Frame " << frame_id_ << " " << ArtMethod::PrettyMethod(method_) << ":"
   1169       << reinterpret_cast<void*>(return_pc_) << " this=" << reinterpret_cast<void*>(this_object_);
   1170   return os.str();
   1171 }
   1172 
   1173 }  // namespace instrumentation
   1174 }  // namespace art
   1175