blob: 6284299855fd2b21ecb5f8e74b9a1dd17d0831ab [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
Alex Lightb7c640d2019-03-20 15:52:13 -070019#include "android-base/macros.h"
Vladimir Markoba118822017-06-12 15:41:56 +010020#include "art_method-inl.h"
Andreas Gampe542451c2016-07-26 09:02:02 -070021#include "base/enums.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070022#include "class_linker-inl.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020023#include "common_runtime_test.h"
24#include "common_throws.h"
David Sehr9e734c72018-01-04 17:56:19 -080025#include "dex/dex_file.h"
Mathieu Chartieraa516822015-10-02 15:53:37 -070026#include "gc/scoped_gc_critical_section.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020027#include "handle_scope-inl.h"
Vladimir Markoa3ad0cd2018-05-04 10:06:38 +010028#include "jni/jni_internal.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020029#include "jvalue.h"
30#include "runtime.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070031#include "scoped_thread_state_change-inl.h"
Alex Lighte814f9d2017-07-31 16:14:39 -070032#include "interpreter/shadow_frame.h"
Alex Lightd7661582017-05-01 13:48:16 -070033#include "thread-inl.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070034#include "thread_list.h"
Alex Lightd7661582017-05-01 13:48:16 -070035#include "well_known_classes.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020036
37namespace art {
38namespace instrumentation {
39
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010040class TestInstrumentationListener final : public instrumentation::InstrumentationListener {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020041 public:
42 TestInstrumentationListener()
Alex Lightd7661582017-05-01 13:48:16 -070043 : received_method_enter_event(false),
44 received_method_exit_event(false),
45 received_method_exit_object_event(false),
46 received_method_unwind_event(false),
47 received_dex_pc_moved_event(false),
48 received_field_read_event(false),
49 received_field_written_event(false),
50 received_field_written_object_event(false),
Alex Light6e1607e2017-08-23 10:06:18 -070051 received_exception_thrown_event(false),
Alex Light9fb1ab12017-09-05 09:32:49 -070052 received_exception_handled_event(false),
Alex Lightd7661582017-05-01 13:48:16 -070053 received_branch_event(false),
Alex Lighte814f9d2017-07-31 16:14:39 -070054 received_watched_frame_pop(false) {}
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020055
56 virtual ~TestInstrumentationListener() {}
57
58 void MethodEntered(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070059 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070060 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020061 uint32_t dex_pc ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010062 override REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020063 received_method_enter_event = true;
64 }
65
66 void MethodExited(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070067 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
68 ArtMethod* method ATTRIBUTE_UNUSED,
69 uint32_t dex_pc ATTRIBUTE_UNUSED,
Alex Lightb7c640d2019-03-20 15:52:13 -070070 instrumentation::OptionalFrame frame ATTRIBUTE_UNUSED,
71 MutableHandle<mirror::Object>& return_value ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010072 override REQUIRES_SHARED(Locks::mutator_lock_) {
Alex Lightd7661582017-05-01 13:48:16 -070073 received_method_exit_object_event = true;
74 }
75
76 void MethodExited(Thread* thread ATTRIBUTE_UNUSED,
77 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070078 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020079 uint32_t dex_pc ATTRIBUTE_UNUSED,
Alex Lightb7c640d2019-03-20 15:52:13 -070080 instrumentation::OptionalFrame frame ATTRIBUTE_UNUSED,
81 JValue& return_value ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010082 override REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020083 received_method_exit_event = true;
84 }
85
86 void MethodUnwind(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070087 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070088 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020089 uint32_t dex_pc ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010090 override REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020091 received_method_unwind_event = true;
92 }
93
94 void DexPcMoved(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070095 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070096 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020097 uint32_t new_dex_pc ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010098 override REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020099 received_dex_pc_moved_event = true;
100 }
101
102 void FieldRead(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -0700103 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700104 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200105 uint32_t dex_pc ATTRIBUTE_UNUSED,
106 ArtField* field ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100107 override REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200108 received_field_read_event = true;
109 }
110
111 void FieldWritten(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -0700112 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
113 ArtMethod* method ATTRIBUTE_UNUSED,
114 uint32_t dex_pc ATTRIBUTE_UNUSED,
115 ArtField* field ATTRIBUTE_UNUSED,
116 Handle<mirror::Object> field_value ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100117 override REQUIRES_SHARED(Locks::mutator_lock_) {
Alex Lightd7661582017-05-01 13:48:16 -0700118 received_field_written_object_event = true;
119 }
120
121 void FieldWritten(Thread* thread ATTRIBUTE_UNUSED,
122 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700123 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200124 uint32_t dex_pc ATTRIBUTE_UNUSED,
125 ArtField* field ATTRIBUTE_UNUSED,
126 const JValue& field_value ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100127 override REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200128 received_field_written_event = true;
129 }
130
Alex Light6e1607e2017-08-23 10:06:18 -0700131 void ExceptionThrown(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -0700132 Handle<mirror::Throwable> exception_object ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100133 override REQUIRES_SHARED(Locks::mutator_lock_) {
Alex Light6e1607e2017-08-23 10:06:18 -0700134 received_exception_thrown_event = true;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200135 }
136
Alex Light9fb1ab12017-09-05 09:32:49 -0700137 void ExceptionHandled(Thread* self ATTRIBUTE_UNUSED,
138 Handle<mirror::Throwable> throwable ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100139 override REQUIRES_SHARED(Locks::mutator_lock_) {
Alex Light9fb1ab12017-09-05 09:32:49 -0700140 received_exception_handled_event = true;
141 }
142
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000143 void Branch(Thread* thread ATTRIBUTE_UNUSED,
144 ArtMethod* method ATTRIBUTE_UNUSED,
145 uint32_t dex_pc ATTRIBUTE_UNUSED,
146 int32_t dex_pc_offset ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100147 override REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000148 received_branch_event = true;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200149 }
150
Alex Lighte814f9d2017-07-31 16:14:39 -0700151 void WatchedFramePop(Thread* thread ATTRIBUTE_UNUSED, const ShadowFrame& frame ATTRIBUTE_UNUSED)
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100152 override REQUIRES_SHARED(Locks::mutator_lock_) {
Alex Lighte814f9d2017-07-31 16:14:39 -0700153 received_watched_frame_pop = true;
154 }
155
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200156 void Reset() {
157 received_method_enter_event = false;
158 received_method_exit_event = false;
Alex Lightd7661582017-05-01 13:48:16 -0700159 received_method_exit_object_event = false;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200160 received_method_unwind_event = false;
161 received_dex_pc_moved_event = false;
162 received_field_read_event = false;
163 received_field_written_event = false;
Alex Lightd7661582017-05-01 13:48:16 -0700164 received_field_written_object_event = false;
Alex Light6e1607e2017-08-23 10:06:18 -0700165 received_exception_thrown_event = false;
Alex Light9fb1ab12017-09-05 09:32:49 -0700166 received_exception_handled_event = false;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000167 received_branch_event = false;
Alex Lighte814f9d2017-07-31 16:14:39 -0700168 received_watched_frame_pop = false;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200169 }
170
171 bool received_method_enter_event;
172 bool received_method_exit_event;
Alex Lightd7661582017-05-01 13:48:16 -0700173 bool received_method_exit_object_event;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200174 bool received_method_unwind_event;
175 bool received_dex_pc_moved_event;
176 bool received_field_read_event;
177 bool received_field_written_event;
Alex Lightd7661582017-05-01 13:48:16 -0700178 bool received_field_written_object_event;
Alex Light6e1607e2017-08-23 10:06:18 -0700179 bool received_exception_thrown_event;
Alex Light9fb1ab12017-09-05 09:32:49 -0700180 bool received_exception_handled_event;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000181 bool received_branch_event;
Alex Lighte814f9d2017-07-31 16:14:39 -0700182 bool received_watched_frame_pop;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200183
184 private:
185 DISALLOW_COPY_AND_ASSIGN(TestInstrumentationListener);
186};
187
188class InstrumentationTest : public CommonRuntimeTest {
189 public:
190 // Unique keys used to test Instrumentation::ConfigureStubs.
191 static constexpr const char* kClientOneKey = "TestClient1";
192 static constexpr const char* kClientTwoKey = "TestClient2";
193
194 void CheckConfigureStubs(const char* key, Instrumentation::InstrumentationLevel level) {
195 ScopedObjectAccess soa(Thread::Current());
196 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700197 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700198 gc::ScopedGCCriticalSection gcs(soa.Self(),
199 gc::kGcCauseInstrumentation,
200 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700201 ScopedSuspendAll ssa("Instrumentation::ConfigureStubs");
202 instr->ConfigureStubs(key, level);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200203 }
204
205 Instrumentation::InstrumentationLevel GetCurrentInstrumentationLevel() {
206 return Runtime::Current()->GetInstrumentation()->GetCurrentInstrumentationLevel();
207 }
208
209 size_t GetInstrumentationUserCount() {
210 ScopedObjectAccess soa(Thread::Current());
211 return Runtime::Current()->GetInstrumentation()->requested_instrumentation_levels_.size();
212 }
213
214 void TestEvent(uint32_t instrumentation_event) {
Alex Lightd7661582017-05-01 13:48:16 -0700215 TestEvent(instrumentation_event, nullptr, nullptr, false);
216 }
217
218 void TestEvent(uint32_t instrumentation_event,
219 ArtMethod* event_method,
220 ArtField* event_field,
221 bool with_object) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200222 ScopedObjectAccess soa(Thread::Current());
223 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
224 TestInstrumentationListener listener;
225 {
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700226 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700227 ScopedSuspendAll ssa("Add instrumentation listener");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200228 instr->AddListener(&listener, instrumentation_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200229 }
230
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200231 mirror::Object* const event_obj = nullptr;
232 const uint32_t event_dex_pc = 0;
Alex Lighte814f9d2017-07-31 16:14:39 -0700233 ShadowFrameAllocaUniquePtr test_frame = CREATE_SHADOW_FRAME(0, nullptr, event_method, 0);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200234
235 // Check the listener is registered and is notified of the event.
236 EXPECT_TRUE(HasEventListener(instr, instrumentation_event));
Alex Lightd7661582017-05-01 13:48:16 -0700237 EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
238 ReportEvent(instr,
239 instrumentation_event,
240 soa.Self(),
241 event_method,
242 event_obj,
243 event_field,
Alex Lighte814f9d2017-07-31 16:14:39 -0700244 event_dex_pc,
245 *test_frame);
Alex Lightd7661582017-05-01 13:48:16 -0700246 EXPECT_TRUE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200247
248 listener.Reset();
249 {
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700250 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700251 ScopedSuspendAll ssa("Remove instrumentation listener");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200252 instr->RemoveListener(&listener, instrumentation_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200253 }
254
255 // Check the listener is not registered and is not notified of the event.
256 EXPECT_FALSE(HasEventListener(instr, instrumentation_event));
Alex Lightd7661582017-05-01 13:48:16 -0700257 EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
258 ReportEvent(instr,
259 instrumentation_event,
260 soa.Self(),
261 event_method,
262 event_obj,
263 event_field,
Alex Lighte814f9d2017-07-31 16:14:39 -0700264 event_dex_pc,
265 *test_frame);
Alex Lightd7661582017-05-01 13:48:16 -0700266 EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200267 }
268
Mathieu Chartiere401d142015-04-22 13:56:20 -0700269 void DeoptimizeMethod(Thread* self, ArtMethod* method, bool enable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700270 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200271 Runtime* runtime = Runtime::Current();
272 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700273 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700274 gc::ScopedGCCriticalSection gcs(self,
275 gc::kGcCauseInstrumentation,
276 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700277 ScopedSuspendAll ssa("Single method deoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200278 if (enable_deoptimization) {
279 instrumentation->EnableDeoptimization();
280 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700281 instrumentation->Deoptimize(method);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200282 }
283
Mathieu Chartiere401d142015-04-22 13:56:20 -0700284 void UndeoptimizeMethod(Thread* self, ArtMethod* method,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200285 const char* key, bool disable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700286 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200287 Runtime* runtime = Runtime::Current();
288 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700289 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700290 gc::ScopedGCCriticalSection gcs(self,
291 gc::kGcCauseInstrumentation,
292 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700293 ScopedSuspendAll ssa("Single method undeoptimization");
Mathieu Chartiere401d142015-04-22 13:56:20 -0700294 instrumentation->Undeoptimize(method);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200295 if (disable_deoptimization) {
296 instrumentation->DisableDeoptimization(key);
297 }
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200298 }
299
300 void DeoptimizeEverything(Thread* self, const char* key, bool enable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700301 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200302 Runtime* runtime = Runtime::Current();
303 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700304 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700305 gc::ScopedGCCriticalSection gcs(self,
306 gc::kGcCauseInstrumentation,
307 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700308 ScopedSuspendAll ssa("Full deoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200309 if (enable_deoptimization) {
310 instrumentation->EnableDeoptimization();
311 }
312 instrumentation->DeoptimizeEverything(key);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200313 }
314
315 void UndeoptimizeEverything(Thread* self, const char* key, bool disable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700316 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200317 Runtime* runtime = Runtime::Current();
318 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700319 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700320 gc::ScopedGCCriticalSection gcs(self,
321 gc::kGcCauseInstrumentation,
322 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700323 ScopedSuspendAll ssa("Full undeoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200324 instrumentation->UndeoptimizeEverything(key);
325 if (disable_deoptimization) {
326 instrumentation->DisableDeoptimization(key);
327 }
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200328 }
329
330 void EnableMethodTracing(Thread* self, const char* key, bool needs_interpreter)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700331 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200332 Runtime* runtime = Runtime::Current();
333 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700334 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700335 gc::ScopedGCCriticalSection gcs(self,
336 gc::kGcCauseInstrumentation,
337 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700338 ScopedSuspendAll ssa("EnableMethodTracing");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200339 instrumentation->EnableMethodTracing(key, needs_interpreter);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200340 }
341
342 void DisableMethodTracing(Thread* self, const char* key)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700343 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200344 Runtime* runtime = Runtime::Current();
345 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700346 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700347 gc::ScopedGCCriticalSection gcs(self,
348 gc::kGcCauseInstrumentation,
349 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700350 ScopedSuspendAll ssa("EnableMethodTracing");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200351 instrumentation->DisableMethodTracing(key);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200352 }
353
354 private:
355 static bool HasEventListener(const instrumentation::Instrumentation* instr, uint32_t event_type)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700356 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200357 switch (event_type) {
358 case instrumentation::Instrumentation::kMethodEntered:
359 return instr->HasMethodEntryListeners();
360 case instrumentation::Instrumentation::kMethodExited:
361 return instr->HasMethodExitListeners();
362 case instrumentation::Instrumentation::kMethodUnwind:
363 return instr->HasMethodUnwindListeners();
364 case instrumentation::Instrumentation::kDexPcMoved:
365 return instr->HasDexPcListeners();
366 case instrumentation::Instrumentation::kFieldRead:
367 return instr->HasFieldReadListeners();
368 case instrumentation::Instrumentation::kFieldWritten:
369 return instr->HasFieldWriteListeners();
Alex Light6e1607e2017-08-23 10:06:18 -0700370 case instrumentation::Instrumentation::kExceptionThrown:
371 return instr->HasExceptionThrownListeners();
Alex Light9fb1ab12017-09-05 09:32:49 -0700372 case instrumentation::Instrumentation::kExceptionHandled:
373 return instr->HasExceptionHandledListeners();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000374 case instrumentation::Instrumentation::kBranch:
375 return instr->HasBranchListeners();
Alex Lighte814f9d2017-07-31 16:14:39 -0700376 case instrumentation::Instrumentation::kWatchedFramePop:
377 return instr->HasWatchedFramePopListeners();
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200378 default:
379 LOG(FATAL) << "Unknown instrumentation event " << event_type;
380 UNREACHABLE();
381 }
382 }
383
Alex Lightd7661582017-05-01 13:48:16 -0700384 static void ReportEvent(const instrumentation::Instrumentation* instr,
385 uint32_t event_type,
386 Thread* self,
387 ArtMethod* method,
388 mirror::Object* obj,
389 ArtField* field,
Alex Lighte814f9d2017-07-31 16:14:39 -0700390 uint32_t dex_pc,
391 const ShadowFrame& frame)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700392 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200393 switch (event_type) {
394 case instrumentation::Instrumentation::kMethodEntered:
395 instr->MethodEnterEvent(self, obj, method, dex_pc);
396 break;
397 case instrumentation::Instrumentation::kMethodExited: {
398 JValue value;
Alex Lightb7c640d2019-03-20 15:52:13 -0700399 instr->MethodExitEvent(self, obj, method, dex_pc, {}, value);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200400 break;
401 }
402 case instrumentation::Instrumentation::kMethodUnwind:
403 instr->MethodUnwindEvent(self, obj, method, dex_pc);
404 break;
405 case instrumentation::Instrumentation::kDexPcMoved:
406 instr->DexPcMovedEvent(self, obj, method, dex_pc);
407 break;
408 case instrumentation::Instrumentation::kFieldRead:
Alex Lightd7661582017-05-01 13:48:16 -0700409 instr->FieldReadEvent(self, obj, method, dex_pc, field);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200410 break;
411 case instrumentation::Instrumentation::kFieldWritten: {
412 JValue value;
Alex Lightd7661582017-05-01 13:48:16 -0700413 instr->FieldWriteEvent(self, obj, method, dex_pc, field, value);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200414 break;
415 }
Alex Light6e1607e2017-08-23 10:06:18 -0700416 case instrumentation::Instrumentation::kExceptionThrown: {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200417 ThrowArithmeticExceptionDivideByZero();
418 mirror::Throwable* event_exception = self->GetException();
Alex Light6e1607e2017-08-23 10:06:18 -0700419 instr->ExceptionThrownEvent(self, event_exception);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200420 self->ClearException();
421 break;
422 }
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000423 case instrumentation::Instrumentation::kBranch:
424 instr->Branch(self, method, dex_pc, -1);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200425 break;
Alex Lighte814f9d2017-07-31 16:14:39 -0700426 case instrumentation::Instrumentation::kWatchedFramePop:
427 instr->WatchedFramePopped(self, frame);
428 break;
Alex Light9fb1ab12017-09-05 09:32:49 -0700429 case instrumentation::Instrumentation::kExceptionHandled: {
430 ThrowArithmeticExceptionDivideByZero();
431 mirror::Throwable* event_exception = self->GetException();
432 self->ClearException();
433 instr->ExceptionHandledEvent(self, event_exception);
434 break;
435 }
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200436 default:
437 LOG(FATAL) << "Unknown instrumentation event " << event_type;
438 UNREACHABLE();
439 }
440 }
441
442 static bool DidListenerReceiveEvent(const TestInstrumentationListener& listener,
Alex Lightd7661582017-05-01 13:48:16 -0700443 uint32_t event_type,
444 bool with_object) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200445 switch (event_type) {
446 case instrumentation::Instrumentation::kMethodEntered:
447 return listener.received_method_enter_event;
448 case instrumentation::Instrumentation::kMethodExited:
Alex Lightd7661582017-05-01 13:48:16 -0700449 return (!with_object && listener.received_method_exit_event) ||
450 (with_object && listener.received_method_exit_object_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200451 case instrumentation::Instrumentation::kMethodUnwind:
452 return listener.received_method_unwind_event;
453 case instrumentation::Instrumentation::kDexPcMoved:
454 return listener.received_dex_pc_moved_event;
455 case instrumentation::Instrumentation::kFieldRead:
456 return listener.received_field_read_event;
457 case instrumentation::Instrumentation::kFieldWritten:
Alex Lightd7661582017-05-01 13:48:16 -0700458 return (!with_object && listener.received_field_written_event) ||
459 (with_object && listener.received_field_written_object_event);
Alex Light6e1607e2017-08-23 10:06:18 -0700460 case instrumentation::Instrumentation::kExceptionThrown:
461 return listener.received_exception_thrown_event;
Alex Light9fb1ab12017-09-05 09:32:49 -0700462 case instrumentation::Instrumentation::kExceptionHandled:
463 return listener.received_exception_handled_event;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000464 case instrumentation::Instrumentation::kBranch:
465 return listener.received_branch_event;
Alex Lighte814f9d2017-07-31 16:14:39 -0700466 case instrumentation::Instrumentation::kWatchedFramePop:
467 return listener.received_watched_frame_pop;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200468 default:
469 LOG(FATAL) << "Unknown instrumentation event " << event_type;
470 UNREACHABLE();
471 }
472 }
473};
474
475TEST_F(InstrumentationTest, NoInstrumentation) {
476 ScopedObjectAccess soa(Thread::Current());
477 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
478 ASSERT_NE(instr, nullptr);
479
480 EXPECT_FALSE(instr->AreExitStubsInstalled());
481 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
482 EXPECT_FALSE(instr->IsActive());
483 EXPECT_FALSE(instr->ShouldNotifyMethodEnterExitEvents());
484
485 // Test interpreter table is the default one.
486 EXPECT_EQ(instrumentation::kMainHandlerTable, instr->GetInterpreterHandlerTable());
487
488 // Check there is no registered listener.
489 EXPECT_FALSE(instr->HasDexPcListeners());
Alex Light6e1607e2017-08-23 10:06:18 -0700490 EXPECT_FALSE(instr->HasExceptionThrownListeners());
Alex Light9fb1ab12017-09-05 09:32:49 -0700491 EXPECT_FALSE(instr->HasExceptionHandledListeners());
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200492 EXPECT_FALSE(instr->HasFieldReadListeners());
493 EXPECT_FALSE(instr->HasFieldWriteListeners());
494 EXPECT_FALSE(instr->HasMethodEntryListeners());
495 EXPECT_FALSE(instr->HasMethodExitListeners());
496 EXPECT_FALSE(instr->IsActive());
497}
498
499// Test instrumentation listeners for each event.
500TEST_F(InstrumentationTest, MethodEntryEvent) {
Mingyao Yang2ee17902017-08-30 11:37:08 -0700501 ScopedObjectAccess soa(Thread::Current());
502 jobject class_loader = LoadDex("Instrumentation");
503 Runtime* const runtime = Runtime::Current();
504 ClassLinker* class_linker = runtime->GetClassLinker();
505 StackHandleScope<1> hs(soa.Self());
506 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Vladimir Markoe9987b02018-05-22 16:26:43 +0100507 ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
Mingyao Yang2ee17902017-08-30 11:37:08 -0700508 ASSERT_TRUE(klass != nullptr);
509 ArtMethod* method =
510 klass->FindClassMethod("returnReference", "()Ljava/lang/Object;", kRuntimePointerSize);
511 ASSERT_TRUE(method != nullptr);
512 ASSERT_TRUE(method->IsDirect());
513 ASSERT_TRUE(method->GetDeclaringClass() == klass);
514 TestEvent(instrumentation::Instrumentation::kMethodEntered,
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700515 /*event_method=*/ method,
516 /*event_field=*/ nullptr,
517 /*with_object=*/ true);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200518}
519
Alex Lightd7661582017-05-01 13:48:16 -0700520TEST_F(InstrumentationTest, MethodExitObjectEvent) {
521 ScopedObjectAccess soa(Thread::Current());
522 jobject class_loader = LoadDex("Instrumentation");
523 Runtime* const runtime = Runtime::Current();
524 ClassLinker* class_linker = runtime->GetClassLinker();
525 StackHandleScope<1> hs(soa.Self());
Alex Lightb7c640d2019-03-20 15:52:13 -0700526 MutableHandle<mirror::ClassLoader> loader(
527 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Vladimir Markoe9987b02018-05-22 16:26:43 +0100528 ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
Alex Lightd7661582017-05-01 13:48:16 -0700529 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100530 ArtMethod* method =
531 klass->FindClassMethod("returnReference", "()Ljava/lang/Object;", kRuntimePointerSize);
Alex Lightd7661582017-05-01 13:48:16 -0700532 ASSERT_TRUE(method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100533 ASSERT_TRUE(method->IsDirect());
534 ASSERT_TRUE(method->GetDeclaringClass() == klass);
Alex Lightd7661582017-05-01 13:48:16 -0700535 TestEvent(instrumentation::Instrumentation::kMethodExited,
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700536 /*event_method=*/ method,
537 /*event_field=*/ nullptr,
538 /*with_object=*/ true);
Alex Lightd7661582017-05-01 13:48:16 -0700539}
540
541TEST_F(InstrumentationTest, MethodExitPrimEvent) {
542 ScopedObjectAccess soa(Thread::Current());
543 jobject class_loader = LoadDex("Instrumentation");
544 Runtime* const runtime = Runtime::Current();
545 ClassLinker* class_linker = runtime->GetClassLinker();
546 StackHandleScope<1> hs(soa.Self());
547 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Vladimir Markoe9987b02018-05-22 16:26:43 +0100548 ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
Alex Lightd7661582017-05-01 13:48:16 -0700549 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100550 ArtMethod* method = klass->FindClassMethod("returnPrimitive", "()I", kRuntimePointerSize);
Alex Lightd7661582017-05-01 13:48:16 -0700551 ASSERT_TRUE(method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100552 ASSERT_TRUE(method->IsDirect());
553 ASSERT_TRUE(method->GetDeclaringClass() == klass);
Alex Lightd7661582017-05-01 13:48:16 -0700554 TestEvent(instrumentation::Instrumentation::kMethodExited,
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700555 /*event_method=*/ method,
556 /*event_field=*/ nullptr,
557 /*with_object=*/ false);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200558}
559
560TEST_F(InstrumentationTest, MethodUnwindEvent) {
561 TestEvent(instrumentation::Instrumentation::kMethodUnwind);
562}
563
564TEST_F(InstrumentationTest, DexPcMovedEvent) {
565 TestEvent(instrumentation::Instrumentation::kDexPcMoved);
566}
567
568TEST_F(InstrumentationTest, FieldReadEvent) {
569 TestEvent(instrumentation::Instrumentation::kFieldRead);
570}
571
Alex Lighte814f9d2017-07-31 16:14:39 -0700572TEST_F(InstrumentationTest, WatchedFramePop) {
573 TestEvent(instrumentation::Instrumentation::kWatchedFramePop);
574}
575
Alex Lightd7661582017-05-01 13:48:16 -0700576TEST_F(InstrumentationTest, FieldWriteObjectEvent) {
577 ScopedObjectAccess soa(Thread::Current());
578 jobject class_loader = LoadDex("Instrumentation");
579 Runtime* const runtime = Runtime::Current();
580 ClassLinker* class_linker = runtime->GetClassLinker();
581 StackHandleScope<1> hs(soa.Self());
582 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Vladimir Markoe9987b02018-05-22 16:26:43 +0100583 ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
Alex Lightd7661582017-05-01 13:48:16 -0700584 ASSERT_TRUE(klass != nullptr);
585 ArtField* field = klass->FindDeclaredStaticField("referenceField", "Ljava/lang/Object;");
586 ASSERT_TRUE(field != nullptr);
587
588 TestEvent(instrumentation::Instrumentation::kFieldWritten,
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700589 /*event_method=*/ nullptr,
590 /*event_field=*/ field,
591 /*with_object=*/ true);
Alex Lightd7661582017-05-01 13:48:16 -0700592}
593
594TEST_F(InstrumentationTest, FieldWritePrimEvent) {
595 ScopedObjectAccess soa(Thread::Current());
596 jobject class_loader = LoadDex("Instrumentation");
597 Runtime* const runtime = Runtime::Current();
598 ClassLinker* class_linker = runtime->GetClassLinker();
599 StackHandleScope<1> hs(soa.Self());
600 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Vladimir Markoe9987b02018-05-22 16:26:43 +0100601 ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
Alex Lightd7661582017-05-01 13:48:16 -0700602 ASSERT_TRUE(klass != nullptr);
603 ArtField* field = klass->FindDeclaredStaticField("primitiveField", "I");
604 ASSERT_TRUE(field != nullptr);
605
606 TestEvent(instrumentation::Instrumentation::kFieldWritten,
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700607 /*event_method=*/ nullptr,
608 /*event_field=*/ field,
609 /*with_object=*/ false);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200610}
611
Alex Light9fb1ab12017-09-05 09:32:49 -0700612TEST_F(InstrumentationTest, ExceptionHandledEvent) {
613 TestEvent(instrumentation::Instrumentation::kExceptionHandled);
614}
615
Alex Light6e1607e2017-08-23 10:06:18 -0700616TEST_F(InstrumentationTest, ExceptionThrownEvent) {
617 TestEvent(instrumentation::Instrumentation::kExceptionThrown);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200618}
619
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000620TEST_F(InstrumentationTest, BranchEvent) {
621 TestEvent(instrumentation::Instrumentation::kBranch);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200622}
623
624TEST_F(InstrumentationTest, DeoptimizeDirectMethod) {
625 ScopedObjectAccess soa(Thread::Current());
626 jobject class_loader = LoadDex("Instrumentation");
627 Runtime* const runtime = Runtime::Current();
628 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
629 ClassLinker* class_linker = runtime->GetClassLinker();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700630 StackHandleScope<1> hs(soa.Self());
Mathieu Chartier0795f232016-09-27 18:43:30 -0700631 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Vladimir Markoe9987b02018-05-22 16:26:43 +0100632 ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200633 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100634 ArtMethod* method_to_deoptimize =
635 klass->FindClassMethod("instanceMethod", "()V", kRuntimePointerSize);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700636 ASSERT_TRUE(method_to_deoptimize != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100637 ASSERT_TRUE(method_to_deoptimize->IsDirect());
638 ASSERT_TRUE(method_to_deoptimize->GetDeclaringClass() == klass);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200639
640 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700641 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200642
643 DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);
644
645 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
646 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700647 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200648
649 constexpr const char* instrumentation_key = "DeoptimizeDirectMethod";
650 UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
651
652 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700653 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200654}
655
656TEST_F(InstrumentationTest, FullDeoptimization) {
657 ScopedObjectAccess soa(Thread::Current());
658 Runtime* const runtime = Runtime::Current();
659 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
660 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
661
662 constexpr const char* instrumentation_key = "FullDeoptimization";
663 DeoptimizeEverything(soa.Self(), instrumentation_key, true);
664
665 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
666 EXPECT_TRUE(instr->AreExitStubsInstalled());
667
668 UndeoptimizeEverything(soa.Self(), instrumentation_key, true);
669
670 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
671}
672
673TEST_F(InstrumentationTest, MixedDeoptimization) {
674 ScopedObjectAccess soa(Thread::Current());
675 jobject class_loader = LoadDex("Instrumentation");
676 Runtime* const runtime = Runtime::Current();
677 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
678 ClassLinker* class_linker = runtime->GetClassLinker();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700679 StackHandleScope<1> hs(soa.Self());
Mathieu Chartier0795f232016-09-27 18:43:30 -0700680 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Vladimir Markoe9987b02018-05-22 16:26:43 +0100681 ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200682 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100683 ArtMethod* method_to_deoptimize =
684 klass->FindClassMethod("instanceMethod", "()V", kRuntimePointerSize);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700685 ASSERT_TRUE(method_to_deoptimize != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100686 ASSERT_TRUE(method_to_deoptimize->IsDirect());
687 ASSERT_TRUE(method_to_deoptimize->GetDeclaringClass() == klass);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200688
689 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700690 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200691
692 DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);
693 // Deoptimizing a method does not change instrumentation level.
694 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
695 GetCurrentInstrumentationLevel());
696 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
697 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700698 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200699
700 constexpr const char* instrumentation_key = "MixedDeoptimization";
701 DeoptimizeEverything(soa.Self(), instrumentation_key, false);
702 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
703 GetCurrentInstrumentationLevel());
704 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
705 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700706 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200707
708 UndeoptimizeEverything(soa.Self(), instrumentation_key, false);
709 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
710 GetCurrentInstrumentationLevel());
711 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
712 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700713 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200714
715 UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
716 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
717 GetCurrentInstrumentationLevel());
718 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700719 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200720}
721
722TEST_F(InstrumentationTest, MethodTracing_Interpreter) {
723 ScopedObjectAccess soa(Thread::Current());
724 Runtime* const runtime = Runtime::Current();
725 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
726 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
727
728 constexpr const char* instrumentation_key = "MethodTracing";
729 EnableMethodTracing(soa.Self(), instrumentation_key, true);
730 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
731 GetCurrentInstrumentationLevel());
732 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
733 EXPECT_TRUE(instr->AreExitStubsInstalled());
734
735 DisableMethodTracing(soa.Self(), instrumentation_key);
736 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
737 GetCurrentInstrumentationLevel());
738 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
739}
740
741TEST_F(InstrumentationTest, MethodTracing_InstrumentationEntryExitStubs) {
742 ScopedObjectAccess soa(Thread::Current());
743 Runtime* const runtime = Runtime::Current();
744 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
745 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
746
747 constexpr const char* instrumentation_key = "MethodTracing";
748 EnableMethodTracing(soa.Self(), instrumentation_key, false);
749 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
750 GetCurrentInstrumentationLevel());
751 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
752 EXPECT_TRUE(instr->AreExitStubsInstalled());
753
754 DisableMethodTracing(soa.Self(), instrumentation_key);
755 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
756 GetCurrentInstrumentationLevel());
757 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
758}
759
760// We use a macro to print the line number where the test is failing.
761#define CHECK_INSTRUMENTATION(_level, _user_count) \
762 do { \
763 Instrumentation* const instr = Runtime::Current()->GetInstrumentation(); \
764 bool interpreter = \
Chih-Hung Hsieh1a0de6a2016-08-26 15:06:11 -0700765 ((_level) == Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter); \
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200766 EXPECT_EQ(_level, GetCurrentInstrumentationLevel()); \
767 EXPECT_EQ(_user_count, GetInstrumentationUserCount()); \
768 if (instr->IsForcedInterpretOnly()) { \
769 EXPECT_TRUE(instr->InterpretOnly()); \
770 } else if (interpreter) { \
771 EXPECT_TRUE(instr->InterpretOnly()); \
772 } else { \
773 EXPECT_FALSE(instr->InterpretOnly()); \
774 } \
775 if (interpreter) { \
776 EXPECT_TRUE(instr->AreAllMethodsDeoptimized()); \
777 } else { \
778 EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); \
779 } \
780 } while (false)
781
782TEST_F(InstrumentationTest, ConfigureStubs_Nothing) {
783 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
784
785 // Check no-op.
786 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
787 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
788}
789
790TEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubs) {
791 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
792
793 // Check we can switch to instrumentation stubs
794 CheckConfigureStubs(kClientOneKey,
795 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
796 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
797 1U);
798
799 // Check we can disable instrumentation.
800 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
801 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
802}
803
804TEST_F(InstrumentationTest, ConfigureStubs_Interpreter) {
805 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
806
807 // Check we can switch to interpreter
808 CheckConfigureStubs(kClientOneKey,
809 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
810 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
811
812 // Check we can disable instrumentation.
813 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
814 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
815}
816
817TEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubsToInterpreter) {
818 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
819
820 // Configure stubs with instrumentation stubs.
821 CheckConfigureStubs(kClientOneKey,
822 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
823 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
824 1U);
825
826 // Configure stubs with interpreter.
827 CheckConfigureStubs(kClientOneKey,
828 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
829 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
830
831 // Check we can disable instrumentation.
832 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
833 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
834}
835
836TEST_F(InstrumentationTest, ConfigureStubs_InterpreterToInstrumentationStubs) {
837 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
838
839 // Configure stubs with interpreter.
840 CheckConfigureStubs(kClientOneKey,
841 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
842 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
843
844 // Configure stubs with instrumentation stubs.
845 CheckConfigureStubs(kClientOneKey,
846 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
Alex Light40607862019-05-06 18:16:24 +0000847 // Make sure we are still interpreter since going from interpreter->instrumentation is dangerous.
848 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200849 1U);
850
851 // Check we can disable instrumentation.
852 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
853 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
854}
855
856TEST_F(InstrumentationTest,
857 ConfigureStubs_InstrumentationStubsToInterpreterToInstrumentationStubs) {
858 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
859
860 // Configure stubs with instrumentation stubs.
861 CheckConfigureStubs(kClientOneKey,
862 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
863 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
864 1U);
865
866 // Configure stubs with interpreter.
867 CheckConfigureStubs(kClientOneKey,
868 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
869 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
870
871 // Configure stubs with instrumentation stubs again.
872 CheckConfigureStubs(kClientOneKey,
873 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
Alex Light40607862019-05-06 18:16:24 +0000874 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200875 1U);
876
877 // Check we can disable instrumentation.
878 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
879 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
880}
881
882TEST_F(InstrumentationTest, MultiConfigureStubs_Nothing) {
883 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
884
885 // Check kInstrumentNothing with two clients.
886 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
887 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
888
889 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
890 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
891}
892
893TEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubs) {
894 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
895
896 // Configure stubs with instrumentation stubs for 1st client.
897 CheckConfigureStubs(kClientOneKey,
898 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
899 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
900 1U);
901
902 // Configure stubs with instrumentation stubs for 2nd client.
903 CheckConfigureStubs(kClientTwoKey,
904 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
905 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
906 2U);
907
908 // 1st client requests instrumentation deactivation but 2nd client still needs
909 // instrumentation stubs.
910 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
911 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
912 1U);
913
914 // 2nd client requests instrumentation deactivation
915 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
916 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
917}
918
919TEST_F(InstrumentationTest, MultiConfigureStubs_Interpreter) {
920 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
921
922 // Configure stubs with interpreter for 1st client.
923 CheckConfigureStubs(kClientOneKey,
924 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
925 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
926
927 // Configure stubs with interpreter for 2nd client.
928 CheckConfigureStubs(kClientTwoKey,
929 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
930 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
931
932 // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
933 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
934 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
935
936 // 2nd client requests instrumentation deactivation
937 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
938 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
939}
940
941TEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubsThenInterpreter) {
942 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
943
944 // Configure stubs with instrumentation stubs for 1st client.
945 CheckConfigureStubs(kClientOneKey,
946 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
947 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
948 1U);
949
950 // Configure stubs with interpreter for 2nd client.
951 CheckConfigureStubs(kClientTwoKey,
952 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
953 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
954
955 // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
956 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
957 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
958
959 // 2nd client requests instrumentation deactivation
960 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
961 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
962}
963
964TEST_F(InstrumentationTest, MultiConfigureStubs_InterpreterThenInstrumentationStubs) {
965 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
966
967 // Configure stubs with interpreter for 1st client.
968 CheckConfigureStubs(kClientOneKey,
969 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
970 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
971
972 // Configure stubs with instrumentation stubs for 2nd client.
973 CheckConfigureStubs(kClientTwoKey,
974 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
975 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
976
977 // 1st client requests instrumentation deactivation but 2nd client still needs
Alex Light40607862019-05-06 18:16:24 +0000978 // instrumentation stubs. Since we already got interpreter stubs we need to stay there.
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200979 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
Alex Light40607862019-05-06 18:16:24 +0000980 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200981 1U);
982
983 // 2nd client requests instrumentation deactivation
984 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
985 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
986}
987
988} // namespace instrumentation
989} // namespace art