blob: 7f9f04f4350e37b6f555025f96e040af5b4b1501 [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"
26#include "jvalue.h"
27#include "runtime.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070028#include "scoped_thread_state_change-inl.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020029#include "thread_list.h"
30#include "thread-inl.h"
31
32namespace art {
33namespace instrumentation {
34
35class TestInstrumentationListener FINAL : public instrumentation::InstrumentationListener {
36 public:
37 TestInstrumentationListener()
38 : received_method_enter_event(false), received_method_exit_event(false),
39 received_method_unwind_event(false), received_dex_pc_moved_event(false),
40 received_field_read_event(false), received_field_written_event(false),
Nicolas Geoffray81f0f952016-01-20 16:25:19 +000041 received_exception_caught_event(false), received_branch_event(false),
Nicolas Geoffray5550ca82015-08-21 18:38:30 +010042 received_invoke_virtual_or_interface_event(false) {}
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020043
44 virtual ~TestInstrumentationListener() {}
45
46 void MethodEntered(Thread* thread ATTRIBUTE_UNUSED,
47 mirror::Object* this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070048 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020049 uint32_t dex_pc ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070050 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020051 received_method_enter_event = true;
52 }
53
54 void MethodExited(Thread* thread ATTRIBUTE_UNUSED,
55 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,
58 const JValue& return_value ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070059 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020060 received_method_exit_event = true;
61 }
62
63 void MethodUnwind(Thread* thread ATTRIBUTE_UNUSED,
64 mirror::Object* this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070065 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020066 uint32_t dex_pc ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070067 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020068 received_method_unwind_event = true;
69 }
70
71 void DexPcMoved(Thread* thread ATTRIBUTE_UNUSED,
72 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 new_dex_pc ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070075 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020076 received_dex_pc_moved_event = true;
77 }
78
79 void FieldRead(Thread* thread ATTRIBUTE_UNUSED,
80 mirror::Object* this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070081 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020082 uint32_t dex_pc ATTRIBUTE_UNUSED,
83 ArtField* field 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_field_read_event = true;
86 }
87
88 void FieldWritten(Thread* thread ATTRIBUTE_UNUSED,
89 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 dex_pc ATTRIBUTE_UNUSED,
92 ArtField* field ATTRIBUTE_UNUSED,
93 const JValue& field_value ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070094 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020095 received_field_written_event = true;
96 }
97
98 void ExceptionCaught(Thread* thread ATTRIBUTE_UNUSED,
99 mirror::Throwable* exception_object ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700100 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200101 received_exception_caught_event = true;
102 }
103
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000104 void Branch(Thread* thread ATTRIBUTE_UNUSED,
105 ArtMethod* method ATTRIBUTE_UNUSED,
106 uint32_t dex_pc ATTRIBUTE_UNUSED,
107 int32_t dex_pc_offset ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700108 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000109 received_branch_event = true;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200110 }
111
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100112 void InvokeVirtualOrInterface(Thread* thread ATTRIBUTE_UNUSED,
113 mirror::Object* this_object ATTRIBUTE_UNUSED,
114 ArtMethod* caller ATTRIBUTE_UNUSED,
115 uint32_t dex_pc ATTRIBUTE_UNUSED,
116 ArtMethod* callee ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700117 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100118 received_invoke_virtual_or_interface_event = true;
119 }
120
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200121 void Reset() {
122 received_method_enter_event = false;
123 received_method_exit_event = false;
124 received_method_unwind_event = false;
125 received_dex_pc_moved_event = false;
126 received_field_read_event = false;
127 received_field_written_event = false;
128 received_exception_caught_event = false;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000129 received_branch_event = false;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100130 received_invoke_virtual_or_interface_event = false;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200131 }
132
133 bool received_method_enter_event;
134 bool received_method_exit_event;
135 bool received_method_unwind_event;
136 bool received_dex_pc_moved_event;
137 bool received_field_read_event;
138 bool received_field_written_event;
139 bool received_exception_caught_event;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000140 bool received_branch_event;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100141 bool received_invoke_virtual_or_interface_event;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200142
143 private:
144 DISALLOW_COPY_AND_ASSIGN(TestInstrumentationListener);
145};
146
147class InstrumentationTest : public CommonRuntimeTest {
148 public:
149 // Unique keys used to test Instrumentation::ConfigureStubs.
150 static constexpr const char* kClientOneKey = "TestClient1";
151 static constexpr const char* kClientTwoKey = "TestClient2";
152
153 void CheckConfigureStubs(const char* key, Instrumentation::InstrumentationLevel level) {
154 ScopedObjectAccess soa(Thread::Current());
155 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700156 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700157 gc::ScopedGCCriticalSection gcs(soa.Self(),
158 gc::kGcCauseInstrumentation,
159 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700160 ScopedSuspendAll ssa("Instrumentation::ConfigureStubs");
161 instr->ConfigureStubs(key, level);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200162 }
163
164 Instrumentation::InstrumentationLevel GetCurrentInstrumentationLevel() {
165 return Runtime::Current()->GetInstrumentation()->GetCurrentInstrumentationLevel();
166 }
167
168 size_t GetInstrumentationUserCount() {
169 ScopedObjectAccess soa(Thread::Current());
170 return Runtime::Current()->GetInstrumentation()->requested_instrumentation_levels_.size();
171 }
172
173 void TestEvent(uint32_t instrumentation_event) {
174 ScopedObjectAccess soa(Thread::Current());
175 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
176 TestInstrumentationListener listener;
177 {
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700178 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700179 ScopedSuspendAll ssa("Add instrumentation listener");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200180 instr->AddListener(&listener, instrumentation_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200181 }
182
Mathieu Chartiere401d142015-04-22 13:56:20 -0700183 ArtMethod* const event_method = nullptr;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200184 mirror::Object* const event_obj = nullptr;
185 const uint32_t event_dex_pc = 0;
186
187 // Check the listener is registered and is notified of the event.
188 EXPECT_TRUE(HasEventListener(instr, instrumentation_event));
189 EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event));
190 ReportEvent(instr, instrumentation_event, soa.Self(), event_method, event_obj, event_dex_pc);
191 EXPECT_TRUE(DidListenerReceiveEvent(listener, instrumentation_event));
192
193 listener.Reset();
194 {
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700195 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700196 ScopedSuspendAll ssa("Remove instrumentation listener");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200197 instr->RemoveListener(&listener, instrumentation_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200198 }
199
200 // Check the listener is not registered and is not notified of the event.
201 EXPECT_FALSE(HasEventListener(instr, instrumentation_event));
202 EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event));
203 ReportEvent(instr, instrumentation_event, soa.Self(), event_method, event_obj, event_dex_pc);
204 EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event));
205 }
206
Mathieu Chartiere401d142015-04-22 13:56:20 -0700207 void DeoptimizeMethod(Thread* self, ArtMethod* method, bool enable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700208 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200209 Runtime* runtime = Runtime::Current();
210 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700211 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700212 gc::ScopedGCCriticalSection gcs(self,
213 gc::kGcCauseInstrumentation,
214 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700215 ScopedSuspendAll ssa("Single method deoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200216 if (enable_deoptimization) {
217 instrumentation->EnableDeoptimization();
218 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700219 instrumentation->Deoptimize(method);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200220 }
221
Mathieu Chartiere401d142015-04-22 13:56:20 -0700222 void UndeoptimizeMethod(Thread* self, ArtMethod* method,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200223 const char* key, bool disable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700224 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200225 Runtime* runtime = Runtime::Current();
226 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700227 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700228 gc::ScopedGCCriticalSection gcs(self,
229 gc::kGcCauseInstrumentation,
230 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700231 ScopedSuspendAll ssa("Single method undeoptimization");
Mathieu Chartiere401d142015-04-22 13:56:20 -0700232 instrumentation->Undeoptimize(method);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200233 if (disable_deoptimization) {
234 instrumentation->DisableDeoptimization(key);
235 }
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200236 }
237
238 void DeoptimizeEverything(Thread* self, const char* key, bool enable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700239 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200240 Runtime* runtime = Runtime::Current();
241 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700242 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700243 gc::ScopedGCCriticalSection gcs(self,
244 gc::kGcCauseInstrumentation,
245 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700246 ScopedSuspendAll ssa("Full deoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200247 if (enable_deoptimization) {
248 instrumentation->EnableDeoptimization();
249 }
250 instrumentation->DeoptimizeEverything(key);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200251 }
252
253 void UndeoptimizeEverything(Thread* self, const char* key, bool disable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700254 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200255 Runtime* runtime = Runtime::Current();
256 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700257 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700258 gc::ScopedGCCriticalSection gcs(self,
259 gc::kGcCauseInstrumentation,
260 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700261 ScopedSuspendAll ssa("Full undeoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200262 instrumentation->UndeoptimizeEverything(key);
263 if (disable_deoptimization) {
264 instrumentation->DisableDeoptimization(key);
265 }
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200266 }
267
268 void EnableMethodTracing(Thread* self, const char* key, bool needs_interpreter)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700269 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200270 Runtime* runtime = Runtime::Current();
271 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700272 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700273 gc::ScopedGCCriticalSection gcs(self,
274 gc::kGcCauseInstrumentation,
275 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700276 ScopedSuspendAll ssa("EnableMethodTracing");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200277 instrumentation->EnableMethodTracing(key, needs_interpreter);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200278 }
279
280 void DisableMethodTracing(Thread* self, const char* key)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700281 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200282 Runtime* runtime = Runtime::Current();
283 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700284 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700285 gc::ScopedGCCriticalSection gcs(self,
286 gc::kGcCauseInstrumentation,
287 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700288 ScopedSuspendAll ssa("EnableMethodTracing");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200289 instrumentation->DisableMethodTracing(key);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200290 }
291
292 private:
293 static bool HasEventListener(const instrumentation::Instrumentation* instr, uint32_t event_type)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700294 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200295 switch (event_type) {
296 case instrumentation::Instrumentation::kMethodEntered:
297 return instr->HasMethodEntryListeners();
298 case instrumentation::Instrumentation::kMethodExited:
299 return instr->HasMethodExitListeners();
300 case instrumentation::Instrumentation::kMethodUnwind:
301 return instr->HasMethodUnwindListeners();
302 case instrumentation::Instrumentation::kDexPcMoved:
303 return instr->HasDexPcListeners();
304 case instrumentation::Instrumentation::kFieldRead:
305 return instr->HasFieldReadListeners();
306 case instrumentation::Instrumentation::kFieldWritten:
307 return instr->HasFieldWriteListeners();
308 case instrumentation::Instrumentation::kExceptionCaught:
309 return instr->HasExceptionCaughtListeners();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000310 case instrumentation::Instrumentation::kBranch:
311 return instr->HasBranchListeners();
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100312 case instrumentation::Instrumentation::kInvokeVirtualOrInterface:
313 return instr->HasInvokeVirtualOrInterfaceListeners();
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200314 default:
315 LOG(FATAL) << "Unknown instrumentation event " << event_type;
316 UNREACHABLE();
317 }
318 }
319
320 static void ReportEvent(const instrumentation::Instrumentation* instr, uint32_t event_type,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700321 Thread* self, ArtMethod* method, mirror::Object* obj,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200322 uint32_t dex_pc)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700323 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200324 switch (event_type) {
325 case instrumentation::Instrumentation::kMethodEntered:
326 instr->MethodEnterEvent(self, obj, method, dex_pc);
327 break;
328 case instrumentation::Instrumentation::kMethodExited: {
329 JValue value;
330 instr->MethodExitEvent(self, obj, method, dex_pc, value);
331 break;
332 }
333 case instrumentation::Instrumentation::kMethodUnwind:
334 instr->MethodUnwindEvent(self, obj, method, dex_pc);
335 break;
336 case instrumentation::Instrumentation::kDexPcMoved:
337 instr->DexPcMovedEvent(self, obj, method, dex_pc);
338 break;
339 case instrumentation::Instrumentation::kFieldRead:
340 instr->FieldReadEvent(self, obj, method, dex_pc, nullptr);
341 break;
342 case instrumentation::Instrumentation::kFieldWritten: {
343 JValue value;
344 instr->FieldWriteEvent(self, obj, method, dex_pc, nullptr, value);
345 break;
346 }
347 case instrumentation::Instrumentation::kExceptionCaught: {
348 ThrowArithmeticExceptionDivideByZero();
349 mirror::Throwable* event_exception = self->GetException();
350 instr->ExceptionCaughtEvent(self, event_exception);
351 self->ClearException();
352 break;
353 }
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000354 case instrumentation::Instrumentation::kBranch:
355 instr->Branch(self, method, dex_pc, -1);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200356 break;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100357 case instrumentation::Instrumentation::kInvokeVirtualOrInterface:
358 instr->InvokeVirtualOrInterface(self, obj, method, dex_pc, method);
359 break;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200360 default:
361 LOG(FATAL) << "Unknown instrumentation event " << event_type;
362 UNREACHABLE();
363 }
364 }
365
366 static bool DidListenerReceiveEvent(const TestInstrumentationListener& listener,
367 uint32_t event_type) {
368 switch (event_type) {
369 case instrumentation::Instrumentation::kMethodEntered:
370 return listener.received_method_enter_event;
371 case instrumentation::Instrumentation::kMethodExited:
372 return listener.received_method_exit_event;
373 case instrumentation::Instrumentation::kMethodUnwind:
374 return listener.received_method_unwind_event;
375 case instrumentation::Instrumentation::kDexPcMoved:
376 return listener.received_dex_pc_moved_event;
377 case instrumentation::Instrumentation::kFieldRead:
378 return listener.received_field_read_event;
379 case instrumentation::Instrumentation::kFieldWritten:
380 return listener.received_field_written_event;
381 case instrumentation::Instrumentation::kExceptionCaught:
382 return listener.received_exception_caught_event;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000383 case instrumentation::Instrumentation::kBranch:
384 return listener.received_branch_event;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100385 case instrumentation::Instrumentation::kInvokeVirtualOrInterface:
386 return listener.received_invoke_virtual_or_interface_event;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200387 default:
388 LOG(FATAL) << "Unknown instrumentation event " << event_type;
389 UNREACHABLE();
390 }
391 }
392};
393
394TEST_F(InstrumentationTest, NoInstrumentation) {
395 ScopedObjectAccess soa(Thread::Current());
396 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
397 ASSERT_NE(instr, nullptr);
398
399 EXPECT_FALSE(instr->AreExitStubsInstalled());
400 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
401 EXPECT_FALSE(instr->IsActive());
402 EXPECT_FALSE(instr->ShouldNotifyMethodEnterExitEvents());
403
404 // Test interpreter table is the default one.
405 EXPECT_EQ(instrumentation::kMainHandlerTable, instr->GetInterpreterHandlerTable());
406
407 // Check there is no registered listener.
408 EXPECT_FALSE(instr->HasDexPcListeners());
409 EXPECT_FALSE(instr->HasExceptionCaughtListeners());
410 EXPECT_FALSE(instr->HasFieldReadListeners());
411 EXPECT_FALSE(instr->HasFieldWriteListeners());
412 EXPECT_FALSE(instr->HasMethodEntryListeners());
413 EXPECT_FALSE(instr->HasMethodExitListeners());
414 EXPECT_FALSE(instr->IsActive());
415}
416
417// Test instrumentation listeners for each event.
418TEST_F(InstrumentationTest, MethodEntryEvent) {
419 TestEvent(instrumentation::Instrumentation::kMethodEntered);
420}
421
422TEST_F(InstrumentationTest, MethodExitEvent) {
423 TestEvent(instrumentation::Instrumentation::kMethodExited);
424}
425
426TEST_F(InstrumentationTest, MethodUnwindEvent) {
427 TestEvent(instrumentation::Instrumentation::kMethodUnwind);
428}
429
430TEST_F(InstrumentationTest, DexPcMovedEvent) {
431 TestEvent(instrumentation::Instrumentation::kDexPcMoved);
432}
433
434TEST_F(InstrumentationTest, FieldReadEvent) {
435 TestEvent(instrumentation::Instrumentation::kFieldRead);
436}
437
438TEST_F(InstrumentationTest, FieldWriteEvent) {
439 TestEvent(instrumentation::Instrumentation::kFieldWritten);
440}
441
442TEST_F(InstrumentationTest, ExceptionCaughtEvent) {
443 TestEvent(instrumentation::Instrumentation::kExceptionCaught);
444}
445
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000446TEST_F(InstrumentationTest, BranchEvent) {
447 TestEvent(instrumentation::Instrumentation::kBranch);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200448}
449
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100450TEST_F(InstrumentationTest, InvokeVirtualOrInterfaceEvent) {
451 TestEvent(instrumentation::Instrumentation::kInvokeVirtualOrInterface);
452}
453
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200454TEST_F(InstrumentationTest, DeoptimizeDirectMethod) {
455 ScopedObjectAccess soa(Thread::Current());
456 jobject class_loader = LoadDex("Instrumentation");
457 Runtime* const runtime = Runtime::Current();
458 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
459 ClassLinker* class_linker = runtime->GetClassLinker();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700460 StackHandleScope<1> hs(soa.Self());
Mathieu Chartier0795f232016-09-27 18:43:30 -0700461 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200462 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
463 ASSERT_TRUE(klass != nullptr);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700464 ArtMethod* method_to_deoptimize = klass->FindDeclaredDirectMethod("instanceMethod", "()V",
Andreas Gampe542451c2016-07-26 09:02:02 -0700465 kRuntimePointerSize);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700466 ASSERT_TRUE(method_to_deoptimize != nullptr);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200467
468 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700469 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200470
471 DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);
472
473 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
474 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700475 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200476
477 constexpr const char* instrumentation_key = "DeoptimizeDirectMethod";
478 UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
479
480 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700481 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200482}
483
484TEST_F(InstrumentationTest, FullDeoptimization) {
485 ScopedObjectAccess soa(Thread::Current());
486 Runtime* const runtime = Runtime::Current();
487 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
488 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
489
490 constexpr const char* instrumentation_key = "FullDeoptimization";
491 DeoptimizeEverything(soa.Self(), instrumentation_key, true);
492
493 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
494 EXPECT_TRUE(instr->AreExitStubsInstalled());
495
496 UndeoptimizeEverything(soa.Self(), instrumentation_key, true);
497
498 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
499}
500
501TEST_F(InstrumentationTest, MixedDeoptimization) {
502 ScopedObjectAccess soa(Thread::Current());
503 jobject class_loader = LoadDex("Instrumentation");
504 Runtime* const runtime = Runtime::Current();
505 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
506 ClassLinker* class_linker = runtime->GetClassLinker();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700507 StackHandleScope<1> hs(soa.Self());
Mathieu Chartier0795f232016-09-27 18:43:30 -0700508 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200509 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
510 ASSERT_TRUE(klass != nullptr);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700511 ArtMethod* method_to_deoptimize = klass->FindDeclaredDirectMethod("instanceMethod", "()V",
Andreas Gampe542451c2016-07-26 09:02:02 -0700512 kRuntimePointerSize);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700513 ASSERT_TRUE(method_to_deoptimize != nullptr);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200514
515 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700516 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200517
518 DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);
519 // Deoptimizing a method does not change instrumentation level.
520 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
521 GetCurrentInstrumentationLevel());
522 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
523 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700524 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200525
526 constexpr const char* instrumentation_key = "MixedDeoptimization";
527 DeoptimizeEverything(soa.Self(), instrumentation_key, false);
528 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
529 GetCurrentInstrumentationLevel());
530 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
531 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700532 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200533
534 UndeoptimizeEverything(soa.Self(), instrumentation_key, false);
535 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
536 GetCurrentInstrumentationLevel());
537 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
538 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700539 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200540
541 UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
542 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
543 GetCurrentInstrumentationLevel());
544 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700545 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200546}
547
548TEST_F(InstrumentationTest, MethodTracing_Interpreter) {
549 ScopedObjectAccess soa(Thread::Current());
550 Runtime* const runtime = Runtime::Current();
551 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
552 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
553
554 constexpr const char* instrumentation_key = "MethodTracing";
555 EnableMethodTracing(soa.Self(), instrumentation_key, true);
556 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
557 GetCurrentInstrumentationLevel());
558 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
559 EXPECT_TRUE(instr->AreExitStubsInstalled());
560
561 DisableMethodTracing(soa.Self(), instrumentation_key);
562 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
563 GetCurrentInstrumentationLevel());
564 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
565}
566
567TEST_F(InstrumentationTest, MethodTracing_InstrumentationEntryExitStubs) {
568 ScopedObjectAccess soa(Thread::Current());
569 Runtime* const runtime = Runtime::Current();
570 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
571 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
572
573 constexpr const char* instrumentation_key = "MethodTracing";
574 EnableMethodTracing(soa.Self(), instrumentation_key, false);
575 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
576 GetCurrentInstrumentationLevel());
577 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
578 EXPECT_TRUE(instr->AreExitStubsInstalled());
579
580 DisableMethodTracing(soa.Self(), instrumentation_key);
581 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
582 GetCurrentInstrumentationLevel());
583 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
584}
585
586// We use a macro to print the line number where the test is failing.
587#define CHECK_INSTRUMENTATION(_level, _user_count) \
588 do { \
589 Instrumentation* const instr = Runtime::Current()->GetInstrumentation(); \
590 bool interpreter = \
Chih-Hung Hsieh1a0de6a2016-08-26 15:06:11 -0700591 ((_level) == Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter); \
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200592 EXPECT_EQ(_level, GetCurrentInstrumentationLevel()); \
593 EXPECT_EQ(_user_count, GetInstrumentationUserCount()); \
594 if (instr->IsForcedInterpretOnly()) { \
595 EXPECT_TRUE(instr->InterpretOnly()); \
596 } else if (interpreter) { \
597 EXPECT_TRUE(instr->InterpretOnly()); \
598 } else { \
599 EXPECT_FALSE(instr->InterpretOnly()); \
600 } \
601 if (interpreter) { \
602 EXPECT_TRUE(instr->AreAllMethodsDeoptimized()); \
603 } else { \
604 EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); \
605 } \
606 } while (false)
607
608TEST_F(InstrumentationTest, ConfigureStubs_Nothing) {
609 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
610
611 // Check no-op.
612 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
613 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
614}
615
616TEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubs) {
617 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
618
619 // Check we can switch to instrumentation stubs
620 CheckConfigureStubs(kClientOneKey,
621 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
622 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
623 1U);
624
625 // Check we can disable instrumentation.
626 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
627 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
628}
629
630TEST_F(InstrumentationTest, ConfigureStubs_Interpreter) {
631 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
632
633 // Check we can switch to interpreter
634 CheckConfigureStubs(kClientOneKey,
635 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
636 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
637
638 // Check we can disable instrumentation.
639 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
640 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
641}
642
643TEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubsToInterpreter) {
644 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
645
646 // Configure stubs with instrumentation stubs.
647 CheckConfigureStubs(kClientOneKey,
648 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
649 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
650 1U);
651
652 // Configure stubs with interpreter.
653 CheckConfigureStubs(kClientOneKey,
654 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
655 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
656
657 // Check we can disable instrumentation.
658 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
659 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
660}
661
662TEST_F(InstrumentationTest, ConfigureStubs_InterpreterToInstrumentationStubs) {
663 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
664
665 // Configure stubs with interpreter.
666 CheckConfigureStubs(kClientOneKey,
667 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
668 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
669
670 // Configure stubs with instrumentation stubs.
671 CheckConfigureStubs(kClientOneKey,
672 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
673 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
674 1U);
675
676 // Check we can disable instrumentation.
677 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
678 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
679}
680
681TEST_F(InstrumentationTest,
682 ConfigureStubs_InstrumentationStubsToInterpreterToInstrumentationStubs) {
683 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
684
685 // Configure stubs with instrumentation stubs.
686 CheckConfigureStubs(kClientOneKey,
687 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
688 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
689 1U);
690
691 // Configure stubs with interpreter.
692 CheckConfigureStubs(kClientOneKey,
693 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
694 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
695
696 // Configure stubs with instrumentation stubs again.
697 CheckConfigureStubs(kClientOneKey,
698 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
699 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
700 1U);
701
702 // Check we can disable instrumentation.
703 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
704 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
705}
706
707TEST_F(InstrumentationTest, MultiConfigureStubs_Nothing) {
708 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
709
710 // Check kInstrumentNothing with two clients.
711 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
712 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
713
714 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
715 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
716}
717
718TEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubs) {
719 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
720
721 // Configure stubs with instrumentation stubs for 1st client.
722 CheckConfigureStubs(kClientOneKey,
723 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
724 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
725 1U);
726
727 // Configure stubs with instrumentation stubs for 2nd client.
728 CheckConfigureStubs(kClientTwoKey,
729 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
730 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
731 2U);
732
733 // 1st client requests instrumentation deactivation but 2nd client still needs
734 // instrumentation stubs.
735 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
736 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
737 1U);
738
739 // 2nd client requests instrumentation deactivation
740 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
741 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
742}
743
744TEST_F(InstrumentationTest, MultiConfigureStubs_Interpreter) {
745 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
746
747 // Configure stubs with interpreter for 1st client.
748 CheckConfigureStubs(kClientOneKey,
749 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
750 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
751
752 // Configure stubs with interpreter for 2nd client.
753 CheckConfigureStubs(kClientTwoKey,
754 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
755 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
756
757 // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
758 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
759 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
760
761 // 2nd client requests instrumentation deactivation
762 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
763 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
764}
765
766TEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubsThenInterpreter) {
767 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
768
769 // Configure stubs with instrumentation stubs for 1st client.
770 CheckConfigureStubs(kClientOneKey,
771 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
772 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
773 1U);
774
775 // Configure stubs with interpreter for 2nd client.
776 CheckConfigureStubs(kClientTwoKey,
777 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
778 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
779
780 // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
781 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
782 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
783
784 // 2nd client requests instrumentation deactivation
785 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
786 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
787}
788
789TEST_F(InstrumentationTest, MultiConfigureStubs_InterpreterThenInstrumentationStubs) {
790 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
791
792 // Configure stubs with interpreter for 1st client.
793 CheckConfigureStubs(kClientOneKey,
794 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
795 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
796
797 // Configure stubs with instrumentation stubs for 2nd client.
798 CheckConfigureStubs(kClientTwoKey,
799 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
800 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
801
802 // 1st client requests instrumentation deactivation but 2nd client still needs
803 // instrumentation stubs.
804 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
805 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
806 1U);
807
808 // 2nd client requests instrumentation deactivation
809 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
810 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
811}
812
813} // namespace instrumentation
814} // namespace art