blob: ca4895557d8d5e9a57550c95649ee45015eb095a [file] [log] [blame]
jeffhao725a9572012-11-13 18:20:12 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "instrumentation.h"
18
Alex Lightb7c640d2019-03-20 15:52:13 -070019#include <functional>
20#include <optional>
Ian Rogersc7dd2952014-10-21 23:31:19 -070021#include <sstream>
22
Andreas Gampec7d878d2018-11-19 18:42:06 +000023#include <android-base/logging.h>
24
Ian Rogerse63db272014-07-15 15:36:11 -070025#include "arch/context.h"
Alex Lightd7661582017-05-01 13:48:16 -070026#include "art_field-inl.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070027#include "art_method-inl.h"
David Sehrc431b9d2018-03-02 12:01:51 -080028#include "base/atomic.h"
Andreas Gampe8228cdf2017-05-30 15:03:54 -070029#include "base/callee_save_type.h"
jeffhao725a9572012-11-13 18:20:12 -080030#include "class_linker.h"
31#include "debugger.h"
David Sehr9e734c72018-01-04 17:56:19 -080032#include "dex/dex_file-inl.h"
33#include "dex/dex_file_types.h"
34#include "dex/dex_instruction-inl.h"
Mathieu Chartierd8891782014-03-02 13:28:37 -080035#include "entrypoints/quick/quick_alloc_entrypoints.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070036#include "entrypoints/quick/quick_entrypoints.h"
Ian Rogers6f3dbba2014-10-14 17:41:57 -070037#include "entrypoints/runtime_asm_entrypoints.h"
Hiroshi Yamauchi94f7b492014-07-22 18:08:23 -070038#include "gc_root-inl.h"
Sebastien Hertz138dbfc2013-12-04 18:15:25 +010039#include "interpreter/interpreter.h"
Mingyao Yang2ee17902017-08-30 11:37:08 -070040#include "interpreter/interpreter_common.h"
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080041#include "jit/jit.h"
42#include "jit/jit_code_cache.h"
Alex Lightd7661582017-05-01 13:48:16 -070043#include "jvalue-inl.h"
Alex Lightb7c640d2019-03-20 15:52:13 -070044#include "jvalue.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080045#include "mirror/class-inl.h"
46#include "mirror/dex_cache.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070047#include "mirror/object-inl.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070048#include "mirror/object_array-inl.h"
Ian Rogers62d6c772013-02-27 08:32:07 -080049#include "nth_caller_visitor.h"
Nicolas Geoffray524e7ea2015-10-16 17:13:34 +010050#include "oat_quick_method_header.h"
David Srbecky28f6cff2018-10-16 15:07:28 +010051#include "runtime-inl.h"
jeffhao725a9572012-11-13 18:20:12 -080052#include "thread.h"
53#include "thread_list.h"
jeffhao725a9572012-11-13 18:20:12 -080054
55namespace art {
Ian Rogers62d6c772013-02-27 08:32:07 -080056namespace instrumentation {
jeffhao725a9572012-11-13 18:20:12 -080057
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020058constexpr bool kVerboseInstrumentation = false;
Sebastien Hertz5bfd5c92013-11-15 11:36:07 +010059
Alex Lightb7c640d2019-03-20 15:52:13 -070060void InstrumentationListener::MethodExited(
61 Thread* thread,
62 Handle<mirror::Object> this_object,
63 ArtMethod* method,
64 uint32_t dex_pc,
65 OptionalFrame frame,
66 MutableHandle<mirror::Object>& return_value) {
Alex Lightd7661582017-05-01 13:48:16 -070067 DCHECK_EQ(method->GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetReturnTypePrimitive(),
68 Primitive::kPrimNot);
Alex Lightb7c640d2019-03-20 15:52:13 -070069 const void* original_ret = return_value.Get();
Alex Lightd7661582017-05-01 13:48:16 -070070 JValue v;
71 v.SetL(return_value.Get());
Alex Lightb7c640d2019-03-20 15:52:13 -070072 MethodExited(thread, this_object, method, dex_pc, frame, v);
73 DCHECK(original_ret == v.GetL()) << "Return value changed";
Alex Lightd7661582017-05-01 13:48:16 -070074}
75
76void InstrumentationListener::FieldWritten(Thread* thread,
77 Handle<mirror::Object> this_object,
78 ArtMethod* method,
79 uint32_t dex_pc,
80 ArtField* field,
81 Handle<mirror::Object> field_value) {
82 DCHECK(!field->IsPrimitiveType());
83 JValue v;
84 v.SetL(field_value.Get());
85 FieldWritten(thread, this_object, method, dex_pc, field, v);
86}
87
Nicolas Geoffray8e5bd182015-05-06 11:34:34 +010088// Instrumentation works on non-inlined frames by updating returned PCs
89// of compiled frames.
90static constexpr StackVisitor::StackWalkKind kInstrumentationStackWalk =
91 StackVisitor::StackWalkKind::kSkipInlinedFrames;
92
Mathieu Chartiere0671ce2015-07-28 17:23:28 -070093class InstallStubsClassVisitor : public ClassVisitor {
94 public:
95 explicit InstallStubsClassVisitor(Instrumentation* instrumentation)
96 : instrumentation_(instrumentation) {}
97
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010098 bool operator()(ObjPtr<mirror::Class> klass) override REQUIRES(Locks::mutator_lock_) {
Mathieu Chartier28357fa2016-10-18 16:27:40 -070099 instrumentation_->InstallStubsForClass(klass.Ptr());
Mathieu Chartiere0671ce2015-07-28 17:23:28 -0700100 return true; // we visit all classes.
101 }
102
103 private:
104 Instrumentation* const instrumentation_;
105};
106
Alex Light2c8206f2018-06-08 14:51:09 -0700107InstrumentationStackPopper::InstrumentationStackPopper(Thread* self)
108 : self_(self),
109 instrumentation_(Runtime::Current()->GetInstrumentation()),
110 frames_to_remove_(0) {}
111
112InstrumentationStackPopper::~InstrumentationStackPopper() {
113 std::deque<instrumentation::InstrumentationStackFrame>* stack = self_->GetInstrumentationStack();
114 for (size_t i = 0; i < frames_to_remove_; i++) {
115 stack->pop_front();
116 }
117}
118
119bool InstrumentationStackPopper::PopFramesTo(uint32_t desired_pops,
120 MutableHandle<mirror::Throwable>& exception) {
121 std::deque<instrumentation::InstrumentationStackFrame>* stack = self_->GetInstrumentationStack();
122 DCHECK_LE(frames_to_remove_, desired_pops);
123 DCHECK_GE(stack->size(), desired_pops);
124 DCHECK(!self_->IsExceptionPending());
125 if (!instrumentation_->HasMethodUnwindListeners()) {
126 frames_to_remove_ = desired_pops;
127 return true;
128 }
129 if (kVerboseInstrumentation) {
130 LOG(INFO) << "Popping frames for exception " << exception->Dump();
131 }
132 // The instrumentation events expect the exception to be set.
133 self_->SetException(exception.Get());
134 bool new_exception_thrown = false;
135 for (; frames_to_remove_ < desired_pops && !new_exception_thrown; frames_to_remove_++) {
136 InstrumentationStackFrame frame = stack->at(frames_to_remove_);
137 ArtMethod* method = frame.method_;
138 // Notify listeners of method unwind.
139 // TODO: improve the dex_pc information here.
140 uint32_t dex_pc = dex::kDexNoIndex;
141 if (kVerboseInstrumentation) {
142 LOG(INFO) << "Popping for unwind " << method->PrettyMethod();
143 }
144 if (!method->IsRuntimeMethod() && !frame.interpreter_entry_) {
145 instrumentation_->MethodUnwindEvent(self_, frame.this_object_, method, dex_pc);
146 new_exception_thrown = self_->GetException() != exception.Get();
147 }
148 }
149 exception.Assign(self_->GetException());
150 self_->ClearException();
151 if (kVerboseInstrumentation && new_exception_thrown) {
152 LOG(INFO) << "Failed to pop " << (desired_pops - frames_to_remove_)
153 << " frames due to new exception";
154 }
155 return !new_exception_thrown;
156}
Ian Rogers62d6c772013-02-27 08:32:07 -0800157
Mathieu Chartier3b05e9b2014-03-25 09:29:43 -0700158Instrumentation::Instrumentation()
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000159 : current_force_deopt_id_(0),
160 instrumentation_stubs_installed_(false),
Nicolas Geoffray5a23d2e2015-11-03 18:58:57 +0000161 entry_exit_stubs_installed_(false),
Mathieu Chartier3b05e9b2014-03-25 09:29:43 -0700162 interpreter_stubs_installed_(false),
Nicolas Geoffray5a23d2e2015-11-03 18:58:57 +0000163 interpret_only_(false),
164 forced_interpret_only_(false),
165 have_method_entry_listeners_(false),
166 have_method_exit_listeners_(false),
167 have_method_unwind_listeners_(false),
168 have_dex_pc_listeners_(false),
169 have_field_read_listeners_(false),
170 have_field_write_listeners_(false),
Alex Light6e1607e2017-08-23 10:06:18 -0700171 have_exception_thrown_listeners_(false),
Alex Lighte814f9d2017-07-31 16:14:39 -0700172 have_watched_frame_pop_listeners_(false),
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000173 have_branch_listeners_(false),
Alex Light9fb1ab12017-09-05 09:32:49 -0700174 have_exception_handled_listeners_(false),
Andreas Gampe7e56a072018-11-29 10:40:06 -0800175 deoptimized_methods_lock_(new ReaderWriterMutex("deoptimized methods lock",
176 kGenericBottomLock)),
Mathieu Chartier3b05e9b2014-03-25 09:29:43 -0700177 deoptimization_enabled_(false),
178 interpreter_handler_table_(kMainHandlerTable),
Mathieu Chartier50e93312016-03-16 11:25:29 -0700179 quick_alloc_entry_points_instrumentation_counter_(0),
Alex Light40607862019-05-06 18:16:24 +0000180 alloc_entrypoints_instrumented_(false),
181 can_use_instrumentation_trampolines_(true) {
Mathieu Chartier3b05e9b2014-03-25 09:29:43 -0700182}
183
Vladimir Marko19711d42019-04-12 14:05:34 +0100184void Instrumentation::InstallStubsForClass(ObjPtr<mirror::Class> klass) {
Vladimir Marko72ab6842017-01-20 19:32:50 +0000185 if (!klass->IsResolved()) {
Sebastien Hertza8a697f2015-01-15 12:28:47 +0100186 // We need the class to be resolved to install/uninstall stubs. Otherwise its methods
187 // could not be initialized or linked with regards to class inheritance.
Vladimir Marko72ab6842017-01-20 19:32:50 +0000188 } else if (klass->IsErroneousResolved()) {
189 // We can't execute code in a erroneous class: do nothing.
Sebastien Hertza8a697f2015-01-15 12:28:47 +0100190 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700191 for (ArtMethod& method : klass->GetMethods(kRuntimePointerSize)) {
Alex Light51a64d52015-12-17 13:55:59 -0800192 InstallStubsForMethod(&method);
Sebastien Hertza8a697f2015-01-15 12:28:47 +0100193 }
jeffhao725a9572012-11-13 18:20:12 -0800194 }
jeffhao725a9572012-11-13 18:20:12 -0800195}
196
Mathieu Chartiere401d142015-04-22 13:56:20 -0700197static void UpdateEntrypoints(ArtMethod* method, const void* quick_code)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700198 REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffrayd5a95872019-08-12 13:24:07 +0100199 if (kIsDebugBuild) {
200 jit::Jit* jit = Runtime::Current()->GetJit();
201 if (jit != nullptr && jit->GetCodeCache()->ContainsPc(quick_code)) {
202 // Ensure we always have the thumb entrypoint for JIT on arm32.
203 if (kRuntimeISA == InstructionSet::kArm) {
204 CHECK_EQ(reinterpret_cast<uintptr_t>(quick_code) & 1, 1u);
205 }
206 }
207 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800208 method->SetEntryPointFromQuickCompiledCode(quick_code);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100209}
210
Alex Light0fa17862017-10-24 13:43:05 -0700211bool Instrumentation::NeedDebugVersionFor(ArtMethod* method) const
212 REQUIRES_SHARED(Locks::mutator_lock_) {
Alex Lightf2858632018-04-02 11:28:50 -0700213 art::Runtime* runtime = Runtime::Current();
214 // If anything says we need the debug version or we are debuggable we will need the debug version
215 // of the method.
216 return (runtime->GetRuntimeCallbacks()->MethodNeedsDebugVersion(method) ||
217 runtime->IsJavaDebuggable()) &&
Mingyao Yang6ea1a0e2016-01-29 12:12:49 -0800218 !method->IsNative() &&
Alex Lightf2858632018-04-02 11:28:50 -0700219 !method->IsProxyMethod();
Mingyao Yang6ea1a0e2016-01-29 12:12:49 -0800220}
221
Mathieu Chartiere401d142015-04-22 13:56:20 -0700222void Instrumentation::InstallStubsForMethod(ArtMethod* method) {
Alex Light9139e002015-10-09 15:59:48 -0700223 if (!method->IsInvokable() || method->IsProxyMethod()) {
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100224 // Do not change stubs for these methods.
225 return;
226 }
Jeff Hao56802772014-08-19 10:17:36 -0700227 // Don't stub Proxy.<init>. Note that the Proxy class itself is not a proxy class.
Alex Light6cae5ea2018-06-07 17:07:02 -0700228 // TODO We should remove the need for this since it means we cannot always correctly detect calls
229 // to Proxy.<init>
230 // Annoyingly this can be called before we have actually initialized WellKnownClasses so therefore
231 // we also need to check this based on the declaring-class descriptor. The check is valid because
232 // Proxy only has a single constructor.
233 ArtMethod* well_known_proxy_init = jni::DecodeArtMethod(
234 WellKnownClasses::java_lang_reflect_Proxy_init);
235 if ((LIKELY(well_known_proxy_init != nullptr) && UNLIKELY(method == well_known_proxy_init)) ||
236 UNLIKELY(method->IsConstructor() &&
237 method->GetDeclaringClass()->DescriptorEquals("Ljava/lang/reflect/Proxy;"))) {
Jeff Haodb8a6642014-08-14 17:18:52 -0700238 return;
239 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800240 const void* new_quick_code;
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100241 bool uninstall = !entry_exit_stubs_installed_ && !interpreter_stubs_installed_;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800242 Runtime* const runtime = Runtime::Current();
243 ClassLinker* const class_linker = runtime->GetClassLinker();
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100244 bool is_class_initialized = method->GetDeclaringClass()->IsInitialized();
245 if (uninstall) {
246 if ((forced_interpret_only_ || IsDeoptimized(method)) && !method->IsNative()) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800247 new_quick_code = GetQuickToInterpreterBridge();
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100248 } else if (is_class_initialized || !method->IsStatic() || method->IsConstructor()) {
Alex Light3e36a9c2018-06-19 09:45:05 -0700249 new_quick_code = GetCodeForInvoke(method);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100250 } else {
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700251 new_quick_code = GetQuickResolutionStub();
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100252 }
253 } else { // !uninstall
Sebastien Hertzbae182c2013-12-17 10:42:03 +0100254 if ((interpreter_stubs_installed_ || forced_interpret_only_ || IsDeoptimized(method)) &&
255 !method->IsNative()) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800256 new_quick_code = GetQuickToInterpreterBridge();
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100257 } else {
258 // Do not overwrite resolution trampoline. When the trampoline initializes the method's
259 // class, all its static methods code will be set to the instrumentation entry point.
260 // For more details, see ClassLinker::FixupStaticTrampolines.
261 if (is_class_initialized || !method->IsStatic() || method->IsConstructor()) {
Alex Light2d441b12018-06-08 15:33:21 -0700262 if (entry_exit_stubs_installed_) {
263 // This needs to be checked first since the instrumentation entrypoint will be able to
264 // find the actual JIT compiled code that corresponds to this method.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800265 new_quick_code = GetQuickInstrumentationEntryPoint();
Alex Light2d441b12018-06-08 15:33:21 -0700266 } else if (NeedDebugVersionFor(method)) {
267 // It would be great to search the JIT for its implementation here but we cannot due to
268 // the locks we hold. Instead just set to the interpreter bridge and that code will search
269 // the JIT when it gets called and replace the entrypoint then.
270 new_quick_code = GetQuickToInterpreterBridge();
Nicolas Geoffraya0619e22016-12-20 13:57:43 +0000271 } else {
Alex Lightfc49fec2018-01-16 22:28:36 +0000272 new_quick_code = class_linker->GetQuickOatCodeFor(method);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100273 }
274 } else {
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700275 new_quick_code = GetQuickResolutionStub();
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100276 }
277 }
278 }
Elliott Hughes956af0f2014-12-11 14:34:28 -0800279 UpdateEntrypoints(method, new_quick_code);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100280}
281
Ian Rogers62d6c772013-02-27 08:32:07 -0800282// Places the instrumentation exit pc as the return PC for every quick frame. This also allows
283// deoptimization of quick frames to interpreter frames.
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100284// Since we may already have done this previously, we need to push new instrumentation frame before
285// existing instrumentation frames.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000286void InstrumentationInstallStack(Thread* thread, void* arg)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700287 REQUIRES_SHARED(Locks::mutator_lock_) {
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100288 struct InstallStackVisitor final : public StackVisitor {
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000289 InstallStackVisitor(Thread* thread_in,
290 Context* context,
291 uintptr_t instrumentation_exit_pc,
292 uint64_t force_deopt_id)
Nicolas Geoffray8e5bd182015-05-06 11:34:34 +0100293 : StackVisitor(thread_in, context, kInstrumentationStackWalk),
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800294 instrumentation_stack_(thread_in->GetInstrumentationStack()),
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100295 instrumentation_exit_pc_(instrumentation_exit_pc),
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000296 reached_existing_instrumentation_frames_(false),
297 instrumentation_stack_depth_(0),
298 last_return_pc_(0),
299 force_deopt_id_(force_deopt_id) {}
jeffhao725a9572012-11-13 18:20:12 -0800300
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100301 bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700302 ArtMethod* m = GetMethod();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700303 if (m == nullptr) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800304 if (kVerboseInstrumentation) {
305 LOG(INFO) << " Skipping upcall. Frame " << GetFrameId();
306 }
307 last_return_pc_ = 0;
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700308 return true; // Ignore upcalls.
Ian Rogers306057f2012-11-26 12:45:53 -0800309 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700310 if (GetCurrentQuickFrame() == nullptr) {
Elliott Hughes956af0f2014-12-11 14:34:28 -0800311 bool interpreter_frame = true;
Vladimir Markoabedfca2019-05-23 14:07:47 +0100312 InstrumentationStackFrame instrumentation_frame(GetThisObject().Ptr(),
313 m,
314 /*return_pc=*/ 0,
315 GetFrameId(),
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000316 interpreter_frame,
317 force_deopt_id_);
Jeff Haoa15a81b2014-05-27 18:25:47 -0700318 if (kVerboseInstrumentation) {
319 LOG(INFO) << "Pushing shadow frame " << instrumentation_frame.Dump();
320 }
321 shadow_stack_.push_back(instrumentation_frame);
322 return true; // Continue.
323 }
Ian Rogers62d6c772013-02-27 08:32:07 -0800324 uintptr_t return_pc = GetReturnPc();
Sebastien Hertz320deb22014-06-11 19:45:05 +0200325 if (kVerboseInstrumentation) {
326 LOG(INFO) << " Installing exit stub in " << DescribeLocation();
327 }
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100328 if (return_pc == instrumentation_exit_pc_) {
Mingyao Yang2ee17902017-08-30 11:37:08 -0700329 CHECK_LT(instrumentation_stack_depth_, instrumentation_stack_->size());
330
331 if (m->IsRuntimeMethod()) {
332 const InstrumentationStackFrame& frame =
Vladimir Marko35d5b8a2018-07-03 09:18:32 +0100333 (*instrumentation_stack_)[instrumentation_stack_depth_];
Mingyao Yang2ee17902017-08-30 11:37:08 -0700334 if (frame.interpreter_entry_) {
335 // This instrumentation frame is for an interpreter bridge and is
336 // pushed when executing the instrumented interpreter bridge. So method
337 // enter event must have been reported. However we need to push a DEX pc
338 // into the dex_pcs_ list to match size of instrumentation stack.
Andreas Gampee2abbc62017-09-15 11:59:26 -0700339 uint32_t dex_pc = dex::kDexNoIndex;
Mingyao Yang2ee17902017-08-30 11:37:08 -0700340 dex_pcs_.push_back(dex_pc);
341 last_return_pc_ = frame.return_pc_;
342 ++instrumentation_stack_depth_;
343 return true;
344 }
345 }
346
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100347 // We've reached a frame which has already been installed with instrumentation exit stub.
Alex Light74c91c92018-03-08 14:01:44 -0800348 // We should have already installed instrumentation or be interpreter on previous frames.
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100349 reached_existing_instrumentation_frames_ = true;
350
Daniel Mihalyica1d06c2014-08-18 18:45:31 +0200351 const InstrumentationStackFrame& frame =
Vladimir Marko35d5b8a2018-07-03 09:18:32 +0100352 (*instrumentation_stack_)[instrumentation_stack_depth_];
Alex Lightfc81d802018-12-07 13:39:05 -0800353 CHECK_EQ(m->GetNonObsoleteMethod(), frame.method_->GetNonObsoleteMethod())
354 << "Expected " << ArtMethod::PrettyMethod(m)
355 << ", Found " << ArtMethod::PrettyMethod(frame.method_);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100356 return_pc = frame.return_pc_;
357 if (kVerboseInstrumentation) {
358 LOG(INFO) << "Ignoring already instrumented " << frame.Dump();
359 }
360 } else {
361 CHECK_NE(return_pc, 0U);
Alex Light74c91c92018-03-08 14:01:44 -0800362 if (UNLIKELY(reached_existing_instrumentation_frames_ && !m->IsRuntimeMethod())) {
363 // We already saw an existing instrumentation frame so this should be a runtime-method
364 // inserted by the interpreter or runtime.
Alex Lighte9278662018-03-08 16:55:58 -0800365 std::string thread_name;
366 GetThread()->GetThreadName(thread_name);
367 uint32_t dex_pc = dex::kDexNoIndex;
368 if (last_return_pc_ != 0 &&
369 GetCurrentOatQuickMethodHeader() != nullptr) {
370 dex_pc = GetCurrentOatQuickMethodHeader()->ToDexPc(m, last_return_pc_);
371 }
Alex Light74c91c92018-03-08 14:01:44 -0800372 LOG(FATAL) << "While walking " << thread_name << " found unexpected non-runtime method"
373 << " without instrumentation exit return or interpreter frame."
Alex Lighte9278662018-03-08 16:55:58 -0800374 << " method is " << GetMethod()->PrettyMethod()
375 << " return_pc is " << std::hex << return_pc
376 << " dex pc: " << dex_pc;
377 UNREACHABLE();
378 }
Mingyao Yang2ee17902017-08-30 11:37:08 -0700379 InstrumentationStackFrame instrumentation_frame(
Vladimir Markoabedfca2019-05-23 14:07:47 +0100380 m->IsRuntimeMethod() ? nullptr : GetThisObject().Ptr(),
Mingyao Yang2ee17902017-08-30 11:37:08 -0700381 m,
382 return_pc,
383 GetFrameId(), // A runtime method still gets a frame id.
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000384 false,
385 force_deopt_id_);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100386 if (kVerboseInstrumentation) {
387 LOG(INFO) << "Pushing frame " << instrumentation_frame.Dump();
388 }
389
Sebastien Hertz320deb22014-06-11 19:45:05 +0200390 // Insert frame at the right position so we do not corrupt the instrumentation stack.
391 // Instrumentation stack frames are in descending frame id order.
392 auto it = instrumentation_stack_->begin();
393 for (auto end = instrumentation_stack_->end(); it != end; ++it) {
394 const InstrumentationStackFrame& current = *it;
395 if (instrumentation_frame.frame_id_ >= current.frame_id_) {
396 break;
397 }
398 }
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100399 instrumentation_stack_->insert(it, instrumentation_frame);
400 SetReturnPc(instrumentation_exit_pc_);
Ian Rogers62d6c772013-02-27 08:32:07 -0800401 }
Andreas Gampee2abbc62017-09-15 11:59:26 -0700402 uint32_t dex_pc = dex::kDexNoIndex;
Mingyao Yang2ee17902017-08-30 11:37:08 -0700403 if (last_return_pc_ != 0 &&
404 GetCurrentOatQuickMethodHeader() != nullptr) {
405 dex_pc = GetCurrentOatQuickMethodHeader()->ToDexPc(m, last_return_pc_);
406 }
407 dex_pcs_.push_back(dex_pc);
Ian Rogers62d6c772013-02-27 08:32:07 -0800408 last_return_pc_ = return_pc;
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100409 ++instrumentation_stack_depth_;
Ian Rogers306057f2012-11-26 12:45:53 -0800410 return true; // Continue.
411 }
Ian Rogers62d6c772013-02-27 08:32:07 -0800412 std::deque<InstrumentationStackFrame>* const instrumentation_stack_;
Jeff Haoa15a81b2014-05-27 18:25:47 -0700413 std::vector<InstrumentationStackFrame> shadow_stack_;
Ian Rogers62d6c772013-02-27 08:32:07 -0800414 std::vector<uint32_t> dex_pcs_;
Ian Rogers306057f2012-11-26 12:45:53 -0800415 const uintptr_t instrumentation_exit_pc_;
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100416 bool reached_existing_instrumentation_frames_;
417 size_t instrumentation_stack_depth_;
Ian Rogers62d6c772013-02-27 08:32:07 -0800418 uintptr_t last_return_pc_;
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000419 uint64_t force_deopt_id_;
Ian Rogers306057f2012-11-26 12:45:53 -0800420 };
Ian Rogers62d6c772013-02-27 08:32:07 -0800421 if (kVerboseInstrumentation) {
422 std::string thread_name;
423 thread->GetThreadName(thread_name);
424 LOG(INFO) << "Installing exit stubs in " << thread_name;
Ian Rogers306057f2012-11-26 12:45:53 -0800425 }
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100426
427 Instrumentation* instrumentation = reinterpret_cast<Instrumentation*>(arg);
Ian Rogers700a4022014-05-19 16:49:03 -0700428 std::unique_ptr<Context> context(Context::Create());
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700429 uintptr_t instrumentation_exit_pc = reinterpret_cast<uintptr_t>(GetQuickInstrumentationExitPc());
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000430 InstallStackVisitor visitor(
431 thread, context.get(), instrumentation_exit_pc, instrumentation->current_force_deopt_id_);
Ian Rogers62d6c772013-02-27 08:32:07 -0800432 visitor.WalkStack(true);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100433 CHECK_EQ(visitor.dex_pcs_.size(), thread->GetInstrumentationStack()->size());
Ian Rogers62d6c772013-02-27 08:32:07 -0800434
Sebastien Hertz7ec2f1c2014-03-27 20:06:47 +0100435 if (instrumentation->ShouldNotifyMethodEnterExitEvents()) {
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100436 // Create method enter events for all methods currently on the thread's stack. We only do this
437 // if no debugger is attached to prevent from posting events twice.
Jeff Haoa15a81b2014-05-27 18:25:47 -0700438 auto ssi = visitor.shadow_stack_.rbegin();
439 for (auto isi = thread->GetInstrumentationStack()->rbegin(),
440 end = thread->GetInstrumentationStack()->rend(); isi != end; ++isi) {
441 while (ssi != visitor.shadow_stack_.rend() && (*ssi).frame_id_ < (*isi).frame_id_) {
442 instrumentation->MethodEnterEvent(thread, (*ssi).this_object_, (*ssi).method_, 0);
443 ++ssi;
444 }
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100445 uint32_t dex_pc = visitor.dex_pcs_.back();
446 visitor.dex_pcs_.pop_back();
Alex Lightdc5423f2018-06-08 10:43:38 -0700447 if (!isi->interpreter_entry_ && !isi->method_->IsRuntimeMethod()) {
Sebastien Hertz320deb22014-06-11 19:45:05 +0200448 instrumentation->MethodEnterEvent(thread, (*isi).this_object_, (*isi).method_, dex_pc);
449 }
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100450 }
Ian Rogers62d6c772013-02-27 08:32:07 -0800451 }
452 thread->VerifyStack();
Ian Rogers306057f2012-11-26 12:45:53 -0800453}
454
Mingyao Yang99170c62015-07-06 11:10:37 -0700455void Instrumentation::InstrumentThreadStack(Thread* thread) {
456 instrumentation_stubs_installed_ = true;
457 InstrumentationInstallStack(thread, this);
458}
459
Ian Rogers62d6c772013-02-27 08:32:07 -0800460// Removes the instrumentation exit pc as the return PC for every quick frame.
461static void InstrumentationRestoreStack(Thread* thread, void* arg)
Nicolas Geoffray5a23d2e2015-11-03 18:58:57 +0000462 REQUIRES(Locks::mutator_lock_) {
463 Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
464
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100465 struct RestoreStackVisitor final : public StackVisitor {
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800466 RestoreStackVisitor(Thread* thread_in, uintptr_t instrumentation_exit_pc,
Ian Rogers62d6c772013-02-27 08:32:07 -0800467 Instrumentation* instrumentation)
Nicolas Geoffray8e5bd182015-05-06 11:34:34 +0100468 : StackVisitor(thread_in, nullptr, kInstrumentationStackWalk),
469 thread_(thread_in),
Ian Rogers62d6c772013-02-27 08:32:07 -0800470 instrumentation_exit_pc_(instrumentation_exit_pc),
471 instrumentation_(instrumentation),
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800472 instrumentation_stack_(thread_in->GetInstrumentationStack()),
Ian Rogers62d6c772013-02-27 08:32:07 -0800473 frames_removed_(0) {}
Ian Rogers306057f2012-11-26 12:45:53 -0800474
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100475 bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800476 if (instrumentation_stack_->size() == 0) {
jeffhao725a9572012-11-13 18:20:12 -0800477 return false; // Stop.
478 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700479 ArtMethod* m = GetMethod();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700480 if (GetCurrentQuickFrame() == nullptr) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800481 if (kVerboseInstrumentation) {
Daniel Mihalyica1d06c2014-08-18 18:45:31 +0200482 LOG(INFO) << " Ignoring a shadow frame. Frame " << GetFrameId()
David Sehr709b0702016-10-13 09:12:37 -0700483 << " Method=" << ArtMethod::PrettyMethod(m);
Ian Rogers62d6c772013-02-27 08:32:07 -0800484 }
485 return true; // Ignore shadow frames.
486 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700487 if (m == nullptr) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800488 if (kVerboseInstrumentation) {
489 LOG(INFO) << " Skipping upcall. Frame " << GetFrameId();
490 }
Ian Rogers306057f2012-11-26 12:45:53 -0800491 return true; // Ignore upcalls.
492 }
Ian Rogers62d6c772013-02-27 08:32:07 -0800493 bool removed_stub = false;
494 // TODO: make this search more efficient?
Sebastien Hertz7ec2f1c2014-03-27 20:06:47 +0100495 const size_t frameId = GetFrameId();
496 for (const InstrumentationStackFrame& instrumentation_frame : *instrumentation_stack_) {
497 if (instrumentation_frame.frame_id_ == frameId) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800498 if (kVerboseInstrumentation) {
499 LOG(INFO) << " Removing exit stub in " << DescribeLocation();
500 }
Jeff Hao9a916d32013-06-27 18:45:37 -0700501 if (instrumentation_frame.interpreter_entry_) {
Andreas Gampe8228cdf2017-05-30 15:03:54 -0700502 CHECK(m == Runtime::Current()->GetCalleeSaveMethod(CalleeSaveType::kSaveRefsAndArgs));
Jeff Hao9a916d32013-06-27 18:45:37 -0700503 } else {
Alex Lightfc81d802018-12-07 13:39:05 -0800504 CHECK_EQ(m->GetNonObsoleteMethod(),
505 instrumentation_frame.method_->GetNonObsoleteMethod())
506 << ArtMethod::PrettyMethod(m);
Jeff Hao9a916d32013-06-27 18:45:37 -0700507 }
Ian Rogers62d6c772013-02-27 08:32:07 -0800508 SetReturnPc(instrumentation_frame.return_pc_);
Mingyao Yang2ee17902017-08-30 11:37:08 -0700509 if (instrumentation_->ShouldNotifyMethodEnterExitEvents() &&
510 !m->IsRuntimeMethod()) {
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100511 // Create the method exit events. As the methods didn't really exit the result is 0.
512 // We only do this if no debugger is attached to prevent from posting events twice.
Alex Lightb7c640d2019-03-20 15:52:13 -0700513 JValue val;
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100514 instrumentation_->MethodExitEvent(thread_, instrumentation_frame.this_object_, m,
Alex Lightb7c640d2019-03-20 15:52:13 -0700515 GetDexPc(), OptionalFrame{}, val);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100516 }
Ian Rogers62d6c772013-02-27 08:32:07 -0800517 frames_removed_++;
518 removed_stub = true;
519 break;
520 }
521 }
522 if (!removed_stub) {
523 if (kVerboseInstrumentation) {
524 LOG(INFO) << " No exit stub in " << DescribeLocation();
Ian Rogers306057f2012-11-26 12:45:53 -0800525 }
jeffhao725a9572012-11-13 18:20:12 -0800526 }
527 return true; // Continue.
528 }
Ian Rogers62d6c772013-02-27 08:32:07 -0800529 Thread* const thread_;
Ian Rogers306057f2012-11-26 12:45:53 -0800530 const uintptr_t instrumentation_exit_pc_;
Ian Rogers62d6c772013-02-27 08:32:07 -0800531 Instrumentation* const instrumentation_;
532 std::deque<instrumentation::InstrumentationStackFrame>* const instrumentation_stack_;
533 size_t frames_removed_;
jeffhao725a9572012-11-13 18:20:12 -0800534 };
Ian Rogers62d6c772013-02-27 08:32:07 -0800535 if (kVerboseInstrumentation) {
536 std::string thread_name;
537 thread->GetThreadName(thread_name);
538 LOG(INFO) << "Removing exit stubs in " << thread_name;
539 }
540 std::deque<instrumentation::InstrumentationStackFrame>* stack = thread->GetInstrumentationStack();
541 if (stack->size() > 0) {
542 Instrumentation* instrumentation = reinterpret_cast<Instrumentation*>(arg);
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700543 uintptr_t instrumentation_exit_pc =
544 reinterpret_cast<uintptr_t>(GetQuickInstrumentationExitPc());
Ian Rogers62d6c772013-02-27 08:32:07 -0800545 RestoreStackVisitor visitor(thread, instrumentation_exit_pc, instrumentation);
546 visitor.WalkStack(true);
547 CHECK_EQ(visitor.frames_removed_, stack->size());
548 while (stack->size() > 0) {
549 stack->pop_front();
550 }
jeffhao725a9572012-11-13 18:20:12 -0800551 }
552}
553
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000554void Instrumentation::DeoptimizeAllThreadFrames() {
555 Thread* self = Thread::Current();
556 MutexLock mu(self, *Locks::thread_list_lock_);
557 ThreadList* tl = Runtime::Current()->GetThreadList();
558 tl->ForEach([&](Thread* t) {
559 Locks::mutator_lock_->AssertExclusiveHeld(self);
560 InstrumentThreadStack(t);
561 });
562 current_force_deopt_id_++;
563}
564
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200565static bool HasEvent(Instrumentation::InstrumentationEvent expected, uint32_t events) {
566 return (events & expected) != 0;
567}
568
Nicolas Geoffray514a6162015-11-03 11:44:24 +0000569static void PotentiallyAddListenerTo(Instrumentation::InstrumentationEvent event,
570 uint32_t events,
571 std::list<InstrumentationListener*>& list,
572 InstrumentationListener* listener,
573 bool* has_listener)
574 REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::classlinker_classes_lock_) {
575 Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
576 if (!HasEvent(event, events)) {
577 return;
578 }
579 // If there is a free slot in the list, we insert the listener in that slot.
580 // Otherwise we add it to the end of the list.
581 auto it = std::find(list.begin(), list.end(), nullptr);
582 if (it != list.end()) {
583 *it = listener;
584 } else {
585 list.push_back(listener);
586 }
David Srbecky28f6cff2018-10-16 15:07:28 +0100587 Runtime::DoAndMaybeSwitchInterpreter([=](){ *has_listener = true; });
Nicolas Geoffray514a6162015-11-03 11:44:24 +0000588}
589
Ian Rogers62d6c772013-02-27 08:32:07 -0800590void Instrumentation::AddListener(InstrumentationListener* listener, uint32_t events) {
591 Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
Nicolas Geoffray514a6162015-11-03 11:44:24 +0000592 PotentiallyAddListenerTo(kMethodEntered,
593 events,
594 method_entry_listeners_,
595 listener,
596 &have_method_entry_listeners_);
597 PotentiallyAddListenerTo(kMethodExited,
598 events,
599 method_exit_listeners_,
600 listener,
601 &have_method_exit_listeners_);
602 PotentiallyAddListenerTo(kMethodUnwind,
603 events,
604 method_unwind_listeners_,
605 listener,
606 &have_method_unwind_listeners_);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000607 PotentiallyAddListenerTo(kBranch,
Nicolas Geoffray514a6162015-11-03 11:44:24 +0000608 events,
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000609 branch_listeners_,
Nicolas Geoffray514a6162015-11-03 11:44:24 +0000610 listener,
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000611 &have_branch_listeners_);
Nicolas Geoffray514a6162015-11-03 11:44:24 +0000612 PotentiallyAddListenerTo(kDexPcMoved,
613 events,
614 dex_pc_listeners_,
615 listener,
616 &have_dex_pc_listeners_);
617 PotentiallyAddListenerTo(kFieldRead,
618 events,
619 field_read_listeners_,
620 listener,
621 &have_field_read_listeners_);
622 PotentiallyAddListenerTo(kFieldWritten,
623 events,
624 field_write_listeners_,
625 listener,
626 &have_field_write_listeners_);
Alex Light6e1607e2017-08-23 10:06:18 -0700627 PotentiallyAddListenerTo(kExceptionThrown,
Nicolas Geoffray514a6162015-11-03 11:44:24 +0000628 events,
Alex Light6e1607e2017-08-23 10:06:18 -0700629 exception_thrown_listeners_,
Nicolas Geoffray514a6162015-11-03 11:44:24 +0000630 listener,
Alex Light6e1607e2017-08-23 10:06:18 -0700631 &have_exception_thrown_listeners_);
Alex Lighte814f9d2017-07-31 16:14:39 -0700632 PotentiallyAddListenerTo(kWatchedFramePop,
633 events,
634 watched_frame_pop_listeners_,
635 listener,
636 &have_watched_frame_pop_listeners_);
Alex Light9fb1ab12017-09-05 09:32:49 -0700637 PotentiallyAddListenerTo(kExceptionHandled,
638 events,
639 exception_handled_listeners_,
640 listener,
641 &have_exception_handled_listeners_);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200642 UpdateInterpreterHandlerTable();
jeffhao725a9572012-11-13 18:20:12 -0800643}
644
Nicolas Geoffray514a6162015-11-03 11:44:24 +0000645static void PotentiallyRemoveListenerFrom(Instrumentation::InstrumentationEvent event,
646 uint32_t events,
647 std::list<InstrumentationListener*>& list,
648 InstrumentationListener* listener,
649 bool* has_listener)
650 REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::classlinker_classes_lock_) {
651 Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
652 if (!HasEvent(event, events)) {
653 return;
654 }
655 auto it = std::find(list.begin(), list.end(), listener);
656 if (it != list.end()) {
657 // Just update the entry, do not remove from the list. Removing entries in the list
658 // is unsafe when mutators are iterating over it.
659 *it = nullptr;
660 }
661
662 // Check if the list contains any non-null listener, and update 'has_listener'.
663 for (InstrumentationListener* l : list) {
664 if (l != nullptr) {
David Srbecky28f6cff2018-10-16 15:07:28 +0100665 Runtime::DoAndMaybeSwitchInterpreter([=](){ *has_listener = true; });
Nicolas Geoffray514a6162015-11-03 11:44:24 +0000666 return;
667 }
668 }
David Srbecky28f6cff2018-10-16 15:07:28 +0100669 Runtime::DoAndMaybeSwitchInterpreter([=](){ *has_listener = false; });
Nicolas Geoffray514a6162015-11-03 11:44:24 +0000670}
671
Ian Rogers62d6c772013-02-27 08:32:07 -0800672void Instrumentation::RemoveListener(InstrumentationListener* listener, uint32_t events) {
673 Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
Nicolas Geoffray514a6162015-11-03 11:44:24 +0000674 PotentiallyRemoveListenerFrom(kMethodEntered,
675 events,
676 method_entry_listeners_,
677 listener,
678 &have_method_entry_listeners_);
679 PotentiallyRemoveListenerFrom(kMethodExited,
680 events,
681 method_exit_listeners_,
682 listener,
683 &have_method_exit_listeners_);
684 PotentiallyRemoveListenerFrom(kMethodUnwind,
685 events,
686 method_unwind_listeners_,
687 listener,
688 &have_method_unwind_listeners_);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000689 PotentiallyRemoveListenerFrom(kBranch,
Nicolas Geoffray514a6162015-11-03 11:44:24 +0000690 events,
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000691 branch_listeners_,
Nicolas Geoffray514a6162015-11-03 11:44:24 +0000692 listener,
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000693 &have_branch_listeners_);
Nicolas Geoffray514a6162015-11-03 11:44:24 +0000694 PotentiallyRemoveListenerFrom(kDexPcMoved,
695 events,
696 dex_pc_listeners_,
697 listener,
698 &have_dex_pc_listeners_);
699 PotentiallyRemoveListenerFrom(kFieldRead,
700 events,
701 field_read_listeners_,
702 listener,
703 &have_field_read_listeners_);
704 PotentiallyRemoveListenerFrom(kFieldWritten,
705 events,
706 field_write_listeners_,
707 listener,
708 &have_field_write_listeners_);
Alex Light6e1607e2017-08-23 10:06:18 -0700709 PotentiallyRemoveListenerFrom(kExceptionThrown,
Nicolas Geoffray514a6162015-11-03 11:44:24 +0000710 events,
Alex Light6e1607e2017-08-23 10:06:18 -0700711 exception_thrown_listeners_,
Nicolas Geoffray514a6162015-11-03 11:44:24 +0000712 listener,
Alex Light6e1607e2017-08-23 10:06:18 -0700713 &have_exception_thrown_listeners_);
Alex Lighte814f9d2017-07-31 16:14:39 -0700714 PotentiallyRemoveListenerFrom(kWatchedFramePop,
715 events,
716 watched_frame_pop_listeners_,
717 listener,
718 &have_watched_frame_pop_listeners_);
Alex Light9fb1ab12017-09-05 09:32:49 -0700719 PotentiallyRemoveListenerFrom(kExceptionHandled,
720 events,
721 exception_handled_listeners_,
722 listener,
723 &have_exception_handled_listeners_);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200724 UpdateInterpreterHandlerTable();
jeffhao725a9572012-11-13 18:20:12 -0800725}
726
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200727Instrumentation::InstrumentationLevel Instrumentation::GetCurrentInstrumentationLevel() const {
Alex Light4ba388a2017-01-27 10:26:49 -0800728 if (interpreter_stubs_installed_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200729 return InstrumentationLevel::kInstrumentWithInterpreter;
Ian Rogers62d6c772013-02-27 08:32:07 -0800730 } else if (entry_exit_stubs_installed_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200731 return InstrumentationLevel::kInstrumentWithInstrumentationStubs;
Ian Rogers62d6c772013-02-27 08:32:07 -0800732 } else {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200733 return InstrumentationLevel::kInstrumentNothing;
Ian Rogers62d6c772013-02-27 08:32:07 -0800734 }
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200735}
736
Alex Lightdba61482016-12-21 08:20:29 -0800737bool Instrumentation::RequiresInstrumentationInstallation(InstrumentationLevel new_level) const {
Alex Light4ba388a2017-01-27 10:26:49 -0800738 // We need to reinstall instrumentation if we go to a different level.
739 return GetCurrentInstrumentationLevel() != new_level;
Alex Lightdba61482016-12-21 08:20:29 -0800740}
741
Alex Light40607862019-05-06 18:16:24 +0000742void Instrumentation::UpdateInstrumentationLevels(InstrumentationLevel level) {
743 if (level == InstrumentationLevel::kInstrumentWithInterpreter) {
744 can_use_instrumentation_trampolines_ = false;
745 }
746 if (UNLIKELY(!can_use_instrumentation_trampolines_)) {
747 for (auto& p : requested_instrumentation_levels_) {
748 if (p.second == InstrumentationLevel::kInstrumentWithInstrumentationStubs) {
749 p.second = InstrumentationLevel::kInstrumentWithInterpreter;
750 }
751 }
752 }
753}
754
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200755void Instrumentation::ConfigureStubs(const char* key, InstrumentationLevel desired_level) {
756 // Store the instrumentation level for this key or remove it.
757 if (desired_level == InstrumentationLevel::kInstrumentNothing) {
758 // The client no longer needs instrumentation.
759 requested_instrumentation_levels_.erase(key);
760 } else {
761 // The client needs instrumentation.
762 requested_instrumentation_levels_.Overwrite(key, desired_level);
763 }
764
Alex Light40607862019-05-06 18:16:24 +0000765 UpdateInstrumentationLevels(desired_level);
766 UpdateStubs();
767}
768
769void Instrumentation::EnableSingleThreadDeopt() {
770 // Single-thread deopt only uses interpreter.
771 can_use_instrumentation_trampolines_ = false;
772 UpdateInstrumentationLevels(InstrumentationLevel::kInstrumentWithInterpreter);
773 UpdateStubs();
774}
775
776void Instrumentation::UpdateStubs() {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200777 // Look for the highest required instrumentation level.
778 InstrumentationLevel requested_level = InstrumentationLevel::kInstrumentNothing;
779 for (const auto& v : requested_instrumentation_levels_) {
780 requested_level = std::max(requested_level, v.second);
781 }
782
Alex Light40607862019-05-06 18:16:24 +0000783 DCHECK(can_use_instrumentation_trampolines_ ||
784 requested_level != InstrumentationLevel::kInstrumentWithInstrumentationStubs)
785 << "Use trampolines: " << can_use_instrumentation_trampolines_ << " level "
786 << requested_level;
787
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200788 interpret_only_ = (requested_level == InstrumentationLevel::kInstrumentWithInterpreter) ||
789 forced_interpret_only_;
790
Alex Lightdba61482016-12-21 08:20:29 -0800791 if (!RequiresInstrumentationInstallation(requested_level)) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800792 // We're already set.
793 return;
794 }
Sebastien Hertz7ec2f1c2014-03-27 20:06:47 +0100795 Thread* const self = Thread::Current();
Ian Rogers62d6c772013-02-27 08:32:07 -0800796 Runtime* runtime = Runtime::Current();
Sebastien Hertza8a697f2015-01-15 12:28:47 +0100797 Locks::mutator_lock_->AssertExclusiveHeld(self);
Ian Rogers62d6c772013-02-27 08:32:07 -0800798 Locks::thread_list_lock_->AssertNotHeld(self);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200799 if (requested_level > InstrumentationLevel::kInstrumentNothing) {
Alex Light4ba388a2017-01-27 10:26:49 -0800800 if (requested_level == InstrumentationLevel::kInstrumentWithInterpreter) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800801 interpreter_stubs_installed_ = true;
Ian Rogers62d6c772013-02-27 08:32:07 -0800802 entry_exit_stubs_installed_ = true;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200803 } else {
804 CHECK_EQ(requested_level, InstrumentationLevel::kInstrumentWithInstrumentationStubs);
805 entry_exit_stubs_installed_ = true;
806 interpreter_stubs_installed_ = false;
Ian Rogers62d6c772013-02-27 08:32:07 -0800807 }
Mathieu Chartiere0671ce2015-07-28 17:23:28 -0700808 InstallStubsClassVisitor visitor(this);
809 runtime->GetClassLinker()->VisitClasses(&visitor);
Ian Rogers62d6c772013-02-27 08:32:07 -0800810 instrumentation_stubs_installed_ = true;
Sebastien Hertz7ec2f1c2014-03-27 20:06:47 +0100811 MutexLock mu(self, *Locks::thread_list_lock_);
Ian Rogers62d6c772013-02-27 08:32:07 -0800812 runtime->GetThreadList()->ForEach(InstrumentationInstallStack, this);
813 } else {
814 interpreter_stubs_installed_ = false;
815 entry_exit_stubs_installed_ = false;
Mathieu Chartiere0671ce2015-07-28 17:23:28 -0700816 InstallStubsClassVisitor visitor(this);
817 runtime->GetClassLinker()->VisitClasses(&visitor);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100818 // Restore stack only if there is no method currently deoptimized.
Mathieu Chartier3b05e9b2014-03-25 09:29:43 -0700819 bool empty;
820 {
Andreas Gampe7e56a072018-11-29 10:40:06 -0800821 ReaderMutexLock mu(self, *GetDeoptimizedMethodsLock());
Hiroshi Yamauchi799eb3a2014-07-18 15:38:17 -0700822 empty = IsDeoptimizedMethodsEmpty(); // Avoid lock violation.
Mathieu Chartier3b05e9b2014-03-25 09:29:43 -0700823 }
824 if (empty) {
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100825 MutexLock mu(self, *Locks::thread_list_lock_);
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +0000826 bool no_remaining_deopts = true;
827 // Check that there are no other forced deoptimizations. Do it here so we only need to lock
828 // thread_list_lock once.
829 runtime->GetThreadList()->ForEach([&](Thread* t) {
830 no_remaining_deopts =
831 no_remaining_deopts && !t->IsForceInterpreter() &&
832 std::all_of(t->GetInstrumentationStack()->cbegin(),
833 t->GetInstrumentationStack()->cend(),
834 [&](const auto& frame) REQUIRES_SHARED(Locks::mutator_lock_) {
835 return frame.force_deopt_id_ == current_force_deopt_id_;
836 });
837 });
838 if (no_remaining_deopts) {
839 Runtime::Current()->GetThreadList()->ForEach(InstrumentationRestoreStack, this);
840 // Only do this after restoring, as walking the stack when restoring will see
841 // the instrumentation exit pc.
842 instrumentation_stubs_installed_ = false;
843 }
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100844 }
Ian Rogers62d6c772013-02-27 08:32:07 -0800845 }
jeffhao725a9572012-11-13 18:20:12 -0800846}
847
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200848static void ResetQuickAllocEntryPointsForThread(Thread* thread, void* arg ATTRIBUTE_UNUSED) {
Mathieu Chartier5ace2012016-11-30 10:15:41 -0800849 thread->ResetQuickAllocEntryPointsForThread(kUseReadBarrier && thread->GetIsGcMarking());
Ian Rogersfa824272013-11-05 16:12:57 -0800850}
851
Mathieu Chartier9ef78b52014-09-25 17:03:12 -0700852void Instrumentation::SetEntrypointsInstrumented(bool instrumented) {
853 Thread* self = Thread::Current();
Mathieu Chartier661974a2014-01-09 11:23:53 -0800854 Runtime* runtime = Runtime::Current();
Mathieu Chartier9ef78b52014-09-25 17:03:12 -0700855 Locks::mutator_lock_->AssertNotHeld(self);
856 Locks::instrument_entrypoints_lock_->AssertHeld(self);
857 if (runtime->IsStarted()) {
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700858 ScopedSuspendAll ssa(__FUNCTION__);
Mathieu Chartier9ef78b52014-09-25 17:03:12 -0700859 MutexLock mu(self, *Locks::runtime_shutdown_lock_);
Mathieu Chartier661974a2014-01-09 11:23:53 -0800860 SetQuickAllocEntryPointsInstrumented(instrumented);
861 ResetQuickAllocEntryPoints();
Mathieu Chartier50e93312016-03-16 11:25:29 -0700862 alloc_entrypoints_instrumented_ = instrumented;
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700863 } else {
864 MutexLock mu(self, *Locks::runtime_shutdown_lock_);
865 SetQuickAllocEntryPointsInstrumented(instrumented);
Andreas Gampe157c77e2016-10-17 17:44:41 -0700866
867 // Note: ResetQuickAllocEntryPoints only works when the runtime is started. Manually run the
868 // update for just this thread.
Andreas Gampe162ae502016-10-18 10:03:42 -0700869 // Note: self may be null. One of those paths is setting instrumentation in the Heap
870 // constructor for gcstress mode.
871 if (self != nullptr) {
872 ResetQuickAllocEntryPointsForThread(self, nullptr);
873 }
Andreas Gampe157c77e2016-10-17 17:44:41 -0700874
Mathieu Chartier50e93312016-03-16 11:25:29 -0700875 alloc_entrypoints_instrumented_ = instrumented;
Mathieu Chartier661974a2014-01-09 11:23:53 -0800876 }
877}
878
Mathieu Chartier9ef78b52014-09-25 17:03:12 -0700879void Instrumentation::InstrumentQuickAllocEntryPoints() {
880 MutexLock mu(Thread::Current(), *Locks::instrument_entrypoints_lock_);
881 InstrumentQuickAllocEntryPointsLocked();
Ian Rogersfa824272013-11-05 16:12:57 -0800882}
883
Mathieu Chartier9ef78b52014-09-25 17:03:12 -0700884void Instrumentation::UninstrumentQuickAllocEntryPoints() {
885 MutexLock mu(Thread::Current(), *Locks::instrument_entrypoints_lock_);
886 UninstrumentQuickAllocEntryPointsLocked();
887}
888
889void Instrumentation::InstrumentQuickAllocEntryPointsLocked() {
890 Locks::instrument_entrypoints_lock_->AssertHeld(Thread::Current());
891 if (quick_alloc_entry_points_instrumentation_counter_ == 0) {
892 SetEntrypointsInstrumented(true);
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800893 }
Mathieu Chartier9ef78b52014-09-25 17:03:12 -0700894 ++quick_alloc_entry_points_instrumentation_counter_;
Mathieu Chartier9ef78b52014-09-25 17:03:12 -0700895}
896
897void Instrumentation::UninstrumentQuickAllocEntryPointsLocked() {
898 Locks::instrument_entrypoints_lock_->AssertHeld(Thread::Current());
899 CHECK_GT(quick_alloc_entry_points_instrumentation_counter_, 0U);
900 --quick_alloc_entry_points_instrumentation_counter_;
901 if (quick_alloc_entry_points_instrumentation_counter_ == 0) {
902 SetEntrypointsInstrumented(false);
903 }
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800904}
905
906void Instrumentation::ResetQuickAllocEntryPoints() {
907 Runtime* runtime = Runtime::Current();
908 if (runtime->IsStarted()) {
Mathieu Chartiere6da9af2013-12-16 11:54:42 -0800909 MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700910 runtime->GetThreadList()->ForEach(ResetQuickAllocEntryPointsForThread, nullptr);
Ian Rogersfa824272013-11-05 16:12:57 -0800911 }
912}
913
Mingyao Yang3fd448a2016-05-10 14:30:41 -0700914void Instrumentation::UpdateMethodsCodeImpl(ArtMethod* method, const void* quick_code) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800915 const void* new_quick_code;
Ian Rogers62d6c772013-02-27 08:32:07 -0800916 if (LIKELY(!instrumentation_stubs_installed_)) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800917 new_quick_code = quick_code;
Jeff Hao65d15d92013-07-16 16:39:33 -0700918 } else {
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100919 if ((interpreter_stubs_installed_ || IsDeoptimized(method)) && !method->IsNative()) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800920 new_quick_code = GetQuickToInterpreterBridge();
Jeff Hao65d15d92013-07-16 16:39:33 -0700921 } else {
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700922 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700923 if (class_linker->IsQuickResolutionStub(quick_code) ||
924 class_linker->IsQuickToInterpreterBridge(quick_code)) {
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700925 new_quick_code = quick_code;
Alex Light6cae5ea2018-06-07 17:07:02 -0700926 } else if (entry_exit_stubs_installed_ &&
927 // We need to make sure not to replace anything that InstallStubsForMethod
928 // wouldn't. Specifically we cannot stub out Proxy.<init> since subtypes copy the
929 // implementation directly and this will confuse the instrumentation trampolines.
930 // TODO We should remove the need for this since it makes it impossible to profile
931 // Proxy.<init> correctly in all cases.
932 method != jni::DecodeArtMethod(WellKnownClasses::java_lang_reflect_Proxy_init)) {
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700933 new_quick_code = GetQuickInstrumentationEntryPoint();
Alex Light2d441b12018-06-08 15:33:21 -0700934 if (!method->IsNative() && Runtime::Current()->GetJit() != nullptr) {
935 // Native methods use trampoline entrypoints during interpreter tracing.
Nicolas Geoffray226805d2018-12-14 10:59:02 +0000936 DCHECK(!Runtime::Current()->GetJit()->GetCodeCache()->GetGarbageCollectCodeUnsafe());
Alex Light2d441b12018-06-08 15:33:21 -0700937 ProfilingInfo* profiling_info = method->GetProfilingInfo(kRuntimePointerSize);
938 // Tracing will look at the saved entry point in the profiling info to know the actual
939 // entrypoint, so we store it here.
940 if (profiling_info != nullptr) {
941 profiling_info->SetSavedEntryPoint(quick_code);
942 }
943 }
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700944 } else {
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700945 new_quick_code = quick_code;
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700946 }
Jeff Hao65d15d92013-07-16 16:39:33 -0700947 }
Ian Rogers62d6c772013-02-27 08:32:07 -0800948 }
Elliott Hughes956af0f2014-12-11 14:34:28 -0800949 UpdateEntrypoints(method, new_quick_code);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +0100950}
951
Nicolas Geoffraya6e0e7d2018-01-26 13:16:50 +0000952void Instrumentation::UpdateNativeMethodsCodeToJitCode(ArtMethod* method, const void* quick_code) {
953 // We don't do any read barrier on `method`'s declaring class in this code, as the JIT might
954 // enter here on a soon-to-be deleted ArtMethod. Updating the entrypoint is OK though, as
955 // the ArtMethod is still in memory.
956 const void* new_quick_code = quick_code;
957 if (UNLIKELY(instrumentation_stubs_installed_) && entry_exit_stubs_installed_) {
958 new_quick_code = GetQuickInstrumentationEntryPoint();
959 }
960 UpdateEntrypoints(method, new_quick_code);
961}
962
Mingyao Yang3fd448a2016-05-10 14:30:41 -0700963void Instrumentation::UpdateMethodsCode(ArtMethod* method, const void* quick_code) {
964 DCHECK(method->GetDeclaringClass()->IsResolved());
965 UpdateMethodsCodeImpl(method, quick_code);
966}
967
Alex Light0a5ec3d2017-07-25 16:50:26 -0700968void Instrumentation::UpdateMethodsCodeToInterpreterEntryPoint(ArtMethod* method) {
969 UpdateMethodsCodeImpl(method, GetQuickToInterpreterBridge());
970}
971
Nicolas Geoffraya0619e22016-12-20 13:57:43 +0000972void Instrumentation::UpdateMethodsCodeForJavaDebuggable(ArtMethod* method,
973 const void* quick_code) {
974 // When the runtime is set to Java debuggable, we may update the entry points of
975 // all methods of a class to the interpreter bridge. A method's declaring class
976 // might not be in resolved state yet in that case, so we bypass the DCHECK in
977 // UpdateMethodsCode.
Mingyao Yang3fd448a2016-05-10 14:30:41 -0700978 UpdateMethodsCodeImpl(method, quick_code);
979}
980
Mathieu Chartiere401d142015-04-22 13:56:20 -0700981bool Instrumentation::AddDeoptimizedMethod(ArtMethod* method) {
982 if (IsDeoptimizedMethod(method)) {
Hiroshi Yamauchi799eb3a2014-07-18 15:38:17 -0700983 // Already in the map. Return.
984 return false;
985 }
986 // Not found. Add it.
Mathieu Chartiere401d142015-04-22 13:56:20 -0700987 deoptimized_methods_.insert(method);
Hiroshi Yamauchi799eb3a2014-07-18 15:38:17 -0700988 return true;
989}
990
Mathieu Chartiere401d142015-04-22 13:56:20 -0700991bool Instrumentation::IsDeoptimizedMethod(ArtMethod* method) {
992 return deoptimized_methods_.find(method) != deoptimized_methods_.end();
Hiroshi Yamauchi799eb3a2014-07-18 15:38:17 -0700993}
994
Mathieu Chartiere401d142015-04-22 13:56:20 -0700995ArtMethod* Instrumentation::BeginDeoptimizedMethod() {
996 if (deoptimized_methods_.empty()) {
Hiroshi Yamauchi799eb3a2014-07-18 15:38:17 -0700997 // Empty.
998 return nullptr;
999 }
Mathieu Chartiere401d142015-04-22 13:56:20 -07001000 return *deoptimized_methods_.begin();
Hiroshi Yamauchi799eb3a2014-07-18 15:38:17 -07001001}
1002
Mathieu Chartiere401d142015-04-22 13:56:20 -07001003bool Instrumentation::RemoveDeoptimizedMethod(ArtMethod* method) {
1004 auto it = deoptimized_methods_.find(method);
1005 if (it == deoptimized_methods_.end()) {
1006 return false;
Hiroshi Yamauchi799eb3a2014-07-18 15:38:17 -07001007 }
Mathieu Chartiere401d142015-04-22 13:56:20 -07001008 deoptimized_methods_.erase(it);
1009 return true;
Hiroshi Yamauchi799eb3a2014-07-18 15:38:17 -07001010}
1011
1012bool Instrumentation::IsDeoptimizedMethodsEmpty() const {
1013 return deoptimized_methods_.empty();
1014}
1015
Mathieu Chartiere401d142015-04-22 13:56:20 -07001016void Instrumentation::Deoptimize(ArtMethod* method) {
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001017 CHECK(!method->IsNative());
1018 CHECK(!method->IsProxyMethod());
Alex Light9139e002015-10-09 15:59:48 -07001019 CHECK(method->IsInvokable());
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001020
Mathieu Chartier3b05e9b2014-03-25 09:29:43 -07001021 Thread* self = Thread::Current();
Mathieu Chartier3b05e9b2014-03-25 09:29:43 -07001022 {
Andreas Gampe7e56a072018-11-29 10:40:06 -08001023 WriterMutexLock mu(self, *GetDeoptimizedMethodsLock());
Hiroshi Yamauchi799eb3a2014-07-18 15:38:17 -07001024 bool has_not_been_deoptimized = AddDeoptimizedMethod(method);
David Sehr709b0702016-10-13 09:12:37 -07001025 CHECK(has_not_been_deoptimized) << "Method " << ArtMethod::PrettyMethod(method)
Daniel Mihalyica1d06c2014-08-18 18:45:31 +02001026 << " is already deoptimized";
Mathieu Chartier3b05e9b2014-03-25 09:29:43 -07001027 }
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001028 if (!interpreter_stubs_installed_) {
Elliott Hughes956af0f2014-12-11 14:34:28 -08001029 UpdateEntrypoints(method, GetQuickInstrumentationEntryPoint());
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001030
1031 // Install instrumentation exit stub and instrumentation frames. We may already have installed
1032 // these previously so it will only cover the newly created frames.
1033 instrumentation_stubs_installed_ = true;
Mathieu Chartier3b05e9b2014-03-25 09:29:43 -07001034 MutexLock mu(self, *Locks::thread_list_lock_);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001035 Runtime::Current()->GetThreadList()->ForEach(InstrumentationInstallStack, this);
1036 }
1037}
1038
Mathieu Chartiere401d142015-04-22 13:56:20 -07001039void Instrumentation::Undeoptimize(ArtMethod* method) {
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001040 CHECK(!method->IsNative());
1041 CHECK(!method->IsProxyMethod());
Alex Light9139e002015-10-09 15:59:48 -07001042 CHECK(method->IsInvokable());
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001043
Mathieu Chartier3b05e9b2014-03-25 09:29:43 -07001044 Thread* self = Thread::Current();
1045 bool empty;
1046 {
Andreas Gampe7e56a072018-11-29 10:40:06 -08001047 WriterMutexLock mu(self, *GetDeoptimizedMethodsLock());
Hiroshi Yamauchi799eb3a2014-07-18 15:38:17 -07001048 bool found_and_erased = RemoveDeoptimizedMethod(method);
David Sehr709b0702016-10-13 09:12:37 -07001049 CHECK(found_and_erased) << "Method " << ArtMethod::PrettyMethod(method)
Mathieu Chartier3b05e9b2014-03-25 09:29:43 -07001050 << " is not deoptimized";
Hiroshi Yamauchi799eb3a2014-07-18 15:38:17 -07001051 empty = IsDeoptimizedMethodsEmpty();
Mathieu Chartier3b05e9b2014-03-25 09:29:43 -07001052 }
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001053
1054 // Restore code and possibly stack only if we did not deoptimize everything.
1055 if (!interpreter_stubs_installed_) {
1056 // Restore its code or resolution trampoline.
1057 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Ian Rogersef7d42f2014-01-06 12:55:46 -08001058 if (method->IsStatic() && !method->IsConstructor() &&
1059 !method->GetDeclaringClass()->IsInitialized()) {
Elliott Hughes956af0f2014-12-11 14:34:28 -08001060 UpdateEntrypoints(method, GetQuickResolutionStub());
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001061 } else {
Nicolas Geoffraya0619e22016-12-20 13:57:43 +00001062 const void* quick_code = NeedDebugVersionFor(method)
1063 ? GetQuickToInterpreterBridge()
Alex Lightfc49fec2018-01-16 22:28:36 +00001064 : class_linker->GetQuickOatCodeFor(method);
Elliott Hughes956af0f2014-12-11 14:34:28 -08001065 UpdateEntrypoints(method, quick_code);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001066 }
1067
1068 // If there is no deoptimized method left, we can restore the stack of each thread.
Alex Lightf244a572018-06-08 13:56:51 -07001069 if (empty && !entry_exit_stubs_installed_) {
Mathieu Chartier3b05e9b2014-03-25 09:29:43 -07001070 MutexLock mu(self, *Locks::thread_list_lock_);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001071 Runtime::Current()->GetThreadList()->ForEach(InstrumentationRestoreStack, this);
1072 instrumentation_stubs_installed_ = false;
1073 }
1074 }
1075}
1076
Mathieu Chartiere401d142015-04-22 13:56:20 -07001077bool Instrumentation::IsDeoptimized(ArtMethod* method) {
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001078 DCHECK(method != nullptr);
Andreas Gampe7e56a072018-11-29 10:40:06 -08001079 ReaderMutexLock mu(Thread::Current(), *GetDeoptimizedMethodsLock());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001080 return IsDeoptimizedMethod(method);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001081}
1082
1083void Instrumentation::EnableDeoptimization() {
Andreas Gampe7e56a072018-11-29 10:40:06 -08001084 ReaderMutexLock mu(Thread::Current(), *GetDeoptimizedMethodsLock());
Hiroshi Yamauchi799eb3a2014-07-18 15:38:17 -07001085 CHECK(IsDeoptimizedMethodsEmpty());
Sebastien Hertz11d40c22014-02-19 18:00:17 +01001086 CHECK_EQ(deoptimization_enabled_, false);
1087 deoptimization_enabled_ = true;
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001088}
1089
Sebastien Hertz0462c4c2015-04-01 16:34:17 +02001090void Instrumentation::DisableDeoptimization(const char* key) {
Sebastien Hertz11d40c22014-02-19 18:00:17 +01001091 CHECK_EQ(deoptimization_enabled_, true);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001092 // If we deoptimized everything, undo it.
Alex Lightdba61482016-12-21 08:20:29 -08001093 InstrumentationLevel level = GetCurrentInstrumentationLevel();
1094 if (level == InstrumentationLevel::kInstrumentWithInterpreter) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +02001095 UndeoptimizeEverything(key);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001096 }
1097 // Undeoptimized selected methods.
Mathieu Chartier3b05e9b2014-03-25 09:29:43 -07001098 while (true) {
Mathieu Chartiere401d142015-04-22 13:56:20 -07001099 ArtMethod* method;
Mathieu Chartier3b05e9b2014-03-25 09:29:43 -07001100 {
Andreas Gampe7e56a072018-11-29 10:40:06 -08001101 ReaderMutexLock mu(Thread::Current(), *GetDeoptimizedMethodsLock());
Hiroshi Yamauchi799eb3a2014-07-18 15:38:17 -07001102 if (IsDeoptimizedMethodsEmpty()) {
Mathieu Chartier3b05e9b2014-03-25 09:29:43 -07001103 break;
1104 }
Hiroshi Yamauchi799eb3a2014-07-18 15:38:17 -07001105 method = BeginDeoptimizedMethod();
1106 CHECK(method != nullptr);
Mathieu Chartier3b05e9b2014-03-25 09:29:43 -07001107 }
1108 Undeoptimize(method);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001109 }
Sebastien Hertz11d40c22014-02-19 18:00:17 +01001110 deoptimization_enabled_ = false;
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001111}
1112
Sebastien Hertz11d40c22014-02-19 18:00:17 +01001113// Indicates if instrumentation should notify method enter/exit events to the listeners.
1114bool Instrumentation::ShouldNotifyMethodEnterExitEvents() const {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +02001115 if (!HasMethodEntryListeners() && !HasMethodExitListeners()) {
1116 return false;
1117 }
Sebastien Hertz7ec2f1c2014-03-27 20:06:47 +01001118 return !deoptimization_enabled_ && !interpreter_stubs_installed_;
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001119}
1120
Sebastien Hertz0462c4c2015-04-01 16:34:17 +02001121void Instrumentation::DeoptimizeEverything(const char* key) {
1122 CHECK(deoptimization_enabled_);
1123 ConfigureStubs(key, InstrumentationLevel::kInstrumentWithInterpreter);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001124}
1125
Sebastien Hertz0462c4c2015-04-01 16:34:17 +02001126void Instrumentation::UndeoptimizeEverything(const char* key) {
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001127 CHECK(interpreter_stubs_installed_);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +02001128 CHECK(deoptimization_enabled_);
1129 ConfigureStubs(key, InstrumentationLevel::kInstrumentNothing);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001130}
1131
Sebastien Hertz0462c4c2015-04-01 16:34:17 +02001132void Instrumentation::EnableMethodTracing(const char* key, bool needs_interpreter) {
1133 InstrumentationLevel level;
1134 if (needs_interpreter) {
1135 level = InstrumentationLevel::kInstrumentWithInterpreter;
1136 } else {
1137 level = InstrumentationLevel::kInstrumentWithInstrumentationStubs;
1138 }
1139 ConfigureStubs(key, level);
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001140}
1141
Sebastien Hertz0462c4c2015-04-01 16:34:17 +02001142void Instrumentation::DisableMethodTracing(const char* key) {
1143 ConfigureStubs(key, InstrumentationLevel::kInstrumentNothing);
jeffhao725a9572012-11-13 18:20:12 -08001144}
1145
Alex Light2d441b12018-06-08 15:33:21 -07001146const void* Instrumentation::GetCodeForInvoke(ArtMethod* method) const {
1147 // This is called by instrumentation entry only and that should never be getting proxy methods.
1148 DCHECK(!method->IsProxyMethod()) << method->PrettyMethod();
1149 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1150 if (LIKELY(!instrumentation_stubs_installed_ && !interpreter_stubs_installed_)) {
1151 // In general we just return whatever the method thinks its entrypoint is here. The only
1152 // exception is if it still has the instrumentation entrypoint. That means we are racing another
1153 // thread getting rid of instrumentation which is unexpected but possible. In that case we want
1154 // to wait and try to get it from the oat file or jit.
1155 const void* code = method->GetEntryPointFromQuickCompiledCodePtrSize(kRuntimePointerSize);
1156 DCHECK(code != nullptr);
1157 if (code != GetQuickInstrumentationEntryPoint()) {
1158 return code;
1159 } else if (method->IsNative()) {
1160 return class_linker->GetQuickOatCodeFor(method);
1161 }
1162 // We don't know what it is. Fallthough to try to find the code from the JIT or Oat file.
1163 } else if (method->IsNative()) {
1164 // TODO We could have JIT compiled native entrypoints. It might be worth it to find these.
1165 return class_linker->GetQuickOatCodeFor(method);
1166 } else if (UNLIKELY(interpreter_stubs_installed_)) {
1167 return GetQuickToInterpreterBridge();
1168 }
1169 // Since the method cannot be native due to ifs above we can always fall back to interpreter
1170 // bridge.
1171 const void* result = GetQuickToInterpreterBridge();
1172 if (!NeedDebugVersionFor(method)) {
1173 // If we don't need a debug version we should see what the oat file/class linker has to say.
1174 result = class_linker->GetQuickOatCodeFor(method);
1175 }
1176 // If both those fail try the jit.
1177 if (result == GetQuickToInterpreterBridge()) {
1178 jit::Jit* jit = Runtime::Current()->GetJit();
1179 if (jit != nullptr) {
1180 const void* res = jit->GetCodeCache()->FindCompiledCodeForInstrumentation(method);
1181 if (res != nullptr) {
1182 result = res;
1183 }
1184 }
1185 }
1186 return result;
1187}
1188
Andreas Gampe542451c2016-07-26 09:02:02 -07001189const void* Instrumentation::GetQuickCodeFor(ArtMethod* method, PointerSize pointer_size) const {
Vladimir Marko97d7e1c2016-10-04 14:44:28 +01001190 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Ian Rogers62d6c772013-02-27 08:32:07 -08001191 if (LIKELY(!instrumentation_stubs_installed_)) {
Mathieu Chartiera7dd0382014-11-20 17:08:58 -08001192 const void* code = method->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size);
Vladimir Marko8a630572014-04-09 18:45:35 +01001193 DCHECK(code != nullptr);
Ian Rogers6f3dbba2014-10-14 17:41:57 -07001194 if (LIKELY(!class_linker->IsQuickResolutionStub(code) &&
1195 !class_linker->IsQuickToInterpreterBridge(code)) &&
1196 !class_linker->IsQuickResolutionStub(code) &&
1197 !class_linker->IsQuickToInterpreterBridge(code)) {
Ian Rogers62d6c772013-02-27 08:32:07 -08001198 return code;
1199 }
1200 }
Alex Lightfc49fec2018-01-16 22:28:36 +00001201 return class_linker->GetQuickOatCodeFor(method);
jeffhao725a9572012-11-13 18:20:12 -08001202}
1203
Alex Lightd7661582017-05-01 13:48:16 -07001204void Instrumentation::MethodEnterEventImpl(Thread* thread,
1205 ObjPtr<mirror::Object> this_object,
Mathieu Chartiere401d142015-04-22 13:56:20 -07001206 ArtMethod* method,
Ian Rogers62d6c772013-02-27 08:32:07 -08001207 uint32_t dex_pc) const {
Mingyao Yang2ee17902017-08-30 11:37:08 -07001208 DCHECK(!method->IsRuntimeMethod());
Nicolas Geoffray514a6162015-11-03 11:44:24 +00001209 if (HasMethodEntryListeners()) {
Alex Lightd7661582017-05-01 13:48:16 -07001210 Thread* self = Thread::Current();
1211 StackHandleScope<1> hs(self);
1212 Handle<mirror::Object> thiz(hs.NewHandle(this_object));
Nicolas Geoffray514a6162015-11-03 11:44:24 +00001213 for (InstrumentationListener* listener : method_entry_listeners_) {
1214 if (listener != nullptr) {
Alex Lightd7661582017-05-01 13:48:16 -07001215 listener->MethodEntered(thread, thiz, method, dex_pc);
Nicolas Geoffray514a6162015-11-03 11:44:24 +00001216 }
1217 }
Ian Rogers62d6c772013-02-27 08:32:07 -08001218 }
1219}
1220
Alex Lightb7c640d2019-03-20 15:52:13 -07001221template <>
Alex Lightd7661582017-05-01 13:48:16 -07001222void Instrumentation::MethodExitEventImpl(Thread* thread,
1223 ObjPtr<mirror::Object> this_object,
Mathieu Chartiere401d142015-04-22 13:56:20 -07001224 ArtMethod* method,
Alex Lightd7661582017-05-01 13:48:16 -07001225 uint32_t dex_pc,
Alex Lightb7c640d2019-03-20 15:52:13 -07001226 OptionalFrame frame,
1227 MutableHandle<mirror::Object>& return_value) const {
1228 if (HasMethodExitListeners()) {
1229 Thread* self = Thread::Current();
1230 StackHandleScope<1> hs(self);
1231 Handle<mirror::Object> thiz(hs.NewHandle(this_object));
1232 for (InstrumentationListener* listener : method_exit_listeners_) {
1233 if (listener != nullptr) {
1234 listener->MethodExited(thread, thiz, method, dex_pc, frame, return_value);
1235 }
1236 }
1237 }
1238}
1239
1240template<> void Instrumentation::MethodExitEventImpl(Thread* thread,
1241 ObjPtr<mirror::Object> this_object,
1242 ArtMethod* method,
1243 uint32_t dex_pc,
1244 OptionalFrame frame,
1245 JValue& return_value) const {
Nicolas Geoffray514a6162015-11-03 11:44:24 +00001246 if (HasMethodExitListeners()) {
Alex Lightd7661582017-05-01 13:48:16 -07001247 Thread* self = Thread::Current();
1248 StackHandleScope<2> hs(self);
1249 Handle<mirror::Object> thiz(hs.NewHandle(this_object));
Alex Lightb7c640d2019-03-20 15:52:13 -07001250 if (method->GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetReturnTypePrimitive() !=
1251 Primitive::kPrimNot) {
Alex Lightd7661582017-05-01 13:48:16 -07001252 for (InstrumentationListener* listener : method_exit_listeners_) {
1253 if (listener != nullptr) {
Alex Lightb7c640d2019-03-20 15:52:13 -07001254 listener->MethodExited(thread, thiz, method, dex_pc, frame, return_value);
Alex Lightd7661582017-05-01 13:48:16 -07001255 }
1256 }
1257 } else {
Alex Lightb7c640d2019-03-20 15:52:13 -07001258 MutableHandle<mirror::Object> ret(hs.NewHandle(return_value.GetL()));
1259 MethodExitEventImpl(thread, thiz.Get(), method, dex_pc, frame, ret);
1260 return_value.SetL(ret.Get());
Nicolas Geoffray514a6162015-11-03 11:44:24 +00001261 }
Ian Rogers62d6c772013-02-27 08:32:07 -08001262 }
1263}
1264
Alex Lightd7661582017-05-01 13:48:16 -07001265void Instrumentation::MethodUnwindEvent(Thread* thread,
Vladimir Marko19711d42019-04-12 14:05:34 +01001266 ObjPtr<mirror::Object> this_object,
Mathieu Chartiere401d142015-04-22 13:56:20 -07001267 ArtMethod* method,
Ian Rogers62d6c772013-02-27 08:32:07 -08001268 uint32_t dex_pc) const {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +02001269 if (HasMethodUnwindListeners()) {
Alex Lightd7661582017-05-01 13:48:16 -07001270 Thread* self = Thread::Current();
1271 StackHandleScope<1> hs(self);
1272 Handle<mirror::Object> thiz(hs.NewHandle(this_object));
Mathieu Chartier02e25112013-08-14 16:14:24 -07001273 for (InstrumentationListener* listener : method_unwind_listeners_) {
Nicolas Geoffray514a6162015-11-03 11:44:24 +00001274 if (listener != nullptr) {
Alex Lightd7661582017-05-01 13:48:16 -07001275 listener->MethodUnwind(thread, thiz, method, dex_pc);
Nicolas Geoffray514a6162015-11-03 11:44:24 +00001276 }
Ian Rogers62d6c772013-02-27 08:32:07 -08001277 }
1278 }
1279}
1280
Alex Lightd7661582017-05-01 13:48:16 -07001281void Instrumentation::DexPcMovedEventImpl(Thread* thread,
1282 ObjPtr<mirror::Object> this_object,
Mathieu Chartiere401d142015-04-22 13:56:20 -07001283 ArtMethod* method,
Ian Rogers62d6c772013-02-27 08:32:07 -08001284 uint32_t dex_pc) const {
Alex Lightd7661582017-05-01 13:48:16 -07001285 Thread* self = Thread::Current();
1286 StackHandleScope<1> hs(self);
1287 Handle<mirror::Object> thiz(hs.NewHandle(this_object));
Nicolas Geoffray514a6162015-11-03 11:44:24 +00001288 for (InstrumentationListener* listener : dex_pc_listeners_) {
1289 if (listener != nullptr) {
Alex Lightd7661582017-05-01 13:48:16 -07001290 listener->DexPcMoved(thread, thiz, method, dex_pc);
Nicolas Geoffray514a6162015-11-03 11:44:24 +00001291 }
Ian Rogers62d6c772013-02-27 08:32:07 -08001292 }
1293}
1294
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001295void Instrumentation::BranchImpl(Thread* thread,
1296 ArtMethod* method,
1297 uint32_t dex_pc,
1298 int32_t offset) const {
1299 for (InstrumentationListener* listener : branch_listeners_) {
Nicolas Geoffray514a6162015-11-03 11:44:24 +00001300 if (listener != nullptr) {
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001301 listener->Branch(thread, method, dex_pc, offset);
Nicolas Geoffray514a6162015-11-03 11:44:24 +00001302 }
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001303 }
1304}
1305
Alex Lighte814f9d2017-07-31 16:14:39 -07001306void Instrumentation::WatchedFramePopImpl(Thread* thread, const ShadowFrame& frame) const {
1307 for (InstrumentationListener* listener : watched_frame_pop_listeners_) {
1308 if (listener != nullptr) {
1309 listener->WatchedFramePop(thread, frame);
1310 }
1311 }
1312}
1313
Alex Lightd7661582017-05-01 13:48:16 -07001314void Instrumentation::FieldReadEventImpl(Thread* thread,
1315 ObjPtr<mirror::Object> this_object,
1316 ArtMethod* method,
1317 uint32_t dex_pc,
Mathieu Chartierc7853442015-03-27 14:35:38 -07001318 ArtField* field) const {
Alex Lightd7661582017-05-01 13:48:16 -07001319 Thread* self = Thread::Current();
1320 StackHandleScope<1> hs(self);
1321 Handle<mirror::Object> thiz(hs.NewHandle(this_object));
Nicolas Geoffray514a6162015-11-03 11:44:24 +00001322 for (InstrumentationListener* listener : field_read_listeners_) {
1323 if (listener != nullptr) {
Alex Lightd7661582017-05-01 13:48:16 -07001324 listener->FieldRead(thread, thiz, method, dex_pc, field);
Nicolas Geoffray514a6162015-11-03 11:44:24 +00001325 }
Sebastien Hertz3f52eaf2014-04-04 17:50:18 +02001326 }
1327}
1328
Alex Lightd7661582017-05-01 13:48:16 -07001329void Instrumentation::FieldWriteEventImpl(Thread* thread,
1330 ObjPtr<mirror::Object> this_object,
1331 ArtMethod* method,
1332 uint32_t dex_pc,
1333 ArtField* field,
1334 const JValue& field_value) const {
1335 Thread* self = Thread::Current();
1336 StackHandleScope<2> hs(self);
1337 Handle<mirror::Object> thiz(hs.NewHandle(this_object));
1338 if (field->IsPrimitiveType()) {
1339 for (InstrumentationListener* listener : field_write_listeners_) {
1340 if (listener != nullptr) {
1341 listener->FieldWritten(thread, thiz, method, dex_pc, field, field_value);
1342 }
1343 }
1344 } else {
1345 Handle<mirror::Object> val(hs.NewHandle(field_value.GetL()));
1346 for (InstrumentationListener* listener : field_write_listeners_) {
1347 if (listener != nullptr) {
1348 listener->FieldWritten(thread, thiz, method, dex_pc, field, val);
1349 }
Nicolas Geoffray514a6162015-11-03 11:44:24 +00001350 }
Sebastien Hertz3f52eaf2014-04-04 17:50:18 +02001351 }
1352}
1353
Alex Light6e1607e2017-08-23 10:06:18 -07001354void Instrumentation::ExceptionThrownEvent(Thread* thread,
Vladimir Marko19711d42019-04-12 14:05:34 +01001355 ObjPtr<mirror::Throwable> exception_object) const {
Hiroshi Yamauchi3481f7a2017-02-10 12:07:36 -08001356 Thread* self = Thread::Current();
1357 StackHandleScope<1> hs(self);
1358 Handle<mirror::Throwable> h_exception(hs.NewHandle(exception_object));
Alex Light6e1607e2017-08-23 10:06:18 -07001359 if (HasExceptionThrownListeners()) {
Hiroshi Yamauchi3481f7a2017-02-10 12:07:36 -08001360 DCHECK_EQ(thread->GetException(), h_exception.Get());
Jeff Haoc0bd4da2013-04-11 15:52:28 -07001361 thread->ClearException();
Alex Light6e1607e2017-08-23 10:06:18 -07001362 for (InstrumentationListener* listener : exception_thrown_listeners_) {
Nicolas Geoffray514a6162015-11-03 11:44:24 +00001363 if (listener != nullptr) {
Alex Light6e1607e2017-08-23 10:06:18 -07001364 listener->ExceptionThrown(thread, h_exception);
Nicolas Geoffray514a6162015-11-03 11:44:24 +00001365 }
Ian Rogers62d6c772013-02-27 08:32:07 -08001366 }
Alex Light9fb1ab12017-09-05 09:32:49 -07001367 // See b/65049545 for discussion about this behavior.
1368 thread->AssertNoPendingException();
Hiroshi Yamauchi3481f7a2017-02-10 12:07:36 -08001369 thread->SetException(h_exception.Get());
Ian Rogers62d6c772013-02-27 08:32:07 -08001370 }
1371}
1372
Alex Light9fb1ab12017-09-05 09:32:49 -07001373void Instrumentation::ExceptionHandledEvent(Thread* thread,
Vladimir Marko19711d42019-04-12 14:05:34 +01001374 ObjPtr<mirror::Throwable> exception_object) const {
Alex Light9fb1ab12017-09-05 09:32:49 -07001375 Thread* self = Thread::Current();
1376 StackHandleScope<1> hs(self);
1377 Handle<mirror::Throwable> h_exception(hs.NewHandle(exception_object));
1378 if (HasExceptionHandledListeners()) {
1379 // We should have cleared the exception so that callers can detect a new one.
1380 DCHECK(thread->GetException() == nullptr);
1381 for (InstrumentationListener* listener : exception_handled_listeners_) {
1382 if (listener != nullptr) {
1383 listener->ExceptionHandled(thread, h_exception);
1384 }
1385 }
1386 }
1387}
1388
Sebastien Hertzb2feaaf2015-10-12 13:40:10 +00001389// Computes a frame ID by ignoring inlined frames.
1390size_t Instrumentation::ComputeFrameId(Thread* self,
1391 size_t frame_depth,
1392 size_t inlined_frames_before_frame) {
1393 CHECK_GE(frame_depth, inlined_frames_before_frame);
1394 size_t no_inline_depth = frame_depth - inlined_frames_before_frame;
1395 return StackVisitor::ComputeNumFrames(self, kInstrumentationStackWalk) - no_inline_depth;
1396}
1397
Ian Rogers62d6c772013-02-27 08:32:07 -08001398static void CheckStackDepth(Thread* self, const InstrumentationStackFrame& instrumentation_frame,
1399 int delta)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001400 REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray8e5bd182015-05-06 11:34:34 +01001401 size_t frame_id = StackVisitor::ComputeNumFrames(self, kInstrumentationStackWalk) + delta;
Ian Rogers62d6c772013-02-27 08:32:07 -08001402 if (frame_id != instrumentation_frame.frame_id_) {
1403 LOG(ERROR) << "Expected frame_id=" << frame_id << " but found "
1404 << instrumentation_frame.frame_id_;
1405 StackVisitor::DescribeStack(self);
1406 CHECK_EQ(frame_id, instrumentation_frame.frame_id_);
1407 }
1408}
1409
Vladimir Marko19711d42019-04-12 14:05:34 +01001410void Instrumentation::PushInstrumentationStackFrame(Thread* self,
1411 ObjPtr<mirror::Object> this_object,
Mathieu Chartiere401d142015-04-22 13:56:20 -07001412 ArtMethod* method,
Vladimir Marko19711d42019-04-12 14:05:34 +01001413 uintptr_t lr,
1414 bool interpreter_entry) {
Alex Lightb7edcda2017-04-27 13:20:31 -07001415 DCHECK(!self->IsExceptionPending());
Ian Rogers62d6c772013-02-27 08:32:07 -08001416 std::deque<instrumentation::InstrumentationStackFrame>* stack = self->GetInstrumentationStack();
1417 if (kVerboseInstrumentation) {
David Sehr709b0702016-10-13 09:12:37 -07001418 LOG(INFO) << "Entering " << ArtMethod::PrettyMethod(method) << " from PC "
1419 << reinterpret_cast<void*>(lr);
Ian Rogers62d6c772013-02-27 08:32:07 -08001420 }
Alex Lightb7edcda2017-04-27 13:20:31 -07001421
1422 // We send the enter event before pushing the instrumentation frame to make cleanup easier. If the
1423 // event causes an exception we can simply send the unwind event and return.
1424 StackHandleScope<1> hs(self);
1425 Handle<mirror::Object> h_this(hs.NewHandle(this_object));
1426 if (!interpreter_entry) {
1427 MethodEnterEvent(self, h_this.Get(), method, 0);
1428 if (self->IsExceptionPending()) {
1429 MethodUnwindEvent(self, h_this.Get(), method, 0);
1430 return;
1431 }
1432 }
1433
1434 // We have a callee-save frame meaning this value is guaranteed to never be 0.
1435 DCHECK(!self->IsExceptionPending());
1436 size_t frame_id = StackVisitor::ComputeNumFrames(self, kInstrumentationStackWalk);
1437
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001438 instrumentation::InstrumentationStackFrame instrumentation_frame(
1439 h_this.Get(), method, lr, frame_id, interpreter_entry, current_force_deopt_id_);
Ian Rogers62d6c772013-02-27 08:32:07 -08001440 stack->push_front(instrumentation_frame);
Ian Rogers62d6c772013-02-27 08:32:07 -08001441}
1442
Mingyao Yang2ee17902017-08-30 11:37:08 -07001443DeoptimizationMethodType Instrumentation::GetDeoptimizationMethodType(ArtMethod* method) {
1444 if (method->IsRuntimeMethod()) {
1445 // Certain methods have strict requirement on whether the dex instruction
1446 // should be re-executed upon deoptimization.
1447 if (method == Runtime::Current()->GetCalleeSaveMethod(
1448 CalleeSaveType::kSaveEverythingForClinit)) {
1449 return DeoptimizationMethodType::kKeepDexPc;
1450 }
1451 if (method == Runtime::Current()->GetCalleeSaveMethod(
1452 CalleeSaveType::kSaveEverythingForSuspendCheck)) {
1453 return DeoptimizationMethodType::kKeepDexPc;
1454 }
1455 }
1456 return DeoptimizationMethodType::kDefault;
1457}
1458
1459// Try to get the shorty of a runtime method if it's an invocation stub.
Andreas Gampec7d878d2018-11-19 18:42:06 +00001460static char GetRuntimeMethodShorty(Thread* thread) REQUIRES_SHARED(Locks::mutator_lock_) {
1461 char shorty = 'V';
1462 StackVisitor::WalkStack(
1463 [&shorty](const art::StackVisitor* stack_visitor) REQUIRES_SHARED(Locks::mutator_lock_) {
1464 ArtMethod* m = stack_visitor->GetMethod();
1465 if (m == nullptr || m->IsRuntimeMethod()) {
1466 return true;
Andreas Gampe3d477f32018-11-16 16:40:45 +00001467 }
Andreas Gampec7d878d2018-11-19 18:42:06 +00001468 // The first Java method.
1469 if (m->IsNative()) {
1470 // Use JNI method's shorty for the jni stub.
1471 shorty = m->GetShorty()[0];
1472 } else if (m->IsProxyMethod()) {
1473 // Proxy method just invokes its proxied method via
1474 // art_quick_proxy_invoke_handler.
1475 shorty = m->GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetShorty()[0];
1476 } else {
1477 const Instruction& instr = m->DexInstructions().InstructionAt(stack_visitor->GetDexPc());
1478 if (instr.IsInvoke()) {
1479 auto get_method_index_fn = [](ArtMethod* caller,
1480 const Instruction& inst,
1481 uint32_t dex_pc)
1482 REQUIRES_SHARED(Locks::mutator_lock_) {
1483 switch (inst.Opcode()) {
1484 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK:
1485 case Instruction::INVOKE_VIRTUAL_QUICK: {
1486 uint16_t method_idx = caller->GetIndexFromQuickening(dex_pc);
1487 CHECK_NE(method_idx, DexFile::kDexNoIndex16);
1488 return method_idx;
1489 }
1490 default: {
1491 return static_cast<uint16_t>(inst.VRegB());
1492 }
1493 }
1494 };
Nicolas Geoffrayec43a012018-11-17 13:10:40 +00001495
Andreas Gampec7d878d2018-11-19 18:42:06 +00001496 uint16_t method_index = get_method_index_fn(m, instr, stack_visitor->GetDexPc());
1497 const DexFile* dex_file = m->GetDexFile();
1498 if (interpreter::IsStringInit(dex_file, method_index)) {
1499 // Invoking string init constructor is turned into invoking
1500 // StringFactory.newStringFromChars() which returns a string.
1501 shorty = 'L';
1502 } else {
1503 shorty = dex_file->GetMethodShorty(method_index)[0];
1504 }
1505
1506 } else {
1507 // It could be that a non-invoke opcode invokes a stub, which in turn
1508 // invokes Java code. In such cases, we should never expect a return
1509 // value from the stub.
1510 }
1511 }
1512 // Stop stack walking since we've seen a Java frame.
1513 return false;
1514 },
1515 thread,
1516 /* context= */ nullptr,
1517 art::StackVisitor::StackWalkKind::kIncludeInlinedFrames);
1518 return shorty;
1519}
Mingyao Yang2ee17902017-08-30 11:37:08 -07001520
Alex Lightb7edcda2017-04-27 13:20:31 -07001521TwoWordReturn Instrumentation::PopInstrumentationStackFrame(Thread* self,
1522 uintptr_t* return_pc,
1523 uint64_t* gpr_result,
1524 uint64_t* fpr_result) {
1525 DCHECK(gpr_result != nullptr);
1526 DCHECK(fpr_result != nullptr);
Ian Rogers62d6c772013-02-27 08:32:07 -08001527 // Do the pop.
1528 std::deque<instrumentation::InstrumentationStackFrame>* stack = self->GetInstrumentationStack();
1529 CHECK_GT(stack->size(), 0U);
1530 InstrumentationStackFrame instrumentation_frame = stack->front();
1531 stack->pop_front();
1532
1533 // Set return PC and check the sanity of the stack.
1534 *return_pc = instrumentation_frame.return_pc_;
1535 CheckStackDepth(self, instrumentation_frame, 0);
Ian Rogers1d8cdbc2014-09-22 22:51:09 -07001536 self->VerifyStack();
Ian Rogers62d6c772013-02-27 08:32:07 -08001537
Mathieu Chartiere401d142015-04-22 13:56:20 -07001538 ArtMethod* method = instrumentation_frame.method_;
Mathieu Chartierbfd9a432014-05-21 17:43:44 -07001539 uint32_t length;
Andreas Gampe542451c2016-07-26 09:02:02 -07001540 const PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Mingyao Yang2ee17902017-08-30 11:37:08 -07001541 char return_shorty;
1542
1543 // Runtime method does not call into MethodExitEvent() so there should not be
1544 // suspension point below.
1545 ScopedAssertNoThreadSuspension ants(__FUNCTION__, method->IsRuntimeMethod());
1546 if (method->IsRuntimeMethod()) {
1547 if (method != Runtime::Current()->GetCalleeSaveMethod(
1548 CalleeSaveType::kSaveEverythingForClinit)) {
1549 // If the caller is at an invocation point and the runtime method is not
1550 // for clinit, we need to pass return results to the caller.
1551 // We need the correct shorty to decide whether we need to pass the return
1552 // result for deoptimization below.
Andreas Gampec7d878d2018-11-19 18:42:06 +00001553 return_shorty = GetRuntimeMethodShorty(self);
Mingyao Yang2ee17902017-08-30 11:37:08 -07001554 } else {
1555 // Some runtime methods such as allocations, unresolved field getters, etc.
1556 // have return value. We don't need to set return_value since MethodExitEvent()
1557 // below isn't called for runtime methods. Deoptimization doesn't need the
1558 // value either since the dex instruction will be re-executed by the
1559 // interpreter, except these two cases:
1560 // (1) For an invoke, which is handled above to get the correct shorty.
1561 // (2) For MONITOR_ENTER/EXIT, which cannot be re-executed since it's not
1562 // idempotent. However there is no return value for it anyway.
1563 return_shorty = 'V';
1564 }
1565 } else {
1566 return_shorty = method->GetInterfaceMethodIfProxy(pointer_size)->GetShorty(&length)[0];
1567 }
1568
Alex Lightb7edcda2017-04-27 13:20:31 -07001569 bool is_ref = return_shorty == '[' || return_shorty == 'L';
1570 StackHandleScope<1> hs(self);
1571 MutableHandle<mirror::Object> res(hs.NewHandle<mirror::Object>(nullptr));
Ian Rogers62d6c772013-02-27 08:32:07 -08001572 JValue return_value;
1573 if (return_shorty == 'V') {
1574 return_value.SetJ(0);
1575 } else if (return_shorty == 'F' || return_shorty == 'D') {
Alex Lightb7edcda2017-04-27 13:20:31 -07001576 return_value.SetJ(*fpr_result);
Ian Rogers62d6c772013-02-27 08:32:07 -08001577 } else {
Alex Lightb7edcda2017-04-27 13:20:31 -07001578 return_value.SetJ(*gpr_result);
1579 }
1580 if (is_ref) {
1581 // Take a handle to the return value so we won't lose it if we suspend.
1582 res.Assign(return_value.GetL());
Ian Rogers62d6c772013-02-27 08:32:07 -08001583 }
1584 // TODO: improve the dex pc information here, requires knowledge of current PC as opposed to
1585 // return_pc.
Andreas Gampee2abbc62017-09-15 11:59:26 -07001586 uint32_t dex_pc = dex::kDexNoIndex;
Mingyao Yang2ee17902017-08-30 11:37:08 -07001587 if (!method->IsRuntimeMethod() && !instrumentation_frame.interpreter_entry_) {
Vladimir Marko19711d42019-04-12 14:05:34 +01001588 ObjPtr<mirror::Object> this_object = instrumentation_frame.this_object_;
Alex Lightb7c640d2019-03-20 15:52:13 -07001589 MethodExitEvent(
1590 self, this_object, instrumentation_frame.method_, dex_pc, OptionalFrame{}, return_value);
Sebastien Hertz320deb22014-06-11 19:45:05 +02001591 }
jeffhao725a9572012-11-13 18:20:12 -08001592
Sebastien Hertz138dbfc2013-12-04 18:15:25 +01001593 // Deoptimize if the caller needs to continue execution in the interpreter. Do nothing if we get
1594 // back to an upcall.
1595 NthCallerVisitor visitor(self, 1, true);
1596 visitor.WalkStack(true);
Sebastien Hertz270a0e12015-01-16 19:49:09 +01001597 bool deoptimize = (visitor.caller != nullptr) &&
Daniel Mihalyieb076692014-08-22 17:33:31 +02001598 (interpreter_stubs_installed_ || IsDeoptimized(visitor.caller) ||
Alex Light3dacdd62019-03-12 15:45:47 +00001599 self->IsForceInterpreter() ||
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001600 // NB Since structurally obsolete compiled methods might have the offsets of
1601 // methods/fields compiled in we need to go back to interpreter whenever we hit
1602 // them.
1603 visitor.caller->GetDeclaringClass()->IsObsoleteObject() ||
1604 // Check if we forced all threads to deoptimize in the time between this frame
1605 // being created and now.
1606 instrumentation_frame.force_deopt_id_ != current_force_deopt_id_ ||
Daniel Mihalyieb076692014-08-22 17:33:31 +02001607 Dbg::IsForcedInterpreterNeededForUpcall(self, visitor.caller));
Alex Lightb7edcda2017-04-27 13:20:31 -07001608 if (is_ref) {
1609 // Restore the return value if it's a reference since it might have moved.
1610 *reinterpret_cast<mirror::Object**>(gpr_result) = res.Get();
1611 }
Nicolas Geoffraya0619e22016-12-20 13:57:43 +00001612 if (deoptimize && Runtime::Current()->IsAsyncDeoptimizeable(*return_pc)) {
Ian Rogers62d6c772013-02-27 08:32:07 -08001613 if (kVerboseInstrumentation) {
Andreas Gampe46ee31b2016-12-14 10:11:49 -08001614 LOG(INFO) << "Deoptimizing "
1615 << visitor.caller->PrettyMethod()
1616 << " by returning from "
1617 << method->PrettyMethod()
1618 << " with result "
1619 << std::hex << return_value.GetJ() << std::dec
1620 << " in "
1621 << *self;
Ian Rogers62d6c772013-02-27 08:32:07 -08001622 }
Mingyao Yang2ee17902017-08-30 11:37:08 -07001623 DeoptimizationMethodType deopt_method_type = GetDeoptimizationMethodType(method);
Nicolas Geoffray73be1e82015-09-17 15:22:56 +01001624 self->PushDeoptimizationContext(return_value,
Mingyao Yang2ee17902017-08-30 11:37:08 -07001625 return_shorty == 'L' || return_shorty == '[',
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001626 /* exception= */ nullptr ,
1627 /* from_code= */ false,
Mingyao Yang2ee17902017-08-30 11:37:08 -07001628 deopt_method_type);
Andreas Gamped58342c2014-06-05 14:18:08 -07001629 return GetTwoWordSuccessValue(*return_pc,
1630 reinterpret_cast<uintptr_t>(GetQuickDeoptimizationEntryPoint()));
Ian Rogers62d6c772013-02-27 08:32:07 -08001631 } else {
Nicolas Geoffraya0619e22016-12-20 13:57:43 +00001632 if (deoptimize && !Runtime::Current()->IsAsyncDeoptimizeable(*return_pc)) {
Alex Lightd8eb6732018-01-29 15:16:02 -08001633 VLOG(deopt) << "Got a deoptimization request on un-deoptimizable " << method->PrettyMethod()
1634 << " at PC " << reinterpret_cast<void*>(*return_pc);
Nicolas Geoffraya0619e22016-12-20 13:57:43 +00001635 }
Ian Rogers62d6c772013-02-27 08:32:07 -08001636 if (kVerboseInstrumentation) {
David Sehr709b0702016-10-13 09:12:37 -07001637 LOG(INFO) << "Returning from " << method->PrettyMethod()
Brian Carlstrom2d888622013-07-18 17:02:00 -07001638 << " to PC " << reinterpret_cast<void*>(*return_pc);
Ian Rogers62d6c772013-02-27 08:32:07 -08001639 }
Andreas Gamped58342c2014-06-05 14:18:08 -07001640 return GetTwoWordSuccessValue(0, *return_pc);
Ian Rogers62d6c772013-02-27 08:32:07 -08001641 }
jeffhao725a9572012-11-13 18:20:12 -08001642}
1643
Alex Light2c8206f2018-06-08 14:51:09 -07001644uintptr_t Instrumentation::PopFramesForDeoptimization(Thread* self, size_t nframes) const {
Ian Rogers62d6c772013-02-27 08:32:07 -08001645 std::deque<instrumentation::InstrumentationStackFrame>* stack = self->GetInstrumentationStack();
Alex Light2c8206f2018-06-08 14:51:09 -07001646 CHECK_GE(stack->size(), nframes);
1647 if (nframes == 0) {
1648 return 0u;
1649 }
1650 // Only need to send instrumentation events if it's not for deopt (do give the log messages if we
1651 // have verbose-instrumentation anyway though).
1652 if (kVerboseInstrumentation) {
1653 for (size_t i = 0; i < nframes; i++) {
1654 LOG(INFO) << "Popping for deoptimization " << stack->at(i).method_->PrettyMethod();
Mingyao Yang2ee17902017-08-30 11:37:08 -07001655 }
Ian Rogers62d6c772013-02-27 08:32:07 -08001656 }
Alex Light2c8206f2018-06-08 14:51:09 -07001657 // Now that we've sent all the instrumentation events we can actually modify the
1658 // instrumentation-stack. We cannot do this earlier since MethodUnwindEvent can re-enter java and
1659 // do other things that require the instrumentation stack to be in a consistent state with the
1660 // actual stack.
1661 for (size_t i = 0; i < nframes - 1; i++) {
1662 stack->pop_front();
1663 }
1664 uintptr_t return_pc = stack->front().return_pc_;
Alex Lightb7edcda2017-04-27 13:20:31 -07001665 stack->pop_front();
Alex Light2c8206f2018-06-08 14:51:09 -07001666 return return_pc;
Ian Rogers62d6c772013-02-27 08:32:07 -08001667}
1668
1669std::string InstrumentationStackFrame::Dump() const {
1670 std::ostringstream os;
David Sehr709b0702016-10-13 09:12:37 -07001671 os << "Frame " << frame_id_ << " " << ArtMethod::PrettyMethod(method_) << ":"
Nicolas Geoffray4ac0e152019-09-18 06:14:50 +00001672 << reinterpret_cast<void*>(return_pc_) << " this=" << reinterpret_cast<void*>(this_object_)
1673 << " force_deopt_id=" << force_deopt_id_;
Ian Rogers62d6c772013-02-27 08:32:07 -08001674 return os.str();
1675}
1676
1677} // namespace instrumentation
jeffhao725a9572012-11-13 18:20:12 -08001678} // namespace art