xref: /aosp_15_r20/art/runtime/instrumentation.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2011 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include "instrumentation.h"
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include <functional>
20*795d594fSAndroid Build Coastguard Worker #include <optional>
21*795d594fSAndroid Build Coastguard Worker #include <sstream>
22*795d594fSAndroid Build Coastguard Worker 
23*795d594fSAndroid Build Coastguard Worker #include <android-base/logging.h>
24*795d594fSAndroid Build Coastguard Worker 
25*795d594fSAndroid Build Coastguard Worker #include "arch/context.h"
26*795d594fSAndroid Build Coastguard Worker #include "art_field-inl.h"
27*795d594fSAndroid Build Coastguard Worker #include "art_method-inl.h"
28*795d594fSAndroid Build Coastguard Worker #include "base/atomic.h"
29*795d594fSAndroid Build Coastguard Worker #include "base/callee_save_type.h"
30*795d594fSAndroid Build Coastguard Worker #include "class_linker.h"
31*795d594fSAndroid Build Coastguard Worker #include "debugger.h"
32*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file-inl.h"
33*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file_types.h"
34*795d594fSAndroid Build Coastguard Worker #include "dex/dex_instruction-inl.h"
35*795d594fSAndroid Build Coastguard Worker #include "entrypoints/quick/quick_alloc_entrypoints.h"
36*795d594fSAndroid Build Coastguard Worker #include "entrypoints/quick/quick_entrypoints.h"
37*795d594fSAndroid Build Coastguard Worker #include "entrypoints/quick/runtime_entrypoints_list.h"
38*795d594fSAndroid Build Coastguard Worker #include "entrypoints/runtime_asm_entrypoints.h"
39*795d594fSAndroid Build Coastguard Worker #include "gc_root-inl.h"
40*795d594fSAndroid Build Coastguard Worker #include "interpreter/interpreter.h"
41*795d594fSAndroid Build Coastguard Worker #include "interpreter/interpreter_common.h"
42*795d594fSAndroid Build Coastguard Worker #include "jit/jit.h"
43*795d594fSAndroid Build Coastguard Worker #include "jit/jit_code_cache.h"
44*795d594fSAndroid Build Coastguard Worker #include "jvalue-inl.h"
45*795d594fSAndroid Build Coastguard Worker #include "jvalue.h"
46*795d594fSAndroid Build Coastguard Worker #include "mirror/class-inl.h"
47*795d594fSAndroid Build Coastguard Worker #include "mirror/dex_cache.h"
48*795d594fSAndroid Build Coastguard Worker #include "mirror/object-inl.h"
49*795d594fSAndroid Build Coastguard Worker #include "mirror/object_array-inl.h"
50*795d594fSAndroid Build Coastguard Worker #include "nterp_helpers.h"
51*795d594fSAndroid Build Coastguard Worker #include "nth_caller_visitor.h"
52*795d594fSAndroid Build Coastguard Worker #include "oat/oat_file_manager.h"
53*795d594fSAndroid Build Coastguard Worker #include "oat/oat_quick_method_header.h"
54*795d594fSAndroid Build Coastguard Worker #include "runtime-inl.h"
55*795d594fSAndroid Build Coastguard Worker #include "thread.h"
56*795d594fSAndroid Build Coastguard Worker #include "thread_list.h"
57*795d594fSAndroid Build Coastguard Worker 
58*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
59*795d594fSAndroid Build Coastguard Worker 
60*795d594fSAndroid Build Coastguard Worker namespace instrumentation {
61*795d594fSAndroid Build Coastguard Worker 
62*795d594fSAndroid Build Coastguard Worker constexpr bool kVerboseInstrumentation = false;
63*795d594fSAndroid Build Coastguard Worker 
MethodExited(Thread * thread,ArtMethod * method,OptionalFrame frame,MutableHandle<mirror::Object> & return_value)64*795d594fSAndroid Build Coastguard Worker void InstrumentationListener::MethodExited(
65*795d594fSAndroid Build Coastguard Worker     Thread* thread,
66*795d594fSAndroid Build Coastguard Worker     ArtMethod* method,
67*795d594fSAndroid Build Coastguard Worker     OptionalFrame frame,
68*795d594fSAndroid Build Coastguard Worker     MutableHandle<mirror::Object>& return_value) {
69*795d594fSAndroid Build Coastguard Worker   DCHECK_EQ(method->GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetReturnTypePrimitive(),
70*795d594fSAndroid Build Coastguard Worker             Primitive::kPrimNot);
71*795d594fSAndroid Build Coastguard Worker   const void* original_ret = return_value.Get();
72*795d594fSAndroid Build Coastguard Worker   JValue v;
73*795d594fSAndroid Build Coastguard Worker   v.SetL(return_value.Get());
74*795d594fSAndroid Build Coastguard Worker   MethodExited(thread, method, frame, v);
75*795d594fSAndroid Build Coastguard Worker   DCHECK(original_ret == v.GetL()) << "Return value changed";
76*795d594fSAndroid Build Coastguard Worker }
77*795d594fSAndroid Build Coastguard Worker 
FieldWritten(Thread * thread,Handle<mirror::Object> this_object,ArtMethod * method,uint32_t dex_pc,ArtField * field,Handle<mirror::Object> field_value)78*795d594fSAndroid Build Coastguard Worker void InstrumentationListener::FieldWritten(Thread* thread,
79*795d594fSAndroid Build Coastguard Worker                                            Handle<mirror::Object> this_object,
80*795d594fSAndroid Build Coastguard Worker                                            ArtMethod* method,
81*795d594fSAndroid Build Coastguard Worker                                            uint32_t dex_pc,
82*795d594fSAndroid Build Coastguard Worker                                            ArtField* field,
83*795d594fSAndroid Build Coastguard Worker                                            Handle<mirror::Object> field_value) {
84*795d594fSAndroid Build Coastguard Worker   DCHECK(!field->IsPrimitiveType());
85*795d594fSAndroid Build Coastguard Worker   JValue v;
86*795d594fSAndroid Build Coastguard Worker   v.SetL(field_value.Get());
87*795d594fSAndroid Build Coastguard Worker   FieldWritten(thread, this_object, method, dex_pc, field, v);
88*795d594fSAndroid Build Coastguard Worker }
89*795d594fSAndroid Build Coastguard Worker 
90*795d594fSAndroid Build Coastguard Worker // Instrumentation works on non-inlined frames by updating returned PCs
91*795d594fSAndroid Build Coastguard Worker // of compiled frames.
92*795d594fSAndroid Build Coastguard Worker static constexpr StackVisitor::StackWalkKind kInstrumentationStackWalk =
93*795d594fSAndroid Build Coastguard Worker     StackVisitor::StackWalkKind::kSkipInlinedFrames;
94*795d594fSAndroid Build Coastguard Worker 
95*795d594fSAndroid Build Coastguard Worker class InstallStubsClassVisitor : public ClassVisitor {
96*795d594fSAndroid Build Coastguard Worker  public:
InstallStubsClassVisitor(Instrumentation * instrumentation)97*795d594fSAndroid Build Coastguard Worker   explicit InstallStubsClassVisitor(Instrumentation* instrumentation)
98*795d594fSAndroid Build Coastguard Worker       : instrumentation_(instrumentation) {}
99*795d594fSAndroid Build Coastguard Worker 
operator ()(ObjPtr<mirror::Class> klass)100*795d594fSAndroid Build Coastguard Worker   bool operator()(ObjPtr<mirror::Class> klass) override REQUIRES(Locks::mutator_lock_) {
101*795d594fSAndroid Build Coastguard Worker     instrumentation_->InstallStubsForClass(klass.Ptr());
102*795d594fSAndroid Build Coastguard Worker     return true;  // we visit all classes.
103*795d594fSAndroid Build Coastguard Worker   }
104*795d594fSAndroid Build Coastguard Worker 
105*795d594fSAndroid Build Coastguard Worker  private:
106*795d594fSAndroid Build Coastguard Worker   Instrumentation* const instrumentation_;
107*795d594fSAndroid Build Coastguard Worker };
108*795d594fSAndroid Build Coastguard Worker 
Instrumentation()109*795d594fSAndroid Build Coastguard Worker Instrumentation::Instrumentation()
110*795d594fSAndroid Build Coastguard Worker     : run_exit_hooks_(false),
111*795d594fSAndroid Build Coastguard Worker       instrumentation_level_(InstrumentationLevel::kInstrumentNothing),
112*795d594fSAndroid Build Coastguard Worker       forced_interpret_only_(false),
113*795d594fSAndroid Build Coastguard Worker       have_method_entry_listeners_(0),
114*795d594fSAndroid Build Coastguard Worker       have_method_exit_listeners_(0),
115*795d594fSAndroid Build Coastguard Worker       have_method_unwind_listeners_(false),
116*795d594fSAndroid Build Coastguard Worker       have_dex_pc_listeners_(false),
117*795d594fSAndroid Build Coastguard Worker       have_field_read_listeners_(false),
118*795d594fSAndroid Build Coastguard Worker       have_field_write_listeners_(false),
119*795d594fSAndroid Build Coastguard Worker       have_exception_thrown_listeners_(false),
120*795d594fSAndroid Build Coastguard Worker       have_watched_frame_pop_listeners_(false),
121*795d594fSAndroid Build Coastguard Worker       have_branch_listeners_(false),
122*795d594fSAndroid Build Coastguard Worker       have_exception_handled_listeners_(false),
123*795d594fSAndroid Build Coastguard Worker       quick_alloc_entry_points_instrumentation_counter_(0),
124*795d594fSAndroid Build Coastguard Worker       alloc_entrypoints_instrumented_(false) {}
125*795d594fSAndroid Build Coastguard Worker 
ProcessMethodUnwindCallbacks(Thread * self,std::queue<ArtMethod * > & methods,MutableHandle<mirror::Throwable> & exception)126*795d594fSAndroid Build Coastguard Worker bool Instrumentation::ProcessMethodUnwindCallbacks(Thread* self,
127*795d594fSAndroid Build Coastguard Worker                                                    std::queue<ArtMethod*>& methods,
128*795d594fSAndroid Build Coastguard Worker                                                    MutableHandle<mirror::Throwable>& exception) {
129*795d594fSAndroid Build Coastguard Worker   DCHECK(!self->IsExceptionPending());
130*795d594fSAndroid Build Coastguard Worker   if (!HasMethodUnwindListeners()) {
131*795d594fSAndroid Build Coastguard Worker     return true;
132*795d594fSAndroid Build Coastguard Worker   }
133*795d594fSAndroid Build Coastguard Worker   if (kVerboseInstrumentation) {
134*795d594fSAndroid Build Coastguard Worker     LOG(INFO) << "Popping frames for exception " << exception->Dump();
135*795d594fSAndroid Build Coastguard Worker   }
136*795d594fSAndroid Build Coastguard Worker   // The instrumentation events expect the exception to be set.
137*795d594fSAndroid Build Coastguard Worker   self->SetException(exception.Get());
138*795d594fSAndroid Build Coastguard Worker   bool new_exception_thrown = false;
139*795d594fSAndroid Build Coastguard Worker 
140*795d594fSAndroid Build Coastguard Worker   // Process callbacks for all methods that would be unwound until a new exception is thrown.
141*795d594fSAndroid Build Coastguard Worker   while (!methods.empty()) {
142*795d594fSAndroid Build Coastguard Worker     ArtMethod* method = methods.front();
143*795d594fSAndroid Build Coastguard Worker     methods.pop();
144*795d594fSAndroid Build Coastguard Worker     if (kVerboseInstrumentation) {
145*795d594fSAndroid Build Coastguard Worker       LOG(INFO) << "Popping for unwind " << method->PrettyMethod();
146*795d594fSAndroid Build Coastguard Worker     }
147*795d594fSAndroid Build Coastguard Worker 
148*795d594fSAndroid Build Coastguard Worker     if (method->IsRuntimeMethod()) {
149*795d594fSAndroid Build Coastguard Worker       continue;
150*795d594fSAndroid Build Coastguard Worker     }
151*795d594fSAndroid Build Coastguard Worker 
152*795d594fSAndroid Build Coastguard Worker     // Notify listeners of method unwind.
153*795d594fSAndroid Build Coastguard Worker     // TODO: improve the dex_pc information here.
154*795d594fSAndroid Build Coastguard Worker     uint32_t dex_pc = dex::kDexNoIndex;
155*795d594fSAndroid Build Coastguard Worker     MethodUnwindEvent(self, method, dex_pc);
156*795d594fSAndroid Build Coastguard Worker     new_exception_thrown = self->GetException() != exception.Get();
157*795d594fSAndroid Build Coastguard Worker     if (new_exception_thrown) {
158*795d594fSAndroid Build Coastguard Worker       break;
159*795d594fSAndroid Build Coastguard Worker     }
160*795d594fSAndroid Build Coastguard Worker   }
161*795d594fSAndroid Build Coastguard Worker 
162*795d594fSAndroid Build Coastguard Worker   exception.Assign(self->GetException());
163*795d594fSAndroid Build Coastguard Worker   self->ClearException();
164*795d594fSAndroid Build Coastguard Worker   if (kVerboseInstrumentation && new_exception_thrown) {
165*795d594fSAndroid Build Coastguard Worker     LOG(INFO) << "Did partial pop of frames due to new exception";
166*795d594fSAndroid Build Coastguard Worker   }
167*795d594fSAndroid Build Coastguard Worker   return !new_exception_thrown;
168*795d594fSAndroid Build Coastguard Worker }
169*795d594fSAndroid Build Coastguard Worker 
InstallStubsForClass(ObjPtr<mirror::Class> klass)170*795d594fSAndroid Build Coastguard Worker void Instrumentation::InstallStubsForClass(ObjPtr<mirror::Class> klass) {
171*795d594fSAndroid Build Coastguard Worker   if (!klass->IsResolved()) {
172*795d594fSAndroid Build Coastguard Worker     // We need the class to be resolved to install/uninstall stubs. Otherwise its methods
173*795d594fSAndroid Build Coastguard Worker     // could not be initialized or linked with regards to class inheritance.
174*795d594fSAndroid Build Coastguard Worker   } else if (klass->IsErroneousResolved()) {
175*795d594fSAndroid Build Coastguard Worker     // We can't execute code in a erroneous class: do nothing.
176*795d594fSAndroid Build Coastguard Worker   } else {
177*795d594fSAndroid Build Coastguard Worker     for (ArtMethod& method : klass->GetMethods(kRuntimePointerSize)) {
178*795d594fSAndroid Build Coastguard Worker       InstallStubsForMethod(&method);
179*795d594fSAndroid Build Coastguard Worker     }
180*795d594fSAndroid Build Coastguard Worker   }
181*795d594fSAndroid Build Coastguard Worker }
182*795d594fSAndroid Build Coastguard Worker 
CanHandleInitializationCheck(const void * code)183*795d594fSAndroid Build Coastguard Worker static bool CanHandleInitializationCheck(const void* code) {
184*795d594fSAndroid Build Coastguard Worker   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
185*795d594fSAndroid Build Coastguard Worker   return class_linker->IsQuickResolutionStub(code) ||
186*795d594fSAndroid Build Coastguard Worker          class_linker->IsQuickToInterpreterBridge(code) ||
187*795d594fSAndroid Build Coastguard Worker          class_linker->IsQuickGenericJniStub(code) ||
188*795d594fSAndroid Build Coastguard Worker          (code == interpreter::GetNterpWithClinitEntryPoint());
189*795d594fSAndroid Build Coastguard Worker }
190*795d594fSAndroid Build Coastguard Worker 
IsProxyInit(ArtMethod * method)191*795d594fSAndroid Build Coastguard Worker static bool IsProxyInit(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) {
192*795d594fSAndroid Build Coastguard Worker   // Annoyingly this can be called before we have actually initialized WellKnownClasses so therefore
193*795d594fSAndroid Build Coastguard Worker   // we also need to check this based on the declaring-class descriptor. The check is valid because
194*795d594fSAndroid Build Coastguard Worker   // Proxy only has a single constructor.
195*795d594fSAndroid Build Coastguard Worker   ArtMethod* well_known_proxy_init = WellKnownClasses::java_lang_reflect_Proxy_init;
196*795d594fSAndroid Build Coastguard Worker   if (well_known_proxy_init == method) {
197*795d594fSAndroid Build Coastguard Worker     return true;
198*795d594fSAndroid Build Coastguard Worker   }
199*795d594fSAndroid Build Coastguard Worker 
200*795d594fSAndroid Build Coastguard Worker   if (well_known_proxy_init != nullptr) {
201*795d594fSAndroid Build Coastguard Worker     return false;
202*795d594fSAndroid Build Coastguard Worker   }
203*795d594fSAndroid Build Coastguard Worker 
204*795d594fSAndroid Build Coastguard Worker   return method->IsConstructor() && !method->IsStatic() &&
205*795d594fSAndroid Build Coastguard Worker       method->GetDeclaringClass()->DescriptorEquals("Ljava/lang/reflect/Proxy;");
206*795d594fSAndroid Build Coastguard Worker }
207*795d594fSAndroid Build Coastguard Worker 
208*795d594fSAndroid Build Coastguard Worker // Returns true if we need entry exit stub to call entry hooks. JITed code
209*795d594fSAndroid Build Coastguard Worker // directly call entry / exit hooks and don't need the stub.
CodeSupportsEntryExitHooks(const void * entry_point,ArtMethod * method)210*795d594fSAndroid Build Coastguard Worker static bool CodeSupportsEntryExitHooks(const void* entry_point, ArtMethod* method)
211*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
212*795d594fSAndroid Build Coastguard Worker   // Proxy.init should always run with the switch interpreter where entry / exit hooks are
213*795d594fSAndroid Build Coastguard Worker   // supported.
214*795d594fSAndroid Build Coastguard Worker   if (IsProxyInit(method)) {
215*795d594fSAndroid Build Coastguard Worker     return true;
216*795d594fSAndroid Build Coastguard Worker   }
217*795d594fSAndroid Build Coastguard Worker 
218*795d594fSAndroid Build Coastguard Worker   // In some tests runtime isn't setup fully and hence the entry points could be nullptr.
219*795d594fSAndroid Build Coastguard Worker   // just be conservative and return false here.
220*795d594fSAndroid Build Coastguard Worker   if (entry_point == nullptr) {
221*795d594fSAndroid Build Coastguard Worker     return false;
222*795d594fSAndroid Build Coastguard Worker   }
223*795d594fSAndroid Build Coastguard Worker 
224*795d594fSAndroid Build Coastguard Worker   ClassLinker* linker = Runtime::Current()->GetClassLinker();
225*795d594fSAndroid Build Coastguard Worker   // Interpreter supports entry / exit hooks. Resolution stubs fetch code that supports entry / exit
226*795d594fSAndroid Build Coastguard Worker   // hooks when required. So return true for both cases.
227*795d594fSAndroid Build Coastguard Worker   if (linker->IsQuickToInterpreterBridge(entry_point) ||
228*795d594fSAndroid Build Coastguard Worker       linker->IsQuickResolutionStub(entry_point)) {
229*795d594fSAndroid Build Coastguard Worker     return true;
230*795d594fSAndroid Build Coastguard Worker   }
231*795d594fSAndroid Build Coastguard Worker 
232*795d594fSAndroid Build Coastguard Worker   // When jiting code for debuggable runtimes / instrumentation is active  we generate the code to
233*795d594fSAndroid Build Coastguard Worker   // call method entry / exit hooks when required.
234*795d594fSAndroid Build Coastguard Worker   jit::Jit* jit = Runtime::Current()->GetJit();
235*795d594fSAndroid Build Coastguard Worker   if (jit != nullptr && jit->GetCodeCache()->ContainsPc(entry_point)) {
236*795d594fSAndroid Build Coastguard Worker     // If JITed code was compiled with instrumentation support we support entry / exit hooks.
237*795d594fSAndroid Build Coastguard Worker     OatQuickMethodHeader* header = OatQuickMethodHeader::FromEntryPoint(entry_point);
238*795d594fSAndroid Build Coastguard Worker     return CodeInfo::IsDebuggable(header->GetOptimizedCodeInfoPtr());
239*795d594fSAndroid Build Coastguard Worker   }
240*795d594fSAndroid Build Coastguard Worker 
241*795d594fSAndroid Build Coastguard Worker   // GenericJni trampoline can handle entry / exit hooks.
242*795d594fSAndroid Build Coastguard Worker   if (linker->IsQuickGenericJniStub(entry_point)) {
243*795d594fSAndroid Build Coastguard Worker     return true;
244*795d594fSAndroid Build Coastguard Worker   }
245*795d594fSAndroid Build Coastguard Worker 
246*795d594fSAndroid Build Coastguard Worker   // The remaining cases are nterp / oat code / JIT code that isn't compiled with instrumentation
247*795d594fSAndroid Build Coastguard Worker   // support.
248*795d594fSAndroid Build Coastguard Worker   return false;
249*795d594fSAndroid Build Coastguard Worker }
250*795d594fSAndroid Build Coastguard Worker 
251*795d594fSAndroid Build Coastguard Worker template <typename T>
CompareExchange(uintptr_t ptr,uintptr_t old_value,uintptr_t new_value)252*795d594fSAndroid Build Coastguard Worker bool CompareExchange(uintptr_t ptr, uintptr_t old_value, uintptr_t new_value) {
253*795d594fSAndroid Build Coastguard Worker   std::atomic<T>* atomic_addr = reinterpret_cast<std::atomic<T>*>(ptr);
254*795d594fSAndroid Build Coastguard Worker   T cast_old_value = dchecked_integral_cast<T>(old_value);
255*795d594fSAndroid Build Coastguard Worker   return atomic_addr->compare_exchange_strong(cast_old_value,
256*795d594fSAndroid Build Coastguard Worker                                               dchecked_integral_cast<T>(new_value),
257*795d594fSAndroid Build Coastguard Worker                                               std::memory_order_relaxed);
258*795d594fSAndroid Build Coastguard Worker }
259*795d594fSAndroid Build Coastguard Worker 
UpdateEntryPoints(ArtMethod * method,const void * new_code)260*795d594fSAndroid Build Coastguard Worker static void UpdateEntryPoints(ArtMethod* method, const void* new_code)
261*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
262*795d594fSAndroid Build Coastguard Worker   if (kIsDebugBuild) {
263*795d594fSAndroid Build Coastguard Worker     if (method->StillNeedsClinitCheckMayBeDead()) {
264*795d594fSAndroid Build Coastguard Worker       CHECK(CanHandleInitializationCheck(new_code));
265*795d594fSAndroid Build Coastguard Worker     }
266*795d594fSAndroid Build Coastguard Worker     jit::Jit* jit = Runtime::Current()->GetJit();
267*795d594fSAndroid Build Coastguard Worker     if (jit != nullptr && jit->GetCodeCache()->ContainsPc(new_code)) {
268*795d594fSAndroid Build Coastguard Worker       // Ensure we always have the thumb entrypoint for JIT on arm32.
269*795d594fSAndroid Build Coastguard Worker       if (kRuntimeQuickCodeISA == InstructionSet::kArm) {
270*795d594fSAndroid Build Coastguard Worker         CHECK_EQ(reinterpret_cast<uintptr_t>(new_code) & 1, 1u);
271*795d594fSAndroid Build Coastguard Worker       }
272*795d594fSAndroid Build Coastguard Worker     }
273*795d594fSAndroid Build Coastguard Worker     const Instrumentation* instr = Runtime::Current()->GetInstrumentation();
274*795d594fSAndroid Build Coastguard Worker     if (instr->EntryExitStubsInstalled()) {
275*795d594fSAndroid Build Coastguard Worker       CHECK(CodeSupportsEntryExitHooks(new_code, method));
276*795d594fSAndroid Build Coastguard Worker     }
277*795d594fSAndroid Build Coastguard Worker     if (instr->InterpreterStubsInstalled() && !method->IsNative()) {
278*795d594fSAndroid Build Coastguard Worker       CHECK_EQ(new_code, GetQuickToInterpreterBridge());
279*795d594fSAndroid Build Coastguard Worker     }
280*795d594fSAndroid Build Coastguard Worker   }
281*795d594fSAndroid Build Coastguard Worker   const void* current_entry_point = method->GetEntryPointFromQuickCompiledCode();
282*795d594fSAndroid Build Coastguard Worker   if (current_entry_point == new_code) {
283*795d594fSAndroid Build Coastguard Worker     // If the method is from a boot image, don't dirty it if the entrypoint
284*795d594fSAndroid Build Coastguard Worker     // doesn't change.
285*795d594fSAndroid Build Coastguard Worker     return;
286*795d594fSAndroid Build Coastguard Worker   }
287*795d594fSAndroid Build Coastguard Worker 
288*795d594fSAndroid Build Coastguard Worker   // Do an atomic exchange to avoid potentially unregistering JIT code twice.
289*795d594fSAndroid Build Coastguard Worker   MemberOffset offset = ArtMethod::EntryPointFromQuickCompiledCodeOffset(kRuntimePointerSize);
290*795d594fSAndroid Build Coastguard Worker   uintptr_t old_value = reinterpret_cast<uintptr_t>(current_entry_point);
291*795d594fSAndroid Build Coastguard Worker   uintptr_t new_value = reinterpret_cast<uintptr_t>(new_code);
292*795d594fSAndroid Build Coastguard Worker   uintptr_t ptr = reinterpret_cast<uintptr_t>(method) + offset.Uint32Value();
293*795d594fSAndroid Build Coastguard Worker   bool success = (kRuntimePointerSize == PointerSize::k32)
294*795d594fSAndroid Build Coastguard Worker       ? CompareExchange<uint32_t>(ptr, old_value, new_value)
295*795d594fSAndroid Build Coastguard Worker       : CompareExchange<uint64_t>(ptr, old_value, new_value);
296*795d594fSAndroid Build Coastguard Worker 
297*795d594fSAndroid Build Coastguard Worker   // If we successfully updated the entrypoint and the old entrypoint is JITted
298*795d594fSAndroid Build Coastguard Worker   // code, register the old entrypoint as zombie.
299*795d594fSAndroid Build Coastguard Worker   jit::Jit* jit = Runtime::Current()->GetJit();
300*795d594fSAndroid Build Coastguard Worker   if (success &&
301*795d594fSAndroid Build Coastguard Worker       jit != nullptr &&
302*795d594fSAndroid Build Coastguard Worker       jit->GetCodeCache()->ContainsPc(current_entry_point)) {
303*795d594fSAndroid Build Coastguard Worker     jit->GetCodeCache()->AddZombieCode(method, current_entry_point);
304*795d594fSAndroid Build Coastguard Worker   }
305*795d594fSAndroid Build Coastguard Worker }
306*795d594fSAndroid Build Coastguard Worker 
NeedsDexPcEvents(ArtMethod * method,Thread * thread)307*795d594fSAndroid Build Coastguard Worker bool Instrumentation::NeedsDexPcEvents(ArtMethod* method, Thread* thread) {
308*795d594fSAndroid Build Coastguard Worker   return (InterpretOnly(method) || thread->IsForceInterpreter()) && HasDexPcListeners();
309*795d594fSAndroid Build Coastguard Worker }
310*795d594fSAndroid Build Coastguard Worker 
InterpretOnly(ArtMethod * method)311*795d594fSAndroid Build Coastguard Worker bool Instrumentation::InterpretOnly(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) {
312*795d594fSAndroid Build Coastguard Worker   if (method->IsNative()) {
313*795d594fSAndroid Build Coastguard Worker     return false;
314*795d594fSAndroid Build Coastguard Worker   }
315*795d594fSAndroid Build Coastguard Worker   return InterpretOnly() || IsDeoptimized(method);
316*795d594fSAndroid Build Coastguard Worker }
317*795d594fSAndroid Build Coastguard Worker 
CanUseAotCode(const void * quick_code)318*795d594fSAndroid Build Coastguard Worker static bool CanUseAotCode(const void* quick_code)
319*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
320*795d594fSAndroid Build Coastguard Worker   if (quick_code == nullptr) {
321*795d594fSAndroid Build Coastguard Worker     return false;
322*795d594fSAndroid Build Coastguard Worker   }
323*795d594fSAndroid Build Coastguard Worker   Runtime* runtime = Runtime::Current();
324*795d594fSAndroid Build Coastguard Worker   // For simplicity, we never use AOT code for debuggable.
325*795d594fSAndroid Build Coastguard Worker   if (runtime->IsJavaDebuggable()) {
326*795d594fSAndroid Build Coastguard Worker     return false;
327*795d594fSAndroid Build Coastguard Worker   }
328*795d594fSAndroid Build Coastguard Worker 
329*795d594fSAndroid Build Coastguard Worker   if (runtime->IsNativeDebuggable()) {
330*795d594fSAndroid Build Coastguard Worker     DCHECK(runtime->UseJitCompilation() && runtime->GetJit()->JitAtFirstUse());
331*795d594fSAndroid Build Coastguard Worker     // If we are doing native debugging, ignore application's AOT code,
332*795d594fSAndroid Build Coastguard Worker     // since we want to JIT it (at first use) with extra stackmaps for native
333*795d594fSAndroid Build Coastguard Worker     // debugging. We keep however all AOT code from the boot image,
334*795d594fSAndroid Build Coastguard Worker     // since the JIT-at-first-use is blocking and would result in non-negligible
335*795d594fSAndroid Build Coastguard Worker     // startup performance impact.
336*795d594fSAndroid Build Coastguard Worker     return runtime->GetHeap()->IsInBootImageOatFile(quick_code);
337*795d594fSAndroid Build Coastguard Worker   }
338*795d594fSAndroid Build Coastguard Worker 
339*795d594fSAndroid Build Coastguard Worker   return true;
340*795d594fSAndroid Build Coastguard Worker }
341*795d594fSAndroid Build Coastguard Worker 
CanUseNterp(ArtMethod * method)342*795d594fSAndroid Build Coastguard Worker static bool CanUseNterp(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) {
343*795d594fSAndroid Build Coastguard Worker   return interpreter::CanRuntimeUseNterp() &&
344*795d594fSAndroid Build Coastguard Worker       CanMethodUseNterp(method) &&
345*795d594fSAndroid Build Coastguard Worker       method->IsDeclaringClassVerifiedMayBeDead();
346*795d594fSAndroid Build Coastguard Worker }
347*795d594fSAndroid Build Coastguard Worker 
GetOptimizedCodeFor(ArtMethod * method)348*795d594fSAndroid Build Coastguard Worker static const void* GetOptimizedCodeFor(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) {
349*795d594fSAndroid Build Coastguard Worker   DCHECK(!Runtime::Current()->GetInstrumentation()->InterpretOnly(method));
350*795d594fSAndroid Build Coastguard Worker   CHECK(method->IsInvokable()) << method->PrettyMethod();
351*795d594fSAndroid Build Coastguard Worker   if (method->IsProxyMethod()) {
352*795d594fSAndroid Build Coastguard Worker     return GetQuickProxyInvokeHandler();
353*795d594fSAndroid Build Coastguard Worker   }
354*795d594fSAndroid Build Coastguard Worker 
355*795d594fSAndroid Build Coastguard Worker   // In debuggable mode, we can only use AOT code for native methods.
356*795d594fSAndroid Build Coastguard Worker   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
357*795d594fSAndroid Build Coastguard Worker   const void* aot_code = method->GetOatMethodQuickCode(class_linker->GetImagePointerSize());
358*795d594fSAndroid Build Coastguard Worker   if (CanUseAotCode(aot_code)) {
359*795d594fSAndroid Build Coastguard Worker     return aot_code;
360*795d594fSAndroid Build Coastguard Worker   }
361*795d594fSAndroid Build Coastguard Worker 
362*795d594fSAndroid Build Coastguard Worker   // If the method has been precompiled, there can be a JIT version.
363*795d594fSAndroid Build Coastguard Worker   jit::Jit* jit = Runtime::Current()->GetJit();
364*795d594fSAndroid Build Coastguard Worker   if (jit != nullptr) {
365*795d594fSAndroid Build Coastguard Worker     const void* code = jit->GetCodeCache()->GetSavedEntryPointOfPreCompiledMethod(method);
366*795d594fSAndroid Build Coastguard Worker     if (code != nullptr) {
367*795d594fSAndroid Build Coastguard Worker       return code;
368*795d594fSAndroid Build Coastguard Worker     }
369*795d594fSAndroid Build Coastguard Worker   }
370*795d594fSAndroid Build Coastguard Worker 
371*795d594fSAndroid Build Coastguard Worker   // We need to check if the class has been verified for setting up nterp, as
372*795d594fSAndroid Build Coastguard Worker   // the verifier could punt the method to the switch interpreter in case we
373*795d594fSAndroid Build Coastguard Worker   // need to do lock counting.
374*795d594fSAndroid Build Coastguard Worker   if (CanUseNterp(method)) {
375*795d594fSAndroid Build Coastguard Worker     return interpreter::GetNterpEntryPoint();
376*795d594fSAndroid Build Coastguard Worker   }
377*795d594fSAndroid Build Coastguard Worker 
378*795d594fSAndroid Build Coastguard Worker   return method->IsNative() ? GetQuickGenericJniStub() : GetQuickToInterpreterBridge();
379*795d594fSAndroid Build Coastguard Worker }
380*795d594fSAndroid Build Coastguard Worker 
InitializeMethodsCode(ArtMethod * method,const void * aot_code)381*795d594fSAndroid Build Coastguard Worker void Instrumentation::InitializeMethodsCode(ArtMethod* method, const void* aot_code)
382*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
383*795d594fSAndroid Build Coastguard Worker   if (!method->IsInvokable()) {
384*795d594fSAndroid Build Coastguard Worker     DCHECK(method->GetEntryPointFromQuickCompiledCode() == nullptr ||
385*795d594fSAndroid Build Coastguard Worker            Runtime::Current()->GetClassLinker()->IsQuickToInterpreterBridge(
386*795d594fSAndroid Build Coastguard Worker                method->GetEntryPointFromQuickCompiledCode()));
387*795d594fSAndroid Build Coastguard Worker     UpdateEntryPoints(method, GetQuickToInterpreterBridge());
388*795d594fSAndroid Build Coastguard Worker     return;
389*795d594fSAndroid Build Coastguard Worker   }
390*795d594fSAndroid Build Coastguard Worker 
391*795d594fSAndroid Build Coastguard Worker   // Use instrumentation entrypoints if instrumentation is installed.
392*795d594fSAndroid Build Coastguard Worker   if (UNLIKELY(EntryExitStubsInstalled() || IsForcedInterpretOnly() || IsDeoptimized(method))) {
393*795d594fSAndroid Build Coastguard Worker     UpdateEntryPoints(
394*795d594fSAndroid Build Coastguard Worker         method, method->IsNative() ? GetQuickGenericJniStub() : GetQuickToInterpreterBridge());
395*795d594fSAndroid Build Coastguard Worker     return;
396*795d594fSAndroid Build Coastguard Worker   }
397*795d594fSAndroid Build Coastguard Worker 
398*795d594fSAndroid Build Coastguard Worker   // Special case if we need an initialization check.
399*795d594fSAndroid Build Coastguard Worker   // The method and its declaring class may be dead when starting JIT GC during managed heap GC.
400*795d594fSAndroid Build Coastguard Worker   if (method->StillNeedsClinitCheckMayBeDead()) {
401*795d594fSAndroid Build Coastguard Worker     // If we have code but the method needs a class initialization check before calling
402*795d594fSAndroid Build Coastguard Worker     // that code, install the resolution stub that will perform the check.
403*795d594fSAndroid Build Coastguard Worker     // It will be replaced by the proper entry point by ClassLinker::FixupStaticTrampolines
404*795d594fSAndroid Build Coastguard Worker     // after initializing class (see ClassLinker::InitializeClass method).
405*795d594fSAndroid Build Coastguard Worker     // Note: this mimics the logic in image_writer.cc that installs the resolution
406*795d594fSAndroid Build Coastguard Worker     // stub only if we have compiled code or we can execute nterp, and the method needs a class
407*795d594fSAndroid Build Coastguard Worker     // initialization check.
408*795d594fSAndroid Build Coastguard Worker     if (aot_code != nullptr || method->IsNative() || CanUseNterp(method)) {
409*795d594fSAndroid Build Coastguard Worker       if (kIsDebugBuild && CanUseNterp(method)) {
410*795d594fSAndroid Build Coastguard Worker         // Adds some test coverage for the nterp clinit entrypoint.
411*795d594fSAndroid Build Coastguard Worker         UpdateEntryPoints(method, interpreter::GetNterpWithClinitEntryPoint());
412*795d594fSAndroid Build Coastguard Worker       } else {
413*795d594fSAndroid Build Coastguard Worker         UpdateEntryPoints(method, GetQuickResolutionStub());
414*795d594fSAndroid Build Coastguard Worker       }
415*795d594fSAndroid Build Coastguard Worker     } else {
416*795d594fSAndroid Build Coastguard Worker       UpdateEntryPoints(method, GetQuickToInterpreterBridge());
417*795d594fSAndroid Build Coastguard Worker     }
418*795d594fSAndroid Build Coastguard Worker     return;
419*795d594fSAndroid Build Coastguard Worker   }
420*795d594fSAndroid Build Coastguard Worker 
421*795d594fSAndroid Build Coastguard Worker   // Use the provided AOT code if possible.
422*795d594fSAndroid Build Coastguard Worker   if (CanUseAotCode(aot_code)) {
423*795d594fSAndroid Build Coastguard Worker     UpdateEntryPoints(method, aot_code);
424*795d594fSAndroid Build Coastguard Worker     return;
425*795d594fSAndroid Build Coastguard Worker   }
426*795d594fSAndroid Build Coastguard Worker 
427*795d594fSAndroid Build Coastguard Worker   // We check if the class is verified as we need the slow interpreter for lock verification.
428*795d594fSAndroid Build Coastguard Worker   // If the class is not verified, This will be updated in
429*795d594fSAndroid Build Coastguard Worker   // ClassLinker::UpdateClassAfterVerification.
430*795d594fSAndroid Build Coastguard Worker   if (CanUseNterp(method)) {
431*795d594fSAndroid Build Coastguard Worker     UpdateEntryPoints(method, interpreter::GetNterpEntryPoint());
432*795d594fSAndroid Build Coastguard Worker     return;
433*795d594fSAndroid Build Coastguard Worker   }
434*795d594fSAndroid Build Coastguard Worker 
435*795d594fSAndroid Build Coastguard Worker   // Use default entrypoints.
436*795d594fSAndroid Build Coastguard Worker   UpdateEntryPoints(
437*795d594fSAndroid Build Coastguard Worker       method, method->IsNative() ? GetQuickGenericJniStub() : GetQuickToInterpreterBridge());
438*795d594fSAndroid Build Coastguard Worker }
439*795d594fSAndroid Build Coastguard Worker 
InstallStubsForMethod(ArtMethod * method)440*795d594fSAndroid Build Coastguard Worker void Instrumentation::InstallStubsForMethod(ArtMethod* method) {
441*795d594fSAndroid Build Coastguard Worker   if (!method->IsInvokable() || method->IsProxyMethod()) {
442*795d594fSAndroid Build Coastguard Worker     // Do not change stubs for these methods.
443*795d594fSAndroid Build Coastguard Worker     return;
444*795d594fSAndroid Build Coastguard Worker   }
445*795d594fSAndroid Build Coastguard Worker   // Don't stub Proxy.<init>. Note that the Proxy class itself is not a proxy class.
446*795d594fSAndroid Build Coastguard Worker   // TODO We should remove the need for this since it means we cannot always correctly detect calls
447*795d594fSAndroid Build Coastguard Worker   // to Proxy.<init>
448*795d594fSAndroid Build Coastguard Worker   if (IsProxyInit(method)) {
449*795d594fSAndroid Build Coastguard Worker     return;
450*795d594fSAndroid Build Coastguard Worker   }
451*795d594fSAndroid Build Coastguard Worker 
452*795d594fSAndroid Build Coastguard Worker   // If the instrumentation needs to go through the interpreter, just update the
453*795d594fSAndroid Build Coastguard Worker   // entrypoint to interpreter.
454*795d594fSAndroid Build Coastguard Worker   if (InterpretOnly(method)) {
455*795d594fSAndroid Build Coastguard Worker     UpdateEntryPoints(method, GetQuickToInterpreterBridge());
456*795d594fSAndroid Build Coastguard Worker     return;
457*795d594fSAndroid Build Coastguard Worker   }
458*795d594fSAndroid Build Coastguard Worker 
459*795d594fSAndroid Build Coastguard Worker   if (EntryExitStubsInstalled()) {
460*795d594fSAndroid Build Coastguard Worker     // Install interpreter bridge / GenericJni stub if the existing code doesn't support
461*795d594fSAndroid Build Coastguard Worker     // entry / exit hooks.
462*795d594fSAndroid Build Coastguard Worker     if (!CodeSupportsEntryExitHooks(method->GetEntryPointFromQuickCompiledCode(), method)) {
463*795d594fSAndroid Build Coastguard Worker       UpdateEntryPoints(
464*795d594fSAndroid Build Coastguard Worker           method, method->IsNative() ? GetQuickGenericJniStub() : GetQuickToInterpreterBridge());
465*795d594fSAndroid Build Coastguard Worker     }
466*795d594fSAndroid Build Coastguard Worker     return;
467*795d594fSAndroid Build Coastguard Worker   }
468*795d594fSAndroid Build Coastguard Worker 
469*795d594fSAndroid Build Coastguard Worker   // We're being asked to restore the entrypoints after instrumentation.
470*795d594fSAndroid Build Coastguard Worker   CHECK_EQ(instrumentation_level_, InstrumentationLevel::kInstrumentNothing);
471*795d594fSAndroid Build Coastguard Worker   // We need to have the resolution stub still if the class is not initialized.
472*795d594fSAndroid Build Coastguard Worker   if (method->StillNeedsClinitCheck()) {
473*795d594fSAndroid Build Coastguard Worker     UpdateEntryPoints(method, GetQuickResolutionStub());
474*795d594fSAndroid Build Coastguard Worker     return;
475*795d594fSAndroid Build Coastguard Worker   }
476*795d594fSAndroid Build Coastguard Worker   UpdateEntryPoints(method, GetOptimizedCodeFor(method));
477*795d594fSAndroid Build Coastguard Worker }
478*795d594fSAndroid Build Coastguard Worker 
UpdateEntrypointsForDebuggable()479*795d594fSAndroid Build Coastguard Worker void Instrumentation::UpdateEntrypointsForDebuggable() {
480*795d594fSAndroid Build Coastguard Worker   Runtime* runtime = Runtime::Current();
481*795d594fSAndroid Build Coastguard Worker   // If we are transitioning from non-debuggable to debuggable, we patch
482*795d594fSAndroid Build Coastguard Worker   // entry points of methods to remove any aot / JITed entry points.
483*795d594fSAndroid Build Coastguard Worker   InstallStubsClassVisitor visitor(this);
484*795d594fSAndroid Build Coastguard Worker   runtime->GetClassLinker()->VisitClasses(&visitor);
485*795d594fSAndroid Build Coastguard Worker }
486*795d594fSAndroid Build Coastguard Worker 
MethodSupportsExitEvents(ArtMethod * method,const OatQuickMethodHeader * header)487*795d594fSAndroid Build Coastguard Worker bool Instrumentation::MethodSupportsExitEvents(ArtMethod* method,
488*795d594fSAndroid Build Coastguard Worker                                                const OatQuickMethodHeader* header) {
489*795d594fSAndroid Build Coastguard Worker   if (header == nullptr) {
490*795d594fSAndroid Build Coastguard Worker     // Header can be a nullptr for runtime / proxy methods that doesn't support method exit hooks
491*795d594fSAndroid Build Coastguard Worker     // or for native methods that use generic jni stubs. Generic jni stubs support method exit
492*795d594fSAndroid Build Coastguard Worker     // hooks.
493*795d594fSAndroid Build Coastguard Worker     return method->IsNative();
494*795d594fSAndroid Build Coastguard Worker   }
495*795d594fSAndroid Build Coastguard Worker 
496*795d594fSAndroid Build Coastguard Worker   if (header->IsNterpMethodHeader()) {
497*795d594fSAndroid Build Coastguard Worker     // Nterp doesn't support method exit events
498*795d594fSAndroid Build Coastguard Worker     return false;
499*795d594fSAndroid Build Coastguard Worker   }
500*795d594fSAndroid Build Coastguard Worker 
501*795d594fSAndroid Build Coastguard Worker   DCHECK(header->IsOptimized());
502*795d594fSAndroid Build Coastguard Worker   if (CodeInfo::IsDebuggable(header->GetOptimizedCodeInfoPtr())) {
503*795d594fSAndroid Build Coastguard Worker     // For optimized code, we only support method entry / exit hooks if they are compiled as
504*795d594fSAndroid Build Coastguard Worker     // debuggable.
505*795d594fSAndroid Build Coastguard Worker     return true;
506*795d594fSAndroid Build Coastguard Worker   }
507*795d594fSAndroid Build Coastguard Worker 
508*795d594fSAndroid Build Coastguard Worker   return false;
509*795d594fSAndroid Build Coastguard Worker }
510*795d594fSAndroid Build Coastguard Worker 
511*795d594fSAndroid Build Coastguard Worker // Updates on stack frames to support any changes related to instrumentation.
512*795d594fSAndroid Build Coastguard Worker // For JITed frames, DeoptimizeFlag is updated to enable deoptimization of
513*795d594fSAndroid Build Coastguard Worker // methods when necessary. Shadow frames are updated if dex pc event
514*795d594fSAndroid Build Coastguard Worker // notification has changed. When force_deopt is true then DeoptimizationFlag is
515*795d594fSAndroid Build Coastguard Worker // updated to force a deoptimization.
InstrumentationInstallStack(Thread * thread,bool deopt_all_frames)516*795d594fSAndroid Build Coastguard Worker void InstrumentationInstallStack(Thread* thread, bool deopt_all_frames)
517*795d594fSAndroid Build Coastguard Worker     REQUIRES(Locks::mutator_lock_) {
518*795d594fSAndroid Build Coastguard Worker   Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
519*795d594fSAndroid Build Coastguard Worker   struct InstallStackVisitor final : public StackVisitor {
520*795d594fSAndroid Build Coastguard Worker     InstallStackVisitor(Thread* thread_in,
521*795d594fSAndroid Build Coastguard Worker                         Context* context,
522*795d594fSAndroid Build Coastguard Worker                         bool deopt_all_frames)
523*795d594fSAndroid Build Coastguard Worker         : StackVisitor(thread_in, context, kInstrumentationStackWalk),
524*795d594fSAndroid Build Coastguard Worker           deopt_all_frames_(deopt_all_frames),
525*795d594fSAndroid Build Coastguard Worker           runtime_methods_need_deopt_check_(false) {}
526*795d594fSAndroid Build Coastguard Worker 
527*795d594fSAndroid Build Coastguard Worker     bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
528*795d594fSAndroid Build Coastguard Worker       ArtMethod* m = GetMethod();
529*795d594fSAndroid Build Coastguard Worker       if (m == nullptr || m->IsRuntimeMethod()) {
530*795d594fSAndroid Build Coastguard Worker         if (kVerboseInstrumentation) {
531*795d594fSAndroid Build Coastguard Worker           LOG(INFO) << "  Skipping upcall / runtime method. Frame " << GetFrameId();
532*795d594fSAndroid Build Coastguard Worker         }
533*795d594fSAndroid Build Coastguard Worker         return true;  // Ignore upcalls and runtime methods.
534*795d594fSAndroid Build Coastguard Worker       }
535*795d594fSAndroid Build Coastguard Worker 
536*795d594fSAndroid Build Coastguard Worker       bool is_shadow_frame = GetCurrentQuickFrame() == nullptr;
537*795d594fSAndroid Build Coastguard Worker       if (kVerboseInstrumentation) {
538*795d594fSAndroid Build Coastguard Worker         LOG(INFO) << "Processing frame: method: " << m->PrettyMethod()
539*795d594fSAndroid Build Coastguard Worker                   << " is_shadow_frame: " << is_shadow_frame;
540*795d594fSAndroid Build Coastguard Worker       }
541*795d594fSAndroid Build Coastguard Worker 
542*795d594fSAndroid Build Coastguard Worker       // Handle interpreter frame.
543*795d594fSAndroid Build Coastguard Worker       if (is_shadow_frame) {
544*795d594fSAndroid Build Coastguard Worker         // Since we are updating the instrumentation related information we have to recalculate
545*795d594fSAndroid Build Coastguard Worker         // NeedsDexPcEvents. For example, when a new method or thread is deoptimized / interpreter
546*795d594fSAndroid Build Coastguard Worker         // stubs are installed the NeedsDexPcEvents could change for the shadow frames on the stack.
547*795d594fSAndroid Build Coastguard Worker         // If we don't update it here we would miss reporting dex pc events which is incorrect.
548*795d594fSAndroid Build Coastguard Worker         ShadowFrame* shadow_frame = GetCurrentShadowFrame();
549*795d594fSAndroid Build Coastguard Worker         DCHECK(shadow_frame != nullptr);
550*795d594fSAndroid Build Coastguard Worker         shadow_frame->SetNotifyDexPcMoveEvents(
551*795d594fSAndroid Build Coastguard Worker             Runtime::Current()->GetInstrumentation()->NeedsDexPcEvents(GetMethod(), GetThread()));
552*795d594fSAndroid Build Coastguard Worker         return true;  // Continue.
553*795d594fSAndroid Build Coastguard Worker       }
554*795d594fSAndroid Build Coastguard Worker 
555*795d594fSAndroid Build Coastguard Worker       DCHECK(!m->IsRuntimeMethod());
556*795d594fSAndroid Build Coastguard Worker       const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader();
557*795d594fSAndroid Build Coastguard Worker       // If it is a JITed frame then just set the deopt bit if required otherwise continue.
558*795d594fSAndroid Build Coastguard Worker       // We need kForceDeoptForRedefinition to ensure we don't use any JITed code after a
559*795d594fSAndroid Build Coastguard Worker       // redefinition. We support redefinition only if the runtime has started off as a
560*795d594fSAndroid Build Coastguard Worker       // debuggable runtime which makes sure we don't use any AOT or Nterp code.
561*795d594fSAndroid Build Coastguard Worker       // The CheckCallerForDeopt is an optimization which we only do for non-native JITed code for
562*795d594fSAndroid Build Coastguard Worker       // now. We can extend it to native methods but that needs reserving an additional stack slot.
563*795d594fSAndroid Build Coastguard Worker       // We don't do it currently since that wasn't important for debugger performance.
564*795d594fSAndroid Build Coastguard Worker       if (method_header != nullptr && method_header->HasShouldDeoptimizeFlag()) {
565*795d594fSAndroid Build Coastguard Worker         if (deopt_all_frames_) {
566*795d594fSAndroid Build Coastguard Worker           runtime_methods_need_deopt_check_ = true;
567*795d594fSAndroid Build Coastguard Worker           SetShouldDeoptimizeFlag(DeoptimizeFlagValue::kForceDeoptForRedefinition);
568*795d594fSAndroid Build Coastguard Worker         }
569*795d594fSAndroid Build Coastguard Worker         SetShouldDeoptimizeFlag(DeoptimizeFlagValue::kCheckCallerForDeopt);
570*795d594fSAndroid Build Coastguard Worker       }
571*795d594fSAndroid Build Coastguard Worker 
572*795d594fSAndroid Build Coastguard Worker       return true;  // Continue.
573*795d594fSAndroid Build Coastguard Worker     }
574*795d594fSAndroid Build Coastguard Worker     bool deopt_all_frames_;
575*795d594fSAndroid Build Coastguard Worker     bool runtime_methods_need_deopt_check_;
576*795d594fSAndroid Build Coastguard Worker   };
577*795d594fSAndroid Build Coastguard Worker   if (kVerboseInstrumentation) {
578*795d594fSAndroid Build Coastguard Worker     std::string thread_name;
579*795d594fSAndroid Build Coastguard Worker     thread->GetThreadName(thread_name);
580*795d594fSAndroid Build Coastguard Worker     LOG(INFO) << "Installing exit stubs in " << thread_name;
581*795d594fSAndroid Build Coastguard Worker   }
582*795d594fSAndroid Build Coastguard Worker 
583*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<Context> context(Context::Create());
584*795d594fSAndroid Build Coastguard Worker   InstallStackVisitor visitor(thread,
585*795d594fSAndroid Build Coastguard Worker                               context.get(),
586*795d594fSAndroid Build Coastguard Worker                               deopt_all_frames);
587*795d594fSAndroid Build Coastguard Worker   visitor.WalkStack(true);
588*795d594fSAndroid Build Coastguard Worker 
589*795d594fSAndroid Build Coastguard Worker   if (visitor.runtime_methods_need_deopt_check_) {
590*795d594fSAndroid Build Coastguard Worker     thread->SetDeoptCheckRequired(true);
591*795d594fSAndroid Build Coastguard Worker   }
592*795d594fSAndroid Build Coastguard Worker 
593*795d594fSAndroid Build Coastguard Worker   thread->VerifyStack();
594*795d594fSAndroid Build Coastguard Worker }
595*795d594fSAndroid Build Coastguard Worker 
UpdateNeedsDexPcEventsOnStack(Thread * thread)596*795d594fSAndroid Build Coastguard Worker void UpdateNeedsDexPcEventsOnStack(Thread* thread) REQUIRES(Locks::mutator_lock_) {
597*795d594fSAndroid Build Coastguard Worker   Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
598*795d594fSAndroid Build Coastguard Worker 
599*795d594fSAndroid Build Coastguard Worker   struct InstallStackVisitor final : public StackVisitor {
600*795d594fSAndroid Build Coastguard Worker     InstallStackVisitor(Thread* thread_in, Context* context)
601*795d594fSAndroid Build Coastguard Worker         : StackVisitor(thread_in, context, kInstrumentationStackWalk) {}
602*795d594fSAndroid Build Coastguard Worker 
603*795d594fSAndroid Build Coastguard Worker     bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
604*795d594fSAndroid Build Coastguard Worker       ShadowFrame* shadow_frame = GetCurrentShadowFrame();
605*795d594fSAndroid Build Coastguard Worker       if (shadow_frame != nullptr) {
606*795d594fSAndroid Build Coastguard Worker         shadow_frame->SetNotifyDexPcMoveEvents(
607*795d594fSAndroid Build Coastguard Worker             Runtime::Current()->GetInstrumentation()->NeedsDexPcEvents(GetMethod(), GetThread()));
608*795d594fSAndroid Build Coastguard Worker       }
609*795d594fSAndroid Build Coastguard Worker       return true;
610*795d594fSAndroid Build Coastguard Worker     }
611*795d594fSAndroid Build Coastguard Worker   };
612*795d594fSAndroid Build Coastguard Worker 
613*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<Context> context(Context::Create());
614*795d594fSAndroid Build Coastguard Worker   InstallStackVisitor visitor(thread, context.get());
615*795d594fSAndroid Build Coastguard Worker   visitor.WalkStack(true);
616*795d594fSAndroid Build Coastguard Worker }
617*795d594fSAndroid Build Coastguard Worker 
ReportMethodEntryForOnStackMethods(InstrumentationListener * listener,Thread * thread)618*795d594fSAndroid Build Coastguard Worker void ReportMethodEntryForOnStackMethods(InstrumentationListener* listener, Thread* thread)
619*795d594fSAndroid Build Coastguard Worker     REQUIRES(Locks::mutator_lock_) {
620*795d594fSAndroid Build Coastguard Worker   Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
621*795d594fSAndroid Build Coastguard Worker 
622*795d594fSAndroid Build Coastguard Worker   struct InstallStackVisitor final : public StackVisitor {
623*795d594fSAndroid Build Coastguard Worker     InstallStackVisitor(Thread* thread_in, Context* context)
624*795d594fSAndroid Build Coastguard Worker         : StackVisitor(thread_in, context, kInstrumentationStackWalk) {}
625*795d594fSAndroid Build Coastguard Worker 
626*795d594fSAndroid Build Coastguard Worker     bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
627*795d594fSAndroid Build Coastguard Worker       ArtMethod* m = GetMethod();
628*795d594fSAndroid Build Coastguard Worker       if (m == nullptr || m->IsRuntimeMethod()) {
629*795d594fSAndroid Build Coastguard Worker         // Skip upcall / runtime methods
630*795d594fSAndroid Build Coastguard Worker         return true;
631*795d594fSAndroid Build Coastguard Worker       }
632*795d594fSAndroid Build Coastguard Worker 
633*795d594fSAndroid Build Coastguard Worker       if (GetCurrentShadowFrame() != nullptr) {
634*795d594fSAndroid Build Coastguard Worker         stack_methods_.push_back(m);
635*795d594fSAndroid Build Coastguard Worker       } else {
636*795d594fSAndroid Build Coastguard Worker         const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader();
637*795d594fSAndroid Build Coastguard Worker         if (Runtime::Current()->GetInstrumentation()->MethodSupportsExitEvents(m, method_header)) {
638*795d594fSAndroid Build Coastguard Worker           // It is unexpected to see a method enter event but not a method exit event so record
639*795d594fSAndroid Build Coastguard Worker           // stack methods only for frames that support method exit events. Even if we deoptimize we
640*795d594fSAndroid Build Coastguard Worker           // make sure that we only call method exit event if the frame supported it in the first
641*795d594fSAndroid Build Coastguard Worker           // place. For ex: deoptimizing from JITed code with debug support calls a method exit hook
642*795d594fSAndroid Build Coastguard Worker           // but deoptimizing from nterp doesn't.
643*795d594fSAndroid Build Coastguard Worker           stack_methods_.push_back(m);
644*795d594fSAndroid Build Coastguard Worker         }
645*795d594fSAndroid Build Coastguard Worker       }
646*795d594fSAndroid Build Coastguard Worker       return true;
647*795d594fSAndroid Build Coastguard Worker     }
648*795d594fSAndroid Build Coastguard Worker 
649*795d594fSAndroid Build Coastguard Worker     std::vector<ArtMethod*> stack_methods_;
650*795d594fSAndroid Build Coastguard Worker   };
651*795d594fSAndroid Build Coastguard Worker 
652*795d594fSAndroid Build Coastguard Worker   if (kVerboseInstrumentation) {
653*795d594fSAndroid Build Coastguard Worker     std::string thread_name;
654*795d594fSAndroid Build Coastguard Worker     thread->GetThreadName(thread_name);
655*795d594fSAndroid Build Coastguard Worker     LOG(INFO) << "Updating DexPcMoveEvents on shadow frames on stack  " << thread_name;
656*795d594fSAndroid Build Coastguard Worker   }
657*795d594fSAndroid Build Coastguard Worker 
658*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<Context> context(Context::Create());
659*795d594fSAndroid Build Coastguard Worker   InstallStackVisitor visitor(thread, context.get());
660*795d594fSAndroid Build Coastguard Worker   visitor.WalkStack(true);
661*795d594fSAndroid Build Coastguard Worker 
662*795d594fSAndroid Build Coastguard Worker   // Create method enter events for all methods currently on the thread's stack.
663*795d594fSAndroid Build Coastguard Worker   for (auto smi = visitor.stack_methods_.rbegin(); smi != visitor.stack_methods_.rend(); smi++) {
664*795d594fSAndroid Build Coastguard Worker     listener->MethodEntered(thread, *smi);
665*795d594fSAndroid Build Coastguard Worker   }
666*795d594fSAndroid Build Coastguard Worker }
667*795d594fSAndroid Build Coastguard Worker 
InstrumentThreadStack(Thread * thread,bool force_deopt)668*795d594fSAndroid Build Coastguard Worker void Instrumentation::InstrumentThreadStack(Thread* thread, bool force_deopt) {
669*795d594fSAndroid Build Coastguard Worker   run_exit_hooks_ = true;
670*795d594fSAndroid Build Coastguard Worker   InstrumentationInstallStack(thread, force_deopt);
671*795d594fSAndroid Build Coastguard Worker }
672*795d594fSAndroid Build Coastguard Worker 
InstrumentAllThreadStacks(bool force_deopt)673*795d594fSAndroid Build Coastguard Worker void Instrumentation::InstrumentAllThreadStacks(bool force_deopt) {
674*795d594fSAndroid Build Coastguard Worker   run_exit_hooks_ = true;
675*795d594fSAndroid Build Coastguard Worker   MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
676*795d594fSAndroid Build Coastguard Worker   for (Thread* thread : Runtime::Current()->GetThreadList()->GetList()) {
677*795d594fSAndroid Build Coastguard Worker     InstrumentThreadStack(thread, force_deopt);
678*795d594fSAndroid Build Coastguard Worker   }
679*795d594fSAndroid Build Coastguard Worker }
680*795d594fSAndroid Build Coastguard Worker 
InstrumentationRestoreStack(Thread * thread)681*795d594fSAndroid Build Coastguard Worker static void InstrumentationRestoreStack(Thread* thread) REQUIRES(Locks::mutator_lock_) {
682*795d594fSAndroid Build Coastguard Worker   Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
683*795d594fSAndroid Build Coastguard Worker 
684*795d594fSAndroid Build Coastguard Worker   struct RestoreStackVisitor final : public StackVisitor {
685*795d594fSAndroid Build Coastguard Worker     RestoreStackVisitor(Thread* thread)
686*795d594fSAndroid Build Coastguard Worker         : StackVisitor(thread, nullptr, kInstrumentationStackWalk), thread_(thread) {}
687*795d594fSAndroid Build Coastguard Worker 
688*795d594fSAndroid Build Coastguard Worker     bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
689*795d594fSAndroid Build Coastguard Worker       if (GetCurrentQuickFrame() == nullptr) {
690*795d594fSAndroid Build Coastguard Worker         return true;
691*795d594fSAndroid Build Coastguard Worker       }
692*795d594fSAndroid Build Coastguard Worker 
693*795d594fSAndroid Build Coastguard Worker       const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader();
694*795d594fSAndroid Build Coastguard Worker       if (method_header != nullptr && method_header->HasShouldDeoptimizeFlag()) {
695*795d594fSAndroid Build Coastguard Worker         // We shouldn't restore stack if any of the frames need a force deopt
696*795d594fSAndroid Build Coastguard Worker         DCHECK(!ShouldForceDeoptForRedefinition());
697*795d594fSAndroid Build Coastguard Worker         UnsetShouldDeoptimizeFlag(DeoptimizeFlagValue::kCheckCallerForDeopt);
698*795d594fSAndroid Build Coastguard Worker       }
699*795d594fSAndroid Build Coastguard Worker       return true;  // Continue.
700*795d594fSAndroid Build Coastguard Worker     }
701*795d594fSAndroid Build Coastguard Worker     Thread* const thread_;
702*795d594fSAndroid Build Coastguard Worker   };
703*795d594fSAndroid Build Coastguard Worker 
704*795d594fSAndroid Build Coastguard Worker   if (kVerboseInstrumentation) {
705*795d594fSAndroid Build Coastguard Worker     std::string thread_name;
706*795d594fSAndroid Build Coastguard Worker     thread->GetThreadName(thread_name);
707*795d594fSAndroid Build Coastguard Worker     LOG(INFO) << "Restoring stack for " << thread_name;
708*795d594fSAndroid Build Coastguard Worker   }
709*795d594fSAndroid Build Coastguard Worker   DCHECK(!thread->IsDeoptCheckRequired());
710*795d594fSAndroid Build Coastguard Worker   RestoreStackVisitor visitor(thread);
711*795d594fSAndroid Build Coastguard Worker   visitor.WalkStack(true);
712*795d594fSAndroid Build Coastguard Worker }
713*795d594fSAndroid Build Coastguard Worker 
HasFramesNeedingForceDeopt(Thread * thread)714*795d594fSAndroid Build Coastguard Worker static bool HasFramesNeedingForceDeopt(Thread* thread) REQUIRES(Locks::mutator_lock_) {
715*795d594fSAndroid Build Coastguard Worker   Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
716*795d594fSAndroid Build Coastguard Worker 
717*795d594fSAndroid Build Coastguard Worker   struct CheckForForceDeoptStackVisitor final : public StackVisitor {
718*795d594fSAndroid Build Coastguard Worker     CheckForForceDeoptStackVisitor(Thread* thread)
719*795d594fSAndroid Build Coastguard Worker         : StackVisitor(thread, nullptr, kInstrumentationStackWalk),
720*795d594fSAndroid Build Coastguard Worker           thread_(thread),
721*795d594fSAndroid Build Coastguard Worker           force_deopt_check_needed_(false) {}
722*795d594fSAndroid Build Coastguard Worker 
723*795d594fSAndroid Build Coastguard Worker     bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
724*795d594fSAndroid Build Coastguard Worker       if (GetCurrentQuickFrame() == nullptr) {
725*795d594fSAndroid Build Coastguard Worker         return true;
726*795d594fSAndroid Build Coastguard Worker       }
727*795d594fSAndroid Build Coastguard Worker 
728*795d594fSAndroid Build Coastguard Worker       const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader();
729*795d594fSAndroid Build Coastguard Worker       if (method_header != nullptr && method_header->HasShouldDeoptimizeFlag()) {
730*795d594fSAndroid Build Coastguard Worker         if (ShouldForceDeoptForRedefinition()) {
731*795d594fSAndroid Build Coastguard Worker           force_deopt_check_needed_ = true;
732*795d594fSAndroid Build Coastguard Worker           return false;
733*795d594fSAndroid Build Coastguard Worker         }
734*795d594fSAndroid Build Coastguard Worker       }
735*795d594fSAndroid Build Coastguard Worker       return true;  // Continue.
736*795d594fSAndroid Build Coastguard Worker     }
737*795d594fSAndroid Build Coastguard Worker     Thread* const thread_;
738*795d594fSAndroid Build Coastguard Worker     bool force_deopt_check_needed_;
739*795d594fSAndroid Build Coastguard Worker   };
740*795d594fSAndroid Build Coastguard Worker 
741*795d594fSAndroid Build Coastguard Worker   CheckForForceDeoptStackVisitor visitor(thread);
742*795d594fSAndroid Build Coastguard Worker   visitor.WalkStack(true);
743*795d594fSAndroid Build Coastguard Worker   // If there is a frame that requires a force deopt we should have set the IsDeoptCheckRequired
744*795d594fSAndroid Build Coastguard Worker   // bit. We don't check if the bit needs to be reset on every method exit / deoptimization. We
745*795d594fSAndroid Build Coastguard Worker   // only check when we no longer need instrumentation support. So it is possible that the bit is
746*795d594fSAndroid Build Coastguard Worker   // set but we don't find any frames that need a force deopt on the stack so reverse implication
747*795d594fSAndroid Build Coastguard Worker   // doesn't hold.
748*795d594fSAndroid Build Coastguard Worker   DCHECK_IMPLIES(visitor.force_deopt_check_needed_, thread->IsDeoptCheckRequired());
749*795d594fSAndroid Build Coastguard Worker   return visitor.force_deopt_check_needed_;
750*795d594fSAndroid Build Coastguard Worker }
751*795d594fSAndroid Build Coastguard Worker 
DeoptimizeAllThreadFrames()752*795d594fSAndroid Build Coastguard Worker void Instrumentation::DeoptimizeAllThreadFrames() {
753*795d594fSAndroid Build Coastguard Worker   InstrumentAllThreadStacks(/* force_deopt= */ true);
754*795d594fSAndroid Build Coastguard Worker }
755*795d594fSAndroid Build Coastguard Worker 
HasEvent(Instrumentation::InstrumentationEvent expected,uint32_t events)756*795d594fSAndroid Build Coastguard Worker static bool HasEvent(Instrumentation::InstrumentationEvent expected, uint32_t events) {
757*795d594fSAndroid Build Coastguard Worker   return (events & expected) != 0;
758*795d594fSAndroid Build Coastguard Worker }
759*795d594fSAndroid Build Coastguard Worker 
PotentiallyAddListenerTo(Instrumentation::InstrumentationEvent event,uint32_t events,std::list<InstrumentationListener * > & list,InstrumentationListener * listener)760*795d594fSAndroid Build Coastguard Worker static bool PotentiallyAddListenerTo(Instrumentation::InstrumentationEvent event,
761*795d594fSAndroid Build Coastguard Worker                                      uint32_t events,
762*795d594fSAndroid Build Coastguard Worker                                      std::list<InstrumentationListener*>& list,
763*795d594fSAndroid Build Coastguard Worker                                      InstrumentationListener* listener)
764*795d594fSAndroid Build Coastguard Worker     REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::classlinker_classes_lock_) {
765*795d594fSAndroid Build Coastguard Worker   Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
766*795d594fSAndroid Build Coastguard Worker   if (!HasEvent(event, events)) {
767*795d594fSAndroid Build Coastguard Worker     return false;
768*795d594fSAndroid Build Coastguard Worker   }
769*795d594fSAndroid Build Coastguard Worker   // If there is a free slot in the list, we insert the listener in that slot.
770*795d594fSAndroid Build Coastguard Worker   // Otherwise we add it to the end of the list.
771*795d594fSAndroid Build Coastguard Worker   auto it = std::find(list.begin(), list.end(), nullptr);
772*795d594fSAndroid Build Coastguard Worker   if (it != list.end()) {
773*795d594fSAndroid Build Coastguard Worker     *it = listener;
774*795d594fSAndroid Build Coastguard Worker   } else {
775*795d594fSAndroid Build Coastguard Worker     list.push_back(listener);
776*795d594fSAndroid Build Coastguard Worker   }
777*795d594fSAndroid Build Coastguard Worker   return true;
778*795d594fSAndroid Build Coastguard Worker }
779*795d594fSAndroid Build Coastguard Worker 
PotentiallyAddListenerTo(Instrumentation::InstrumentationEvent event,uint32_t events,std::list<InstrumentationListener * > & list,InstrumentationListener * listener,bool * has_listener)780*795d594fSAndroid Build Coastguard Worker static void PotentiallyAddListenerTo(Instrumentation::InstrumentationEvent event,
781*795d594fSAndroid Build Coastguard Worker                                      uint32_t events,
782*795d594fSAndroid Build Coastguard Worker                                      std::list<InstrumentationListener*>& list,
783*795d594fSAndroid Build Coastguard Worker                                      InstrumentationListener* listener,
784*795d594fSAndroid Build Coastguard Worker                                      bool* has_listener)
785*795d594fSAndroid Build Coastguard Worker     REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::classlinker_classes_lock_) {
786*795d594fSAndroid Build Coastguard Worker   if (PotentiallyAddListenerTo(event, events, list, listener)) {
787*795d594fSAndroid Build Coastguard Worker     *has_listener = true;
788*795d594fSAndroid Build Coastguard Worker   }
789*795d594fSAndroid Build Coastguard Worker }
790*795d594fSAndroid Build Coastguard Worker 
PotentiallyAddListenerTo(Instrumentation::InstrumentationEvent event,uint32_t events,std::list<InstrumentationListener * > & list,InstrumentationListener * listener,uint8_t * has_listener,uint8_t flag)791*795d594fSAndroid Build Coastguard Worker static void PotentiallyAddListenerTo(Instrumentation::InstrumentationEvent event,
792*795d594fSAndroid Build Coastguard Worker                                      uint32_t events,
793*795d594fSAndroid Build Coastguard Worker                                      std::list<InstrumentationListener*>& list,
794*795d594fSAndroid Build Coastguard Worker                                      InstrumentationListener* listener,
795*795d594fSAndroid Build Coastguard Worker                                      uint8_t* has_listener,
796*795d594fSAndroid Build Coastguard Worker                                      uint8_t flag)
797*795d594fSAndroid Build Coastguard Worker     REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::classlinker_classes_lock_) {
798*795d594fSAndroid Build Coastguard Worker   if (PotentiallyAddListenerTo(event, events, list, listener)) {
799*795d594fSAndroid Build Coastguard Worker     *has_listener = *has_listener | flag;
800*795d594fSAndroid Build Coastguard Worker   }
801*795d594fSAndroid Build Coastguard Worker }
802*795d594fSAndroid Build Coastguard Worker 
AddListener(InstrumentationListener * listener,uint32_t events,bool is_trace_listener)803*795d594fSAndroid Build Coastguard Worker void Instrumentation::AddListener(InstrumentationListener* listener,
804*795d594fSAndroid Build Coastguard Worker                                   uint32_t events,
805*795d594fSAndroid Build Coastguard Worker                                   bool is_trace_listener) {
806*795d594fSAndroid Build Coastguard Worker   Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
807*795d594fSAndroid Build Coastguard Worker   if (is_trace_listener) {
808*795d594fSAndroid Build Coastguard Worker     PotentiallyAddListenerTo(kMethodEntered,
809*795d594fSAndroid Build Coastguard Worker                              events,
810*795d594fSAndroid Build Coastguard Worker                              method_entry_fast_trace_listeners_,
811*795d594fSAndroid Build Coastguard Worker                              listener,
812*795d594fSAndroid Build Coastguard Worker                              &have_method_entry_listeners_,
813*795d594fSAndroid Build Coastguard Worker                              kFastTraceListeners);
814*795d594fSAndroid Build Coastguard Worker   } else {
815*795d594fSAndroid Build Coastguard Worker     PotentiallyAddListenerTo(kMethodEntered,
816*795d594fSAndroid Build Coastguard Worker                              events,
817*795d594fSAndroid Build Coastguard Worker                              method_entry_slow_listeners_,
818*795d594fSAndroid Build Coastguard Worker                              listener,
819*795d594fSAndroid Build Coastguard Worker                              &have_method_entry_listeners_,
820*795d594fSAndroid Build Coastguard Worker                              kSlowMethodEntryExitListeners);
821*795d594fSAndroid Build Coastguard Worker   }
822*795d594fSAndroid Build Coastguard Worker   if (is_trace_listener) {
823*795d594fSAndroid Build Coastguard Worker     PotentiallyAddListenerTo(kMethodExited,
824*795d594fSAndroid Build Coastguard Worker                              events,
825*795d594fSAndroid Build Coastguard Worker                              method_exit_fast_trace_listeners_,
826*795d594fSAndroid Build Coastguard Worker                              listener,
827*795d594fSAndroid Build Coastguard Worker                              &have_method_exit_listeners_,
828*795d594fSAndroid Build Coastguard Worker                              kFastTraceListeners);
829*795d594fSAndroid Build Coastguard Worker   } else {
830*795d594fSAndroid Build Coastguard Worker     PotentiallyAddListenerTo(kMethodExited,
831*795d594fSAndroid Build Coastguard Worker                              events,
832*795d594fSAndroid Build Coastguard Worker                              method_exit_slow_listeners_,
833*795d594fSAndroid Build Coastguard Worker                              listener,
834*795d594fSAndroid Build Coastguard Worker                              &have_method_exit_listeners_,
835*795d594fSAndroid Build Coastguard Worker                              kSlowMethodEntryExitListeners);
836*795d594fSAndroid Build Coastguard Worker   }
837*795d594fSAndroid Build Coastguard Worker   PotentiallyAddListenerTo(kMethodUnwind,
838*795d594fSAndroid Build Coastguard Worker                            events,
839*795d594fSAndroid Build Coastguard Worker                            method_unwind_listeners_,
840*795d594fSAndroid Build Coastguard Worker                            listener,
841*795d594fSAndroid Build Coastguard Worker                            &have_method_unwind_listeners_);
842*795d594fSAndroid Build Coastguard Worker   PotentiallyAddListenerTo(kBranch,
843*795d594fSAndroid Build Coastguard Worker                            events,
844*795d594fSAndroid Build Coastguard Worker                            branch_listeners_,
845*795d594fSAndroid Build Coastguard Worker                            listener,
846*795d594fSAndroid Build Coastguard Worker                            &have_branch_listeners_);
847*795d594fSAndroid Build Coastguard Worker   PotentiallyAddListenerTo(kDexPcMoved,
848*795d594fSAndroid Build Coastguard Worker                            events,
849*795d594fSAndroid Build Coastguard Worker                            dex_pc_listeners_,
850*795d594fSAndroid Build Coastguard Worker                            listener,
851*795d594fSAndroid Build Coastguard Worker                            &have_dex_pc_listeners_);
852*795d594fSAndroid Build Coastguard Worker   PotentiallyAddListenerTo(kFieldRead,
853*795d594fSAndroid Build Coastguard Worker                            events,
854*795d594fSAndroid Build Coastguard Worker                            field_read_listeners_,
855*795d594fSAndroid Build Coastguard Worker                            listener,
856*795d594fSAndroid Build Coastguard Worker                            &have_field_read_listeners_);
857*795d594fSAndroid Build Coastguard Worker   PotentiallyAddListenerTo(kFieldWritten,
858*795d594fSAndroid Build Coastguard Worker                            events,
859*795d594fSAndroid Build Coastguard Worker                            field_write_listeners_,
860*795d594fSAndroid Build Coastguard Worker                            listener,
861*795d594fSAndroid Build Coastguard Worker                            &have_field_write_listeners_);
862*795d594fSAndroid Build Coastguard Worker   PotentiallyAddListenerTo(kExceptionThrown,
863*795d594fSAndroid Build Coastguard Worker                            events,
864*795d594fSAndroid Build Coastguard Worker                            exception_thrown_listeners_,
865*795d594fSAndroid Build Coastguard Worker                            listener,
866*795d594fSAndroid Build Coastguard Worker                            &have_exception_thrown_listeners_);
867*795d594fSAndroid Build Coastguard Worker   PotentiallyAddListenerTo(kWatchedFramePop,
868*795d594fSAndroid Build Coastguard Worker                            events,
869*795d594fSAndroid Build Coastguard Worker                            watched_frame_pop_listeners_,
870*795d594fSAndroid Build Coastguard Worker                            listener,
871*795d594fSAndroid Build Coastguard Worker                            &have_watched_frame_pop_listeners_);
872*795d594fSAndroid Build Coastguard Worker   PotentiallyAddListenerTo(kExceptionHandled,
873*795d594fSAndroid Build Coastguard Worker                            events,
874*795d594fSAndroid Build Coastguard Worker                            exception_handled_listeners_,
875*795d594fSAndroid Build Coastguard Worker                            listener,
876*795d594fSAndroid Build Coastguard Worker                            &have_exception_handled_listeners_);
877*795d594fSAndroid Build Coastguard Worker   if (HasEvent(kDexPcMoved, events)) {
878*795d594fSAndroid Build Coastguard Worker     MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
879*795d594fSAndroid Build Coastguard Worker     for (Thread* thread : Runtime::Current()->GetThreadList()->GetList()) {
880*795d594fSAndroid Build Coastguard Worker       UpdateNeedsDexPcEventsOnStack(thread);
881*795d594fSAndroid Build Coastguard Worker     }
882*795d594fSAndroid Build Coastguard Worker   }
883*795d594fSAndroid Build Coastguard Worker }
884*795d594fSAndroid Build Coastguard Worker 
PotentiallyRemoveListenerFrom(Instrumentation::InstrumentationEvent event,uint32_t events,std::list<InstrumentationListener * > & list,InstrumentationListener * listener)885*795d594fSAndroid Build Coastguard Worker static bool PotentiallyRemoveListenerFrom(Instrumentation::InstrumentationEvent event,
886*795d594fSAndroid Build Coastguard Worker                                           uint32_t events,
887*795d594fSAndroid Build Coastguard Worker                                           std::list<InstrumentationListener*>& list,
888*795d594fSAndroid Build Coastguard Worker                                           InstrumentationListener* listener)
889*795d594fSAndroid Build Coastguard Worker     REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::classlinker_classes_lock_) {
890*795d594fSAndroid Build Coastguard Worker   Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
891*795d594fSAndroid Build Coastguard Worker   if (!HasEvent(event, events)) {
892*795d594fSAndroid Build Coastguard Worker     return false;
893*795d594fSAndroid Build Coastguard Worker   }
894*795d594fSAndroid Build Coastguard Worker   auto it = std::find(list.begin(), list.end(), listener);
895*795d594fSAndroid Build Coastguard Worker   if (it != list.end()) {
896*795d594fSAndroid Build Coastguard Worker     // Just update the entry, do not remove from the list. Removing entries in the list
897*795d594fSAndroid Build Coastguard Worker     // is unsafe when mutators are iterating over it.
898*795d594fSAndroid Build Coastguard Worker     *it = nullptr;
899*795d594fSAndroid Build Coastguard Worker   }
900*795d594fSAndroid Build Coastguard Worker 
901*795d594fSAndroid Build Coastguard Worker   // Check if the list contains any non-null listener.
902*795d594fSAndroid Build Coastguard Worker   for (InstrumentationListener* l : list) {
903*795d594fSAndroid Build Coastguard Worker     if (l != nullptr) {
904*795d594fSAndroid Build Coastguard Worker       return false;
905*795d594fSAndroid Build Coastguard Worker     }
906*795d594fSAndroid Build Coastguard Worker   }
907*795d594fSAndroid Build Coastguard Worker 
908*795d594fSAndroid Build Coastguard Worker   return true;
909*795d594fSAndroid Build Coastguard Worker }
910*795d594fSAndroid Build Coastguard Worker 
PotentiallyRemoveListenerFrom(Instrumentation::InstrumentationEvent event,uint32_t events,std::list<InstrumentationListener * > & list,InstrumentationListener * listener,bool * has_listener)911*795d594fSAndroid Build Coastguard Worker static void PotentiallyRemoveListenerFrom(Instrumentation::InstrumentationEvent event,
912*795d594fSAndroid Build Coastguard Worker                                           uint32_t events,
913*795d594fSAndroid Build Coastguard Worker                                           std::list<InstrumentationListener*>& list,
914*795d594fSAndroid Build Coastguard Worker                                           InstrumentationListener* listener,
915*795d594fSAndroid Build Coastguard Worker                                           bool* has_listener)
916*795d594fSAndroid Build Coastguard Worker     REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::classlinker_classes_lock_) {
917*795d594fSAndroid Build Coastguard Worker   if (PotentiallyRemoveListenerFrom(event, events, list, listener)) {
918*795d594fSAndroid Build Coastguard Worker     *has_listener = false;
919*795d594fSAndroid Build Coastguard Worker   }
920*795d594fSAndroid Build Coastguard Worker }
921*795d594fSAndroid Build Coastguard Worker 
PotentiallyRemoveListenerFrom(Instrumentation::InstrumentationEvent event,uint32_t events,std::list<InstrumentationListener * > & list,InstrumentationListener * listener,uint8_t * has_listener,uint8_t flag)922*795d594fSAndroid Build Coastguard Worker static void PotentiallyRemoveListenerFrom(Instrumentation::InstrumentationEvent event,
923*795d594fSAndroid Build Coastguard Worker                                           uint32_t events,
924*795d594fSAndroid Build Coastguard Worker                                           std::list<InstrumentationListener*>& list,
925*795d594fSAndroid Build Coastguard Worker                                           InstrumentationListener* listener,
926*795d594fSAndroid Build Coastguard Worker                                           uint8_t* has_listener,
927*795d594fSAndroid Build Coastguard Worker                                           uint8_t flag)
928*795d594fSAndroid Build Coastguard Worker     REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::classlinker_classes_lock_) {
929*795d594fSAndroid Build Coastguard Worker   if (PotentiallyRemoveListenerFrom(event, events, list, listener)) {
930*795d594fSAndroid Build Coastguard Worker     *has_listener = *has_listener & ~flag;
931*795d594fSAndroid Build Coastguard Worker   }
932*795d594fSAndroid Build Coastguard Worker }
933*795d594fSAndroid Build Coastguard Worker 
RemoveListener(InstrumentationListener * listener,uint32_t events,bool is_trace_listener)934*795d594fSAndroid Build Coastguard Worker void Instrumentation::RemoveListener(InstrumentationListener* listener,
935*795d594fSAndroid Build Coastguard Worker                                      uint32_t events,
936*795d594fSAndroid Build Coastguard Worker                                      bool is_trace_listener) {
937*795d594fSAndroid Build Coastguard Worker   Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
938*795d594fSAndroid Build Coastguard Worker   if (is_trace_listener) {
939*795d594fSAndroid Build Coastguard Worker     PotentiallyRemoveListenerFrom(kMethodEntered,
940*795d594fSAndroid Build Coastguard Worker                                   events,
941*795d594fSAndroid Build Coastguard Worker                                   method_entry_fast_trace_listeners_,
942*795d594fSAndroid Build Coastguard Worker                                   listener,
943*795d594fSAndroid Build Coastguard Worker                                   &have_method_entry_listeners_,
944*795d594fSAndroid Build Coastguard Worker                                   kFastTraceListeners);
945*795d594fSAndroid Build Coastguard Worker   } else {
946*795d594fSAndroid Build Coastguard Worker     PotentiallyRemoveListenerFrom(kMethodEntered,
947*795d594fSAndroid Build Coastguard Worker                                   events,
948*795d594fSAndroid Build Coastguard Worker                                   method_entry_slow_listeners_,
949*795d594fSAndroid Build Coastguard Worker                                   listener,
950*795d594fSAndroid Build Coastguard Worker                                   &have_method_entry_listeners_,
951*795d594fSAndroid Build Coastguard Worker                                   kSlowMethodEntryExitListeners);
952*795d594fSAndroid Build Coastguard Worker   }
953*795d594fSAndroid Build Coastguard Worker   if (is_trace_listener) {
954*795d594fSAndroid Build Coastguard Worker     PotentiallyRemoveListenerFrom(kMethodExited,
955*795d594fSAndroid Build Coastguard Worker                                   events,
956*795d594fSAndroid Build Coastguard Worker                                   method_exit_fast_trace_listeners_,
957*795d594fSAndroid Build Coastguard Worker                                   listener,
958*795d594fSAndroid Build Coastguard Worker                                   &have_method_exit_listeners_,
959*795d594fSAndroid Build Coastguard Worker                                   kFastTraceListeners);
960*795d594fSAndroid Build Coastguard Worker   } else {
961*795d594fSAndroid Build Coastguard Worker     PotentiallyRemoveListenerFrom(kMethodExited,
962*795d594fSAndroid Build Coastguard Worker                                   events,
963*795d594fSAndroid Build Coastguard Worker                                   method_exit_slow_listeners_,
964*795d594fSAndroid Build Coastguard Worker                                   listener,
965*795d594fSAndroid Build Coastguard Worker                                   &have_method_exit_listeners_,
966*795d594fSAndroid Build Coastguard Worker                                   kSlowMethodEntryExitListeners);
967*795d594fSAndroid Build Coastguard Worker   }
968*795d594fSAndroid Build Coastguard Worker   PotentiallyRemoveListenerFrom(kMethodUnwind,
969*795d594fSAndroid Build Coastguard Worker                                 events,
970*795d594fSAndroid Build Coastguard Worker                                 method_unwind_listeners_,
971*795d594fSAndroid Build Coastguard Worker                                 listener,
972*795d594fSAndroid Build Coastguard Worker                                 &have_method_unwind_listeners_);
973*795d594fSAndroid Build Coastguard Worker   PotentiallyRemoveListenerFrom(kBranch,
974*795d594fSAndroid Build Coastguard Worker                                 events,
975*795d594fSAndroid Build Coastguard Worker                                 branch_listeners_,
976*795d594fSAndroid Build Coastguard Worker                                 listener,
977*795d594fSAndroid Build Coastguard Worker                                 &have_branch_listeners_);
978*795d594fSAndroid Build Coastguard Worker   PotentiallyRemoveListenerFrom(kDexPcMoved,
979*795d594fSAndroid Build Coastguard Worker                                 events,
980*795d594fSAndroid Build Coastguard Worker                                 dex_pc_listeners_,
981*795d594fSAndroid Build Coastguard Worker                                 listener,
982*795d594fSAndroid Build Coastguard Worker                                 &have_dex_pc_listeners_);
983*795d594fSAndroid Build Coastguard Worker   PotentiallyRemoveListenerFrom(kFieldRead,
984*795d594fSAndroid Build Coastguard Worker                                 events,
985*795d594fSAndroid Build Coastguard Worker                                 field_read_listeners_,
986*795d594fSAndroid Build Coastguard Worker                                 listener,
987*795d594fSAndroid Build Coastguard Worker                                 &have_field_read_listeners_);
988*795d594fSAndroid Build Coastguard Worker   PotentiallyRemoveListenerFrom(kFieldWritten,
989*795d594fSAndroid Build Coastguard Worker                                 events,
990*795d594fSAndroid Build Coastguard Worker                                 field_write_listeners_,
991*795d594fSAndroid Build Coastguard Worker                                 listener,
992*795d594fSAndroid Build Coastguard Worker                                 &have_field_write_listeners_);
993*795d594fSAndroid Build Coastguard Worker   PotentiallyRemoveListenerFrom(kExceptionThrown,
994*795d594fSAndroid Build Coastguard Worker                                 events,
995*795d594fSAndroid Build Coastguard Worker                                 exception_thrown_listeners_,
996*795d594fSAndroid Build Coastguard Worker                                 listener,
997*795d594fSAndroid Build Coastguard Worker                                 &have_exception_thrown_listeners_);
998*795d594fSAndroid Build Coastguard Worker   PotentiallyRemoveListenerFrom(kWatchedFramePop,
999*795d594fSAndroid Build Coastguard Worker                                 events,
1000*795d594fSAndroid Build Coastguard Worker                                 watched_frame_pop_listeners_,
1001*795d594fSAndroid Build Coastguard Worker                                 listener,
1002*795d594fSAndroid Build Coastguard Worker                                 &have_watched_frame_pop_listeners_);
1003*795d594fSAndroid Build Coastguard Worker   PotentiallyRemoveListenerFrom(kExceptionHandled,
1004*795d594fSAndroid Build Coastguard Worker                                 events,
1005*795d594fSAndroid Build Coastguard Worker                                 exception_handled_listeners_,
1006*795d594fSAndroid Build Coastguard Worker                                 listener,
1007*795d594fSAndroid Build Coastguard Worker                                 &have_exception_handled_listeners_);
1008*795d594fSAndroid Build Coastguard Worker   if (HasEvent(kDexPcMoved, events)) {
1009*795d594fSAndroid Build Coastguard Worker     MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
1010*795d594fSAndroid Build Coastguard Worker     for (Thread* thread : Runtime::Current()->GetThreadList()->GetList()) {
1011*795d594fSAndroid Build Coastguard Worker       UpdateNeedsDexPcEventsOnStack(thread);
1012*795d594fSAndroid Build Coastguard Worker     }
1013*795d594fSAndroid Build Coastguard Worker   }
1014*795d594fSAndroid Build Coastguard Worker }
1015*795d594fSAndroid Build Coastguard Worker 
GetCurrentInstrumentationLevel() const1016*795d594fSAndroid Build Coastguard Worker Instrumentation::InstrumentationLevel Instrumentation::GetCurrentInstrumentationLevel() const {
1017*795d594fSAndroid Build Coastguard Worker   return instrumentation_level_;
1018*795d594fSAndroid Build Coastguard Worker }
1019*795d594fSAndroid Build Coastguard Worker 
ConfigureStubs(const char * key,InstrumentationLevel desired_level,bool try_switch_to_non_debuggable)1020*795d594fSAndroid Build Coastguard Worker void Instrumentation::ConfigureStubs(const char* key,
1021*795d594fSAndroid Build Coastguard Worker                                      InstrumentationLevel desired_level,
1022*795d594fSAndroid Build Coastguard Worker                                      bool try_switch_to_non_debuggable) {
1023*795d594fSAndroid Build Coastguard Worker   // Store the instrumentation level for this key or remove it.
1024*795d594fSAndroid Build Coastguard Worker   if (desired_level == InstrumentationLevel::kInstrumentNothing) {
1025*795d594fSAndroid Build Coastguard Worker     // The client no longer needs instrumentation.
1026*795d594fSAndroid Build Coastguard Worker     requested_instrumentation_levels_.erase(key);
1027*795d594fSAndroid Build Coastguard Worker   } else {
1028*795d594fSAndroid Build Coastguard Worker     // The client needs instrumentation.
1029*795d594fSAndroid Build Coastguard Worker     requested_instrumentation_levels_.Overwrite(key, desired_level);
1030*795d594fSAndroid Build Coastguard Worker   }
1031*795d594fSAndroid Build Coastguard Worker 
1032*795d594fSAndroid Build Coastguard Worker   UpdateStubs(try_switch_to_non_debuggable);
1033*795d594fSAndroid Build Coastguard Worker }
1034*795d594fSAndroid Build Coastguard Worker 
UpdateInstrumentationLevel(InstrumentationLevel requested_level)1035*795d594fSAndroid Build Coastguard Worker void Instrumentation::UpdateInstrumentationLevel(InstrumentationLevel requested_level) {
1036*795d594fSAndroid Build Coastguard Worker   instrumentation_level_ = requested_level;
1037*795d594fSAndroid Build Coastguard Worker }
1038*795d594fSAndroid Build Coastguard Worker 
EnableEntryExitHooks(const char * key)1039*795d594fSAndroid Build Coastguard Worker void Instrumentation::EnableEntryExitHooks(const char* key) {
1040*795d594fSAndroid Build Coastguard Worker   DCHECK(Runtime::Current()->IsJavaDebuggable());
1041*795d594fSAndroid Build Coastguard Worker   ConfigureStubs(key,
1042*795d594fSAndroid Build Coastguard Worker                  InstrumentationLevel::kInstrumentWithEntryExitHooks,
1043*795d594fSAndroid Build Coastguard Worker                  /*try_switch_to_non_debuggable=*/false);
1044*795d594fSAndroid Build Coastguard Worker }
1045*795d594fSAndroid Build Coastguard Worker 
MaybeRestoreInstrumentationStack()1046*795d594fSAndroid Build Coastguard Worker void Instrumentation::MaybeRestoreInstrumentationStack() {
1047*795d594fSAndroid Build Coastguard Worker   // Restore stack only if there is no method currently deoptimized.
1048*795d594fSAndroid Build Coastguard Worker   if (!IsDeoptimizedMethodsEmpty()) {
1049*795d594fSAndroid Build Coastguard Worker     return;
1050*795d594fSAndroid Build Coastguard Worker   }
1051*795d594fSAndroid Build Coastguard Worker 
1052*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
1053*795d594fSAndroid Build Coastguard Worker   MutexLock mu(self, *Locks::thread_list_lock_);
1054*795d594fSAndroid Build Coastguard Worker   bool no_remaining_deopts = true;
1055*795d594fSAndroid Build Coastguard Worker   // Check that there are no other forced deoptimizations. Do it here so we only need to lock
1056*795d594fSAndroid Build Coastguard Worker   // thread_list_lock once.
1057*795d594fSAndroid Build Coastguard Worker   // The compiler gets confused on the thread annotations, so use
1058*795d594fSAndroid Build Coastguard Worker   // NO_THREAD_SAFETY_ANALYSIS. Note that we hold the mutator lock
1059*795d594fSAndroid Build Coastguard Worker   // exclusively at this point.
1060*795d594fSAndroid Build Coastguard Worker   Locks::mutator_lock_->AssertExclusiveHeld(self);
1061*795d594fSAndroid Build Coastguard Worker   Runtime::Current()->GetThreadList()->ForEach([&](Thread* t) NO_THREAD_SAFETY_ANALYSIS {
1062*795d594fSAndroid Build Coastguard Worker     bool has_force_deopt_frames = HasFramesNeedingForceDeopt(t);
1063*795d594fSAndroid Build Coastguard Worker     if (!has_force_deopt_frames) {
1064*795d594fSAndroid Build Coastguard Worker       // We no longer have any frames that require a force deopt check. If the bit was true then we
1065*795d594fSAndroid Build Coastguard Worker       // had some frames earlier but they already got deoptimized and are no longer on stack.
1066*795d594fSAndroid Build Coastguard Worker       t->SetDeoptCheckRequired(false);
1067*795d594fSAndroid Build Coastguard Worker     }
1068*795d594fSAndroid Build Coastguard Worker     no_remaining_deopts =
1069*795d594fSAndroid Build Coastguard Worker         no_remaining_deopts &&
1070*795d594fSAndroid Build Coastguard Worker         !t->IsForceInterpreter() &&
1071*795d594fSAndroid Build Coastguard Worker         !t->HasDebuggerShadowFrames() &&
1072*795d594fSAndroid Build Coastguard Worker         !has_force_deopt_frames;
1073*795d594fSAndroid Build Coastguard Worker   });
1074*795d594fSAndroid Build Coastguard Worker   if (no_remaining_deopts) {
1075*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetThreadList()->ForEach(InstrumentationRestoreStack);
1076*795d594fSAndroid Build Coastguard Worker     run_exit_hooks_ = false;
1077*795d594fSAndroid Build Coastguard Worker   }
1078*795d594fSAndroid Build Coastguard Worker }
1079*795d594fSAndroid Build Coastguard Worker 
UpdateStubs(bool try_switch_to_non_debuggable)1080*795d594fSAndroid Build Coastguard Worker void Instrumentation::UpdateStubs(bool try_switch_to_non_debuggable) {
1081*795d594fSAndroid Build Coastguard Worker   // Look for the highest required instrumentation level.
1082*795d594fSAndroid Build Coastguard Worker   InstrumentationLevel requested_level = InstrumentationLevel::kInstrumentNothing;
1083*795d594fSAndroid Build Coastguard Worker   for (const auto& v : requested_instrumentation_levels_) {
1084*795d594fSAndroid Build Coastguard Worker     requested_level = std::max(requested_level, v.second);
1085*795d594fSAndroid Build Coastguard Worker   }
1086*795d594fSAndroid Build Coastguard Worker 
1087*795d594fSAndroid Build Coastguard Worker   if (GetCurrentInstrumentationLevel() == requested_level) {
1088*795d594fSAndroid Build Coastguard Worker     // We're already set.
1089*795d594fSAndroid Build Coastguard Worker     return;
1090*795d594fSAndroid Build Coastguard Worker   }
1091*795d594fSAndroid Build Coastguard Worker 
1092*795d594fSAndroid Build Coastguard Worker   Thread* const self = Thread::Current();
1093*795d594fSAndroid Build Coastguard Worker   Runtime* runtime = Runtime::Current();
1094*795d594fSAndroid Build Coastguard Worker   Locks::mutator_lock_->AssertExclusiveHeld(self);
1095*795d594fSAndroid Build Coastguard Worker   Locks::thread_list_lock_->AssertNotHeld(self);
1096*795d594fSAndroid Build Coastguard Worker   // The following needs to happen in the same order.
1097*795d594fSAndroid Build Coastguard Worker   // 1. Update the instrumentation level
1098*795d594fSAndroid Build Coastguard Worker   // 2. Switch the runtime to non-debuggable if requested. We switch to non-debuggable only when
1099*795d594fSAndroid Build Coastguard Worker   // the instrumentation level is set to kInstrumentNothing. So this needs to happen only after
1100*795d594fSAndroid Build Coastguard Worker   // updating the instrumentation level.
1101*795d594fSAndroid Build Coastguard Worker   // 3. Update the entry points. We use AOT code only if we aren't debuggable runtime. So update
1102*795d594fSAndroid Build Coastguard Worker   // entrypoints after switching the instrumentation level.
1103*795d594fSAndroid Build Coastguard Worker   UpdateInstrumentationLevel(requested_level);
1104*795d594fSAndroid Build Coastguard Worker   if (try_switch_to_non_debuggable) {
1105*795d594fSAndroid Build Coastguard Worker     MaybeSwitchRuntimeDebugState(self);
1106*795d594fSAndroid Build Coastguard Worker   }
1107*795d594fSAndroid Build Coastguard Worker   InstallStubsClassVisitor visitor(this);
1108*795d594fSAndroid Build Coastguard Worker   runtime->GetClassLinker()->VisitClasses(&visitor);
1109*795d594fSAndroid Build Coastguard Worker   if (requested_level > InstrumentationLevel::kInstrumentNothing) {
1110*795d594fSAndroid Build Coastguard Worker     InstrumentAllThreadStacks(/* force_deopt= */ false);
1111*795d594fSAndroid Build Coastguard Worker   } else {
1112*795d594fSAndroid Build Coastguard Worker     MaybeRestoreInstrumentationStack();
1113*795d594fSAndroid Build Coastguard Worker   }
1114*795d594fSAndroid Build Coastguard Worker }
1115*795d594fSAndroid Build Coastguard Worker 
ResetQuickAllocEntryPointsForThread(Thread * thread,void * arg)1116*795d594fSAndroid Build Coastguard Worker static void ResetQuickAllocEntryPointsForThread(Thread* thread, [[maybe_unused]] void* arg) {
1117*795d594fSAndroid Build Coastguard Worker   thread->ResetQuickAllocEntryPointsForThread();
1118*795d594fSAndroid Build Coastguard Worker }
1119*795d594fSAndroid Build Coastguard Worker 
SetEntrypointsInstrumented(bool instrumented)1120*795d594fSAndroid Build Coastguard Worker void Instrumentation::SetEntrypointsInstrumented(bool instrumented) {
1121*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
1122*795d594fSAndroid Build Coastguard Worker   Runtime* runtime = Runtime::Current();
1123*795d594fSAndroid Build Coastguard Worker   Locks::mutator_lock_->AssertNotHeld(self);
1124*795d594fSAndroid Build Coastguard Worker   Locks::instrument_entrypoints_lock_->AssertHeld(self);
1125*795d594fSAndroid Build Coastguard Worker   if (runtime->IsStarted()) {
1126*795d594fSAndroid Build Coastguard Worker     ScopedSuspendAll ssa(__FUNCTION__);
1127*795d594fSAndroid Build Coastguard Worker     MutexLock mu(self, *Locks::runtime_shutdown_lock_);
1128*795d594fSAndroid Build Coastguard Worker     SetQuickAllocEntryPointsInstrumented(instrumented);
1129*795d594fSAndroid Build Coastguard Worker     ResetQuickAllocEntryPoints();
1130*795d594fSAndroid Build Coastguard Worker     alloc_entrypoints_instrumented_ = instrumented;
1131*795d594fSAndroid Build Coastguard Worker   } else {
1132*795d594fSAndroid Build Coastguard Worker     MutexLock mu(self, *Locks::runtime_shutdown_lock_);
1133*795d594fSAndroid Build Coastguard Worker     SetQuickAllocEntryPointsInstrumented(instrumented);
1134*795d594fSAndroid Build Coastguard Worker 
1135*795d594fSAndroid Build Coastguard Worker     // Note: ResetQuickAllocEntryPoints only works when the runtime is started. Manually run the
1136*795d594fSAndroid Build Coastguard Worker     //       update for just this thread.
1137*795d594fSAndroid Build Coastguard Worker     // Note: self may be null. One of those paths is setting instrumentation in the Heap
1138*795d594fSAndroid Build Coastguard Worker     //       constructor for gcstress mode.
1139*795d594fSAndroid Build Coastguard Worker     if (self != nullptr) {
1140*795d594fSAndroid Build Coastguard Worker       ResetQuickAllocEntryPointsForThread(self, nullptr);
1141*795d594fSAndroid Build Coastguard Worker     }
1142*795d594fSAndroid Build Coastguard Worker 
1143*795d594fSAndroid Build Coastguard Worker     alloc_entrypoints_instrumented_ = instrumented;
1144*795d594fSAndroid Build Coastguard Worker   }
1145*795d594fSAndroid Build Coastguard Worker }
1146*795d594fSAndroid Build Coastguard Worker 
InstrumentQuickAllocEntryPoints()1147*795d594fSAndroid Build Coastguard Worker void Instrumentation::InstrumentQuickAllocEntryPoints() {
1148*795d594fSAndroid Build Coastguard Worker   MutexLock mu(Thread::Current(), *Locks::instrument_entrypoints_lock_);
1149*795d594fSAndroid Build Coastguard Worker   InstrumentQuickAllocEntryPointsLocked();
1150*795d594fSAndroid Build Coastguard Worker }
1151*795d594fSAndroid Build Coastguard Worker 
UninstrumentQuickAllocEntryPoints()1152*795d594fSAndroid Build Coastguard Worker void Instrumentation::UninstrumentQuickAllocEntryPoints() {
1153*795d594fSAndroid Build Coastguard Worker   MutexLock mu(Thread::Current(), *Locks::instrument_entrypoints_lock_);
1154*795d594fSAndroid Build Coastguard Worker   UninstrumentQuickAllocEntryPointsLocked();
1155*795d594fSAndroid Build Coastguard Worker }
1156*795d594fSAndroid Build Coastguard Worker 
InstrumentQuickAllocEntryPointsLocked()1157*795d594fSAndroid Build Coastguard Worker void Instrumentation::InstrumentQuickAllocEntryPointsLocked() {
1158*795d594fSAndroid Build Coastguard Worker   Locks::instrument_entrypoints_lock_->AssertHeld(Thread::Current());
1159*795d594fSAndroid Build Coastguard Worker   if (quick_alloc_entry_points_instrumentation_counter_ == 0) {
1160*795d594fSAndroid Build Coastguard Worker     SetEntrypointsInstrumented(true);
1161*795d594fSAndroid Build Coastguard Worker   }
1162*795d594fSAndroid Build Coastguard Worker   ++quick_alloc_entry_points_instrumentation_counter_;
1163*795d594fSAndroid Build Coastguard Worker }
1164*795d594fSAndroid Build Coastguard Worker 
UninstrumentQuickAllocEntryPointsLocked()1165*795d594fSAndroid Build Coastguard Worker void Instrumentation::UninstrumentQuickAllocEntryPointsLocked() {
1166*795d594fSAndroid Build Coastguard Worker   Locks::instrument_entrypoints_lock_->AssertHeld(Thread::Current());
1167*795d594fSAndroid Build Coastguard Worker   CHECK_GT(quick_alloc_entry_points_instrumentation_counter_, 0U);
1168*795d594fSAndroid Build Coastguard Worker   --quick_alloc_entry_points_instrumentation_counter_;
1169*795d594fSAndroid Build Coastguard Worker   if (quick_alloc_entry_points_instrumentation_counter_ == 0) {
1170*795d594fSAndroid Build Coastguard Worker     SetEntrypointsInstrumented(false);
1171*795d594fSAndroid Build Coastguard Worker   }
1172*795d594fSAndroid Build Coastguard Worker }
1173*795d594fSAndroid Build Coastguard Worker 
ResetQuickAllocEntryPoints()1174*795d594fSAndroid Build Coastguard Worker void Instrumentation::ResetQuickAllocEntryPoints() {
1175*795d594fSAndroid Build Coastguard Worker   Runtime* runtime = Runtime::Current();
1176*795d594fSAndroid Build Coastguard Worker   if (runtime->IsStarted()) {
1177*795d594fSAndroid Build Coastguard Worker     MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
1178*795d594fSAndroid Build Coastguard Worker     runtime->GetThreadList()->ForEach(ResetQuickAllocEntryPointsForThread, nullptr);
1179*795d594fSAndroid Build Coastguard Worker   }
1180*795d594fSAndroid Build Coastguard Worker }
1181*795d594fSAndroid Build Coastguard Worker 
EntryPointString(const void * code)1182*795d594fSAndroid Build Coastguard Worker std::string Instrumentation::EntryPointString(const void* code) {
1183*795d594fSAndroid Build Coastguard Worker   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1184*795d594fSAndroid Build Coastguard Worker   jit::Jit* jit = Runtime::Current()->GetJit();
1185*795d594fSAndroid Build Coastguard Worker   if (class_linker->IsQuickToInterpreterBridge(code)) {
1186*795d594fSAndroid Build Coastguard Worker     return "interpreter";
1187*795d594fSAndroid Build Coastguard Worker   } else if (class_linker->IsQuickResolutionStub(code)) {
1188*795d594fSAndroid Build Coastguard Worker     return "resolution";
1189*795d594fSAndroid Build Coastguard Worker   } else if (jit != nullptr && jit->GetCodeCache()->ContainsPc(code)) {
1190*795d594fSAndroid Build Coastguard Worker     return "jit";
1191*795d594fSAndroid Build Coastguard Worker   } else if (code == GetInvokeObsoleteMethodStub()) {
1192*795d594fSAndroid Build Coastguard Worker     return "obsolete";
1193*795d594fSAndroid Build Coastguard Worker   } else if (code == interpreter::GetNterpEntryPoint()) {
1194*795d594fSAndroid Build Coastguard Worker     return "nterp";
1195*795d594fSAndroid Build Coastguard Worker   } else if (code == interpreter::GetNterpWithClinitEntryPoint()) {
1196*795d594fSAndroid Build Coastguard Worker     return "nterp with clinit";
1197*795d594fSAndroid Build Coastguard Worker   } else if (class_linker->IsQuickGenericJniStub(code)) {
1198*795d594fSAndroid Build Coastguard Worker     return "generic jni";
1199*795d594fSAndroid Build Coastguard Worker   } else if (Runtime::Current()->GetOatFileManager().ContainsPc(code)) {
1200*795d594fSAndroid Build Coastguard Worker     return "oat";
1201*795d594fSAndroid Build Coastguard Worker   } else if (OatQuickMethodHeader::IsStub(reinterpret_cast<const uint8_t*>(code)).value_or(false)) {
1202*795d594fSAndroid Build Coastguard Worker     return "stub";
1203*795d594fSAndroid Build Coastguard Worker   }
1204*795d594fSAndroid Build Coastguard Worker   return "unknown";
1205*795d594fSAndroid Build Coastguard Worker }
1206*795d594fSAndroid Build Coastguard Worker 
UpdateMethodsCodeImpl(ArtMethod * method,const void * new_code)1207*795d594fSAndroid Build Coastguard Worker void Instrumentation::UpdateMethodsCodeImpl(ArtMethod* method, const void* new_code) {
1208*795d594fSAndroid Build Coastguard Worker   if (!EntryExitStubsInstalled()) {
1209*795d594fSAndroid Build Coastguard Worker     // Fast path: no instrumentation.
1210*795d594fSAndroid Build Coastguard Worker     DCHECK(!IsDeoptimized(method));
1211*795d594fSAndroid Build Coastguard Worker     UpdateEntryPoints(method, new_code);
1212*795d594fSAndroid Build Coastguard Worker     return;
1213*795d594fSAndroid Build Coastguard Worker   }
1214*795d594fSAndroid Build Coastguard Worker 
1215*795d594fSAndroid Build Coastguard Worker   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1216*795d594fSAndroid Build Coastguard Worker   if (class_linker->IsQuickToInterpreterBridge(new_code)) {
1217*795d594fSAndroid Build Coastguard Worker     // It's always OK to update to the interpreter.
1218*795d594fSAndroid Build Coastguard Worker     UpdateEntryPoints(method, new_code);
1219*795d594fSAndroid Build Coastguard Worker     return;
1220*795d594fSAndroid Build Coastguard Worker   }
1221*795d594fSAndroid Build Coastguard Worker 
1222*795d594fSAndroid Build Coastguard Worker   if (InterpretOnly(method)) {
1223*795d594fSAndroid Build Coastguard Worker     DCHECK(class_linker->IsQuickToInterpreterBridge(method->GetEntryPointFromQuickCompiledCode()))
1224*795d594fSAndroid Build Coastguard Worker         << EntryPointString(method->GetEntryPointFromQuickCompiledCode());
1225*795d594fSAndroid Build Coastguard Worker     // Don't update, stay deoptimized.
1226*795d594fSAndroid Build Coastguard Worker     return;
1227*795d594fSAndroid Build Coastguard Worker   }
1228*795d594fSAndroid Build Coastguard Worker 
1229*795d594fSAndroid Build Coastguard Worker   if (EntryExitStubsInstalled() && !CodeSupportsEntryExitHooks(new_code, method)) {
1230*795d594fSAndroid Build Coastguard Worker     DCHECK(CodeSupportsEntryExitHooks(method->GetEntryPointFromQuickCompiledCode(), method))
1231*795d594fSAndroid Build Coastguard Worker         << EntryPointString(method->GetEntryPointFromQuickCompiledCode()) << " "
1232*795d594fSAndroid Build Coastguard Worker         << method->PrettyMethod();
1233*795d594fSAndroid Build Coastguard Worker     // If we need entry / exit stubs but the new_code doesn't support entry / exit hooks just skip.
1234*795d594fSAndroid Build Coastguard Worker     return;
1235*795d594fSAndroid Build Coastguard Worker   }
1236*795d594fSAndroid Build Coastguard Worker 
1237*795d594fSAndroid Build Coastguard Worker   // At this point, we can update as asked.
1238*795d594fSAndroid Build Coastguard Worker   UpdateEntryPoints(method, new_code);
1239*795d594fSAndroid Build Coastguard Worker }
1240*795d594fSAndroid Build Coastguard Worker 
UpdateNativeMethodsCodeToJitCode(ArtMethod * method,const void * new_code)1241*795d594fSAndroid Build Coastguard Worker void Instrumentation::UpdateNativeMethodsCodeToJitCode(ArtMethod* method, const void* new_code) {
1242*795d594fSAndroid Build Coastguard Worker   // We don't do any read barrier on `method`'s declaring class in this code, as the JIT might
1243*795d594fSAndroid Build Coastguard Worker   // enter here on a soon-to-be deleted ArtMethod. Updating the entrypoint is OK though, as
1244*795d594fSAndroid Build Coastguard Worker   // the ArtMethod is still in memory.
1245*795d594fSAndroid Build Coastguard Worker   if (EntryExitStubsInstalled() && !CodeSupportsEntryExitHooks(new_code, method)) {
1246*795d594fSAndroid Build Coastguard Worker     // If the new code doesn't support entry exit hooks but we need them don't update with the new
1247*795d594fSAndroid Build Coastguard Worker     // code.
1248*795d594fSAndroid Build Coastguard Worker     return;
1249*795d594fSAndroid Build Coastguard Worker   }
1250*795d594fSAndroid Build Coastguard Worker   UpdateEntryPoints(method, new_code);
1251*795d594fSAndroid Build Coastguard Worker }
1252*795d594fSAndroid Build Coastguard Worker 
UpdateMethodsCode(ArtMethod * method,const void * new_code)1253*795d594fSAndroid Build Coastguard Worker void Instrumentation::UpdateMethodsCode(ArtMethod* method, const void* new_code) {
1254*795d594fSAndroid Build Coastguard Worker   DCHECK(method->GetDeclaringClass()->IsResolved());
1255*795d594fSAndroid Build Coastguard Worker   UpdateMethodsCodeImpl(method, new_code);
1256*795d594fSAndroid Build Coastguard Worker }
1257*795d594fSAndroid Build Coastguard Worker 
AddDeoptimizedMethod(ArtMethod * method)1258*795d594fSAndroid Build Coastguard Worker bool Instrumentation::AddDeoptimizedMethod(ArtMethod* method) {
1259*795d594fSAndroid Build Coastguard Worker   if (IsDeoptimizedMethod(method)) {
1260*795d594fSAndroid Build Coastguard Worker     // Already in the map. Return.
1261*795d594fSAndroid Build Coastguard Worker     return false;
1262*795d594fSAndroid Build Coastguard Worker   }
1263*795d594fSAndroid Build Coastguard Worker   // Not found. Add it.
1264*795d594fSAndroid Build Coastguard Worker   deoptimized_methods_.insert(method);
1265*795d594fSAndroid Build Coastguard Worker   return true;
1266*795d594fSAndroid Build Coastguard Worker }
1267*795d594fSAndroid Build Coastguard Worker 
IsDeoptimizedMethod(ArtMethod * method)1268*795d594fSAndroid Build Coastguard Worker bool Instrumentation::IsDeoptimizedMethod(ArtMethod* method) {
1269*795d594fSAndroid Build Coastguard Worker   return deoptimized_methods_.find(method) != deoptimized_methods_.end();
1270*795d594fSAndroid Build Coastguard Worker }
1271*795d594fSAndroid Build Coastguard Worker 
RemoveDeoptimizedMethod(ArtMethod * method)1272*795d594fSAndroid Build Coastguard Worker bool Instrumentation::RemoveDeoptimizedMethod(ArtMethod* method) {
1273*795d594fSAndroid Build Coastguard Worker   auto it = deoptimized_methods_.find(method);
1274*795d594fSAndroid Build Coastguard Worker   if (it == deoptimized_methods_.end()) {
1275*795d594fSAndroid Build Coastguard Worker     return false;
1276*795d594fSAndroid Build Coastguard Worker   }
1277*795d594fSAndroid Build Coastguard Worker   deoptimized_methods_.erase(it);
1278*795d594fSAndroid Build Coastguard Worker   return true;
1279*795d594fSAndroid Build Coastguard Worker }
1280*795d594fSAndroid Build Coastguard Worker 
Deoptimize(ArtMethod * method)1281*795d594fSAndroid Build Coastguard Worker void Instrumentation::Deoptimize(ArtMethod* method) {
1282*795d594fSAndroid Build Coastguard Worker   CHECK(!method->IsNative());
1283*795d594fSAndroid Build Coastguard Worker   CHECK(!method->IsProxyMethod());
1284*795d594fSAndroid Build Coastguard Worker   CHECK(method->IsInvokable());
1285*795d594fSAndroid Build Coastguard Worker 
1286*795d594fSAndroid Build Coastguard Worker   {
1287*795d594fSAndroid Build Coastguard Worker     Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
1288*795d594fSAndroid Build Coastguard Worker     bool has_not_been_deoptimized = AddDeoptimizedMethod(method);
1289*795d594fSAndroid Build Coastguard Worker     CHECK(has_not_been_deoptimized) << "Method " << ArtMethod::PrettyMethod(method)
1290*795d594fSAndroid Build Coastguard Worker         << " is already deoptimized";
1291*795d594fSAndroid Build Coastguard Worker   }
1292*795d594fSAndroid Build Coastguard Worker 
1293*795d594fSAndroid Build Coastguard Worker   if (method->IsObsolete()) {
1294*795d594fSAndroid Build Coastguard Worker     // If method was marked as obsolete it should have `GetInvokeObsoleteMethodStub`
1295*795d594fSAndroid Build Coastguard Worker     // as its quick entry point
1296*795d594fSAndroid Build Coastguard Worker     CHECK_EQ(method->GetEntryPointFromQuickCompiledCode(), GetInvokeObsoleteMethodStub());
1297*795d594fSAndroid Build Coastguard Worker     return;
1298*795d594fSAndroid Build Coastguard Worker   }
1299*795d594fSAndroid Build Coastguard Worker 
1300*795d594fSAndroid Build Coastguard Worker   if (!InterpreterStubsInstalled()) {
1301*795d594fSAndroid Build Coastguard Worker     UpdateEntryPoints(method, GetQuickToInterpreterBridge());
1302*795d594fSAndroid Build Coastguard Worker 
1303*795d594fSAndroid Build Coastguard Worker     // Instrument thread stacks to request a check if the caller needs a deoptimization.
1304*795d594fSAndroid Build Coastguard Worker     // This isn't a strong deopt. We deopt this method if it is still in the deopt methods list.
1305*795d594fSAndroid Build Coastguard Worker     // If by the time we hit this frame we no longer need a deopt it is safe to continue.
1306*795d594fSAndroid Build Coastguard Worker     InstrumentAllThreadStacks(/* force_deopt= */ false);
1307*795d594fSAndroid Build Coastguard Worker   }
1308*795d594fSAndroid Build Coastguard Worker   CHECK_EQ(method->GetEntryPointFromQuickCompiledCode(), GetQuickToInterpreterBridge());
1309*795d594fSAndroid Build Coastguard Worker }
1310*795d594fSAndroid Build Coastguard Worker 
Undeoptimize(ArtMethod * method)1311*795d594fSAndroid Build Coastguard Worker void Instrumentation::Undeoptimize(ArtMethod* method) {
1312*795d594fSAndroid Build Coastguard Worker   CHECK(!method->IsNative());
1313*795d594fSAndroid Build Coastguard Worker   CHECK(!method->IsProxyMethod());
1314*795d594fSAndroid Build Coastguard Worker   CHECK(method->IsInvokable());
1315*795d594fSAndroid Build Coastguard Worker 
1316*795d594fSAndroid Build Coastguard Worker   {
1317*795d594fSAndroid Build Coastguard Worker     Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
1318*795d594fSAndroid Build Coastguard Worker     bool found_and_erased = RemoveDeoptimizedMethod(method);
1319*795d594fSAndroid Build Coastguard Worker     CHECK(found_and_erased) << "Method " << ArtMethod::PrettyMethod(method)
1320*795d594fSAndroid Build Coastguard Worker         << " is not deoptimized";
1321*795d594fSAndroid Build Coastguard Worker   }
1322*795d594fSAndroid Build Coastguard Worker 
1323*795d594fSAndroid Build Coastguard Worker   // If interpreter stubs are still needed nothing to do.
1324*795d594fSAndroid Build Coastguard Worker   if (InterpreterStubsInstalled()) {
1325*795d594fSAndroid Build Coastguard Worker     return;
1326*795d594fSAndroid Build Coastguard Worker   }
1327*795d594fSAndroid Build Coastguard Worker 
1328*795d594fSAndroid Build Coastguard Worker   if (method->IsObsolete()) {
1329*795d594fSAndroid Build Coastguard Worker     // Don't update entry points for obsolete methods. The entrypoint should
1330*795d594fSAndroid Build Coastguard Worker     // have been set to InvokeObsoleteMethoStub.
1331*795d594fSAndroid Build Coastguard Worker     DCHECK_EQ(method->GetEntryPointFromQuickCompiledCodePtrSize(kRuntimePointerSize),
1332*795d594fSAndroid Build Coastguard Worker               GetInvokeObsoleteMethodStub());
1333*795d594fSAndroid Build Coastguard Worker     return;
1334*795d594fSAndroid Build Coastguard Worker   }
1335*795d594fSAndroid Build Coastguard Worker 
1336*795d594fSAndroid Build Coastguard Worker   // We are not using interpreter stubs for deoptimization. Restore the code of the method.
1337*795d594fSAndroid Build Coastguard Worker   // We still retain interpreter bridge if we need it for other reasons.
1338*795d594fSAndroid Build Coastguard Worker   if (InterpretOnly(method)) {
1339*795d594fSAndroid Build Coastguard Worker     UpdateEntryPoints(method, GetQuickToInterpreterBridge());
1340*795d594fSAndroid Build Coastguard Worker   } else if (method->StillNeedsClinitCheck()) {
1341*795d594fSAndroid Build Coastguard Worker     UpdateEntryPoints(method, GetQuickResolutionStub());
1342*795d594fSAndroid Build Coastguard Worker   } else {
1343*795d594fSAndroid Build Coastguard Worker     UpdateEntryPoints(method, GetMaybeInstrumentedCodeForInvoke(method));
1344*795d594fSAndroid Build Coastguard Worker   }
1345*795d594fSAndroid Build Coastguard Worker 
1346*795d594fSAndroid Build Coastguard Worker   // If there is no deoptimized method left, we can restore the stack of each thread.
1347*795d594fSAndroid Build Coastguard Worker   if (!EntryExitStubsInstalled()) {
1348*795d594fSAndroid Build Coastguard Worker     MaybeRestoreInstrumentationStack();
1349*795d594fSAndroid Build Coastguard Worker   }
1350*795d594fSAndroid Build Coastguard Worker }
1351*795d594fSAndroid Build Coastguard Worker 
IsDeoptimizedMethodsEmpty() const1352*795d594fSAndroid Build Coastguard Worker bool Instrumentation::IsDeoptimizedMethodsEmpty() const {
1353*795d594fSAndroid Build Coastguard Worker   return deoptimized_methods_.empty();
1354*795d594fSAndroid Build Coastguard Worker }
1355*795d594fSAndroid Build Coastguard Worker 
IsDeoptimized(ArtMethod * method)1356*795d594fSAndroid Build Coastguard Worker bool Instrumentation::IsDeoptimized(ArtMethod* method) {
1357*795d594fSAndroid Build Coastguard Worker   DCHECK(method != nullptr);
1358*795d594fSAndroid Build Coastguard Worker   return IsDeoptimizedMethod(method);
1359*795d594fSAndroid Build Coastguard Worker }
1360*795d594fSAndroid Build Coastguard Worker 
DisableDeoptimization(const char * key,bool try_switch_to_non_debuggable)1361*795d594fSAndroid Build Coastguard Worker void Instrumentation::DisableDeoptimization(const char* key, bool try_switch_to_non_debuggable) {
1362*795d594fSAndroid Build Coastguard Worker   // Remove any instrumentation support added for deoptimization.
1363*795d594fSAndroid Build Coastguard Worker   ConfigureStubs(key, InstrumentationLevel::kInstrumentNothing, try_switch_to_non_debuggable);
1364*795d594fSAndroid Build Coastguard Worker   Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
1365*795d594fSAndroid Build Coastguard Worker   // Undeoptimized selected methods.
1366*795d594fSAndroid Build Coastguard Worker   while (true) {
1367*795d594fSAndroid Build Coastguard Worker     ArtMethod* method;
1368*795d594fSAndroid Build Coastguard Worker     {
1369*795d594fSAndroid Build Coastguard Worker       if (deoptimized_methods_.empty()) {
1370*795d594fSAndroid Build Coastguard Worker         break;
1371*795d594fSAndroid Build Coastguard Worker       }
1372*795d594fSAndroid Build Coastguard Worker       method = *deoptimized_methods_.begin();
1373*795d594fSAndroid Build Coastguard Worker       CHECK(method != nullptr);
1374*795d594fSAndroid Build Coastguard Worker     }
1375*795d594fSAndroid Build Coastguard Worker     Undeoptimize(method);
1376*795d594fSAndroid Build Coastguard Worker   }
1377*795d594fSAndroid Build Coastguard Worker }
1378*795d594fSAndroid Build Coastguard Worker 
MaybeSwitchRuntimeDebugState(Thread * self)1379*795d594fSAndroid Build Coastguard Worker void Instrumentation::MaybeSwitchRuntimeDebugState(Thread* self) {
1380*795d594fSAndroid Build Coastguard Worker   Runtime* runtime = Runtime::Current();
1381*795d594fSAndroid Build Coastguard Worker   // Return early if runtime is shutting down.
1382*795d594fSAndroid Build Coastguard Worker   if (runtime->IsShuttingDown(self)) {
1383*795d594fSAndroid Build Coastguard Worker     return;
1384*795d594fSAndroid Build Coastguard Worker   }
1385*795d594fSAndroid Build Coastguard Worker 
1386*795d594fSAndroid Build Coastguard Worker   // Don't switch the state if we started off as JavaDebuggable or if we still need entry / exit
1387*795d594fSAndroid Build Coastguard Worker   // hooks for other reasons.
1388*795d594fSAndroid Build Coastguard Worker   if (EntryExitStubsInstalled() || runtime->IsJavaDebuggableAtInit()) {
1389*795d594fSAndroid Build Coastguard Worker     return;
1390*795d594fSAndroid Build Coastguard Worker   }
1391*795d594fSAndroid Build Coastguard Worker 
1392*795d594fSAndroid Build Coastguard Worker   art::jit::Jit* jit = runtime->GetJit();
1393*795d594fSAndroid Build Coastguard Worker   if (jit != nullptr) {
1394*795d594fSAndroid Build Coastguard Worker     jit->GetCodeCache()->InvalidateAllCompiledCode();
1395*795d594fSAndroid Build Coastguard Worker     jit->GetJitCompiler()->SetDebuggableCompilerOption(false);
1396*795d594fSAndroid Build Coastguard Worker   }
1397*795d594fSAndroid Build Coastguard Worker   runtime->SetRuntimeDebugState(art::Runtime::RuntimeDebugState::kNonJavaDebuggable);
1398*795d594fSAndroid Build Coastguard Worker }
1399*795d594fSAndroid Build Coastguard Worker 
DeoptimizeEverything(const char * key)1400*795d594fSAndroid Build Coastguard Worker void Instrumentation::DeoptimizeEverything(const char* key) {
1401*795d594fSAndroid Build Coastguard Worker   // We want to switch to non-debuggable only when the debugger / profile tools are detaching.
1402*795d594fSAndroid Build Coastguard Worker   // This call is used for supporting debug related features (ex: single stepping across all
1403*795d594fSAndroid Build Coastguard Worker   // threads) while the debugger is still connected.
1404*795d594fSAndroid Build Coastguard Worker   ConfigureStubs(key,
1405*795d594fSAndroid Build Coastguard Worker                  InstrumentationLevel::kInstrumentWithInterpreter,
1406*795d594fSAndroid Build Coastguard Worker                  /*try_switch_to_non_debuggable=*/false);
1407*795d594fSAndroid Build Coastguard Worker }
1408*795d594fSAndroid Build Coastguard Worker 
UndeoptimizeEverything(const char * key)1409*795d594fSAndroid Build Coastguard Worker void Instrumentation::UndeoptimizeEverything(const char* key) {
1410*795d594fSAndroid Build Coastguard Worker   CHECK(InterpreterStubsInstalled());
1411*795d594fSAndroid Build Coastguard Worker   // We want to switch to non-debuggable only when the debugger / profile tools are detaching.
1412*795d594fSAndroid Build Coastguard Worker   // This is used when we no longer need to run in interpreter. The debugger is still connected
1413*795d594fSAndroid Build Coastguard Worker   // so don't switch the runtime. We use "DisableDeoptimization" when detaching the debugger.
1414*795d594fSAndroid Build Coastguard Worker   ConfigureStubs(key,
1415*795d594fSAndroid Build Coastguard Worker                  InstrumentationLevel::kInstrumentNothing,
1416*795d594fSAndroid Build Coastguard Worker                  /*try_switch_to_non_debuggable=*/false);
1417*795d594fSAndroid Build Coastguard Worker }
1418*795d594fSAndroid Build Coastguard Worker 
EnableMethodTracing(const char * key,InstrumentationListener * listener,bool needs_interpreter)1419*795d594fSAndroid Build Coastguard Worker void Instrumentation::EnableMethodTracing(const char* key,
1420*795d594fSAndroid Build Coastguard Worker                                           InstrumentationListener* listener,
1421*795d594fSAndroid Build Coastguard Worker                                           bool needs_interpreter) {
1422*795d594fSAndroid Build Coastguard Worker   InstrumentationLevel level;
1423*795d594fSAndroid Build Coastguard Worker   if (needs_interpreter) {
1424*795d594fSAndroid Build Coastguard Worker     level = InstrumentationLevel::kInstrumentWithInterpreter;
1425*795d594fSAndroid Build Coastguard Worker   } else {
1426*795d594fSAndroid Build Coastguard Worker     level = InstrumentationLevel::kInstrumentWithEntryExitHooks;
1427*795d594fSAndroid Build Coastguard Worker   }
1428*795d594fSAndroid Build Coastguard Worker   // We are enabling method tracing here and need to stay in debuggable.
1429*795d594fSAndroid Build Coastguard Worker   ConfigureStubs(key, level, /*try_switch_to_non_debuggable=*/false);
1430*795d594fSAndroid Build Coastguard Worker 
1431*795d594fSAndroid Build Coastguard Worker   MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
1432*795d594fSAndroid Build Coastguard Worker   for (Thread* thread : Runtime::Current()->GetThreadList()->GetList()) {
1433*795d594fSAndroid Build Coastguard Worker     ReportMethodEntryForOnStackMethods(listener, thread);
1434*795d594fSAndroid Build Coastguard Worker   }
1435*795d594fSAndroid Build Coastguard Worker }
1436*795d594fSAndroid Build Coastguard Worker 
DisableMethodTracing(const char * key)1437*795d594fSAndroid Build Coastguard Worker void Instrumentation::DisableMethodTracing(const char* key) {
1438*795d594fSAndroid Build Coastguard Worker   // We no longer need to be in debuggable runtime since we are stopping method tracing. If no
1439*795d594fSAndroid Build Coastguard Worker   // other debugger / profiling tools are active switch back to non-debuggable.
1440*795d594fSAndroid Build Coastguard Worker   ConfigureStubs(key,
1441*795d594fSAndroid Build Coastguard Worker                  InstrumentationLevel::kInstrumentNothing,
1442*795d594fSAndroid Build Coastguard Worker                  /*try_switch_to_non_debuggable=*/true);
1443*795d594fSAndroid Build Coastguard Worker }
1444*795d594fSAndroid Build Coastguard Worker 
GetCodeForInvoke(ArtMethod * method)1445*795d594fSAndroid Build Coastguard Worker const void* Instrumentation::GetCodeForInvoke(ArtMethod* method) {
1446*795d594fSAndroid Build Coastguard Worker   // This is called by instrumentation and resolution trampolines
1447*795d594fSAndroid Build Coastguard Worker   // and that should never be getting proxy methods.
1448*795d594fSAndroid Build Coastguard Worker   DCHECK(!method->IsProxyMethod()) << method->PrettyMethod();
1449*795d594fSAndroid Build Coastguard Worker   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1450*795d594fSAndroid Build Coastguard Worker   const void* code = method->GetEntryPointFromQuickCompiledCodePtrSize(kRuntimePointerSize);
1451*795d594fSAndroid Build Coastguard Worker   // If we don't have the instrumentation, the resolution stub, or the
1452*795d594fSAndroid Build Coastguard Worker   // interpreter, just return the current entrypoint,
1453*795d594fSAndroid Build Coastguard Worker   // assuming it's the most optimized.
1454*795d594fSAndroid Build Coastguard Worker   if (!class_linker->IsQuickResolutionStub(code) &&
1455*795d594fSAndroid Build Coastguard Worker       !class_linker->IsQuickToInterpreterBridge(code)) {
1456*795d594fSAndroid Build Coastguard Worker     return code;
1457*795d594fSAndroid Build Coastguard Worker   }
1458*795d594fSAndroid Build Coastguard Worker 
1459*795d594fSAndroid Build Coastguard Worker   if (InterpretOnly(method)) {
1460*795d594fSAndroid Build Coastguard Worker     // If we're forced into interpreter just use it.
1461*795d594fSAndroid Build Coastguard Worker     return GetQuickToInterpreterBridge();
1462*795d594fSAndroid Build Coastguard Worker   }
1463*795d594fSAndroid Build Coastguard Worker 
1464*795d594fSAndroid Build Coastguard Worker   return GetOptimizedCodeFor(method);
1465*795d594fSAndroid Build Coastguard Worker }
1466*795d594fSAndroid Build Coastguard Worker 
GetMaybeInstrumentedCodeForInvoke(ArtMethod * method)1467*795d594fSAndroid Build Coastguard Worker const void* Instrumentation::GetMaybeInstrumentedCodeForInvoke(ArtMethod* method) {
1468*795d594fSAndroid Build Coastguard Worker   // This is called by resolution trampolines and that should never be getting proxy methods.
1469*795d594fSAndroid Build Coastguard Worker   DCHECK(!method->IsProxyMethod()) << method->PrettyMethod();
1470*795d594fSAndroid Build Coastguard Worker   const void* code = GetCodeForInvoke(method);
1471*795d594fSAndroid Build Coastguard Worker   if (EntryExitStubsInstalled() && !CodeSupportsEntryExitHooks(code, method)) {
1472*795d594fSAndroid Build Coastguard Worker     return method->IsNative() ? GetQuickGenericJniStub() : GetQuickToInterpreterBridge();
1473*795d594fSAndroid Build Coastguard Worker   }
1474*795d594fSAndroid Build Coastguard Worker   return code;
1475*795d594fSAndroid Build Coastguard Worker }
1476*795d594fSAndroid Build Coastguard Worker 
MethodEnterEventImpl(Thread * thread,ArtMethod * method) const1477*795d594fSAndroid Build Coastguard Worker void Instrumentation::MethodEnterEventImpl(Thread* thread, ArtMethod* method) const {
1478*795d594fSAndroid Build Coastguard Worker   DCHECK(!method->IsRuntimeMethod());
1479*795d594fSAndroid Build Coastguard Worker   if (HasMethodEntryListeners()) {
1480*795d594fSAndroid Build Coastguard Worker     for (InstrumentationListener* listener : method_entry_slow_listeners_) {
1481*795d594fSAndroid Build Coastguard Worker       if (listener != nullptr) {
1482*795d594fSAndroid Build Coastguard Worker         listener->MethodEntered(thread, method);
1483*795d594fSAndroid Build Coastguard Worker       }
1484*795d594fSAndroid Build Coastguard Worker     }
1485*795d594fSAndroid Build Coastguard Worker     for (InstrumentationListener* listener : method_entry_fast_trace_listeners_) {
1486*795d594fSAndroid Build Coastguard Worker       if (listener != nullptr) {
1487*795d594fSAndroid Build Coastguard Worker         listener->MethodEntered(thread, method);
1488*795d594fSAndroid Build Coastguard Worker       }
1489*795d594fSAndroid Build Coastguard Worker     }
1490*795d594fSAndroid Build Coastguard Worker   }
1491*795d594fSAndroid Build Coastguard Worker }
1492*795d594fSAndroid Build Coastguard Worker 
1493*795d594fSAndroid Build Coastguard Worker template <>
MethodExitEventImpl(Thread * thread,ArtMethod * method,OptionalFrame frame,MutableHandle<mirror::Object> & return_value) const1494*795d594fSAndroid Build Coastguard Worker void Instrumentation::MethodExitEventImpl(Thread* thread,
1495*795d594fSAndroid Build Coastguard Worker                                           ArtMethod* method,
1496*795d594fSAndroid Build Coastguard Worker                                           OptionalFrame frame,
1497*795d594fSAndroid Build Coastguard Worker                                           MutableHandle<mirror::Object>& return_value) const {
1498*795d594fSAndroid Build Coastguard Worker   if (HasMethodExitListeners()) {
1499*795d594fSAndroid Build Coastguard Worker     for (InstrumentationListener* listener : method_exit_slow_listeners_) {
1500*795d594fSAndroid Build Coastguard Worker       if (listener != nullptr) {
1501*795d594fSAndroid Build Coastguard Worker         listener->MethodExited(thread, method, frame, return_value);
1502*795d594fSAndroid Build Coastguard Worker       }
1503*795d594fSAndroid Build Coastguard Worker     }
1504*795d594fSAndroid Build Coastguard Worker     for (InstrumentationListener* listener : method_exit_fast_trace_listeners_) {
1505*795d594fSAndroid Build Coastguard Worker       if (listener != nullptr) {
1506*795d594fSAndroid Build Coastguard Worker         listener->MethodExited(thread, method, frame, return_value);
1507*795d594fSAndroid Build Coastguard Worker       }
1508*795d594fSAndroid Build Coastguard Worker     }
1509*795d594fSAndroid Build Coastguard Worker   }
1510*795d594fSAndroid Build Coastguard Worker }
1511*795d594fSAndroid Build Coastguard Worker 
MethodExitEventImpl(Thread * thread,ArtMethod * method,OptionalFrame frame,JValue & return_value) const1512*795d594fSAndroid Build Coastguard Worker template<> void Instrumentation::MethodExitEventImpl(Thread* thread,
1513*795d594fSAndroid Build Coastguard Worker                                                      ArtMethod* method,
1514*795d594fSAndroid Build Coastguard Worker                                                      OptionalFrame frame,
1515*795d594fSAndroid Build Coastguard Worker                                                      JValue& return_value) const {
1516*795d594fSAndroid Build Coastguard Worker   if (HasMethodExitListeners()) {
1517*795d594fSAndroid Build Coastguard Worker     Thread* self = Thread::Current();
1518*795d594fSAndroid Build Coastguard Worker     StackHandleScope<1> hs(self);
1519*795d594fSAndroid Build Coastguard Worker     if (method->GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetReturnTypePrimitive() !=
1520*795d594fSAndroid Build Coastguard Worker         Primitive::kPrimNot) {
1521*795d594fSAndroid Build Coastguard Worker       for (InstrumentationListener* listener : method_exit_slow_listeners_) {
1522*795d594fSAndroid Build Coastguard Worker         if (listener != nullptr) {
1523*795d594fSAndroid Build Coastguard Worker           listener->MethodExited(thread, method, frame, return_value);
1524*795d594fSAndroid Build Coastguard Worker         }
1525*795d594fSAndroid Build Coastguard Worker       }
1526*795d594fSAndroid Build Coastguard Worker       for (InstrumentationListener* listener : method_exit_fast_trace_listeners_) {
1527*795d594fSAndroid Build Coastguard Worker         if (listener != nullptr) {
1528*795d594fSAndroid Build Coastguard Worker           listener->MethodExited(thread, method, frame, return_value);
1529*795d594fSAndroid Build Coastguard Worker         }
1530*795d594fSAndroid Build Coastguard Worker       }
1531*795d594fSAndroid Build Coastguard Worker     } else {
1532*795d594fSAndroid Build Coastguard Worker       MutableHandle<mirror::Object> ret(hs.NewHandle(return_value.GetL()));
1533*795d594fSAndroid Build Coastguard Worker       MethodExitEventImpl(thread, method, frame, ret);
1534*795d594fSAndroid Build Coastguard Worker       return_value.SetL(ret.Get());
1535*795d594fSAndroid Build Coastguard Worker     }
1536*795d594fSAndroid Build Coastguard Worker   }
1537*795d594fSAndroid Build Coastguard Worker }
1538*795d594fSAndroid Build Coastguard Worker 
MethodUnwindEvent(Thread * thread,ArtMethod * method,uint32_t dex_pc) const1539*795d594fSAndroid Build Coastguard Worker void Instrumentation::MethodUnwindEvent(Thread* thread,
1540*795d594fSAndroid Build Coastguard Worker                                         ArtMethod* method,
1541*795d594fSAndroid Build Coastguard Worker                                         uint32_t dex_pc) const {
1542*795d594fSAndroid Build Coastguard Worker   if (HasMethodUnwindListeners()) {
1543*795d594fSAndroid Build Coastguard Worker     for (InstrumentationListener* listener : method_unwind_listeners_) {
1544*795d594fSAndroid Build Coastguard Worker       if (listener != nullptr) {
1545*795d594fSAndroid Build Coastguard Worker         listener->MethodUnwind(thread, method, dex_pc);
1546*795d594fSAndroid Build Coastguard Worker       }
1547*795d594fSAndroid Build Coastguard Worker     }
1548*795d594fSAndroid Build Coastguard Worker   }
1549*795d594fSAndroid Build Coastguard Worker }
1550*795d594fSAndroid Build Coastguard Worker 
DexPcMovedEventImpl(Thread * thread,ObjPtr<mirror::Object> this_object,ArtMethod * method,uint32_t dex_pc) const1551*795d594fSAndroid Build Coastguard Worker void Instrumentation::DexPcMovedEventImpl(Thread* thread,
1552*795d594fSAndroid Build Coastguard Worker                                           ObjPtr<mirror::Object> this_object,
1553*795d594fSAndroid Build Coastguard Worker                                           ArtMethod* method,
1554*795d594fSAndroid Build Coastguard Worker                                           uint32_t dex_pc) const {
1555*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
1556*795d594fSAndroid Build Coastguard Worker   StackHandleScope<1> hs(self);
1557*795d594fSAndroid Build Coastguard Worker   Handle<mirror::Object> thiz(hs.NewHandle(this_object));
1558*795d594fSAndroid Build Coastguard Worker   for (InstrumentationListener* listener : dex_pc_listeners_) {
1559*795d594fSAndroid Build Coastguard Worker     if (listener != nullptr) {
1560*795d594fSAndroid Build Coastguard Worker       listener->DexPcMoved(thread, thiz, method, dex_pc);
1561*795d594fSAndroid Build Coastguard Worker     }
1562*795d594fSAndroid Build Coastguard Worker   }
1563*795d594fSAndroid Build Coastguard Worker }
1564*795d594fSAndroid Build Coastguard Worker 
BranchImpl(Thread * thread,ArtMethod * method,uint32_t dex_pc,int32_t offset) const1565*795d594fSAndroid Build Coastguard Worker void Instrumentation::BranchImpl(Thread* thread,
1566*795d594fSAndroid Build Coastguard Worker                                  ArtMethod* method,
1567*795d594fSAndroid Build Coastguard Worker                                  uint32_t dex_pc,
1568*795d594fSAndroid Build Coastguard Worker                                  int32_t offset) const {
1569*795d594fSAndroid Build Coastguard Worker   for (InstrumentationListener* listener : branch_listeners_) {
1570*795d594fSAndroid Build Coastguard Worker     if (listener != nullptr) {
1571*795d594fSAndroid Build Coastguard Worker       listener->Branch(thread, method, dex_pc, offset);
1572*795d594fSAndroid Build Coastguard Worker     }
1573*795d594fSAndroid Build Coastguard Worker   }
1574*795d594fSAndroid Build Coastguard Worker }
1575*795d594fSAndroid Build Coastguard Worker 
WatchedFramePopImpl(Thread * thread,const ShadowFrame & frame) const1576*795d594fSAndroid Build Coastguard Worker void Instrumentation::WatchedFramePopImpl(Thread* thread, const ShadowFrame& frame) const {
1577*795d594fSAndroid Build Coastguard Worker   for (InstrumentationListener* listener : watched_frame_pop_listeners_) {
1578*795d594fSAndroid Build Coastguard Worker     if (listener != nullptr) {
1579*795d594fSAndroid Build Coastguard Worker       listener->WatchedFramePop(thread, frame);
1580*795d594fSAndroid Build Coastguard Worker     }
1581*795d594fSAndroid Build Coastguard Worker   }
1582*795d594fSAndroid Build Coastguard Worker }
1583*795d594fSAndroid Build Coastguard Worker 
FieldReadEventImpl(Thread * thread,ObjPtr<mirror::Object> this_object,ArtMethod * method,uint32_t dex_pc,ArtField * field) const1584*795d594fSAndroid Build Coastguard Worker void Instrumentation::FieldReadEventImpl(Thread* thread,
1585*795d594fSAndroid Build Coastguard Worker                                          ObjPtr<mirror::Object> this_object,
1586*795d594fSAndroid Build Coastguard Worker                                          ArtMethod* method,
1587*795d594fSAndroid Build Coastguard Worker                                          uint32_t dex_pc,
1588*795d594fSAndroid Build Coastguard Worker                                          ArtField* field) const {
1589*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
1590*795d594fSAndroid Build Coastguard Worker   StackHandleScope<1> hs(self);
1591*795d594fSAndroid Build Coastguard Worker   Handle<mirror::Object> thiz(hs.NewHandle(this_object));
1592*795d594fSAndroid Build Coastguard Worker   for (InstrumentationListener* listener : field_read_listeners_) {
1593*795d594fSAndroid Build Coastguard Worker     if (listener != nullptr) {
1594*795d594fSAndroid Build Coastguard Worker       listener->FieldRead(thread, thiz, method, dex_pc, field);
1595*795d594fSAndroid Build Coastguard Worker     }
1596*795d594fSAndroid Build Coastguard Worker   }
1597*795d594fSAndroid Build Coastguard Worker }
1598*795d594fSAndroid Build Coastguard Worker 
FieldWriteEventImpl(Thread * thread,ObjPtr<mirror::Object> this_object,ArtMethod * method,uint32_t dex_pc,ArtField * field,const JValue & field_value) const1599*795d594fSAndroid Build Coastguard Worker void Instrumentation::FieldWriteEventImpl(Thread* thread,
1600*795d594fSAndroid Build Coastguard Worker                                           ObjPtr<mirror::Object> this_object,
1601*795d594fSAndroid Build Coastguard Worker                                           ArtMethod* method,
1602*795d594fSAndroid Build Coastguard Worker                                           uint32_t dex_pc,
1603*795d594fSAndroid Build Coastguard Worker                                           ArtField* field,
1604*795d594fSAndroid Build Coastguard Worker                                           const JValue& field_value) const {
1605*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
1606*795d594fSAndroid Build Coastguard Worker   StackHandleScope<2> hs(self);
1607*795d594fSAndroid Build Coastguard Worker   Handle<mirror::Object> thiz(hs.NewHandle(this_object));
1608*795d594fSAndroid Build Coastguard Worker   if (field->IsPrimitiveType()) {
1609*795d594fSAndroid Build Coastguard Worker     for (InstrumentationListener* listener : field_write_listeners_) {
1610*795d594fSAndroid Build Coastguard Worker       if (listener != nullptr) {
1611*795d594fSAndroid Build Coastguard Worker         listener->FieldWritten(thread, thiz, method, dex_pc, field, field_value);
1612*795d594fSAndroid Build Coastguard Worker       }
1613*795d594fSAndroid Build Coastguard Worker     }
1614*795d594fSAndroid Build Coastguard Worker   } else {
1615*795d594fSAndroid Build Coastguard Worker     Handle<mirror::Object> val(hs.NewHandle(field_value.GetL()));
1616*795d594fSAndroid Build Coastguard Worker     for (InstrumentationListener* listener : field_write_listeners_) {
1617*795d594fSAndroid Build Coastguard Worker       if (listener != nullptr) {
1618*795d594fSAndroid Build Coastguard Worker         listener->FieldWritten(thread, thiz, method, dex_pc, field, val);
1619*795d594fSAndroid Build Coastguard Worker       }
1620*795d594fSAndroid Build Coastguard Worker     }
1621*795d594fSAndroid Build Coastguard Worker   }
1622*795d594fSAndroid Build Coastguard Worker }
1623*795d594fSAndroid Build Coastguard Worker 
ExceptionThrownEvent(Thread * thread,ObjPtr<mirror::Throwable> exception_object) const1624*795d594fSAndroid Build Coastguard Worker void Instrumentation::ExceptionThrownEvent(Thread* thread,
1625*795d594fSAndroid Build Coastguard Worker                                            ObjPtr<mirror::Throwable> exception_object) const {
1626*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
1627*795d594fSAndroid Build Coastguard Worker   StackHandleScope<1> hs(self);
1628*795d594fSAndroid Build Coastguard Worker   Handle<mirror::Throwable> h_exception(hs.NewHandle(exception_object));
1629*795d594fSAndroid Build Coastguard Worker   if (HasExceptionThrownListeners()) {
1630*795d594fSAndroid Build Coastguard Worker     DCHECK_EQ(thread->GetException(), h_exception.Get());
1631*795d594fSAndroid Build Coastguard Worker     thread->ClearException();
1632*795d594fSAndroid Build Coastguard Worker     for (InstrumentationListener* listener : exception_thrown_listeners_) {
1633*795d594fSAndroid Build Coastguard Worker       if (listener != nullptr) {
1634*795d594fSAndroid Build Coastguard Worker         listener->ExceptionThrown(thread, h_exception);
1635*795d594fSAndroid Build Coastguard Worker       }
1636*795d594fSAndroid Build Coastguard Worker     }
1637*795d594fSAndroid Build Coastguard Worker     // See b/65049545 for discussion about this behavior.
1638*795d594fSAndroid Build Coastguard Worker     thread->AssertNoPendingException();
1639*795d594fSAndroid Build Coastguard Worker     thread->SetException(h_exception.Get());
1640*795d594fSAndroid Build Coastguard Worker   }
1641*795d594fSAndroid Build Coastguard Worker }
1642*795d594fSAndroid Build Coastguard Worker 
ExceptionHandledEvent(Thread * thread,ObjPtr<mirror::Throwable> exception_object) const1643*795d594fSAndroid Build Coastguard Worker void Instrumentation::ExceptionHandledEvent(Thread* thread,
1644*795d594fSAndroid Build Coastguard Worker                                             ObjPtr<mirror::Throwable> exception_object) const {
1645*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
1646*795d594fSAndroid Build Coastguard Worker   StackHandleScope<1> hs(self);
1647*795d594fSAndroid Build Coastguard Worker   Handle<mirror::Throwable> h_exception(hs.NewHandle(exception_object));
1648*795d594fSAndroid Build Coastguard Worker   if (HasExceptionHandledListeners()) {
1649*795d594fSAndroid Build Coastguard Worker     // We should have cleared the exception so that callers can detect a new one.
1650*795d594fSAndroid Build Coastguard Worker     DCHECK(thread->GetException() == nullptr);
1651*795d594fSAndroid Build Coastguard Worker     for (InstrumentationListener* listener : exception_handled_listeners_) {
1652*795d594fSAndroid Build Coastguard Worker       if (listener != nullptr) {
1653*795d594fSAndroid Build Coastguard Worker         listener->ExceptionHandled(thread, h_exception);
1654*795d594fSAndroid Build Coastguard Worker       }
1655*795d594fSAndroid Build Coastguard Worker     }
1656*795d594fSAndroid Build Coastguard Worker   }
1657*795d594fSAndroid Build Coastguard Worker }
1658*795d594fSAndroid Build Coastguard Worker 
GetDeoptimizationMethodType(ArtMethod * method)1659*795d594fSAndroid Build Coastguard Worker DeoptimizationMethodType Instrumentation::GetDeoptimizationMethodType(ArtMethod* method) {
1660*795d594fSAndroid Build Coastguard Worker   if (method->IsRuntimeMethod()) {
1661*795d594fSAndroid Build Coastguard Worker     // Certain methods have strict requirement on whether the dex instruction
1662*795d594fSAndroid Build Coastguard Worker     // should be re-executed upon deoptimization.
1663*795d594fSAndroid Build Coastguard Worker     if (method == Runtime::Current()->GetCalleeSaveMethod(
1664*795d594fSAndroid Build Coastguard Worker         CalleeSaveType::kSaveEverythingForClinit)) {
1665*795d594fSAndroid Build Coastguard Worker       return DeoptimizationMethodType::kKeepDexPc;
1666*795d594fSAndroid Build Coastguard Worker     }
1667*795d594fSAndroid Build Coastguard Worker     if (method == Runtime::Current()->GetCalleeSaveMethod(
1668*795d594fSAndroid Build Coastguard Worker         CalleeSaveType::kSaveEverythingForSuspendCheck)) {
1669*795d594fSAndroid Build Coastguard Worker       return DeoptimizationMethodType::kKeepDexPc;
1670*795d594fSAndroid Build Coastguard Worker     }
1671*795d594fSAndroid Build Coastguard Worker   }
1672*795d594fSAndroid Build Coastguard Worker   return DeoptimizationMethodType::kDefault;
1673*795d594fSAndroid Build Coastguard Worker }
1674*795d594fSAndroid Build Coastguard Worker 
GetReturnValue(ArtMethod * method,bool * is_ref,uint64_t * gpr_result,uint64_t * fpr_result)1675*795d594fSAndroid Build Coastguard Worker JValue Instrumentation::GetReturnValue(ArtMethod* method,
1676*795d594fSAndroid Build Coastguard Worker                                        bool* is_ref,
1677*795d594fSAndroid Build Coastguard Worker                                        uint64_t* gpr_result,
1678*795d594fSAndroid Build Coastguard Worker                                        uint64_t* fpr_result) {
1679*795d594fSAndroid Build Coastguard Worker   uint32_t length;
1680*795d594fSAndroid Build Coastguard Worker   const PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
1681*795d594fSAndroid Build Coastguard Worker 
1682*795d594fSAndroid Build Coastguard Worker   // Runtime method does not call into MethodExitEvent() so there should not be
1683*795d594fSAndroid Build Coastguard Worker   // suspension point below.
1684*795d594fSAndroid Build Coastguard Worker   ScopedAssertNoThreadSuspension ants(__FUNCTION__, method->IsRuntimeMethod());
1685*795d594fSAndroid Build Coastguard Worker   DCHECK(!method->IsRuntimeMethod());
1686*795d594fSAndroid Build Coastguard Worker   char return_shorty = method->GetInterfaceMethodIfProxy(pointer_size)->GetShorty(&length)[0];
1687*795d594fSAndroid Build Coastguard Worker 
1688*795d594fSAndroid Build Coastguard Worker   *is_ref = return_shorty == '[' || return_shorty == 'L';
1689*795d594fSAndroid Build Coastguard Worker   JValue return_value;
1690*795d594fSAndroid Build Coastguard Worker   if (return_shorty == 'V') {
1691*795d594fSAndroid Build Coastguard Worker     return_value.SetJ(0);
1692*795d594fSAndroid Build Coastguard Worker   } else if (return_shorty == 'F' || return_shorty == 'D') {
1693*795d594fSAndroid Build Coastguard Worker     return_value.SetJ(*fpr_result);
1694*795d594fSAndroid Build Coastguard Worker   } else {
1695*795d594fSAndroid Build Coastguard Worker     return_value.SetJ(*gpr_result);
1696*795d594fSAndroid Build Coastguard Worker   }
1697*795d594fSAndroid Build Coastguard Worker   return return_value;
1698*795d594fSAndroid Build Coastguard Worker }
1699*795d594fSAndroid Build Coastguard Worker 
PushDeoptContextIfNeeded(Thread * self,DeoptimizationMethodType deopt_type,bool is_ref,const JValue & return_value)1700*795d594fSAndroid Build Coastguard Worker bool Instrumentation::PushDeoptContextIfNeeded(Thread* self,
1701*795d594fSAndroid Build Coastguard Worker                                                DeoptimizationMethodType deopt_type,
1702*795d594fSAndroid Build Coastguard Worker                                                bool is_ref,
1703*795d594fSAndroid Build Coastguard Worker                                                const JValue& return_value)
1704*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
1705*795d594fSAndroid Build Coastguard Worker   if (self->IsExceptionPending()) {
1706*795d594fSAndroid Build Coastguard Worker     return false;
1707*795d594fSAndroid Build Coastguard Worker   }
1708*795d594fSAndroid Build Coastguard Worker 
1709*795d594fSAndroid Build Coastguard Worker   ArtMethod** sp = self->GetManagedStack()->GetTopQuickFrame();
1710*795d594fSAndroid Build Coastguard Worker   DCHECK(sp != nullptr && (*sp)->IsRuntimeMethod());
1711*795d594fSAndroid Build Coastguard Worker   if (!ShouldDeoptimizeCaller(self, sp)) {
1712*795d594fSAndroid Build Coastguard Worker     return false;
1713*795d594fSAndroid Build Coastguard Worker   }
1714*795d594fSAndroid Build Coastguard Worker 
1715*795d594fSAndroid Build Coastguard Worker   // TODO(mythria): The current deopt behaviour is we just re-execute the
1716*795d594fSAndroid Build Coastguard Worker   // alloc instruction so we don't need the return value. For instrumentation
1717*795d594fSAndroid Build Coastguard Worker   // related deopts, we actually don't need to and can use the result we got
1718*795d594fSAndroid Build Coastguard Worker   // here. Since this is a debug only feature it is not very important but
1719*795d594fSAndroid Build Coastguard Worker   // consider reusing the result in future.
1720*795d594fSAndroid Build Coastguard Worker   self->PushDeoptimizationContext(
1721*795d594fSAndroid Build Coastguard Worker       return_value, is_ref, nullptr, /* from_code= */ false, deopt_type);
1722*795d594fSAndroid Build Coastguard Worker   self->SetException(Thread::GetDeoptimizationException());
1723*795d594fSAndroid Build Coastguard Worker   return true;
1724*795d594fSAndroid Build Coastguard Worker }
1725*795d594fSAndroid Build Coastguard Worker 
DeoptimizeIfNeeded(Thread * self,ArtMethod ** sp,DeoptimizationMethodType type,JValue return_value,bool is_reference)1726*795d594fSAndroid Build Coastguard Worker std::unique_ptr<Context> Instrumentation::DeoptimizeIfNeeded(Thread* self,
1727*795d594fSAndroid Build Coastguard Worker                                                              ArtMethod** sp,
1728*795d594fSAndroid Build Coastguard Worker                                                              DeoptimizationMethodType type,
1729*795d594fSAndroid Build Coastguard Worker                                                              JValue return_value,
1730*795d594fSAndroid Build Coastguard Worker                                                              bool is_reference) {
1731*795d594fSAndroid Build Coastguard Worker   if (self->IsAsyncExceptionPending() || ShouldDeoptimizeCaller(self, sp)) {
1732*795d594fSAndroid Build Coastguard Worker     self->PushDeoptimizationContext(return_value,
1733*795d594fSAndroid Build Coastguard Worker                                     is_reference,
1734*795d594fSAndroid Build Coastguard Worker                                     nullptr,
1735*795d594fSAndroid Build Coastguard Worker                                     /* from_code= */ false,
1736*795d594fSAndroid Build Coastguard Worker                                     type);
1737*795d594fSAndroid Build Coastguard Worker     // This is requested from suspend points or when returning from runtime methods so exit
1738*795d594fSAndroid Build Coastguard Worker     // callbacks wouldn't be run yet. So don't skip method callbacks.
1739*795d594fSAndroid Build Coastguard Worker     return self->Deoptimize(DeoptimizationKind::kFullFrame,
1740*795d594fSAndroid Build Coastguard Worker                             /* single_frame= */ false,
1741*795d594fSAndroid Build Coastguard Worker                             /* skip_method_exit_callbacks= */ false);
1742*795d594fSAndroid Build Coastguard Worker   }
1743*795d594fSAndroid Build Coastguard Worker   // No exception or deoptimization.
1744*795d594fSAndroid Build Coastguard Worker   return nullptr;
1745*795d594fSAndroid Build Coastguard Worker }
1746*795d594fSAndroid Build Coastguard Worker 
NeedsSlowInterpreterForMethod(Thread * self,ArtMethod * method)1747*795d594fSAndroid Build Coastguard Worker bool Instrumentation::NeedsSlowInterpreterForMethod(Thread* self, ArtMethod* method) {
1748*795d594fSAndroid Build Coastguard Worker   return (method != nullptr) &&
1749*795d594fSAndroid Build Coastguard Worker          (InterpreterStubsInstalled() ||
1750*795d594fSAndroid Build Coastguard Worker           IsDeoptimized(method) ||
1751*795d594fSAndroid Build Coastguard Worker           self->IsForceInterpreter() ||
1752*795d594fSAndroid Build Coastguard Worker           // NB Since structurally obsolete compiled methods might have the offsets of
1753*795d594fSAndroid Build Coastguard Worker           // methods/fields compiled in we need to go back to interpreter whenever we hit
1754*795d594fSAndroid Build Coastguard Worker           // them.
1755*795d594fSAndroid Build Coastguard Worker           method->GetDeclaringClass()->IsObsoleteObject() ||
1756*795d594fSAndroid Build Coastguard Worker           Dbg::IsForcedInterpreterNeededForUpcall(self, method));
1757*795d594fSAndroid Build Coastguard Worker }
1758*795d594fSAndroid Build Coastguard Worker 
ShouldDeoptimizeCaller(Thread * self,ArtMethod ** sp)1759*795d594fSAndroid Build Coastguard Worker bool Instrumentation::ShouldDeoptimizeCaller(Thread* self, ArtMethod** sp) {
1760*795d594fSAndroid Build Coastguard Worker   // When exit stubs aren't called we don't need to check for any instrumentation related
1761*795d594fSAndroid Build Coastguard Worker   // deoptimizations.
1762*795d594fSAndroid Build Coastguard Worker   if (!RunExitHooks()) {
1763*795d594fSAndroid Build Coastguard Worker     return false;
1764*795d594fSAndroid Build Coastguard Worker   }
1765*795d594fSAndroid Build Coastguard Worker 
1766*795d594fSAndroid Build Coastguard Worker   ArtMethod* runtime_method = *sp;
1767*795d594fSAndroid Build Coastguard Worker   DCHECK(runtime_method->IsRuntimeMethod());
1768*795d594fSAndroid Build Coastguard Worker   QuickMethodFrameInfo frame_info = Runtime::Current()->GetRuntimeMethodFrameInfo(runtime_method);
1769*795d594fSAndroid Build Coastguard Worker   return ShouldDeoptimizeCaller(self, sp, frame_info.FrameSizeInBytes());
1770*795d594fSAndroid Build Coastguard Worker }
1771*795d594fSAndroid Build Coastguard Worker 
ShouldDeoptimizeCaller(Thread * self,ArtMethod ** sp,size_t frame_size)1772*795d594fSAndroid Build Coastguard Worker bool Instrumentation::ShouldDeoptimizeCaller(Thread* self, ArtMethod** sp, size_t frame_size) {
1773*795d594fSAndroid Build Coastguard Worker   uintptr_t caller_sp = reinterpret_cast<uintptr_t>(sp) + frame_size;
1774*795d594fSAndroid Build Coastguard Worker   ArtMethod* caller = *(reinterpret_cast<ArtMethod**>(caller_sp));
1775*795d594fSAndroid Build Coastguard Worker   uintptr_t caller_pc_addr = reinterpret_cast<uintptr_t>(sp) + (frame_size - sizeof(void*));
1776*795d594fSAndroid Build Coastguard Worker   uintptr_t caller_pc = *reinterpret_cast<uintptr_t*>(caller_pc_addr);
1777*795d594fSAndroid Build Coastguard Worker 
1778*795d594fSAndroid Build Coastguard Worker   if (caller == nullptr ||
1779*795d594fSAndroid Build Coastguard Worker       caller->IsNative() ||
1780*795d594fSAndroid Build Coastguard Worker       caller->IsRuntimeMethod()) {
1781*795d594fSAndroid Build Coastguard Worker     // We need to check for a deoptimization here because when a redefinition happens it is
1782*795d594fSAndroid Build Coastguard Worker     // not safe to use any compiled code because the field offsets might change. For native
1783*795d594fSAndroid Build Coastguard Worker     // methods, we don't embed any field offsets so no need to check for a deoptimization.
1784*795d594fSAndroid Build Coastguard Worker     // If the caller is null we don't need to do anything. This can happen when the caller
1785*795d594fSAndroid Build Coastguard Worker     // is being interpreted by the switch interpreter (when called from
1786*795d594fSAndroid Build Coastguard Worker     // artQuickToInterpreterBridge) / during shutdown / early startup.
1787*795d594fSAndroid Build Coastguard Worker     return false;
1788*795d594fSAndroid Build Coastguard Worker   }
1789*795d594fSAndroid Build Coastguard Worker 
1790*795d594fSAndroid Build Coastguard Worker   bool needs_deopt = NeedsSlowInterpreterForMethod(self, caller);
1791*795d594fSAndroid Build Coastguard Worker 
1792*795d594fSAndroid Build Coastguard Worker   // Non java debuggable apps don't support redefinition and hence it isn't required to check if
1793*795d594fSAndroid Build Coastguard Worker   // frame needs to be deoptimized. Even in debuggable apps, we only need this check when a
1794*795d594fSAndroid Build Coastguard Worker   // redefinition has actually happened. This is indicated by IsDeoptCheckRequired flag. We also
1795*795d594fSAndroid Build Coastguard Worker   // want to avoid getting method header when we need a deopt anyway.
1796*795d594fSAndroid Build Coastguard Worker   if (Runtime::Current()->IsJavaDebuggable() && !needs_deopt && self->IsDeoptCheckRequired()) {
1797*795d594fSAndroid Build Coastguard Worker     const OatQuickMethodHeader* header = caller->GetOatQuickMethodHeader(caller_pc);
1798*795d594fSAndroid Build Coastguard Worker     if (header != nullptr && header->HasShouldDeoptimizeFlag()) {
1799*795d594fSAndroid Build Coastguard Worker       DCHECK(header->IsOptimized());
1800*795d594fSAndroid Build Coastguard Worker       uint8_t* should_deopt_flag_addr =
1801*795d594fSAndroid Build Coastguard Worker           reinterpret_cast<uint8_t*>(caller_sp) + header->GetShouldDeoptimizeFlagOffset();
1802*795d594fSAndroid Build Coastguard Worker       if ((*should_deopt_flag_addr &
1803*795d594fSAndroid Build Coastguard Worker            static_cast<uint8_t>(DeoptimizeFlagValue::kForceDeoptForRedefinition)) != 0) {
1804*795d594fSAndroid Build Coastguard Worker         needs_deopt = true;
1805*795d594fSAndroid Build Coastguard Worker       }
1806*795d594fSAndroid Build Coastguard Worker     }
1807*795d594fSAndroid Build Coastguard Worker   }
1808*795d594fSAndroid Build Coastguard Worker 
1809*795d594fSAndroid Build Coastguard Worker   if (needs_deopt) {
1810*795d594fSAndroid Build Coastguard Worker     if (!Runtime::Current()->IsAsyncDeoptimizeable(caller, caller_pc)) {
1811*795d594fSAndroid Build Coastguard Worker       LOG(WARNING) << "Got a deoptimization request on un-deoptimizable method "
1812*795d594fSAndroid Build Coastguard Worker                    << caller->PrettyMethod();
1813*795d594fSAndroid Build Coastguard Worker       return false;
1814*795d594fSAndroid Build Coastguard Worker     }
1815*795d594fSAndroid Build Coastguard Worker     return true;
1816*795d594fSAndroid Build Coastguard Worker   }
1817*795d594fSAndroid Build Coastguard Worker 
1818*795d594fSAndroid Build Coastguard Worker   return false;
1819*795d594fSAndroid Build Coastguard Worker }
1820*795d594fSAndroid Build Coastguard Worker 
1821*795d594fSAndroid Build Coastguard Worker }  // namespace instrumentation
1822*795d594fSAndroid Build Coastguard Worker }  // namespace art
1823