2 * Copyright (C) 2011 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "instrumentation.h"
21 #include "arch/context.h"
22 #include "art_method-inl.h"
24 #include "class_linker.h"
26 #include "dex_file-inl.h"
27 #include "entrypoints/quick/quick_entrypoints.h"
28 #include "entrypoints/quick/quick_alloc_entrypoints.h"
29 #include "entrypoints/runtime_asm_entrypoints.h"
30 #include "gc_root-inl.h"
31 #include "interpreter/interpreter.h"
33 #include "jit/jit_code_cache.h"
34 #include "mirror/class-inl.h"
35 #include "mirror/dex_cache.h"
36 #include "mirror/object_array-inl.h"
37 #include "mirror/object-inl.h"
38 #include "nth_caller_visitor.h"
39 #include "oat_quick_method_header.h"
41 #include "thread_list.h"
44 namespace instrumentation {
46 constexpr bool kVerboseInstrumentation = false;
48 // Instrumentation works on non-inlined frames by updating returned PCs
49 // of compiled frames.
50 static constexpr StackVisitor::StackWalkKind kInstrumentationStackWalk =
51 StackVisitor::StackWalkKind::kSkipInlinedFrames;
53 class InstallStubsClassVisitor : public ClassVisitor {
55 explicit InstallStubsClassVisitor(Instrumentation* instrumentation)
56 : instrumentation_(instrumentation) {}
58 bool operator()(ObjPtr<mirror::Class> klass) OVERRIDE REQUIRES(Locks::mutator_lock_) {
59 instrumentation_->InstallStubsForClass(klass.Ptr());
60 return true; // we visit all classes.
64 Instrumentation* const instrumentation_;
68 Instrumentation::Instrumentation()
69 : instrumentation_stubs_installed_(false),
70 entry_exit_stubs_installed_(false),
71 interpreter_stubs_installed_(false),
72 interpret_only_(false),
73 forced_interpret_only_(false),
74 have_method_entry_listeners_(false),
75 have_method_exit_listeners_(false),
76 have_method_unwind_listeners_(false),
77 have_dex_pc_listeners_(false),
78 have_field_read_listeners_(false),
79 have_field_write_listeners_(false),
80 have_exception_caught_listeners_(false),
81 have_branch_listeners_(false),
82 have_invoke_virtual_or_interface_listeners_(false),
83 deoptimized_methods_lock_("deoptimized methods lock", kDeoptimizedMethodsLock),
84 deoptimization_enabled_(false),
85 interpreter_handler_table_(kMainHandlerTable),
86 quick_alloc_entry_points_instrumentation_counter_(0),
87 alloc_entrypoints_instrumented_(false) {
90 void Instrumentation::InstallStubsForClass(mirror::Class* klass) {
91 if (!klass->IsResolved()) {
92 // We need the class to be resolved to install/uninstall stubs. Otherwise its methods
93 // could not be initialized or linked with regards to class inheritance.
94 } else if (klass->IsErroneousResolved()) {
95 // We can't execute code in a erroneous class: do nothing.
97 for (ArtMethod& method : klass->GetMethods(kRuntimePointerSize)) {
98 InstallStubsForMethod(&method);
103 static void UpdateEntrypoints(ArtMethod* method, const void* quick_code)
104 REQUIRES_SHARED(Locks::mutator_lock_) {
105 method->SetEntryPointFromQuickCompiledCode(quick_code);
108 bool Instrumentation::NeedDebugVersionFor(ArtMethod* method) const REQUIRES_SHARED(Locks::mutator_lock_) {
109 return Dbg::IsDebuggerActive() &&
110 Runtime::Current()->IsJavaDebuggable() &&
111 !method->IsNative() &&
112 !method->IsProxyMethod();
115 void Instrumentation::InstallStubsForMethod(ArtMethod* method) {
116 if (!method->IsInvokable() || method->IsProxyMethod()) {
117 // Do not change stubs for these methods.
120 // Don't stub Proxy.<init>. Note that the Proxy class itself is not a proxy class.
121 if (method->IsConstructor() &&
122 method->GetDeclaringClass()->DescriptorEquals("Ljava/lang/reflect/Proxy;")) {
125 const void* new_quick_code;
126 bool uninstall = !entry_exit_stubs_installed_ && !interpreter_stubs_installed_;
127 Runtime* const runtime = Runtime::Current();
128 ClassLinker* const class_linker = runtime->GetClassLinker();
129 bool is_class_initialized = method->GetDeclaringClass()->IsInitialized();
131 if ((forced_interpret_only_ || IsDeoptimized(method)) && !method->IsNative()) {
132 new_quick_code = GetQuickToInterpreterBridge();
133 } else if (is_class_initialized || !method->IsStatic() || method->IsConstructor()) {
134 if (NeedDebugVersionFor(method)) {
135 new_quick_code = GetQuickToInterpreterBridge();
137 new_quick_code = class_linker->GetQuickOatCodeFor(method);
140 new_quick_code = GetQuickResolutionStub();
142 } else { // !uninstall
143 if ((interpreter_stubs_installed_ || forced_interpret_only_ || IsDeoptimized(method)) &&
144 !method->IsNative()) {
145 new_quick_code = GetQuickToInterpreterBridge();
147 // Do not overwrite resolution trampoline. When the trampoline initializes the method's
148 // class, all its static methods code will be set to the instrumentation entry point.
149 // For more details, see ClassLinker::FixupStaticTrampolines.
150 if (is_class_initialized || !method->IsStatic() || method->IsConstructor()) {
151 if (NeedDebugVersionFor(method)) {
152 // Oat code should not be used. Don't install instrumentation stub and
153 // use interpreter for instrumentation.
154 new_quick_code = GetQuickToInterpreterBridge();
155 } else if (entry_exit_stubs_installed_) {
156 new_quick_code = GetQuickInstrumentationEntryPoint();
158 new_quick_code = class_linker->GetQuickOatCodeFor(method);
161 new_quick_code = GetQuickResolutionStub();
165 UpdateEntrypoints(method, new_quick_code);
168 // Places the instrumentation exit pc as the return PC for every quick frame. This also allows
169 // deoptimization of quick frames to interpreter frames.
170 // Since we may already have done this previously, we need to push new instrumentation frame before
171 // existing instrumentation frames.
172 static void InstrumentationInstallStack(Thread* thread, void* arg)
173 REQUIRES_SHARED(Locks::mutator_lock_) {
174 struct InstallStackVisitor FINAL : public StackVisitor {
175 InstallStackVisitor(Thread* thread_in, Context* context, uintptr_t instrumentation_exit_pc)
176 : StackVisitor(thread_in, context, kInstrumentationStackWalk),
177 instrumentation_stack_(thread_in->GetInstrumentationStack()),
178 instrumentation_exit_pc_(instrumentation_exit_pc),
179 reached_existing_instrumentation_frames_(false), instrumentation_stack_depth_(0),
183 bool VisitFrame() OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
184 ArtMethod* m = GetMethod();
186 if (kVerboseInstrumentation) {
187 LOG(INFO) << " Skipping upcall. Frame " << GetFrameId();
190 return true; // Ignore upcalls.
192 if (GetCurrentQuickFrame() == nullptr) {
193 bool interpreter_frame = true;
194 InstrumentationStackFrame instrumentation_frame(GetThisObject(), m, 0, GetFrameId(),
196 if (kVerboseInstrumentation) {
197 LOG(INFO) << "Pushing shadow frame " << instrumentation_frame.Dump();
199 shadow_stack_.push_back(instrumentation_frame);
200 return true; // Continue.
202 uintptr_t return_pc = GetReturnPc();
203 if (m->IsRuntimeMethod()) {
204 if (return_pc == instrumentation_exit_pc_) {
205 if (kVerboseInstrumentation) {
206 LOG(INFO) << " Handling quick to interpreter transition. Frame " << GetFrameId();
208 CHECK_LT(instrumentation_stack_depth_, instrumentation_stack_->size());
209 const InstrumentationStackFrame& frame =
210 instrumentation_stack_->at(instrumentation_stack_depth_);
211 CHECK(frame.interpreter_entry_);
212 // This is an interpreter frame so method enter event must have been reported. However we
213 // need to push a DEX pc into the dex_pcs_ list to match size of instrumentation stack.
214 // Since we won't report method entry here, we can safely push any DEX pc.
215 dex_pcs_.push_back(0);
216 last_return_pc_ = frame.return_pc_;
217 ++instrumentation_stack_depth_;
220 if (kVerboseInstrumentation) {
221 LOG(INFO) << " Skipping runtime method. Frame " << GetFrameId();
223 last_return_pc_ = GetReturnPc();
224 return true; // Ignore unresolved methods since they will be instrumented after resolution.
227 if (kVerboseInstrumentation) {
228 LOG(INFO) << " Installing exit stub in " << DescribeLocation();
230 if (return_pc == instrumentation_exit_pc_) {
231 // We've reached a frame which has already been installed with instrumentation exit stub.
232 // We should have already installed instrumentation on previous frames.
233 reached_existing_instrumentation_frames_ = true;
235 CHECK_LT(instrumentation_stack_depth_, instrumentation_stack_->size());
236 const InstrumentationStackFrame& frame =
237 instrumentation_stack_->at(instrumentation_stack_depth_);
238 CHECK_EQ(m, frame.method_) << "Expected " << ArtMethod::PrettyMethod(m)
239 << ", Found " << ArtMethod::PrettyMethod(frame.method_);
240 return_pc = frame.return_pc_;
241 if (kVerboseInstrumentation) {
242 LOG(INFO) << "Ignoring already instrumented " << frame.Dump();
245 CHECK_NE(return_pc, 0U);
246 CHECK(!reached_existing_instrumentation_frames_);
247 InstrumentationStackFrame instrumentation_frame(GetThisObject(), m, return_pc, GetFrameId(),
249 if (kVerboseInstrumentation) {
250 LOG(INFO) << "Pushing frame " << instrumentation_frame.Dump();
253 // Insert frame at the right position so we do not corrupt the instrumentation stack.
254 // Instrumentation stack frames are in descending frame id order.
255 auto it = instrumentation_stack_->begin();
256 for (auto end = instrumentation_stack_->end(); it != end; ++it) {
257 const InstrumentationStackFrame& current = *it;
258 if (instrumentation_frame.frame_id_ >= current.frame_id_) {
262 instrumentation_stack_->insert(it, instrumentation_frame);
263 SetReturnPc(instrumentation_exit_pc_);
265 dex_pcs_.push_back((GetCurrentOatQuickMethodHeader() == nullptr)
266 ? DexFile::kDexNoIndex
267 : GetCurrentOatQuickMethodHeader()->ToDexPc(m, last_return_pc_));
268 last_return_pc_ = return_pc;
269 ++instrumentation_stack_depth_;
270 return true; // Continue.
272 std::deque<InstrumentationStackFrame>* const instrumentation_stack_;
273 std::vector<InstrumentationStackFrame> shadow_stack_;
274 std::vector<uint32_t> dex_pcs_;
275 const uintptr_t instrumentation_exit_pc_;
276 bool reached_existing_instrumentation_frames_;
277 size_t instrumentation_stack_depth_;
278 uintptr_t last_return_pc_;
280 if (kVerboseInstrumentation) {
281 std::string thread_name;
282 thread->GetThreadName(thread_name);
283 LOG(INFO) << "Installing exit stubs in " << thread_name;
286 Instrumentation* instrumentation = reinterpret_cast<Instrumentation*>(arg);
287 std::unique_ptr<Context> context(Context::Create());
288 uintptr_t instrumentation_exit_pc = reinterpret_cast<uintptr_t>(GetQuickInstrumentationExitPc());
289 InstallStackVisitor visitor(thread, context.get(), instrumentation_exit_pc);
290 visitor.WalkStack(true);
291 CHECK_EQ(visitor.dex_pcs_.size(), thread->GetInstrumentationStack()->size());
293 if (instrumentation->ShouldNotifyMethodEnterExitEvents()) {
294 // Create method enter events for all methods currently on the thread's stack. We only do this
295 // if no debugger is attached to prevent from posting events twice.
296 auto ssi = visitor.shadow_stack_.rbegin();
297 for (auto isi = thread->GetInstrumentationStack()->rbegin(),
298 end = thread->GetInstrumentationStack()->rend(); isi != end; ++isi) {
299 while (ssi != visitor.shadow_stack_.rend() && (*ssi).frame_id_ < (*isi).frame_id_) {
300 instrumentation->MethodEnterEvent(thread, (*ssi).this_object_, (*ssi).method_, 0);
303 uint32_t dex_pc = visitor.dex_pcs_.back();
304 visitor.dex_pcs_.pop_back();
305 if (!isi->interpreter_entry_) {
306 instrumentation->MethodEnterEvent(thread, (*isi).this_object_, (*isi).method_, dex_pc);
310 thread->VerifyStack();
313 void Instrumentation::InstrumentThreadStack(Thread* thread) {
314 instrumentation_stubs_installed_ = true;
315 InstrumentationInstallStack(thread, this);
318 // Removes the instrumentation exit pc as the return PC for every quick frame.
319 static void InstrumentationRestoreStack(Thread* thread, void* arg)
320 REQUIRES(Locks::mutator_lock_) {
321 Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
323 struct RestoreStackVisitor FINAL : public StackVisitor {
324 RestoreStackVisitor(Thread* thread_in, uintptr_t instrumentation_exit_pc,
325 Instrumentation* instrumentation)
326 : StackVisitor(thread_in, nullptr, kInstrumentationStackWalk),
328 instrumentation_exit_pc_(instrumentation_exit_pc),
329 instrumentation_(instrumentation),
330 instrumentation_stack_(thread_in->GetInstrumentationStack()),
331 frames_removed_(0) {}
333 bool VisitFrame() OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
334 if (instrumentation_stack_->size() == 0) {
335 return false; // Stop.
337 ArtMethod* m = GetMethod();
338 if (GetCurrentQuickFrame() == nullptr) {
339 if (kVerboseInstrumentation) {
340 LOG(INFO) << " Ignoring a shadow frame. Frame " << GetFrameId()
341 << " Method=" << ArtMethod::PrettyMethod(m);
343 return true; // Ignore shadow frames.
346 if (kVerboseInstrumentation) {
347 LOG(INFO) << " Skipping upcall. Frame " << GetFrameId();
349 return true; // Ignore upcalls.
351 bool removed_stub = false;
352 // TODO: make this search more efficient?
353 const size_t frameId = GetFrameId();
354 for (const InstrumentationStackFrame& instrumentation_frame : *instrumentation_stack_) {
355 if (instrumentation_frame.frame_id_ == frameId) {
356 if (kVerboseInstrumentation) {
357 LOG(INFO) << " Removing exit stub in " << DescribeLocation();
359 if (instrumentation_frame.interpreter_entry_) {
360 CHECK(m == Runtime::Current()->GetCalleeSaveMethod(Runtime::kSaveRefsAndArgs));
362 CHECK(m == instrumentation_frame.method_) << ArtMethod::PrettyMethod(m);
364 SetReturnPc(instrumentation_frame.return_pc_);
365 if (instrumentation_->ShouldNotifyMethodEnterExitEvents()) {
366 // Create the method exit events. As the methods didn't really exit the result is 0.
367 // We only do this if no debugger is attached to prevent from posting events twice.
368 instrumentation_->MethodExitEvent(thread_, instrumentation_frame.this_object_, m,
369 GetDexPc(), JValue());
377 if (kVerboseInstrumentation) {
378 LOG(INFO) << " No exit stub in " << DescribeLocation();
381 return true; // Continue.
383 Thread* const thread_;
384 const uintptr_t instrumentation_exit_pc_;
385 Instrumentation* const instrumentation_;
386 std::deque<instrumentation::InstrumentationStackFrame>* const instrumentation_stack_;
387 size_t frames_removed_;
389 if (kVerboseInstrumentation) {
390 std::string thread_name;
391 thread->GetThreadName(thread_name);
392 LOG(INFO) << "Removing exit stubs in " << thread_name;
394 std::deque<instrumentation::InstrumentationStackFrame>* stack = thread->GetInstrumentationStack();
395 if (stack->size() > 0) {
396 Instrumentation* instrumentation = reinterpret_cast<Instrumentation*>(arg);
397 uintptr_t instrumentation_exit_pc =
398 reinterpret_cast<uintptr_t>(GetQuickInstrumentationExitPc());
399 RestoreStackVisitor visitor(thread, instrumentation_exit_pc, instrumentation);
400 visitor.WalkStack(true);
401 CHECK_EQ(visitor.frames_removed_, stack->size());
402 while (stack->size() > 0) {
408 static bool HasEvent(Instrumentation::InstrumentationEvent expected, uint32_t events) {
409 return (events & expected) != 0;
412 static void PotentiallyAddListenerTo(Instrumentation::InstrumentationEvent event,
414 std::list<InstrumentationListener*>& list,
415 InstrumentationListener* listener,
417 REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::classlinker_classes_lock_) {
418 Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
419 if (!HasEvent(event, events)) {
422 // If there is a free slot in the list, we insert the listener in that slot.
423 // Otherwise we add it to the end of the list.
424 auto it = std::find(list.begin(), list.end(), nullptr);
425 if (it != list.end()) {
428 list.push_back(listener);
430 *has_listener = true;
433 void Instrumentation::AddListener(InstrumentationListener* listener, uint32_t events) {
434 Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
435 PotentiallyAddListenerTo(kMethodEntered,
437 method_entry_listeners_,
439 &have_method_entry_listeners_);
440 PotentiallyAddListenerTo(kMethodExited,
442 method_exit_listeners_,
444 &have_method_exit_listeners_);
445 PotentiallyAddListenerTo(kMethodUnwind,
447 method_unwind_listeners_,
449 &have_method_unwind_listeners_);
450 PotentiallyAddListenerTo(kBranch,
454 &have_branch_listeners_);
455 PotentiallyAddListenerTo(kInvokeVirtualOrInterface,
457 invoke_virtual_or_interface_listeners_,
459 &have_invoke_virtual_or_interface_listeners_);
460 PotentiallyAddListenerTo(kDexPcMoved,
464 &have_dex_pc_listeners_);
465 PotentiallyAddListenerTo(kFieldRead,
467 field_read_listeners_,
469 &have_field_read_listeners_);
470 PotentiallyAddListenerTo(kFieldWritten,
472 field_write_listeners_,
474 &have_field_write_listeners_);
475 PotentiallyAddListenerTo(kExceptionCaught,
477 exception_caught_listeners_,
479 &have_exception_caught_listeners_);
480 UpdateInterpreterHandlerTable();
483 static void PotentiallyRemoveListenerFrom(Instrumentation::InstrumentationEvent event,
485 std::list<InstrumentationListener*>& list,
486 InstrumentationListener* listener,
488 REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::classlinker_classes_lock_) {
489 Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
490 if (!HasEvent(event, events)) {
493 auto it = std::find(list.begin(), list.end(), listener);
494 if (it != list.end()) {
495 // Just update the entry, do not remove from the list. Removing entries in the list
496 // is unsafe when mutators are iterating over it.
500 // Check if the list contains any non-null listener, and update 'has_listener'.
501 for (InstrumentationListener* l : list) {
503 *has_listener = true;
507 *has_listener = false;
510 void Instrumentation::RemoveListener(InstrumentationListener* listener, uint32_t events) {
511 Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
512 PotentiallyRemoveListenerFrom(kMethodEntered,
514 method_entry_listeners_,
516 &have_method_entry_listeners_);
517 PotentiallyRemoveListenerFrom(kMethodExited,
519 method_exit_listeners_,
521 &have_method_exit_listeners_);
522 PotentiallyRemoveListenerFrom(kMethodUnwind,
524 method_unwind_listeners_,
526 &have_method_unwind_listeners_);
527 PotentiallyRemoveListenerFrom(kBranch,
531 &have_branch_listeners_);
532 PotentiallyRemoveListenerFrom(kInvokeVirtualOrInterface,
534 invoke_virtual_or_interface_listeners_,
536 &have_invoke_virtual_or_interface_listeners_);
537 PotentiallyRemoveListenerFrom(kDexPcMoved,
541 &have_dex_pc_listeners_);
542 PotentiallyRemoveListenerFrom(kFieldRead,
544 field_read_listeners_,
546 &have_field_read_listeners_);
547 PotentiallyRemoveListenerFrom(kFieldWritten,
549 field_write_listeners_,
551 &have_field_write_listeners_);
552 PotentiallyRemoveListenerFrom(kExceptionCaught,
554 exception_caught_listeners_,
556 &have_exception_caught_listeners_);
557 UpdateInterpreterHandlerTable();
560 Instrumentation::InstrumentationLevel Instrumentation::GetCurrentInstrumentationLevel() const {
561 if (interpreter_stubs_installed_) {
562 return InstrumentationLevel::kInstrumentWithInterpreter;
563 } else if (entry_exit_stubs_installed_) {
564 return InstrumentationLevel::kInstrumentWithInstrumentationStubs;
566 return InstrumentationLevel::kInstrumentNothing;
570 bool Instrumentation::RequiresInstrumentationInstallation(InstrumentationLevel new_level) const {
571 // We need to reinstall instrumentation if we go to a different level.
572 return GetCurrentInstrumentationLevel() != new_level;
575 void Instrumentation::ConfigureStubs(const char* key, InstrumentationLevel desired_level) {
576 // Store the instrumentation level for this key or remove it.
577 if (desired_level == InstrumentationLevel::kInstrumentNothing) {
578 // The client no longer needs instrumentation.
579 requested_instrumentation_levels_.erase(key);
581 // The client needs instrumentation.
582 requested_instrumentation_levels_.Overwrite(key, desired_level);
585 // Look for the highest required instrumentation level.
586 InstrumentationLevel requested_level = InstrumentationLevel::kInstrumentNothing;
587 for (const auto& v : requested_instrumentation_levels_) {
588 requested_level = std::max(requested_level, v.second);
591 interpret_only_ = (requested_level == InstrumentationLevel::kInstrumentWithInterpreter) ||
592 forced_interpret_only_;
594 if (!RequiresInstrumentationInstallation(requested_level)) {
595 // We're already set.
598 Thread* const self = Thread::Current();
599 Runtime* runtime = Runtime::Current();
600 Locks::mutator_lock_->AssertExclusiveHeld(self);
601 Locks::thread_list_lock_->AssertNotHeld(self);
602 if (requested_level > InstrumentationLevel::kInstrumentNothing) {
603 if (requested_level == InstrumentationLevel::kInstrumentWithInterpreter) {
604 interpreter_stubs_installed_ = true;
605 entry_exit_stubs_installed_ = true;
607 CHECK_EQ(requested_level, InstrumentationLevel::kInstrumentWithInstrumentationStubs);
608 entry_exit_stubs_installed_ = true;
609 interpreter_stubs_installed_ = false;
611 InstallStubsClassVisitor visitor(this);
612 runtime->GetClassLinker()->VisitClasses(&visitor);
613 instrumentation_stubs_installed_ = true;
614 MutexLock mu(self, *Locks::thread_list_lock_);
615 runtime->GetThreadList()->ForEach(InstrumentationInstallStack, this);
617 interpreter_stubs_installed_ = false;
618 entry_exit_stubs_installed_ = false;
619 InstallStubsClassVisitor visitor(this);
620 runtime->GetClassLinker()->VisitClasses(&visitor);
621 // Restore stack only if there is no method currently deoptimized.
624 ReaderMutexLock mu(self, deoptimized_methods_lock_);
625 empty = IsDeoptimizedMethodsEmpty(); // Avoid lock violation.
628 MutexLock mu(self, *Locks::thread_list_lock_);
629 Runtime::Current()->GetThreadList()->ForEach(InstrumentationRestoreStack, this);
630 // Only do this after restoring, as walking the stack when restoring will see
631 // the instrumentation exit pc.
632 instrumentation_stubs_installed_ = false;
637 static void ResetQuickAllocEntryPointsForThread(Thread* thread, void* arg ATTRIBUTE_UNUSED) {
638 thread->ResetQuickAllocEntryPointsForThread(kUseReadBarrier && thread->GetIsGcMarking());
641 void Instrumentation::SetEntrypointsInstrumented(bool instrumented) {
642 Thread* self = Thread::Current();
643 Runtime* runtime = Runtime::Current();
644 Locks::mutator_lock_->AssertNotHeld(self);
645 Locks::instrument_entrypoints_lock_->AssertHeld(self);
646 if (runtime->IsStarted()) {
647 ScopedSuspendAll ssa(__FUNCTION__);
648 MutexLock mu(self, *Locks::runtime_shutdown_lock_);
649 SetQuickAllocEntryPointsInstrumented(instrumented);
650 ResetQuickAllocEntryPoints();
651 alloc_entrypoints_instrumented_ = instrumented;
653 MutexLock mu(self, *Locks::runtime_shutdown_lock_);
654 SetQuickAllocEntryPointsInstrumented(instrumented);
656 // Note: ResetQuickAllocEntryPoints only works when the runtime is started. Manually run the
657 // update for just this thread.
658 // Note: self may be null. One of those paths is setting instrumentation in the Heap
659 // constructor for gcstress mode.
660 if (self != nullptr) {
661 ResetQuickAllocEntryPointsForThread(self, nullptr);
664 alloc_entrypoints_instrumented_ = instrumented;
668 void Instrumentation::InstrumentQuickAllocEntryPoints() {
669 MutexLock mu(Thread::Current(), *Locks::instrument_entrypoints_lock_);
670 InstrumentQuickAllocEntryPointsLocked();
673 void Instrumentation::UninstrumentQuickAllocEntryPoints() {
674 MutexLock mu(Thread::Current(), *Locks::instrument_entrypoints_lock_);
675 UninstrumentQuickAllocEntryPointsLocked();
678 void Instrumentation::InstrumentQuickAllocEntryPointsLocked() {
679 Locks::instrument_entrypoints_lock_->AssertHeld(Thread::Current());
680 if (quick_alloc_entry_points_instrumentation_counter_ == 0) {
681 SetEntrypointsInstrumented(true);
683 ++quick_alloc_entry_points_instrumentation_counter_;
686 void Instrumentation::UninstrumentQuickAllocEntryPointsLocked() {
687 Locks::instrument_entrypoints_lock_->AssertHeld(Thread::Current());
688 CHECK_GT(quick_alloc_entry_points_instrumentation_counter_, 0U);
689 --quick_alloc_entry_points_instrumentation_counter_;
690 if (quick_alloc_entry_points_instrumentation_counter_ == 0) {
691 SetEntrypointsInstrumented(false);
695 void Instrumentation::ResetQuickAllocEntryPoints() {
696 Runtime* runtime = Runtime::Current();
697 if (runtime->IsStarted()) {
698 MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
699 runtime->GetThreadList()->ForEach(ResetQuickAllocEntryPointsForThread, nullptr);
703 void Instrumentation::UpdateMethodsCodeImpl(ArtMethod* method, const void* quick_code) {
704 const void* new_quick_code;
705 if (LIKELY(!instrumentation_stubs_installed_)) {
706 new_quick_code = quick_code;
708 if ((interpreter_stubs_installed_ || IsDeoptimized(method)) && !method->IsNative()) {
709 new_quick_code = GetQuickToInterpreterBridge();
711 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
712 if (class_linker->IsQuickResolutionStub(quick_code) ||
713 class_linker->IsQuickToInterpreterBridge(quick_code)) {
714 new_quick_code = quick_code;
715 } else if (entry_exit_stubs_installed_) {
716 new_quick_code = GetQuickInstrumentationEntryPoint();
718 new_quick_code = quick_code;
722 UpdateEntrypoints(method, new_quick_code);
725 void Instrumentation::UpdateMethodsCode(ArtMethod* method, const void* quick_code) {
726 DCHECK(method->GetDeclaringClass()->IsResolved());
727 UpdateMethodsCodeImpl(method, quick_code);
730 void Instrumentation::UpdateMethodsCodeForJavaDebuggable(ArtMethod* method,
731 const void* quick_code) {
732 // When the runtime is set to Java debuggable, we may update the entry points of
733 // all methods of a class to the interpreter bridge. A method's declaring class
734 // might not be in resolved state yet in that case, so we bypass the DCHECK in
735 // UpdateMethodsCode.
736 UpdateMethodsCodeImpl(method, quick_code);
739 bool Instrumentation::AddDeoptimizedMethod(ArtMethod* method) {
740 if (IsDeoptimizedMethod(method)) {
741 // Already in the map. Return.
744 // Not found. Add it.
745 deoptimized_methods_.insert(method);
749 bool Instrumentation::IsDeoptimizedMethod(ArtMethod* method) {
750 return deoptimized_methods_.find(method) != deoptimized_methods_.end();
753 ArtMethod* Instrumentation::BeginDeoptimizedMethod() {
754 if (deoptimized_methods_.empty()) {
758 return *deoptimized_methods_.begin();
761 bool Instrumentation::RemoveDeoptimizedMethod(ArtMethod* method) {
762 auto it = deoptimized_methods_.find(method);
763 if (it == deoptimized_methods_.end()) {
766 deoptimized_methods_.erase(it);
770 bool Instrumentation::IsDeoptimizedMethodsEmpty() const {
771 return deoptimized_methods_.empty();
774 void Instrumentation::Deoptimize(ArtMethod* method) {
775 CHECK(!method->IsNative());
776 CHECK(!method->IsProxyMethod());
777 CHECK(method->IsInvokable());
779 Thread* self = Thread::Current();
781 WriterMutexLock mu(self, deoptimized_methods_lock_);
782 bool has_not_been_deoptimized = AddDeoptimizedMethod(method);
783 CHECK(has_not_been_deoptimized) << "Method " << ArtMethod::PrettyMethod(method)
784 << " is already deoptimized";
786 if (!interpreter_stubs_installed_) {
787 UpdateEntrypoints(method, GetQuickInstrumentationEntryPoint());
789 // Install instrumentation exit stub and instrumentation frames. We may already have installed
790 // these previously so it will only cover the newly created frames.
791 instrumentation_stubs_installed_ = true;
792 MutexLock mu(self, *Locks::thread_list_lock_);
793 Runtime::Current()->GetThreadList()->ForEach(InstrumentationInstallStack, this);
797 void Instrumentation::Undeoptimize(ArtMethod* method) {
798 CHECK(!method->IsNative());
799 CHECK(!method->IsProxyMethod());
800 CHECK(method->IsInvokable());
802 Thread* self = Thread::Current();
805 WriterMutexLock mu(self, deoptimized_methods_lock_);
806 bool found_and_erased = RemoveDeoptimizedMethod(method);
807 CHECK(found_and_erased) << "Method " << ArtMethod::PrettyMethod(method)
808 << " is not deoptimized";
809 empty = IsDeoptimizedMethodsEmpty();
812 // Restore code and possibly stack only if we did not deoptimize everything.
813 if (!interpreter_stubs_installed_) {
814 // Restore its code or resolution trampoline.
815 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
816 if (method->IsStatic() && !method->IsConstructor() &&
817 !method->GetDeclaringClass()->IsInitialized()) {
818 UpdateEntrypoints(method, GetQuickResolutionStub());
820 const void* quick_code = NeedDebugVersionFor(method)
821 ? GetQuickToInterpreterBridge()
822 : class_linker->GetQuickOatCodeFor(method);
823 UpdateEntrypoints(method, quick_code);
826 // If there is no deoptimized method left, we can restore the stack of each thread.
828 MutexLock mu(self, *Locks::thread_list_lock_);
829 Runtime::Current()->GetThreadList()->ForEach(InstrumentationRestoreStack, this);
830 instrumentation_stubs_installed_ = false;
835 bool Instrumentation::IsDeoptimized(ArtMethod* method) {
836 DCHECK(method != nullptr);
837 ReaderMutexLock mu(Thread::Current(), deoptimized_methods_lock_);
838 return IsDeoptimizedMethod(method);
841 void Instrumentation::EnableDeoptimization() {
842 ReaderMutexLock mu(Thread::Current(), deoptimized_methods_lock_);
843 CHECK(IsDeoptimizedMethodsEmpty());
844 CHECK_EQ(deoptimization_enabled_, false);
845 deoptimization_enabled_ = true;
848 void Instrumentation::DisableDeoptimization(const char* key) {
849 CHECK_EQ(deoptimization_enabled_, true);
850 // If we deoptimized everything, undo it.
851 InstrumentationLevel level = GetCurrentInstrumentationLevel();
852 if (level == InstrumentationLevel::kInstrumentWithInterpreter) {
853 UndeoptimizeEverything(key);
855 // Undeoptimized selected methods.
859 ReaderMutexLock mu(Thread::Current(), deoptimized_methods_lock_);
860 if (IsDeoptimizedMethodsEmpty()) {
863 method = BeginDeoptimizedMethod();
864 CHECK(method != nullptr);
866 Undeoptimize(method);
868 deoptimization_enabled_ = false;
871 // Indicates if instrumentation should notify method enter/exit events to the listeners.
872 bool Instrumentation::ShouldNotifyMethodEnterExitEvents() const {
873 if (!HasMethodEntryListeners() && !HasMethodExitListeners()) {
876 return !deoptimization_enabled_ && !interpreter_stubs_installed_;
879 void Instrumentation::DeoptimizeEverything(const char* key) {
880 CHECK(deoptimization_enabled_);
881 ConfigureStubs(key, InstrumentationLevel::kInstrumentWithInterpreter);
884 void Instrumentation::UndeoptimizeEverything(const char* key) {
885 CHECK(interpreter_stubs_installed_);
886 CHECK(deoptimization_enabled_);
887 ConfigureStubs(key, InstrumentationLevel::kInstrumentNothing);
890 void Instrumentation::EnableMethodTracing(const char* key, bool needs_interpreter) {
891 InstrumentationLevel level;
892 if (needs_interpreter) {
893 level = InstrumentationLevel::kInstrumentWithInterpreter;
895 level = InstrumentationLevel::kInstrumentWithInstrumentationStubs;
897 ConfigureStubs(key, level);
900 void Instrumentation::DisableMethodTracing(const char* key) {
901 ConfigureStubs(key, InstrumentationLevel::kInstrumentNothing);
904 const void* Instrumentation::GetQuickCodeFor(ArtMethod* method, PointerSize pointer_size) const {
905 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
906 if (LIKELY(!instrumentation_stubs_installed_)) {
907 const void* code = method->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size);
908 DCHECK(code != nullptr);
909 if (LIKELY(!class_linker->IsQuickResolutionStub(code) &&
910 !class_linker->IsQuickToInterpreterBridge(code)) &&
911 !class_linker->IsQuickResolutionStub(code) &&
912 !class_linker->IsQuickToInterpreterBridge(code)) {
916 return class_linker->GetQuickOatCodeFor(method);
919 void Instrumentation::MethodEnterEventImpl(Thread* thread, mirror::Object* this_object,
921 uint32_t dex_pc) const {
922 if (HasMethodEntryListeners()) {
923 for (InstrumentationListener* listener : method_entry_listeners_) {
924 if (listener != nullptr) {
925 listener->MethodEntered(thread, this_object, method, dex_pc);
931 void Instrumentation::MethodExitEventImpl(Thread* thread, mirror::Object* this_object,
933 uint32_t dex_pc, const JValue& return_value) const {
934 if (HasMethodExitListeners()) {
935 for (InstrumentationListener* listener : method_exit_listeners_) {
936 if (listener != nullptr) {
937 listener->MethodExited(thread, this_object, method, dex_pc, return_value);
943 void Instrumentation::MethodUnwindEvent(Thread* thread, mirror::Object* this_object,
945 uint32_t dex_pc) const {
946 if (HasMethodUnwindListeners()) {
947 for (InstrumentationListener* listener : method_unwind_listeners_) {
948 if (listener != nullptr) {
949 listener->MethodUnwind(thread, this_object, method, dex_pc);
955 void Instrumentation::DexPcMovedEventImpl(Thread* thread, mirror::Object* this_object,
957 uint32_t dex_pc) const {
958 for (InstrumentationListener* listener : dex_pc_listeners_) {
959 if (listener != nullptr) {
960 listener->DexPcMoved(thread, this_object, method, dex_pc);
965 void Instrumentation::BranchImpl(Thread* thread,
968 int32_t offset) const {
969 for (InstrumentationListener* listener : branch_listeners_) {
970 if (listener != nullptr) {
971 listener->Branch(thread, method, dex_pc, offset);
976 void Instrumentation::InvokeVirtualOrInterfaceImpl(Thread* thread,
977 mirror::Object* this_object,
980 ArtMethod* callee) const {
981 // We cannot have thread suspension since that would cause the this_object parameter to
982 // potentially become a dangling pointer. An alternative could be to put it in a handle instead.
983 ScopedAssertNoThreadSuspension ants(__FUNCTION__);
984 for (InstrumentationListener* listener : invoke_virtual_or_interface_listeners_) {
985 if (listener != nullptr) {
986 listener->InvokeVirtualOrInterface(thread, this_object, caller, dex_pc, callee);
991 void Instrumentation::FieldReadEventImpl(Thread* thread, mirror::Object* this_object,
992 ArtMethod* method, uint32_t dex_pc,
993 ArtField* field) const {
994 for (InstrumentationListener* listener : field_read_listeners_) {
995 if (listener != nullptr) {
996 listener->FieldRead(thread, this_object, method, dex_pc, field);
1001 void Instrumentation::FieldWriteEventImpl(Thread* thread, mirror::Object* this_object,
1002 ArtMethod* method, uint32_t dex_pc,
1003 ArtField* field, const JValue& field_value) const {
1004 for (InstrumentationListener* listener : field_write_listeners_) {
1005 if (listener != nullptr) {
1006 listener->FieldWritten(thread, this_object, method, dex_pc, field, field_value);
1011 void Instrumentation::ExceptionCaughtEvent(Thread* thread,
1012 mirror::Throwable* exception_object) const {
1013 Thread* self = Thread::Current();
1014 StackHandleScope<1> hs(self);
1015 Handle<mirror::Throwable> h_exception(hs.NewHandle(exception_object));
1016 if (HasExceptionCaughtListeners()) {
1017 DCHECK_EQ(thread->GetException(), h_exception.Get());
1018 thread->ClearException();
1019 for (InstrumentationListener* listener : exception_caught_listeners_) {
1020 if (listener != nullptr) {
1021 listener->ExceptionCaught(thread, h_exception.Get());
1024 thread->SetException(h_exception.Get());
1028 // Computes a frame ID by ignoring inlined frames.
1029 size_t Instrumentation::ComputeFrameId(Thread* self,
1031 size_t inlined_frames_before_frame) {
1032 CHECK_GE(frame_depth, inlined_frames_before_frame);
1033 size_t no_inline_depth = frame_depth - inlined_frames_before_frame;
1034 return StackVisitor::ComputeNumFrames(self, kInstrumentationStackWalk) - no_inline_depth;
1037 static void CheckStackDepth(Thread* self, const InstrumentationStackFrame& instrumentation_frame,
1039 REQUIRES_SHARED(Locks::mutator_lock_) {
1040 size_t frame_id = StackVisitor::ComputeNumFrames(self, kInstrumentationStackWalk) + delta;
1041 if (frame_id != instrumentation_frame.frame_id_) {
1042 LOG(ERROR) << "Expected frame_id=" << frame_id << " but found "
1043 << instrumentation_frame.frame_id_;
1044 StackVisitor::DescribeStack(self);
1045 CHECK_EQ(frame_id, instrumentation_frame.frame_id_);
1049 void Instrumentation::PushInstrumentationStackFrame(Thread* self, mirror::Object* this_object,
1051 uintptr_t lr, bool interpreter_entry) {
1052 // We have a callee-save frame meaning this value is guaranteed to never be 0.
1053 size_t frame_id = StackVisitor::ComputeNumFrames(self, kInstrumentationStackWalk);
1054 std::deque<instrumentation::InstrumentationStackFrame>* stack = self->GetInstrumentationStack();
1055 if (kVerboseInstrumentation) {
1056 LOG(INFO) << "Entering " << ArtMethod::PrettyMethod(method) << " from PC "
1057 << reinterpret_cast<void*>(lr);
1059 instrumentation::InstrumentationStackFrame instrumentation_frame(this_object, method, lr,
1060 frame_id, interpreter_entry);
1061 stack->push_front(instrumentation_frame);
1063 if (!interpreter_entry) {
1064 MethodEnterEvent(self, this_object, method, 0);
1068 TwoWordReturn Instrumentation::PopInstrumentationStackFrame(Thread* self, uintptr_t* return_pc,
1069 uint64_t gpr_result,
1070 uint64_t fpr_result) {
1072 std::deque<instrumentation::InstrumentationStackFrame>* stack = self->GetInstrumentationStack();
1073 CHECK_GT(stack->size(), 0U);
1074 InstrumentationStackFrame instrumentation_frame = stack->front();
1077 // Set return PC and check the sanity of the stack.
1078 *return_pc = instrumentation_frame.return_pc_;
1079 CheckStackDepth(self, instrumentation_frame, 0);
1080 self->VerifyStack();
1082 ArtMethod* method = instrumentation_frame.method_;
1084 const PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
1085 char return_shorty = method->GetInterfaceMethodIfProxy(pointer_size)->GetShorty(&length)[0];
1086 JValue return_value;
1087 if (return_shorty == 'V') {
1088 return_value.SetJ(0);
1089 } else if (return_shorty == 'F' || return_shorty == 'D') {
1090 return_value.SetJ(fpr_result);
1092 return_value.SetJ(gpr_result);
1094 // TODO: improve the dex pc information here, requires knowledge of current PC as opposed to
1096 uint32_t dex_pc = DexFile::kDexNoIndex;
1097 mirror::Object* this_object = instrumentation_frame.this_object_;
1098 if (!instrumentation_frame.interpreter_entry_) {
1099 MethodExitEvent(self, this_object, instrumentation_frame.method_, dex_pc, return_value);
1102 // Deoptimize if the caller needs to continue execution in the interpreter. Do nothing if we get
1103 // back to an upcall.
1104 NthCallerVisitor visitor(self, 1, true);
1105 visitor.WalkStack(true);
1106 bool deoptimize = (visitor.caller != nullptr) &&
1107 (interpreter_stubs_installed_ || IsDeoptimized(visitor.caller) ||
1108 Dbg::IsForcedInterpreterNeededForUpcall(self, visitor.caller));
1109 if (deoptimize && Runtime::Current()->IsAsyncDeoptimizeable(*return_pc)) {
1110 if (kVerboseInstrumentation) {
1111 LOG(INFO) << "Deoptimizing "
1112 << visitor.caller->PrettyMethod()
1113 << " by returning from "
1114 << method->PrettyMethod()
1116 << std::hex << return_value.GetJ() << std::dec
1120 self->PushDeoptimizationContext(return_value,
1121 return_shorty == 'L',
1122 false /* from_code */,
1123 nullptr /* no pending exception */);
1124 return GetTwoWordSuccessValue(*return_pc,
1125 reinterpret_cast<uintptr_t>(GetQuickDeoptimizationEntryPoint()));
1127 if (deoptimize && !Runtime::Current()->IsAsyncDeoptimizeable(*return_pc)) {
1128 LOG(WARNING) << "Got a deoptimization request on un-deoptimizable " << method->PrettyMethod()
1129 << " at PC " << reinterpret_cast<void*>(*return_pc);
1131 if (kVerboseInstrumentation) {
1132 LOG(INFO) << "Returning from " << method->PrettyMethod()
1133 << " to PC " << reinterpret_cast<void*>(*return_pc);
1135 return GetTwoWordSuccessValue(0, *return_pc);
1139 uintptr_t Instrumentation::PopMethodForUnwind(Thread* self, bool is_deoptimization) const {
1141 std::deque<instrumentation::InstrumentationStackFrame>* stack = self->GetInstrumentationStack();
1142 CHECK_GT(stack->size(), 0U);
1143 InstrumentationStackFrame instrumentation_frame = stack->front();
1144 // TODO: bring back CheckStackDepth(self, instrumentation_frame, 2);
1147 ArtMethod* method = instrumentation_frame.method_;
1148 if (is_deoptimization) {
1149 if (kVerboseInstrumentation) {
1150 LOG(INFO) << "Popping for deoptimization " << ArtMethod::PrettyMethod(method);
1153 if (kVerboseInstrumentation) {
1154 LOG(INFO) << "Popping for unwind " << ArtMethod::PrettyMethod(method);
1157 // Notify listeners of method unwind.
1158 // TODO: improve the dex pc information here, requires knowledge of current PC as opposed to
1160 uint32_t dex_pc = DexFile::kDexNoIndex;
1161 MethodUnwindEvent(self, instrumentation_frame.this_object_, method, dex_pc);
1163 return instrumentation_frame.return_pc_;
1166 std::string InstrumentationStackFrame::Dump() const {
1167 std::ostringstream os;
1168 os << "Frame " << frame_id_ << " " << ArtMethod::PrettyMethod(method_) << ":"
1169 << reinterpret_cast<void*>(return_pc_) << " this=" << reinterpret_cast<void*>(this_object_);
1173 } // namespace instrumentation