blob: 2a601c9cf2f373d3ea0e526956b6f48d956cbcf4 [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
Andreas Gampe542451c2016-07-26 09:02:02 -070019#include "base/enums.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020020#include "common_runtime_test.h"
21#include "common_throws.h"
22#include "class_linker-inl.h"
23#include "dex_file.h"
Mathieu Chartieraa516822015-10-02 15:53:37 -070024#include "gc/scoped_gc_critical_section.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020025#include "handle_scope-inl.h"
Alex Lightd7661582017-05-01 13:48:16 -070026#include "jni_internal.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020027#include "jvalue.h"
28#include "runtime.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070029#include "scoped_thread_state_change-inl.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020030#include "thread_list.h"
Alex Lightd7661582017-05-01 13:48:16 -070031#include "thread-inl.h"
32#include "well_known_classes.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020033
34namespace art {
35namespace instrumentation {
36
37class TestInstrumentationListener FINAL : public instrumentation::InstrumentationListener {
38 public:
39 TestInstrumentationListener()
Alex Lightd7661582017-05-01 13:48:16 -070040 : received_method_enter_event(false),
41 received_method_exit_event(false),
42 received_method_exit_object_event(false),
43 received_method_unwind_event(false),
44 received_dex_pc_moved_event(false),
45 received_field_read_event(false),
46 received_field_written_event(false),
47 received_field_written_object_event(false),
48 received_exception_caught_event(false),
49 received_branch_event(false),
Nicolas Geoffray5550ca82015-08-21 18:38:30 +010050 received_invoke_virtual_or_interface_event(false) {}
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020051
52 virtual ~TestInstrumentationListener() {}
53
54 void MethodEntered(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070055 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070056 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020057 uint32_t dex_pc ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070058 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020059 received_method_enter_event = true;
60 }
61
62 void MethodExited(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070063 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
64 ArtMethod* method ATTRIBUTE_UNUSED,
65 uint32_t dex_pc ATTRIBUTE_UNUSED,
66 Handle<mirror::Object> return_value ATTRIBUTE_UNUSED)
67 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
68 received_method_exit_object_event = true;
69 }
70
71 void MethodExited(Thread* thread ATTRIBUTE_UNUSED,
72 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070073 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020074 uint32_t dex_pc ATTRIBUTE_UNUSED,
75 const JValue& return_value ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070076 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020077 received_method_exit_event = true;
78 }
79
80 void MethodUnwind(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070081 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070082 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020083 uint32_t dex_pc ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070084 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020085 received_method_unwind_event = true;
86 }
87
88 void DexPcMoved(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070089 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070090 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020091 uint32_t new_dex_pc ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070092 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020093 received_dex_pc_moved_event = true;
94 }
95
96 void FieldRead(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070097 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070098 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020099 uint32_t dex_pc ATTRIBUTE_UNUSED,
100 ArtField* field ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700101 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200102 received_field_read_event = true;
103 }
104
105 void FieldWritten(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -0700106 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
107 ArtMethod* method ATTRIBUTE_UNUSED,
108 uint32_t dex_pc ATTRIBUTE_UNUSED,
109 ArtField* field ATTRIBUTE_UNUSED,
110 Handle<mirror::Object> field_value ATTRIBUTE_UNUSED)
111 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
112 received_field_written_object_event = true;
113 }
114
115 void FieldWritten(Thread* thread ATTRIBUTE_UNUSED,
116 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700117 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200118 uint32_t dex_pc ATTRIBUTE_UNUSED,
119 ArtField* field ATTRIBUTE_UNUSED,
120 const JValue& field_value ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700121 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200122 received_field_written_event = true;
123 }
124
125 void ExceptionCaught(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -0700126 Handle<mirror::Throwable> exception_object ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700127 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200128 received_exception_caught_event = true;
129 }
130
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000131 void Branch(Thread* thread ATTRIBUTE_UNUSED,
132 ArtMethod* method ATTRIBUTE_UNUSED,
133 uint32_t dex_pc ATTRIBUTE_UNUSED,
134 int32_t dex_pc_offset ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700135 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000136 received_branch_event = true;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200137 }
138
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100139 void InvokeVirtualOrInterface(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -0700140 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100141 ArtMethod* caller ATTRIBUTE_UNUSED,
142 uint32_t dex_pc ATTRIBUTE_UNUSED,
143 ArtMethod* callee ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700144 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100145 received_invoke_virtual_or_interface_event = true;
146 }
147
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200148 void Reset() {
149 received_method_enter_event = false;
150 received_method_exit_event = false;
Alex Lightd7661582017-05-01 13:48:16 -0700151 received_method_exit_object_event = false;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200152 received_method_unwind_event = false;
153 received_dex_pc_moved_event = false;
154 received_field_read_event = false;
155 received_field_written_event = false;
Alex Lightd7661582017-05-01 13:48:16 -0700156 received_field_written_object_event = false;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200157 received_exception_caught_event = false;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000158 received_branch_event = false;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100159 received_invoke_virtual_or_interface_event = false;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200160 }
161
162 bool received_method_enter_event;
163 bool received_method_exit_event;
Alex Lightd7661582017-05-01 13:48:16 -0700164 bool received_method_exit_object_event;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200165 bool received_method_unwind_event;
166 bool received_dex_pc_moved_event;
167 bool received_field_read_event;
168 bool received_field_written_event;
Alex Lightd7661582017-05-01 13:48:16 -0700169 bool received_field_written_object_event;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200170 bool received_exception_caught_event;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000171 bool received_branch_event;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100172 bool received_invoke_virtual_or_interface_event;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200173
174 private:
175 DISALLOW_COPY_AND_ASSIGN(TestInstrumentationListener);
176};
177
178class InstrumentationTest : public CommonRuntimeTest {
179 public:
180 // Unique keys used to test Instrumentation::ConfigureStubs.
181 static constexpr const char* kClientOneKey = "TestClient1";
182 static constexpr const char* kClientTwoKey = "TestClient2";
183
184 void CheckConfigureStubs(const char* key, Instrumentation::InstrumentationLevel level) {
185 ScopedObjectAccess soa(Thread::Current());
186 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700187 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700188 gc::ScopedGCCriticalSection gcs(soa.Self(),
189 gc::kGcCauseInstrumentation,
190 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700191 ScopedSuspendAll ssa("Instrumentation::ConfigureStubs");
192 instr->ConfigureStubs(key, level);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200193 }
194
195 Instrumentation::InstrumentationLevel GetCurrentInstrumentationLevel() {
196 return Runtime::Current()->GetInstrumentation()->GetCurrentInstrumentationLevel();
197 }
198
199 size_t GetInstrumentationUserCount() {
200 ScopedObjectAccess soa(Thread::Current());
201 return Runtime::Current()->GetInstrumentation()->requested_instrumentation_levels_.size();
202 }
203
204 void TestEvent(uint32_t instrumentation_event) {
Alex Lightd7661582017-05-01 13:48:16 -0700205 TestEvent(instrumentation_event, nullptr, nullptr, false);
206 }
207
208 void TestEvent(uint32_t instrumentation_event,
209 ArtMethod* event_method,
210 ArtField* event_field,
211 bool with_object) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200212 ScopedObjectAccess soa(Thread::Current());
213 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
214 TestInstrumentationListener listener;
215 {
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700216 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700217 ScopedSuspendAll ssa("Add instrumentation listener");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200218 instr->AddListener(&listener, instrumentation_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200219 }
220
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200221 mirror::Object* const event_obj = nullptr;
222 const uint32_t event_dex_pc = 0;
223
224 // Check the listener is registered and is notified of the event.
225 EXPECT_TRUE(HasEventListener(instr, instrumentation_event));
Alex Lightd7661582017-05-01 13:48:16 -0700226 EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
227 ReportEvent(instr,
228 instrumentation_event,
229 soa.Self(),
230 event_method,
231 event_obj,
232 event_field,
233 event_dex_pc);
234 EXPECT_TRUE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200235
236 listener.Reset();
237 {
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700238 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700239 ScopedSuspendAll ssa("Remove instrumentation listener");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200240 instr->RemoveListener(&listener, instrumentation_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200241 }
242
243 // Check the listener is not registered and is not notified of the event.
244 EXPECT_FALSE(HasEventListener(instr, instrumentation_event));
Alex Lightd7661582017-05-01 13:48:16 -0700245 EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
246 ReportEvent(instr,
247 instrumentation_event,
248 soa.Self(),
249 event_method,
250 event_obj,
251 event_field,
252 event_dex_pc);
253 EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200254 }
255
Mathieu Chartiere401d142015-04-22 13:56:20 -0700256 void DeoptimizeMethod(Thread* self, ArtMethod* method, bool enable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700257 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200258 Runtime* runtime = Runtime::Current();
259 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700260 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700261 gc::ScopedGCCriticalSection gcs(self,
262 gc::kGcCauseInstrumentation,
263 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700264 ScopedSuspendAll ssa("Single method deoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200265 if (enable_deoptimization) {
266 instrumentation->EnableDeoptimization();
267 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700268 instrumentation->Deoptimize(method);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200269 }
270
Mathieu Chartiere401d142015-04-22 13:56:20 -0700271 void UndeoptimizeMethod(Thread* self, ArtMethod* method,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200272 const char* key, bool disable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700273 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200274 Runtime* runtime = Runtime::Current();
275 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700276 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700277 gc::ScopedGCCriticalSection gcs(self,
278 gc::kGcCauseInstrumentation,
279 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700280 ScopedSuspendAll ssa("Single method undeoptimization");
Mathieu Chartiere401d142015-04-22 13:56:20 -0700281 instrumentation->Undeoptimize(method);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200282 if (disable_deoptimization) {
283 instrumentation->DisableDeoptimization(key);
284 }
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200285 }
286
287 void DeoptimizeEverything(Thread* self, const char* key, bool enable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700288 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200289 Runtime* runtime = Runtime::Current();
290 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700291 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700292 gc::ScopedGCCriticalSection gcs(self,
293 gc::kGcCauseInstrumentation,
294 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700295 ScopedSuspendAll ssa("Full deoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200296 if (enable_deoptimization) {
297 instrumentation->EnableDeoptimization();
298 }
299 instrumentation->DeoptimizeEverything(key);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200300 }
301
302 void UndeoptimizeEverything(Thread* self, const char* key, bool disable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700303 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200304 Runtime* runtime = Runtime::Current();
305 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700306 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700307 gc::ScopedGCCriticalSection gcs(self,
308 gc::kGcCauseInstrumentation,
309 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700310 ScopedSuspendAll ssa("Full undeoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200311 instrumentation->UndeoptimizeEverything(key);
312 if (disable_deoptimization) {
313 instrumentation->DisableDeoptimization(key);
314 }
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200315 }
316
317 void EnableMethodTracing(Thread* self, const char* key, bool needs_interpreter)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700318 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200319 Runtime* runtime = Runtime::Current();
320 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700321 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700322 gc::ScopedGCCriticalSection gcs(self,
323 gc::kGcCauseInstrumentation,
324 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700325 ScopedSuspendAll ssa("EnableMethodTracing");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200326 instrumentation->EnableMethodTracing(key, needs_interpreter);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200327 }
328
329 void DisableMethodTracing(Thread* self, const char* key)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700330 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200331 Runtime* runtime = Runtime::Current();
332 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700333 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700334 gc::ScopedGCCriticalSection gcs(self,
335 gc::kGcCauseInstrumentation,
336 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700337 ScopedSuspendAll ssa("EnableMethodTracing");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200338 instrumentation->DisableMethodTracing(key);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200339 }
340
341 private:
342 static bool HasEventListener(const instrumentation::Instrumentation* instr, uint32_t event_type)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700343 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200344 switch (event_type) {
345 case instrumentation::Instrumentation::kMethodEntered:
346 return instr->HasMethodEntryListeners();
347 case instrumentation::Instrumentation::kMethodExited:
348 return instr->HasMethodExitListeners();
349 case instrumentation::Instrumentation::kMethodUnwind:
350 return instr->HasMethodUnwindListeners();
351 case instrumentation::Instrumentation::kDexPcMoved:
352 return instr->HasDexPcListeners();
353 case instrumentation::Instrumentation::kFieldRead:
354 return instr->HasFieldReadListeners();
355 case instrumentation::Instrumentation::kFieldWritten:
356 return instr->HasFieldWriteListeners();
357 case instrumentation::Instrumentation::kExceptionCaught:
358 return instr->HasExceptionCaughtListeners();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000359 case instrumentation::Instrumentation::kBranch:
360 return instr->HasBranchListeners();
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100361 case instrumentation::Instrumentation::kInvokeVirtualOrInterface:
362 return instr->HasInvokeVirtualOrInterfaceListeners();
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200363 default:
364 LOG(FATAL) << "Unknown instrumentation event " << event_type;
365 UNREACHABLE();
366 }
367 }
368
Alex Lightd7661582017-05-01 13:48:16 -0700369 static void ReportEvent(const instrumentation::Instrumentation* instr,
370 uint32_t event_type,
371 Thread* self,
372 ArtMethod* method,
373 mirror::Object* obj,
374 ArtField* field,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200375 uint32_t dex_pc)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700376 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200377 switch (event_type) {
378 case instrumentation::Instrumentation::kMethodEntered:
379 instr->MethodEnterEvent(self, obj, method, dex_pc);
380 break;
381 case instrumentation::Instrumentation::kMethodExited: {
382 JValue value;
383 instr->MethodExitEvent(self, obj, method, dex_pc, value);
384 break;
385 }
386 case instrumentation::Instrumentation::kMethodUnwind:
387 instr->MethodUnwindEvent(self, obj, method, dex_pc);
388 break;
389 case instrumentation::Instrumentation::kDexPcMoved:
390 instr->DexPcMovedEvent(self, obj, method, dex_pc);
391 break;
392 case instrumentation::Instrumentation::kFieldRead:
Alex Lightd7661582017-05-01 13:48:16 -0700393 instr->FieldReadEvent(self, obj, method, dex_pc, field);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200394 break;
395 case instrumentation::Instrumentation::kFieldWritten: {
396 JValue value;
Alex Lightd7661582017-05-01 13:48:16 -0700397 instr->FieldWriteEvent(self, obj, method, dex_pc, field, value);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200398 break;
399 }
400 case instrumentation::Instrumentation::kExceptionCaught: {
401 ThrowArithmeticExceptionDivideByZero();
402 mirror::Throwable* event_exception = self->GetException();
403 instr->ExceptionCaughtEvent(self, event_exception);
404 self->ClearException();
405 break;
406 }
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000407 case instrumentation::Instrumentation::kBranch:
408 instr->Branch(self, method, dex_pc, -1);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200409 break;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100410 case instrumentation::Instrumentation::kInvokeVirtualOrInterface:
411 instr->InvokeVirtualOrInterface(self, obj, method, dex_pc, method);
412 break;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200413 default:
414 LOG(FATAL) << "Unknown instrumentation event " << event_type;
415 UNREACHABLE();
416 }
417 }
418
419 static bool DidListenerReceiveEvent(const TestInstrumentationListener& listener,
Alex Lightd7661582017-05-01 13:48:16 -0700420 uint32_t event_type,
421 bool with_object) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200422 switch (event_type) {
423 case instrumentation::Instrumentation::kMethodEntered:
424 return listener.received_method_enter_event;
425 case instrumentation::Instrumentation::kMethodExited:
Alex Lightd7661582017-05-01 13:48:16 -0700426 return (!with_object && listener.received_method_exit_event) ||
427 (with_object && listener.received_method_exit_object_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200428 case instrumentation::Instrumentation::kMethodUnwind:
429 return listener.received_method_unwind_event;
430 case instrumentation::Instrumentation::kDexPcMoved:
431 return listener.received_dex_pc_moved_event;
432 case instrumentation::Instrumentation::kFieldRead:
433 return listener.received_field_read_event;
434 case instrumentation::Instrumentation::kFieldWritten:
Alex Lightd7661582017-05-01 13:48:16 -0700435 return (!with_object && listener.received_field_written_event) ||
436 (with_object && listener.received_field_written_object_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200437 case instrumentation::Instrumentation::kExceptionCaught:
438 return listener.received_exception_caught_event;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000439 case instrumentation::Instrumentation::kBranch:
440 return listener.received_branch_event;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100441 case instrumentation::Instrumentation::kInvokeVirtualOrInterface:
442 return listener.received_invoke_virtual_or_interface_event;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200443 default:
444 LOG(FATAL) << "Unknown instrumentation event " << event_type;
445 UNREACHABLE();
446 }
447 }
448};
449
450TEST_F(InstrumentationTest, NoInstrumentation) {
451 ScopedObjectAccess soa(Thread::Current());
452 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
453 ASSERT_NE(instr, nullptr);
454
455 EXPECT_FALSE(instr->AreExitStubsInstalled());
456 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
457 EXPECT_FALSE(instr->IsActive());
458 EXPECT_FALSE(instr->ShouldNotifyMethodEnterExitEvents());
459
460 // Test interpreter table is the default one.
461 EXPECT_EQ(instrumentation::kMainHandlerTable, instr->GetInterpreterHandlerTable());
462
463 // Check there is no registered listener.
464 EXPECT_FALSE(instr->HasDexPcListeners());
465 EXPECT_FALSE(instr->HasExceptionCaughtListeners());
466 EXPECT_FALSE(instr->HasFieldReadListeners());
467 EXPECT_FALSE(instr->HasFieldWriteListeners());
468 EXPECT_FALSE(instr->HasMethodEntryListeners());
469 EXPECT_FALSE(instr->HasMethodExitListeners());
470 EXPECT_FALSE(instr->IsActive());
471}
472
473// Test instrumentation listeners for each event.
474TEST_F(InstrumentationTest, MethodEntryEvent) {
475 TestEvent(instrumentation::Instrumentation::kMethodEntered);
476}
477
Alex Lightd7661582017-05-01 13:48:16 -0700478TEST_F(InstrumentationTest, MethodExitObjectEvent) {
479 ScopedObjectAccess soa(Thread::Current());
480 jobject class_loader = LoadDex("Instrumentation");
481 Runtime* const runtime = Runtime::Current();
482 ClassLinker* class_linker = runtime->GetClassLinker();
483 StackHandleScope<1> hs(soa.Self());
484 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
485 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
486 ASSERT_TRUE(klass != nullptr);
487 ArtMethod* method = klass->FindDeclaredDirectMethod("returnReference",
488 "()Ljava/lang/Object;",
489 kRuntimePointerSize);
490 ASSERT_TRUE(method != nullptr);
491 TestEvent(instrumentation::Instrumentation::kMethodExited,
492 /*event_method*/ method,
493 /*event_field*/ nullptr,
494 /*with_object*/ true);
495}
496
497TEST_F(InstrumentationTest, MethodExitPrimEvent) {
498 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)));
504 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
505 ASSERT_TRUE(klass != nullptr);
506 ArtMethod* method = klass->FindDeclaredDirectMethod("returnPrimitive",
507 "()I",
508 kRuntimePointerSize);
509 ASSERT_TRUE(method != nullptr);
510 TestEvent(instrumentation::Instrumentation::kMethodExited,
511 /*event_method*/ method,
512 /*event_field*/ nullptr,
513 /*with_object*/ false);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200514}
515
516TEST_F(InstrumentationTest, MethodUnwindEvent) {
517 TestEvent(instrumentation::Instrumentation::kMethodUnwind);
518}
519
520TEST_F(InstrumentationTest, DexPcMovedEvent) {
521 TestEvent(instrumentation::Instrumentation::kDexPcMoved);
522}
523
524TEST_F(InstrumentationTest, FieldReadEvent) {
525 TestEvent(instrumentation::Instrumentation::kFieldRead);
526}
527
Alex Lightd7661582017-05-01 13:48:16 -0700528TEST_F(InstrumentationTest, FieldWriteObjectEvent) {
529 ScopedObjectAccess soa(Thread::Current());
530 jobject class_loader = LoadDex("Instrumentation");
531 Runtime* const runtime = Runtime::Current();
532 ClassLinker* class_linker = runtime->GetClassLinker();
533 StackHandleScope<1> hs(soa.Self());
534 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
535 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
536 ASSERT_TRUE(klass != nullptr);
537 ArtField* field = klass->FindDeclaredStaticField("referenceField", "Ljava/lang/Object;");
538 ASSERT_TRUE(field != nullptr);
539
540 TestEvent(instrumentation::Instrumentation::kFieldWritten,
541 /*event_method*/ nullptr,
542 /*event_field*/ field,
543 /*with_object*/ true);
544}
545
546TEST_F(InstrumentationTest, FieldWritePrimEvent) {
547 ScopedObjectAccess soa(Thread::Current());
548 jobject class_loader = LoadDex("Instrumentation");
549 Runtime* const runtime = Runtime::Current();
550 ClassLinker* class_linker = runtime->GetClassLinker();
551 StackHandleScope<1> hs(soa.Self());
552 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
553 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
554 ASSERT_TRUE(klass != nullptr);
555 ArtField* field = klass->FindDeclaredStaticField("primitiveField", "I");
556 ASSERT_TRUE(field != nullptr);
557
558 TestEvent(instrumentation::Instrumentation::kFieldWritten,
559 /*event_method*/ nullptr,
560 /*event_field*/ field,
561 /*with_object*/ false);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200562}
563
564TEST_F(InstrumentationTest, ExceptionCaughtEvent) {
565 TestEvent(instrumentation::Instrumentation::kExceptionCaught);
566}
567
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000568TEST_F(InstrumentationTest, BranchEvent) {
569 TestEvent(instrumentation::Instrumentation::kBranch);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200570}
571
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100572TEST_F(InstrumentationTest, InvokeVirtualOrInterfaceEvent) {
573 TestEvent(instrumentation::Instrumentation::kInvokeVirtualOrInterface);
574}
575
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200576TEST_F(InstrumentationTest, DeoptimizeDirectMethod) {
577 ScopedObjectAccess soa(Thread::Current());
578 jobject class_loader = LoadDex("Instrumentation");
579 Runtime* const runtime = Runtime::Current();
580 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
581 ClassLinker* class_linker = runtime->GetClassLinker();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700582 StackHandleScope<1> hs(soa.Self());
Mathieu Chartier0795f232016-09-27 18:43:30 -0700583 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200584 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
585 ASSERT_TRUE(klass != nullptr);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700586 ArtMethod* method_to_deoptimize = klass->FindDeclaredDirectMethod("instanceMethod", "()V",
Andreas Gampe542451c2016-07-26 09:02:02 -0700587 kRuntimePointerSize);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700588 ASSERT_TRUE(method_to_deoptimize != nullptr);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200589
590 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700591 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200592
593 DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);
594
595 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
596 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700597 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200598
599 constexpr const char* instrumentation_key = "DeoptimizeDirectMethod";
600 UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
601
602 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700603 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200604}
605
606TEST_F(InstrumentationTest, FullDeoptimization) {
607 ScopedObjectAccess soa(Thread::Current());
608 Runtime* const runtime = Runtime::Current();
609 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
610 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
611
612 constexpr const char* instrumentation_key = "FullDeoptimization";
613 DeoptimizeEverything(soa.Self(), instrumentation_key, true);
614
615 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
616 EXPECT_TRUE(instr->AreExitStubsInstalled());
617
618 UndeoptimizeEverything(soa.Self(), instrumentation_key, true);
619
620 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
621}
622
623TEST_F(InstrumentationTest, MixedDeoptimization) {
624 ScopedObjectAccess soa(Thread::Current());
625 jobject class_loader = LoadDex("Instrumentation");
626 Runtime* const runtime = Runtime::Current();
627 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
628 ClassLinker* class_linker = runtime->GetClassLinker();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700629 StackHandleScope<1> hs(soa.Self());
Mathieu Chartier0795f232016-09-27 18:43:30 -0700630 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200631 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
632 ASSERT_TRUE(klass != nullptr);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700633 ArtMethod* method_to_deoptimize = klass->FindDeclaredDirectMethod("instanceMethod", "()V",
Andreas Gampe542451c2016-07-26 09:02:02 -0700634 kRuntimePointerSize);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700635 ASSERT_TRUE(method_to_deoptimize != nullptr);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200636
637 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700638 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200639
640 DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);
641 // Deoptimizing a method does not change instrumentation level.
642 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
643 GetCurrentInstrumentationLevel());
644 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
645 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700646 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200647
648 constexpr const char* instrumentation_key = "MixedDeoptimization";
649 DeoptimizeEverything(soa.Self(), instrumentation_key, false);
650 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
651 GetCurrentInstrumentationLevel());
652 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
653 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700654 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200655
656 UndeoptimizeEverything(soa.Self(), instrumentation_key, false);
657 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
658 GetCurrentInstrumentationLevel());
659 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
660 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700661 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200662
663 UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
664 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
665 GetCurrentInstrumentationLevel());
666 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700667 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200668}
669
670TEST_F(InstrumentationTest, MethodTracing_Interpreter) {
671 ScopedObjectAccess soa(Thread::Current());
672 Runtime* const runtime = Runtime::Current();
673 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
674 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
675
676 constexpr const char* instrumentation_key = "MethodTracing";
677 EnableMethodTracing(soa.Self(), instrumentation_key, true);
678 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
679 GetCurrentInstrumentationLevel());
680 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
681 EXPECT_TRUE(instr->AreExitStubsInstalled());
682
683 DisableMethodTracing(soa.Self(), instrumentation_key);
684 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
685 GetCurrentInstrumentationLevel());
686 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
687}
688
689TEST_F(InstrumentationTest, MethodTracing_InstrumentationEntryExitStubs) {
690 ScopedObjectAccess soa(Thread::Current());
691 Runtime* const runtime = Runtime::Current();
692 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
693 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
694
695 constexpr const char* instrumentation_key = "MethodTracing";
696 EnableMethodTracing(soa.Self(), instrumentation_key, false);
697 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
698 GetCurrentInstrumentationLevel());
699 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
700 EXPECT_TRUE(instr->AreExitStubsInstalled());
701
702 DisableMethodTracing(soa.Self(), instrumentation_key);
703 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
704 GetCurrentInstrumentationLevel());
705 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
706}
707
708// We use a macro to print the line number where the test is failing.
709#define CHECK_INSTRUMENTATION(_level, _user_count) \
710 do { \
711 Instrumentation* const instr = Runtime::Current()->GetInstrumentation(); \
712 bool interpreter = \
Chih-Hung Hsieh1a0de6a2016-08-26 15:06:11 -0700713 ((_level) == Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter); \
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200714 EXPECT_EQ(_level, GetCurrentInstrumentationLevel()); \
715 EXPECT_EQ(_user_count, GetInstrumentationUserCount()); \
716 if (instr->IsForcedInterpretOnly()) { \
717 EXPECT_TRUE(instr->InterpretOnly()); \
718 } else if (interpreter) { \
719 EXPECT_TRUE(instr->InterpretOnly()); \
720 } else { \
721 EXPECT_FALSE(instr->InterpretOnly()); \
722 } \
723 if (interpreter) { \
724 EXPECT_TRUE(instr->AreAllMethodsDeoptimized()); \
725 } else { \
726 EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); \
727 } \
728 } while (false)
729
730TEST_F(InstrumentationTest, ConfigureStubs_Nothing) {
731 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
732
733 // Check no-op.
734 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
735 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
736}
737
738TEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubs) {
739 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
740
741 // Check we can switch to instrumentation stubs
742 CheckConfigureStubs(kClientOneKey,
743 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
744 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
745 1U);
746
747 // Check we can disable instrumentation.
748 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
749 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
750}
751
752TEST_F(InstrumentationTest, ConfigureStubs_Interpreter) {
753 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
754
755 // Check we can switch to interpreter
756 CheckConfigureStubs(kClientOneKey,
757 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
758 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
759
760 // Check we can disable instrumentation.
761 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
762 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
763}
764
765TEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubsToInterpreter) {
766 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
767
768 // Configure stubs with instrumentation stubs.
769 CheckConfigureStubs(kClientOneKey,
770 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
771 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
772 1U);
773
774 // Configure stubs with interpreter.
775 CheckConfigureStubs(kClientOneKey,
776 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
777 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
778
779 // Check we can disable instrumentation.
780 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
781 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
782}
783
784TEST_F(InstrumentationTest, ConfigureStubs_InterpreterToInstrumentationStubs) {
785 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
786
787 // Configure stubs with interpreter.
788 CheckConfigureStubs(kClientOneKey,
789 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
790 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
791
792 // Configure stubs with instrumentation stubs.
793 CheckConfigureStubs(kClientOneKey,
794 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
795 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
796 1U);
797
798 // Check we can disable instrumentation.
799 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
800 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
801}
802
803TEST_F(InstrumentationTest,
804 ConfigureStubs_InstrumentationStubsToInterpreterToInstrumentationStubs) {
805 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
806
807 // Configure stubs with instrumentation stubs.
808 CheckConfigureStubs(kClientOneKey,
809 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
810 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
811 1U);
812
813 // Configure stubs with interpreter.
814 CheckConfigureStubs(kClientOneKey,
815 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
816 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
817
818 // Configure stubs with instrumentation stubs again.
819 CheckConfigureStubs(kClientOneKey,
820 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
821 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
822 1U);
823
824 // Check we can disable instrumentation.
825 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
826 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
827}
828
829TEST_F(InstrumentationTest, MultiConfigureStubs_Nothing) {
830 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
831
832 // Check kInstrumentNothing with two clients.
833 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
834 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
835
836 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
837 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
838}
839
840TEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubs) {
841 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
842
843 // Configure stubs with instrumentation stubs for 1st client.
844 CheckConfigureStubs(kClientOneKey,
845 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
846 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
847 1U);
848
849 // Configure stubs with instrumentation stubs for 2nd client.
850 CheckConfigureStubs(kClientTwoKey,
851 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
852 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
853 2U);
854
855 // 1st client requests instrumentation deactivation but 2nd client still needs
856 // instrumentation stubs.
857 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
858 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
859 1U);
860
861 // 2nd client requests instrumentation deactivation
862 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
863 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
864}
865
866TEST_F(InstrumentationTest, MultiConfigureStubs_Interpreter) {
867 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
868
869 // Configure stubs with interpreter for 1st client.
870 CheckConfigureStubs(kClientOneKey,
871 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
872 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
873
874 // Configure stubs with interpreter for 2nd client.
875 CheckConfigureStubs(kClientTwoKey,
876 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
877 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
878
879 // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
880 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
881 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
882
883 // 2nd client requests instrumentation deactivation
884 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
885 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
886}
887
888TEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubsThenInterpreter) {
889 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
890
891 // Configure stubs with instrumentation stubs for 1st client.
892 CheckConfigureStubs(kClientOneKey,
893 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
894 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
895 1U);
896
897 // Configure stubs with interpreter for 2nd client.
898 CheckConfigureStubs(kClientTwoKey,
899 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
900 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
901
902 // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
903 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
904 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
905
906 // 2nd client requests instrumentation deactivation
907 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
908 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
909}
910
911TEST_F(InstrumentationTest, MultiConfigureStubs_InterpreterThenInstrumentationStubs) {
912 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
913
914 // Configure stubs with interpreter for 1st client.
915 CheckConfigureStubs(kClientOneKey,
916 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
917 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
918
919 // Configure stubs with instrumentation stubs for 2nd client.
920 CheckConfigureStubs(kClientTwoKey,
921 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
922 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
923
924 // 1st client requests instrumentation deactivation but 2nd client still needs
925 // instrumentation stubs.
926 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
927 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
928 1U);
929
930 // 2nd client requests instrumentation deactivation
931 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
932 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
933}
934
935} // namespace instrumentation
936} // namespace art