blob: cf5d3ed1391d0a58156a5c86b1144e70f2527998 [file] [log] [blame]
Sebastien Hertz0462c4c2015-04-01 16:34:17 +02001/*
2 * Copyright (C) 2015 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
Vladimir Markoba118822017-06-12 15:41:56 +010019#include "art_method-inl.h"
Andreas Gampe542451c2016-07-26 09:02:02 -070020#include "base/enums.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070021#include "class_linker-inl.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020022#include "common_runtime_test.h"
23#include "common_throws.h"
David Sehr9e734c72018-01-04 17:56:19 -080024#include "dex/dex_file.h"
Mathieu Chartieraa516822015-10-02 15:53:37 -070025#include "gc/scoped_gc_critical_section.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020026#include "handle_scope-inl.h"
Vladimir Markoa3ad0cd2018-05-04 10:06:38 +010027#include "jni/jni_internal.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020028#include "jvalue.h"
29#include "runtime.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070030#include "scoped_thread_state_change-inl.h"
Alex Lighte814f9d2017-07-31 16:14:39 -070031#include "interpreter/shadow_frame.h"
Alex Lightd7661582017-05-01 13:48:16 -070032#include "thread-inl.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070033#include "thread_list.h"
Alex Lightd7661582017-05-01 13:48:16 -070034#include "well_known_classes.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020035
36namespace art {
37namespace instrumentation {
38
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010039class TestInstrumentationListener final : public instrumentation::InstrumentationListener {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020040 public:
41 TestInstrumentationListener()
Alex Lightd7661582017-05-01 13:48:16 -070042 : received_method_enter_event(false),
43 received_method_exit_event(false),
44 received_method_exit_object_event(false),
45 received_method_unwind_event(false),
46 received_dex_pc_moved_event(false),
47 received_field_read_event(false),
48 received_field_written_event(false),
49 received_field_written_object_event(false),
Alex Light6e1607e2017-08-23 10:06:18 -070050 received_exception_thrown_event(false),
Alex Light9fb1ab12017-09-05 09:32:49 -070051 received_exception_handled_event(false),
Alex Lightd7661582017-05-01 13:48:16 -070052 received_branch_event(false),
Alex Lighte814f9d2017-07-31 16:14:39 -070053 received_watched_frame_pop(false) {}
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020054
55 virtual ~TestInstrumentationListener() {}
56
57 void MethodEntered(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070058 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070059 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020060 uint32_t dex_pc ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010061 override REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020062 received_method_enter_event = true;
63 }
64
65 void MethodExited(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070066 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
67 ArtMethod* method ATTRIBUTE_UNUSED,
68 uint32_t dex_pc ATTRIBUTE_UNUSED,
69 Handle<mirror::Object> return_value ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010070 override REQUIRES_SHARED(Locks::mutator_lock_) {
Alex Lightd7661582017-05-01 13:48:16 -070071 received_method_exit_object_event = true;
72 }
73
74 void MethodExited(Thread* thread ATTRIBUTE_UNUSED,
75 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070076 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020077 uint32_t dex_pc ATTRIBUTE_UNUSED,
78 const JValue& return_value ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010079 override REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020080 received_method_exit_event = true;
81 }
82
83 void MethodUnwind(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070084 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070085 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020086 uint32_t dex_pc ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010087 override REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020088 received_method_unwind_event = true;
89 }
90
91 void DexPcMoved(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070092 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070093 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020094 uint32_t new_dex_pc ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010095 override REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020096 received_dex_pc_moved_event = true;
97 }
98
99 void FieldRead(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -0700100 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700101 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200102 uint32_t dex_pc ATTRIBUTE_UNUSED,
103 ArtField* field ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100104 override REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200105 received_field_read_event = true;
106 }
107
108 void FieldWritten(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -0700109 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
110 ArtMethod* method ATTRIBUTE_UNUSED,
111 uint32_t dex_pc ATTRIBUTE_UNUSED,
112 ArtField* field ATTRIBUTE_UNUSED,
113 Handle<mirror::Object> field_value ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100114 override REQUIRES_SHARED(Locks::mutator_lock_) {
Alex Lightd7661582017-05-01 13:48:16 -0700115 received_field_written_object_event = true;
116 }
117
118 void FieldWritten(Thread* thread ATTRIBUTE_UNUSED,
119 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700120 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200121 uint32_t dex_pc ATTRIBUTE_UNUSED,
122 ArtField* field ATTRIBUTE_UNUSED,
123 const JValue& field_value ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100124 override REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200125 received_field_written_event = true;
126 }
127
Alex Light6e1607e2017-08-23 10:06:18 -0700128 void ExceptionThrown(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -0700129 Handle<mirror::Throwable> exception_object ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100130 override REQUIRES_SHARED(Locks::mutator_lock_) {
Alex Light6e1607e2017-08-23 10:06:18 -0700131 received_exception_thrown_event = true;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200132 }
133
Alex Light9fb1ab12017-09-05 09:32:49 -0700134 void ExceptionHandled(Thread* self ATTRIBUTE_UNUSED,
135 Handle<mirror::Throwable> throwable ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100136 override REQUIRES_SHARED(Locks::mutator_lock_) {
Alex Light9fb1ab12017-09-05 09:32:49 -0700137 received_exception_handled_event = true;
138 }
139
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000140 void Branch(Thread* thread ATTRIBUTE_UNUSED,
141 ArtMethod* method ATTRIBUTE_UNUSED,
142 uint32_t dex_pc ATTRIBUTE_UNUSED,
143 int32_t dex_pc_offset ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100144 override REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000145 received_branch_event = true;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200146 }
147
Alex Lighte814f9d2017-07-31 16:14:39 -0700148 void WatchedFramePop(Thread* thread ATTRIBUTE_UNUSED, const ShadowFrame& frame ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100149 override REQUIRES_SHARED(Locks::mutator_lock_) {
Alex Lighte814f9d2017-07-31 16:14:39 -0700150 received_watched_frame_pop = true;
151 }
152
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200153 void Reset() {
154 received_method_enter_event = false;
155 received_method_exit_event = false;
Alex Lightd7661582017-05-01 13:48:16 -0700156 received_method_exit_object_event = false;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200157 received_method_unwind_event = false;
158 received_dex_pc_moved_event = false;
159 received_field_read_event = false;
160 received_field_written_event = false;
Alex Lightd7661582017-05-01 13:48:16 -0700161 received_field_written_object_event = false;
Alex Light6e1607e2017-08-23 10:06:18 -0700162 received_exception_thrown_event = false;
Alex Light9fb1ab12017-09-05 09:32:49 -0700163 received_exception_handled_event = false;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000164 received_branch_event = false;
Alex Lighte814f9d2017-07-31 16:14:39 -0700165 received_watched_frame_pop = false;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200166 }
167
168 bool received_method_enter_event;
169 bool received_method_exit_event;
Alex Lightd7661582017-05-01 13:48:16 -0700170 bool received_method_exit_object_event;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200171 bool received_method_unwind_event;
172 bool received_dex_pc_moved_event;
173 bool received_field_read_event;
174 bool received_field_written_event;
Alex Lightd7661582017-05-01 13:48:16 -0700175 bool received_field_written_object_event;
Alex Light6e1607e2017-08-23 10:06:18 -0700176 bool received_exception_thrown_event;
Alex Light9fb1ab12017-09-05 09:32:49 -0700177 bool received_exception_handled_event;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000178 bool received_branch_event;
Alex Lighte814f9d2017-07-31 16:14:39 -0700179 bool received_watched_frame_pop;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200180
181 private:
182 DISALLOW_COPY_AND_ASSIGN(TestInstrumentationListener);
183};
184
185class InstrumentationTest : public CommonRuntimeTest {
186 public:
187 // Unique keys used to test Instrumentation::ConfigureStubs.
188 static constexpr const char* kClientOneKey = "TestClient1";
189 static constexpr const char* kClientTwoKey = "TestClient2";
190
191 void CheckConfigureStubs(const char* key, Instrumentation::InstrumentationLevel level) {
192 ScopedObjectAccess soa(Thread::Current());
193 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700194 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700195 gc::ScopedGCCriticalSection gcs(soa.Self(),
196 gc::kGcCauseInstrumentation,
197 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700198 ScopedSuspendAll ssa("Instrumentation::ConfigureStubs");
199 instr->ConfigureStubs(key, level);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200200 }
201
202 Instrumentation::InstrumentationLevel GetCurrentInstrumentationLevel() {
203 return Runtime::Current()->GetInstrumentation()->GetCurrentInstrumentationLevel();
204 }
205
206 size_t GetInstrumentationUserCount() {
207 ScopedObjectAccess soa(Thread::Current());
208 return Runtime::Current()->GetInstrumentation()->requested_instrumentation_levels_.size();
209 }
210
211 void TestEvent(uint32_t instrumentation_event) {
Alex Lightd7661582017-05-01 13:48:16 -0700212 TestEvent(instrumentation_event, nullptr, nullptr, false);
213 }
214
215 void TestEvent(uint32_t instrumentation_event,
216 ArtMethod* event_method,
217 ArtField* event_field,
218 bool with_object) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200219 ScopedObjectAccess soa(Thread::Current());
220 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
221 TestInstrumentationListener listener;
222 {
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700223 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700224 ScopedSuspendAll ssa("Add instrumentation listener");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200225 instr->AddListener(&listener, instrumentation_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200226 }
227
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200228 mirror::Object* const event_obj = nullptr;
229 const uint32_t event_dex_pc = 0;
Alex Lighte814f9d2017-07-31 16:14:39 -0700230 ShadowFrameAllocaUniquePtr test_frame = CREATE_SHADOW_FRAME(0, nullptr, event_method, 0);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200231
232 // Check the listener is registered and is notified of the event.
233 EXPECT_TRUE(HasEventListener(instr, instrumentation_event));
Alex Lightd7661582017-05-01 13:48:16 -0700234 EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
235 ReportEvent(instr,
236 instrumentation_event,
237 soa.Self(),
238 event_method,
239 event_obj,
240 event_field,
Alex Lighte814f9d2017-07-31 16:14:39 -0700241 event_dex_pc,
242 *test_frame);
Alex Lightd7661582017-05-01 13:48:16 -0700243 EXPECT_TRUE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200244
245 listener.Reset();
246 {
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700247 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700248 ScopedSuspendAll ssa("Remove instrumentation listener");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200249 instr->RemoveListener(&listener, instrumentation_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200250 }
251
252 // Check the listener is not registered and is not notified of the event.
253 EXPECT_FALSE(HasEventListener(instr, instrumentation_event));
Alex Lightd7661582017-05-01 13:48:16 -0700254 EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
255 ReportEvent(instr,
256 instrumentation_event,
257 soa.Self(),
258 event_method,
259 event_obj,
260 event_field,
Alex Lighte814f9d2017-07-31 16:14:39 -0700261 event_dex_pc,
262 *test_frame);
Alex Lightd7661582017-05-01 13:48:16 -0700263 EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200264 }
265
Mathieu Chartiere401d142015-04-22 13:56:20 -0700266 void DeoptimizeMethod(Thread* self, ArtMethod* method, bool enable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700267 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200268 Runtime* runtime = Runtime::Current();
269 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700270 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700271 gc::ScopedGCCriticalSection gcs(self,
272 gc::kGcCauseInstrumentation,
273 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700274 ScopedSuspendAll ssa("Single method deoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200275 if (enable_deoptimization) {
276 instrumentation->EnableDeoptimization();
277 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700278 instrumentation->Deoptimize(method);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200279 }
280
Mathieu Chartiere401d142015-04-22 13:56:20 -0700281 void UndeoptimizeMethod(Thread* self, ArtMethod* method,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200282 const char* key, bool disable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700283 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200284 Runtime* runtime = Runtime::Current();
285 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700286 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700287 gc::ScopedGCCriticalSection gcs(self,
288 gc::kGcCauseInstrumentation,
289 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700290 ScopedSuspendAll ssa("Single method undeoptimization");
Mathieu Chartiere401d142015-04-22 13:56:20 -0700291 instrumentation->Undeoptimize(method);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200292 if (disable_deoptimization) {
293 instrumentation->DisableDeoptimization(key);
294 }
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200295 }
296
297 void DeoptimizeEverything(Thread* self, const char* key, bool enable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700298 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200299 Runtime* runtime = Runtime::Current();
300 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700301 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700302 gc::ScopedGCCriticalSection gcs(self,
303 gc::kGcCauseInstrumentation,
304 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700305 ScopedSuspendAll ssa("Full deoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200306 if (enable_deoptimization) {
307 instrumentation->EnableDeoptimization();
308 }
309 instrumentation->DeoptimizeEverything(key);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200310 }
311
312 void UndeoptimizeEverything(Thread* self, const char* key, bool disable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700313 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200314 Runtime* runtime = Runtime::Current();
315 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700316 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700317 gc::ScopedGCCriticalSection gcs(self,
318 gc::kGcCauseInstrumentation,
319 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700320 ScopedSuspendAll ssa("Full undeoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200321 instrumentation->UndeoptimizeEverything(key);
322 if (disable_deoptimization) {
323 instrumentation->DisableDeoptimization(key);
324 }
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200325 }
326
327 void EnableMethodTracing(Thread* self, const char* key, bool needs_interpreter)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700328 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200329 Runtime* runtime = Runtime::Current();
330 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700331 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700332 gc::ScopedGCCriticalSection gcs(self,
333 gc::kGcCauseInstrumentation,
334 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700335 ScopedSuspendAll ssa("EnableMethodTracing");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200336 instrumentation->EnableMethodTracing(key, needs_interpreter);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200337 }
338
339 void DisableMethodTracing(Thread* self, const char* key)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700340 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200341 Runtime* runtime = Runtime::Current();
342 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700343 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700344 gc::ScopedGCCriticalSection gcs(self,
345 gc::kGcCauseInstrumentation,
346 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700347 ScopedSuspendAll ssa("EnableMethodTracing");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200348 instrumentation->DisableMethodTracing(key);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200349 }
350
351 private:
352 static bool HasEventListener(const instrumentation::Instrumentation* instr, uint32_t event_type)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700353 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200354 switch (event_type) {
355 case instrumentation::Instrumentation::kMethodEntered:
356 return instr->HasMethodEntryListeners();
357 case instrumentation::Instrumentation::kMethodExited:
358 return instr->HasMethodExitListeners();
359 case instrumentation::Instrumentation::kMethodUnwind:
360 return instr->HasMethodUnwindListeners();
361 case instrumentation::Instrumentation::kDexPcMoved:
362 return instr->HasDexPcListeners();
363 case instrumentation::Instrumentation::kFieldRead:
364 return instr->HasFieldReadListeners();
365 case instrumentation::Instrumentation::kFieldWritten:
366 return instr->HasFieldWriteListeners();
Alex Light6e1607e2017-08-23 10:06:18 -0700367 case instrumentation::Instrumentation::kExceptionThrown:
368 return instr->HasExceptionThrownListeners();
Alex Light9fb1ab12017-09-05 09:32:49 -0700369 case instrumentation::Instrumentation::kExceptionHandled:
370 return instr->HasExceptionHandledListeners();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000371 case instrumentation::Instrumentation::kBranch:
372 return instr->HasBranchListeners();
Alex Lighte814f9d2017-07-31 16:14:39 -0700373 case instrumentation::Instrumentation::kWatchedFramePop:
374 return instr->HasWatchedFramePopListeners();
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200375 default:
376 LOG(FATAL) << "Unknown instrumentation event " << event_type;
377 UNREACHABLE();
378 }
379 }
380
Alex Lightd7661582017-05-01 13:48:16 -0700381 static void ReportEvent(const instrumentation::Instrumentation* instr,
382 uint32_t event_type,
383 Thread* self,
384 ArtMethod* method,
385 mirror::Object* obj,
386 ArtField* field,
Alex Lighte814f9d2017-07-31 16:14:39 -0700387 uint32_t dex_pc,
388 const ShadowFrame& frame)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700389 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200390 switch (event_type) {
391 case instrumentation::Instrumentation::kMethodEntered:
392 instr->MethodEnterEvent(self, obj, method, dex_pc);
393 break;
394 case instrumentation::Instrumentation::kMethodExited: {
395 JValue value;
396 instr->MethodExitEvent(self, obj, method, dex_pc, value);
397 break;
398 }
399 case instrumentation::Instrumentation::kMethodUnwind:
400 instr->MethodUnwindEvent(self, obj, method, dex_pc);
401 break;
402 case instrumentation::Instrumentation::kDexPcMoved:
403 instr->DexPcMovedEvent(self, obj, method, dex_pc);
404 break;
405 case instrumentation::Instrumentation::kFieldRead:
Alex Lightd7661582017-05-01 13:48:16 -0700406 instr->FieldReadEvent(self, obj, method, dex_pc, field);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200407 break;
408 case instrumentation::Instrumentation::kFieldWritten: {
409 JValue value;
Alex Lightd7661582017-05-01 13:48:16 -0700410 instr->FieldWriteEvent(self, obj, method, dex_pc, field, value);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200411 break;
412 }
Alex Light6e1607e2017-08-23 10:06:18 -0700413 case instrumentation::Instrumentation::kExceptionThrown: {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200414 ThrowArithmeticExceptionDivideByZero();
415 mirror::Throwable* event_exception = self->GetException();
Alex Light6e1607e2017-08-23 10:06:18 -0700416 instr->ExceptionThrownEvent(self, event_exception);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200417 self->ClearException();
418 break;
419 }
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000420 case instrumentation::Instrumentation::kBranch:
421 instr->Branch(self, method, dex_pc, -1);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200422 break;
Alex Lighte814f9d2017-07-31 16:14:39 -0700423 case instrumentation::Instrumentation::kWatchedFramePop:
424 instr->WatchedFramePopped(self, frame);
425 break;
Alex Light9fb1ab12017-09-05 09:32:49 -0700426 case instrumentation::Instrumentation::kExceptionHandled: {
427 ThrowArithmeticExceptionDivideByZero();
428 mirror::Throwable* event_exception = self->GetException();
429 self->ClearException();
430 instr->ExceptionHandledEvent(self, event_exception);
431 break;
432 }
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200433 default:
434 LOG(FATAL) << "Unknown instrumentation event " << event_type;
435 UNREACHABLE();
436 }
437 }
438
439 static bool DidListenerReceiveEvent(const TestInstrumentationListener& listener,
Alex Lightd7661582017-05-01 13:48:16 -0700440 uint32_t event_type,
441 bool with_object) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200442 switch (event_type) {
443 case instrumentation::Instrumentation::kMethodEntered:
444 return listener.received_method_enter_event;
445 case instrumentation::Instrumentation::kMethodExited:
Alex Lightd7661582017-05-01 13:48:16 -0700446 return (!with_object && listener.received_method_exit_event) ||
447 (with_object && listener.received_method_exit_object_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200448 case instrumentation::Instrumentation::kMethodUnwind:
449 return listener.received_method_unwind_event;
450 case instrumentation::Instrumentation::kDexPcMoved:
451 return listener.received_dex_pc_moved_event;
452 case instrumentation::Instrumentation::kFieldRead:
453 return listener.received_field_read_event;
454 case instrumentation::Instrumentation::kFieldWritten:
Alex Lightd7661582017-05-01 13:48:16 -0700455 return (!with_object && listener.received_field_written_event) ||
456 (with_object && listener.received_field_written_object_event);
Alex Light6e1607e2017-08-23 10:06:18 -0700457 case instrumentation::Instrumentation::kExceptionThrown:
458 return listener.received_exception_thrown_event;
Alex Light9fb1ab12017-09-05 09:32:49 -0700459 case instrumentation::Instrumentation::kExceptionHandled:
460 return listener.received_exception_handled_event;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000461 case instrumentation::Instrumentation::kBranch:
462 return listener.received_branch_event;
Alex Lighte814f9d2017-07-31 16:14:39 -0700463 case instrumentation::Instrumentation::kWatchedFramePop:
464 return listener.received_watched_frame_pop;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200465 default:
466 LOG(FATAL) << "Unknown instrumentation event " << event_type;
467 UNREACHABLE();
468 }
469 }
470};
471
472TEST_F(InstrumentationTest, NoInstrumentation) {
473 ScopedObjectAccess soa(Thread::Current());
474 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
475 ASSERT_NE(instr, nullptr);
476
477 EXPECT_FALSE(instr->AreExitStubsInstalled());
478 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
479 EXPECT_FALSE(instr->IsActive());
480 EXPECT_FALSE(instr->ShouldNotifyMethodEnterExitEvents());
481
482 // Test interpreter table is the default one.
483 EXPECT_EQ(instrumentation::kMainHandlerTable, instr->GetInterpreterHandlerTable());
484
485 // Check there is no registered listener.
486 EXPECT_FALSE(instr->HasDexPcListeners());
Alex Light6e1607e2017-08-23 10:06:18 -0700487 EXPECT_FALSE(instr->HasExceptionThrownListeners());
Alex Light9fb1ab12017-09-05 09:32:49 -0700488 EXPECT_FALSE(instr->HasExceptionHandledListeners());
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200489 EXPECT_FALSE(instr->HasFieldReadListeners());
490 EXPECT_FALSE(instr->HasFieldWriteListeners());
491 EXPECT_FALSE(instr->HasMethodEntryListeners());
492 EXPECT_FALSE(instr->HasMethodExitListeners());
493 EXPECT_FALSE(instr->IsActive());
494}
495
496// Test instrumentation listeners for each event.
497TEST_F(InstrumentationTest, MethodEntryEvent) {
Mingyao Yang2ee17902017-08-30 11:37:08 -0700498 ScopedObjectAccess soa(Thread::Current());
499 jobject class_loader = LoadDex("Instrumentation");
500 Runtime* const runtime = Runtime::Current();
501 ClassLinker* class_linker = runtime->GetClassLinker();
502 StackHandleScope<1> hs(soa.Self());
503 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Vladimir Markoe9987b02018-05-22 16:26:43 +0100504 ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
Mingyao Yang2ee17902017-08-30 11:37:08 -0700505 ASSERT_TRUE(klass != nullptr);
506 ArtMethod* method =
507 klass->FindClassMethod("returnReference", "()Ljava/lang/Object;", kRuntimePointerSize);
508 ASSERT_TRUE(method != nullptr);
509 ASSERT_TRUE(method->IsDirect());
510 ASSERT_TRUE(method->GetDeclaringClass() == klass);
511 TestEvent(instrumentation::Instrumentation::kMethodEntered,
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700512 /*event_method=*/ method,
513 /*event_field=*/ nullptr,
514 /*with_object=*/ true);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200515}
516
Alex Lightd7661582017-05-01 13:48:16 -0700517TEST_F(InstrumentationTest, MethodExitObjectEvent) {
518 ScopedObjectAccess soa(Thread::Current());
519 jobject class_loader = LoadDex("Instrumentation");
520 Runtime* const runtime = Runtime::Current();
521 ClassLinker* class_linker = runtime->GetClassLinker();
522 StackHandleScope<1> hs(soa.Self());
523 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Vladimir Markoe9987b02018-05-22 16:26:43 +0100524 ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
Alex Lightd7661582017-05-01 13:48:16 -0700525 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100526 ArtMethod* method =
527 klass->FindClassMethod("returnReference", "()Ljava/lang/Object;", kRuntimePointerSize);
Alex Lightd7661582017-05-01 13:48:16 -0700528 ASSERT_TRUE(method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100529 ASSERT_TRUE(method->IsDirect());
530 ASSERT_TRUE(method->GetDeclaringClass() == klass);
Alex Lightd7661582017-05-01 13:48:16 -0700531 TestEvent(instrumentation::Instrumentation::kMethodExited,
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700532 /*event_method=*/ method,
533 /*event_field=*/ nullptr,
534 /*with_object=*/ true);
Alex Lightd7661582017-05-01 13:48:16 -0700535}
536
537TEST_F(InstrumentationTest, MethodExitPrimEvent) {
538 ScopedObjectAccess soa(Thread::Current());
539 jobject class_loader = LoadDex("Instrumentation");
540 Runtime* const runtime = Runtime::Current();
541 ClassLinker* class_linker = runtime->GetClassLinker();
542 StackHandleScope<1> hs(soa.Self());
543 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Vladimir Markoe9987b02018-05-22 16:26:43 +0100544 ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
Alex Lightd7661582017-05-01 13:48:16 -0700545 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100546 ArtMethod* method = klass->FindClassMethod("returnPrimitive", "()I", kRuntimePointerSize);
Alex Lightd7661582017-05-01 13:48:16 -0700547 ASSERT_TRUE(method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100548 ASSERT_TRUE(method->IsDirect());
549 ASSERT_TRUE(method->GetDeclaringClass() == klass);
Alex Lightd7661582017-05-01 13:48:16 -0700550 TestEvent(instrumentation::Instrumentation::kMethodExited,
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700551 /*event_method=*/ method,
552 /*event_field=*/ nullptr,
553 /*with_object=*/ false);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200554}
555
556TEST_F(InstrumentationTest, MethodUnwindEvent) {
557 TestEvent(instrumentation::Instrumentation::kMethodUnwind);
558}
559
560TEST_F(InstrumentationTest, DexPcMovedEvent) {
561 TestEvent(instrumentation::Instrumentation::kDexPcMoved);
562}
563
564TEST_F(InstrumentationTest, FieldReadEvent) {
565 TestEvent(instrumentation::Instrumentation::kFieldRead);
566}
567
Alex Lighte814f9d2017-07-31 16:14:39 -0700568TEST_F(InstrumentationTest, WatchedFramePop) {
569 TestEvent(instrumentation::Instrumentation::kWatchedFramePop);
570}
571
Alex Lightd7661582017-05-01 13:48:16 -0700572TEST_F(InstrumentationTest, FieldWriteObjectEvent) {
573 ScopedObjectAccess soa(Thread::Current());
574 jobject class_loader = LoadDex("Instrumentation");
575 Runtime* const runtime = Runtime::Current();
576 ClassLinker* class_linker = runtime->GetClassLinker();
577 StackHandleScope<1> hs(soa.Self());
578 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Vladimir Markoe9987b02018-05-22 16:26:43 +0100579 ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
Alex Lightd7661582017-05-01 13:48:16 -0700580 ASSERT_TRUE(klass != nullptr);
581 ArtField* field = klass->FindDeclaredStaticField("referenceField", "Ljava/lang/Object;");
582 ASSERT_TRUE(field != nullptr);
583
584 TestEvent(instrumentation::Instrumentation::kFieldWritten,
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700585 /*event_method=*/ nullptr,
586 /*event_field=*/ field,
587 /*with_object=*/ true);
Alex Lightd7661582017-05-01 13:48:16 -0700588}
589
590TEST_F(InstrumentationTest, FieldWritePrimEvent) {
591 ScopedObjectAccess soa(Thread::Current());
592 jobject class_loader = LoadDex("Instrumentation");
593 Runtime* const runtime = Runtime::Current();
594 ClassLinker* class_linker = runtime->GetClassLinker();
595 StackHandleScope<1> hs(soa.Self());
596 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Vladimir Markoe9987b02018-05-22 16:26:43 +0100597 ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
Alex Lightd7661582017-05-01 13:48:16 -0700598 ASSERT_TRUE(klass != nullptr);
599 ArtField* field = klass->FindDeclaredStaticField("primitiveField", "I");
600 ASSERT_TRUE(field != nullptr);
601
602 TestEvent(instrumentation::Instrumentation::kFieldWritten,
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700603 /*event_method=*/ nullptr,
604 /*event_field=*/ field,
605 /*with_object=*/ false);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200606}
607
Alex Light9fb1ab12017-09-05 09:32:49 -0700608TEST_F(InstrumentationTest, ExceptionHandledEvent) {
609 TestEvent(instrumentation::Instrumentation::kExceptionHandled);
610}
611
Alex Light6e1607e2017-08-23 10:06:18 -0700612TEST_F(InstrumentationTest, ExceptionThrownEvent) {
613 TestEvent(instrumentation::Instrumentation::kExceptionThrown);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200614}
615
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000616TEST_F(InstrumentationTest, BranchEvent) {
617 TestEvent(instrumentation::Instrumentation::kBranch);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200618}
619
620TEST_F(InstrumentationTest, DeoptimizeDirectMethod) {
621 ScopedObjectAccess soa(Thread::Current());
622 jobject class_loader = LoadDex("Instrumentation");
623 Runtime* const runtime = Runtime::Current();
624 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
625 ClassLinker* class_linker = runtime->GetClassLinker();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700626 StackHandleScope<1> hs(soa.Self());
Mathieu Chartier0795f232016-09-27 18:43:30 -0700627 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Vladimir Markoe9987b02018-05-22 16:26:43 +0100628 ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200629 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100630 ArtMethod* method_to_deoptimize =
631 klass->FindClassMethod("instanceMethod", "()V", kRuntimePointerSize);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700632 ASSERT_TRUE(method_to_deoptimize != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100633 ASSERT_TRUE(method_to_deoptimize->IsDirect());
634 ASSERT_TRUE(method_to_deoptimize->GetDeclaringClass() == klass);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200635
636 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700637 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200638
639 DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);
640
641 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
642 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700643 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200644
645 constexpr const char* instrumentation_key = "DeoptimizeDirectMethod";
646 UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
647
648 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700649 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200650}
651
652TEST_F(InstrumentationTest, FullDeoptimization) {
653 ScopedObjectAccess soa(Thread::Current());
654 Runtime* const runtime = Runtime::Current();
655 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
656 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
657
658 constexpr const char* instrumentation_key = "FullDeoptimization";
659 DeoptimizeEverything(soa.Self(), instrumentation_key, true);
660
661 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
662 EXPECT_TRUE(instr->AreExitStubsInstalled());
663
664 UndeoptimizeEverything(soa.Self(), instrumentation_key, true);
665
666 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
667}
668
669TEST_F(InstrumentationTest, MixedDeoptimization) {
670 ScopedObjectAccess soa(Thread::Current());
671 jobject class_loader = LoadDex("Instrumentation");
672 Runtime* const runtime = Runtime::Current();
673 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
674 ClassLinker* class_linker = runtime->GetClassLinker();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700675 StackHandleScope<1> hs(soa.Self());
Mathieu Chartier0795f232016-09-27 18:43:30 -0700676 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Vladimir Markoe9987b02018-05-22 16:26:43 +0100677 ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200678 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100679 ArtMethod* method_to_deoptimize =
680 klass->FindClassMethod("instanceMethod", "()V", kRuntimePointerSize);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700681 ASSERT_TRUE(method_to_deoptimize != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100682 ASSERT_TRUE(method_to_deoptimize->IsDirect());
683 ASSERT_TRUE(method_to_deoptimize->GetDeclaringClass() == klass);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200684
685 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700686 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200687
688 DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);
689 // Deoptimizing a method does not change instrumentation level.
690 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
691 GetCurrentInstrumentationLevel());
692 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
693 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700694 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200695
696 constexpr const char* instrumentation_key = "MixedDeoptimization";
697 DeoptimizeEverything(soa.Self(), instrumentation_key, false);
698 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
699 GetCurrentInstrumentationLevel());
700 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
701 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700702 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200703
704 UndeoptimizeEverything(soa.Self(), instrumentation_key, false);
705 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
706 GetCurrentInstrumentationLevel());
707 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
708 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700709 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200710
711 UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
712 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
713 GetCurrentInstrumentationLevel());
714 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700715 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200716}
717
718TEST_F(InstrumentationTest, MethodTracing_Interpreter) {
719 ScopedObjectAccess soa(Thread::Current());
720 Runtime* const runtime = Runtime::Current();
721 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
722 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
723
724 constexpr const char* instrumentation_key = "MethodTracing";
725 EnableMethodTracing(soa.Self(), instrumentation_key, true);
726 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
727 GetCurrentInstrumentationLevel());
728 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
729 EXPECT_TRUE(instr->AreExitStubsInstalled());
730
731 DisableMethodTracing(soa.Self(), instrumentation_key);
732 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
733 GetCurrentInstrumentationLevel());
734 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
735}
736
737TEST_F(InstrumentationTest, MethodTracing_InstrumentationEntryExitStubs) {
738 ScopedObjectAccess soa(Thread::Current());
739 Runtime* const runtime = Runtime::Current();
740 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
741 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
742
743 constexpr const char* instrumentation_key = "MethodTracing";
744 EnableMethodTracing(soa.Self(), instrumentation_key, false);
745 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
746 GetCurrentInstrumentationLevel());
747 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
748 EXPECT_TRUE(instr->AreExitStubsInstalled());
749
750 DisableMethodTracing(soa.Self(), instrumentation_key);
751 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
752 GetCurrentInstrumentationLevel());
753 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
754}
755
756// We use a macro to print the line number where the test is failing.
757#define CHECK_INSTRUMENTATION(_level, _user_count) \
758 do { \
759 Instrumentation* const instr = Runtime::Current()->GetInstrumentation(); \
760 bool interpreter = \
Chih-Hung Hsieh1a0de6a2016-08-26 15:06:11 -0700761 ((_level) == Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter); \
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200762 EXPECT_EQ(_level, GetCurrentInstrumentationLevel()); \
763 EXPECT_EQ(_user_count, GetInstrumentationUserCount()); \
764 if (instr->IsForcedInterpretOnly()) { \
765 EXPECT_TRUE(instr->InterpretOnly()); \
766 } else if (interpreter) { \
767 EXPECT_TRUE(instr->InterpretOnly()); \
768 } else { \
769 EXPECT_FALSE(instr->InterpretOnly()); \
770 } \
771 if (interpreter) { \
772 EXPECT_TRUE(instr->AreAllMethodsDeoptimized()); \
773 } else { \
774 EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); \
775 } \
776 } while (false)
777
778TEST_F(InstrumentationTest, ConfigureStubs_Nothing) {
779 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
780
781 // Check no-op.
782 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
783 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
784}
785
786TEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubs) {
787 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
788
789 // Check we can switch to instrumentation stubs
790 CheckConfigureStubs(kClientOneKey,
791 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
792 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
793 1U);
794
795 // Check we can disable instrumentation.
796 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
797 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
798}
799
800TEST_F(InstrumentationTest, ConfigureStubs_Interpreter) {
801 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
802
803 // Check we can switch to interpreter
804 CheckConfigureStubs(kClientOneKey,
805 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
806 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
807
808 // Check we can disable instrumentation.
809 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
810 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
811}
812
813TEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubsToInterpreter) {
814 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
815
816 // Configure stubs with instrumentation stubs.
817 CheckConfigureStubs(kClientOneKey,
818 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
819 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
820 1U);
821
822 // Configure stubs with interpreter.
823 CheckConfigureStubs(kClientOneKey,
824 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
825 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
826
827 // Check we can disable instrumentation.
828 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
829 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
830}
831
832TEST_F(InstrumentationTest, ConfigureStubs_InterpreterToInstrumentationStubs) {
833 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
834
835 // Configure stubs with interpreter.
836 CheckConfigureStubs(kClientOneKey,
837 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
838 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
839
840 // Configure stubs with instrumentation stubs.
841 CheckConfigureStubs(kClientOneKey,
842 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
Alex Light40607862019-05-06 18:16:24 +0000843 // Make sure we are still interpreter since going from interpreter->instrumentation is dangerous.
844 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200845 1U);
846
847 // Check we can disable instrumentation.
848 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
849 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
850}
851
852TEST_F(InstrumentationTest,
853 ConfigureStubs_InstrumentationStubsToInterpreterToInstrumentationStubs) {
854 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
855
856 // Configure stubs with instrumentation stubs.
857 CheckConfigureStubs(kClientOneKey,
858 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
859 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
860 1U);
861
862 // Configure stubs with interpreter.
863 CheckConfigureStubs(kClientOneKey,
864 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
865 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
866
867 // Configure stubs with instrumentation stubs again.
868 CheckConfigureStubs(kClientOneKey,
869 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
Alex Light40607862019-05-06 18:16:24 +0000870 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200871 1U);
872
873 // Check we can disable instrumentation.
874 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
875 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
876}
877
878TEST_F(InstrumentationTest, MultiConfigureStubs_Nothing) {
879 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
880
881 // Check kInstrumentNothing with two clients.
882 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
883 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
884
885 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
886 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
887}
888
889TEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubs) {
890 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
891
892 // Configure stubs with instrumentation stubs for 1st client.
893 CheckConfigureStubs(kClientOneKey,
894 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
895 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
896 1U);
897
898 // Configure stubs with instrumentation stubs for 2nd client.
899 CheckConfigureStubs(kClientTwoKey,
900 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
901 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
902 2U);
903
904 // 1st client requests instrumentation deactivation but 2nd client still needs
905 // instrumentation stubs.
906 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
907 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
908 1U);
909
910 // 2nd client requests instrumentation deactivation
911 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
912 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
913}
914
915TEST_F(InstrumentationTest, MultiConfigureStubs_Interpreter) {
916 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
917
918 // Configure stubs with interpreter for 1st client.
919 CheckConfigureStubs(kClientOneKey,
920 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
921 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
922
923 // Configure stubs with interpreter for 2nd client.
924 CheckConfigureStubs(kClientTwoKey,
925 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
926 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
927
928 // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
929 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
930 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
931
932 // 2nd client requests instrumentation deactivation
933 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
934 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
935}
936
937TEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubsThenInterpreter) {
938 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
939
940 // Configure stubs with instrumentation stubs for 1st client.
941 CheckConfigureStubs(kClientOneKey,
942 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
943 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
944 1U);
945
946 // Configure stubs with interpreter for 2nd client.
947 CheckConfigureStubs(kClientTwoKey,
948 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
949 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
950
951 // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
952 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
953 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
954
955 // 2nd client requests instrumentation deactivation
956 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
957 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
958}
959
960TEST_F(InstrumentationTest, MultiConfigureStubs_InterpreterThenInstrumentationStubs) {
961 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
962
963 // Configure stubs with interpreter for 1st client.
964 CheckConfigureStubs(kClientOneKey,
965 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
966 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
967
968 // Configure stubs with instrumentation stubs for 2nd client.
969 CheckConfigureStubs(kClientTwoKey,
970 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
971 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
972
973 // 1st client requests instrumentation deactivation but 2nd client still needs
Alex Light40607862019-05-06 18:16:24 +0000974 // instrumentation stubs. Since we already got interpreter stubs we need to stay there.
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200975 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
Alex Light40607862019-05-06 18:16:24 +0000976 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200977 1U);
978
979 // 2nd client requests instrumentation deactivation
980 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
981 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
982}
983
984} // namespace instrumentation
985} // namespace art