1 /*
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 
19 #include "art_method-inl.h"
20 #include "base/enums.h"
21 #include "class_linker-inl.h"
22 #include "common_runtime_test.h"
23 #include "common_throws.h"
24 #include "dex/dex_file.h"
25 #include "gc/scoped_gc_critical_section.h"
26 #include "handle_scope-inl.h"
27 #include "jni/jni_internal.h"
28 #include "jvalue.h"
29 #include "runtime.h"
30 #include "scoped_thread_state_change-inl.h"
31 #include "interpreter/shadow_frame.h"
32 #include "thread-inl.h"
33 #include "thread_list.h"
34 #include "well_known_classes.h"
35 
36 namespace art {
37 namespace instrumentation {
38 
39 class TestInstrumentationListener final : public instrumentation::InstrumentationListener {
40  public:
TestInstrumentationListener()41   TestInstrumentationListener()
42     : received_method_enter_event(false),
43       received_method_exit_event(false),
44       received_method_exit_object_event(false),
45       received_method_unwind_event(false),
46       received_dex_pc_moved_event(false),
47       received_field_read_event(false),
48       received_field_written_event(false),
49       received_field_written_object_event(false),
50       received_exception_thrown_event(false),
51       received_exception_handled_event(false),
52       received_branch_event(false),
53       received_watched_frame_pop(false) {}
54 
~TestInstrumentationListener()55   virtual ~TestInstrumentationListener() {}
56 
MethodEntered(Thread * thread ATTRIBUTE_UNUSED,Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,uint32_t dex_pc ATTRIBUTE_UNUSED)57   void MethodEntered(Thread* thread ATTRIBUTE_UNUSED,
58                      Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
59                      ArtMethod* method ATTRIBUTE_UNUSED,
60                      uint32_t dex_pc ATTRIBUTE_UNUSED)
61       override REQUIRES_SHARED(Locks::mutator_lock_) {
62     received_method_enter_event = true;
63   }
64 
MethodExited(Thread * thread ATTRIBUTE_UNUSED,Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,uint32_t dex_pc ATTRIBUTE_UNUSED,Handle<mirror::Object> return_value ATTRIBUTE_UNUSED)65   void MethodExited(Thread* thread ATTRIBUTE_UNUSED,
66                     Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
67                     ArtMethod* method ATTRIBUTE_UNUSED,
68                     uint32_t dex_pc ATTRIBUTE_UNUSED,
69                     Handle<mirror::Object> return_value ATTRIBUTE_UNUSED)
70       override REQUIRES_SHARED(Locks::mutator_lock_) {
71     received_method_exit_object_event = true;
72   }
73 
MethodExited(Thread * thread ATTRIBUTE_UNUSED,Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,uint32_t dex_pc ATTRIBUTE_UNUSED,const JValue & return_value ATTRIBUTE_UNUSED)74   void MethodExited(Thread* thread ATTRIBUTE_UNUSED,
75                     Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
76                     ArtMethod* method ATTRIBUTE_UNUSED,
77                     uint32_t dex_pc ATTRIBUTE_UNUSED,
78                     const JValue& return_value ATTRIBUTE_UNUSED)
79       override REQUIRES_SHARED(Locks::mutator_lock_) {
80     received_method_exit_event = true;
81   }
82 
MethodUnwind(Thread * thread ATTRIBUTE_UNUSED,Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,uint32_t dex_pc ATTRIBUTE_UNUSED)83   void MethodUnwind(Thread* thread ATTRIBUTE_UNUSED,
84                     Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
85                     ArtMethod* method ATTRIBUTE_UNUSED,
86                     uint32_t dex_pc ATTRIBUTE_UNUSED)
87       override REQUIRES_SHARED(Locks::mutator_lock_) {
88     received_method_unwind_event = true;
89   }
90 
DexPcMoved(Thread * thread ATTRIBUTE_UNUSED,Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,uint32_t new_dex_pc ATTRIBUTE_UNUSED)91   void DexPcMoved(Thread* thread ATTRIBUTE_UNUSED,
92                   Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
93                   ArtMethod* method ATTRIBUTE_UNUSED,
94                   uint32_t new_dex_pc ATTRIBUTE_UNUSED)
95       override REQUIRES_SHARED(Locks::mutator_lock_) {
96     received_dex_pc_moved_event = true;
97   }
98 
FieldRead(Thread * thread ATTRIBUTE_UNUSED,Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,uint32_t dex_pc ATTRIBUTE_UNUSED,ArtField * field ATTRIBUTE_UNUSED)99   void FieldRead(Thread* thread ATTRIBUTE_UNUSED,
100                  Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
101                  ArtMethod* method ATTRIBUTE_UNUSED,
102                  uint32_t dex_pc ATTRIBUTE_UNUSED,
103                  ArtField* field ATTRIBUTE_UNUSED)
104       override REQUIRES_SHARED(Locks::mutator_lock_) {
105     received_field_read_event = true;
106   }
107 
FieldWritten(Thread * thread ATTRIBUTE_UNUSED,Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,uint32_t dex_pc ATTRIBUTE_UNUSED,ArtField * field ATTRIBUTE_UNUSED,Handle<mirror::Object> field_value ATTRIBUTE_UNUSED)108   void FieldWritten(Thread* thread ATTRIBUTE_UNUSED,
109                     Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
110                     ArtMethod* method ATTRIBUTE_UNUSED,
111                     uint32_t dex_pc ATTRIBUTE_UNUSED,
112                     ArtField* field ATTRIBUTE_UNUSED,
113                     Handle<mirror::Object> field_value ATTRIBUTE_UNUSED)
114       override REQUIRES_SHARED(Locks::mutator_lock_) {
115     received_field_written_object_event = true;
116   }
117 
FieldWritten(Thread * thread ATTRIBUTE_UNUSED,Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,uint32_t dex_pc ATTRIBUTE_UNUSED,ArtField * field ATTRIBUTE_UNUSED,const JValue & field_value ATTRIBUTE_UNUSED)118   void FieldWritten(Thread* thread ATTRIBUTE_UNUSED,
119                     Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
120                     ArtMethod* method ATTRIBUTE_UNUSED,
121                     uint32_t dex_pc ATTRIBUTE_UNUSED,
122                     ArtField* field ATTRIBUTE_UNUSED,
123                     const JValue& field_value ATTRIBUTE_UNUSED)
124       override REQUIRES_SHARED(Locks::mutator_lock_) {
125     received_field_written_event = true;
126   }
127 
ExceptionThrown(Thread * thread ATTRIBUTE_UNUSED,Handle<mirror::Throwable> exception_object ATTRIBUTE_UNUSED)128   void ExceptionThrown(Thread* thread ATTRIBUTE_UNUSED,
129                        Handle<mirror::Throwable> exception_object ATTRIBUTE_UNUSED)
130       override REQUIRES_SHARED(Locks::mutator_lock_) {
131     received_exception_thrown_event = true;
132   }
133 
ExceptionHandled(Thread * self ATTRIBUTE_UNUSED,Handle<mirror::Throwable> throwable ATTRIBUTE_UNUSED)134   void ExceptionHandled(Thread* self ATTRIBUTE_UNUSED,
135                         Handle<mirror::Throwable> throwable ATTRIBUTE_UNUSED)
136       override REQUIRES_SHARED(Locks::mutator_lock_) {
137     received_exception_handled_event = true;
138   }
139 
Branch(Thread * thread ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,uint32_t dex_pc ATTRIBUTE_UNUSED,int32_t dex_pc_offset ATTRIBUTE_UNUSED)140   void Branch(Thread* thread ATTRIBUTE_UNUSED,
141               ArtMethod* method ATTRIBUTE_UNUSED,
142               uint32_t dex_pc ATTRIBUTE_UNUSED,
143               int32_t dex_pc_offset ATTRIBUTE_UNUSED)
144       override REQUIRES_SHARED(Locks::mutator_lock_) {
145     received_branch_event = true;
146   }
147 
WatchedFramePop(Thread * thread ATTRIBUTE_UNUSED,const ShadowFrame & frame ATTRIBUTE_UNUSED)148   void WatchedFramePop(Thread* thread ATTRIBUTE_UNUSED, const ShadowFrame& frame ATTRIBUTE_UNUSED)
149       override REQUIRES_SHARED(Locks::mutator_lock_) {
150     received_watched_frame_pop  = true;
151   }
152 
Reset()153   void Reset() {
154     received_method_enter_event = false;
155     received_method_exit_event = false;
156     received_method_exit_object_event = false;
157     received_method_unwind_event = false;
158     received_dex_pc_moved_event = false;
159     received_field_read_event = false;
160     received_field_written_event = false;
161     received_field_written_object_event = false;
162     received_exception_thrown_event = false;
163     received_exception_handled_event = false;
164     received_branch_event = false;
165     received_watched_frame_pop = false;
166   }
167 
168   bool received_method_enter_event;
169   bool received_method_exit_event;
170   bool received_method_exit_object_event;
171   bool received_method_unwind_event;
172   bool received_dex_pc_moved_event;
173   bool received_field_read_event;
174   bool received_field_written_event;
175   bool received_field_written_object_event;
176   bool received_exception_thrown_event;
177   bool received_exception_handled_event;
178   bool received_branch_event;
179   bool received_watched_frame_pop;
180 
181  private:
182   DISALLOW_COPY_AND_ASSIGN(TestInstrumentationListener);
183 };
184 
185 class InstrumentationTest : public CommonRuntimeTest {
186  public:
187   // Unique keys used to test Instrumentation::ConfigureStubs.
188   static constexpr const char* kClientOneKey = "TestClient1";
189   static constexpr const char* kClientTwoKey = "TestClient2";
190 
CheckConfigureStubs(const char * key,Instrumentation::InstrumentationLevel level)191   void CheckConfigureStubs(const char* key, Instrumentation::InstrumentationLevel level) {
192     ScopedObjectAccess soa(Thread::Current());
193     instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
194     ScopedThreadSuspension sts(soa.Self(), kSuspended);
195     gc::ScopedGCCriticalSection gcs(soa.Self(),
196                                     gc::kGcCauseInstrumentation,
197                                     gc::kCollectorTypeInstrumentation);
198     ScopedSuspendAll ssa("Instrumentation::ConfigureStubs");
199     instr->ConfigureStubs(key, level);
200   }
201 
GetCurrentInstrumentationLevel()202   Instrumentation::InstrumentationLevel GetCurrentInstrumentationLevel() {
203     return Runtime::Current()->GetInstrumentation()->GetCurrentInstrumentationLevel();
204   }
205 
GetInstrumentationUserCount()206   size_t GetInstrumentationUserCount() {
207     ScopedObjectAccess soa(Thread::Current());
208     return Runtime::Current()->GetInstrumentation()->requested_instrumentation_levels_.size();
209   }
210 
TestEvent(uint32_t instrumentation_event)211   void TestEvent(uint32_t instrumentation_event) {
212     TestEvent(instrumentation_event, nullptr, nullptr, false);
213   }
214 
TestEvent(uint32_t instrumentation_event,ArtMethod * event_method,ArtField * event_field,bool with_object)215   void TestEvent(uint32_t instrumentation_event,
216                  ArtMethod* event_method,
217                  ArtField* event_field,
218                  bool with_object) {
219     ScopedObjectAccess soa(Thread::Current());
220     instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
221     TestInstrumentationListener listener;
222     {
223       ScopedThreadSuspension sts(soa.Self(), kSuspended);
224       ScopedSuspendAll ssa("Add instrumentation listener");
225       instr->AddListener(&listener, instrumentation_event);
226     }
227 
228     mirror::Object* const event_obj = nullptr;
229     const uint32_t event_dex_pc = 0;
230     ShadowFrameAllocaUniquePtr test_frame = CREATE_SHADOW_FRAME(0, nullptr, event_method, 0);
231 
232     // Check the listener is registered and is notified of the event.
233     EXPECT_TRUE(HasEventListener(instr, instrumentation_event));
234     EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
235     ReportEvent(instr,
236                 instrumentation_event,
237                 soa.Self(),
238                 event_method,
239                 event_obj,
240                 event_field,
241                 event_dex_pc,
242                 *test_frame);
243     EXPECT_TRUE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
244 
245     listener.Reset();
246     {
247       ScopedThreadSuspension sts(soa.Self(), kSuspended);
248       ScopedSuspendAll ssa("Remove instrumentation listener");
249       instr->RemoveListener(&listener, instrumentation_event);
250     }
251 
252     // Check the listener is not registered and is not notified of the event.
253     EXPECT_FALSE(HasEventListener(instr, instrumentation_event));
254     EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
255     ReportEvent(instr,
256                 instrumentation_event,
257                 soa.Self(),
258                 event_method,
259                 event_obj,
260                 event_field,
261                 event_dex_pc,
262                 *test_frame);
263     EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
264   }
265 
DeoptimizeMethod(Thread * self,ArtMethod * method,bool enable_deoptimization)266   void DeoptimizeMethod(Thread* self, ArtMethod* method, bool enable_deoptimization)
267       REQUIRES_SHARED(Locks::mutator_lock_) {
268     Runtime* runtime = Runtime::Current();
269     instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
270     ScopedThreadSuspension sts(self, kSuspended);
271     gc::ScopedGCCriticalSection gcs(self,
272                                     gc::kGcCauseInstrumentation,
273                                     gc::kCollectorTypeInstrumentation);
274     ScopedSuspendAll ssa("Single method deoptimization");
275     if (enable_deoptimization) {
276       instrumentation->EnableDeoptimization();
277     }
278     instrumentation->Deoptimize(method);
279   }
280 
UndeoptimizeMethod(Thread * self,ArtMethod * method,const char * key,bool disable_deoptimization)281   void UndeoptimizeMethod(Thread* self, ArtMethod* method,
282                           const char* key, bool disable_deoptimization)
283       REQUIRES_SHARED(Locks::mutator_lock_) {
284     Runtime* runtime = Runtime::Current();
285     instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
286     ScopedThreadSuspension sts(self, kSuspended);
287     gc::ScopedGCCriticalSection gcs(self,
288                                     gc::kGcCauseInstrumentation,
289                                     gc::kCollectorTypeInstrumentation);
290     ScopedSuspendAll ssa("Single method undeoptimization");
291     instrumentation->Undeoptimize(method);
292     if (disable_deoptimization) {
293       instrumentation->DisableDeoptimization(key);
294     }
295   }
296 
DeoptimizeEverything(Thread * self,const char * key,bool enable_deoptimization)297   void DeoptimizeEverything(Thread* self, const char* key, bool enable_deoptimization)
298         REQUIRES_SHARED(Locks::mutator_lock_) {
299     Runtime* runtime = Runtime::Current();
300     instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
301     ScopedThreadSuspension sts(self, kSuspended);
302     gc::ScopedGCCriticalSection gcs(self,
303                                     gc::kGcCauseInstrumentation,
304                                     gc::kCollectorTypeInstrumentation);
305     ScopedSuspendAll ssa("Full deoptimization");
306     if (enable_deoptimization) {
307       instrumentation->EnableDeoptimization();
308     }
309     instrumentation->DeoptimizeEverything(key);
310   }
311 
UndeoptimizeEverything(Thread * self,const char * key,bool disable_deoptimization)312   void UndeoptimizeEverything(Thread* self, const char* key, bool disable_deoptimization)
313         REQUIRES_SHARED(Locks::mutator_lock_) {
314     Runtime* runtime = Runtime::Current();
315     instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
316     ScopedThreadSuspension sts(self, kSuspended);
317     gc::ScopedGCCriticalSection gcs(self,
318                                     gc::kGcCauseInstrumentation,
319                                     gc::kCollectorTypeInstrumentation);
320     ScopedSuspendAll ssa("Full undeoptimization");
321     instrumentation->UndeoptimizeEverything(key);
322     if (disable_deoptimization) {
323       instrumentation->DisableDeoptimization(key);
324     }
325   }
326 
EnableMethodTracing(Thread * self,const char * key,bool needs_interpreter)327   void EnableMethodTracing(Thread* self, const char* key, bool needs_interpreter)
328         REQUIRES_SHARED(Locks::mutator_lock_) {
329     Runtime* runtime = Runtime::Current();
330     instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
331     ScopedThreadSuspension sts(self, kSuspended);
332     gc::ScopedGCCriticalSection gcs(self,
333                                     gc::kGcCauseInstrumentation,
334                                     gc::kCollectorTypeInstrumentation);
335     ScopedSuspendAll ssa("EnableMethodTracing");
336     instrumentation->EnableMethodTracing(key, needs_interpreter);
337   }
338 
DisableMethodTracing(Thread * self,const char * key)339   void DisableMethodTracing(Thread* self, const char* key)
340         REQUIRES_SHARED(Locks::mutator_lock_) {
341     Runtime* runtime = Runtime::Current();
342     instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
343     ScopedThreadSuspension sts(self, kSuspended);
344     gc::ScopedGCCriticalSection gcs(self,
345                                     gc::kGcCauseInstrumentation,
346                                     gc::kCollectorTypeInstrumentation);
347     ScopedSuspendAll ssa("EnableMethodTracing");
348     instrumentation->DisableMethodTracing(key);
349   }
350 
351  private:
HasEventListener(const instrumentation::Instrumentation * instr,uint32_t event_type)352   static bool HasEventListener(const instrumentation::Instrumentation* instr, uint32_t event_type)
353       REQUIRES_SHARED(Locks::mutator_lock_) {
354     switch (event_type) {
355       case instrumentation::Instrumentation::kMethodEntered:
356         return instr->HasMethodEntryListeners();
357       case instrumentation::Instrumentation::kMethodExited:
358         return instr->HasMethodExitListeners();
359       case instrumentation::Instrumentation::kMethodUnwind:
360         return instr->HasMethodUnwindListeners();
361       case instrumentation::Instrumentation::kDexPcMoved:
362         return instr->HasDexPcListeners();
363       case instrumentation::Instrumentation::kFieldRead:
364         return instr->HasFieldReadListeners();
365       case instrumentation::Instrumentation::kFieldWritten:
366         return instr->HasFieldWriteListeners();
367       case instrumentation::Instrumentation::kExceptionThrown:
368         return instr->HasExceptionThrownListeners();
369       case instrumentation::Instrumentation::kExceptionHandled:
370         return instr->HasExceptionHandledListeners();
371       case instrumentation::Instrumentation::kBranch:
372         return instr->HasBranchListeners();
373       case instrumentation::Instrumentation::kWatchedFramePop:
374         return instr->HasWatchedFramePopListeners();
375       default:
376         LOG(FATAL) << "Unknown instrumentation event " << event_type;
377         UNREACHABLE();
378     }
379   }
380 
ReportEvent(const instrumentation::Instrumentation * instr,uint32_t event_type,Thread * self,ArtMethod * method,mirror::Object * obj,ArtField * field,uint32_t dex_pc,const ShadowFrame & frame)381   static void ReportEvent(const instrumentation::Instrumentation* instr,
382                           uint32_t event_type,
383                           Thread* self,
384                           ArtMethod* method,
385                           mirror::Object* obj,
386                           ArtField* field,
387                           uint32_t dex_pc,
388                           const ShadowFrame& frame)
389       REQUIRES_SHARED(Locks::mutator_lock_) {
390     switch (event_type) {
391       case instrumentation::Instrumentation::kMethodEntered:
392         instr->MethodEnterEvent(self, obj, method, dex_pc);
393         break;
394       case instrumentation::Instrumentation::kMethodExited: {
395         JValue value;
396         instr->MethodExitEvent(self, obj, method, dex_pc, value);
397         break;
398       }
399       case instrumentation::Instrumentation::kMethodUnwind:
400         instr->MethodUnwindEvent(self, obj, method, dex_pc);
401         break;
402       case instrumentation::Instrumentation::kDexPcMoved:
403         instr->DexPcMovedEvent(self, obj, method, dex_pc);
404         break;
405       case instrumentation::Instrumentation::kFieldRead:
406         instr->FieldReadEvent(self, obj, method, dex_pc, field);
407         break;
408       case instrumentation::Instrumentation::kFieldWritten: {
409         JValue value;
410         instr->FieldWriteEvent(self, obj, method, dex_pc, field, value);
411         break;
412       }
413       case instrumentation::Instrumentation::kExceptionThrown: {
414         ThrowArithmeticExceptionDivideByZero();
415         mirror::Throwable* event_exception = self->GetException();
416         instr->ExceptionThrownEvent(self, event_exception);
417         self->ClearException();
418         break;
419       }
420       case instrumentation::Instrumentation::kBranch:
421         instr->Branch(self, method, dex_pc, -1);
422         break;
423       case instrumentation::Instrumentation::kWatchedFramePop:
424         instr->WatchedFramePopped(self, frame);
425         break;
426       case instrumentation::Instrumentation::kExceptionHandled: {
427         ThrowArithmeticExceptionDivideByZero();
428         mirror::Throwable* event_exception = self->GetException();
429         self->ClearException();
430         instr->ExceptionHandledEvent(self, event_exception);
431         break;
432       }
433       default:
434         LOG(FATAL) << "Unknown instrumentation event " << event_type;
435         UNREACHABLE();
436     }
437   }
438 
DidListenerReceiveEvent(const TestInstrumentationListener & listener,uint32_t event_type,bool with_object)439   static bool DidListenerReceiveEvent(const TestInstrumentationListener& listener,
440                                       uint32_t event_type,
441                                       bool with_object) {
442     switch (event_type) {
443       case instrumentation::Instrumentation::kMethodEntered:
444         return listener.received_method_enter_event;
445       case instrumentation::Instrumentation::kMethodExited:
446         return (!with_object && listener.received_method_exit_event) ||
447             (with_object && listener.received_method_exit_object_event);
448       case instrumentation::Instrumentation::kMethodUnwind:
449         return listener.received_method_unwind_event;
450       case instrumentation::Instrumentation::kDexPcMoved:
451         return listener.received_dex_pc_moved_event;
452       case instrumentation::Instrumentation::kFieldRead:
453         return listener.received_field_read_event;
454       case instrumentation::Instrumentation::kFieldWritten:
455         return (!with_object && listener.received_field_written_event) ||
456             (with_object && listener.received_field_written_object_event);
457       case instrumentation::Instrumentation::kExceptionThrown:
458         return listener.received_exception_thrown_event;
459       case instrumentation::Instrumentation::kExceptionHandled:
460         return listener.received_exception_handled_event;
461       case instrumentation::Instrumentation::kBranch:
462         return listener.received_branch_event;
463       case instrumentation::Instrumentation::kWatchedFramePop:
464         return listener.received_watched_frame_pop;
465       default:
466         LOG(FATAL) << "Unknown instrumentation event " << event_type;
467         UNREACHABLE();
468     }
469   }
470 };
471 
TEST_F(InstrumentationTest,NoInstrumentation)472 TEST_F(InstrumentationTest, NoInstrumentation) {
473   ScopedObjectAccess soa(Thread::Current());
474   instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
475   ASSERT_NE(instr, nullptr);
476 
477   EXPECT_FALSE(instr->AreExitStubsInstalled());
478   EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
479   EXPECT_FALSE(instr->IsActive());
480   EXPECT_FALSE(instr->ShouldNotifyMethodEnterExitEvents());
481 
482   // Test interpreter table is the default one.
483   EXPECT_EQ(instrumentation::kMainHandlerTable, instr->GetInterpreterHandlerTable());
484 
485   // Check there is no registered listener.
486   EXPECT_FALSE(instr->HasDexPcListeners());
487   EXPECT_FALSE(instr->HasExceptionThrownListeners());
488   EXPECT_FALSE(instr->HasExceptionHandledListeners());
489   EXPECT_FALSE(instr->HasFieldReadListeners());
490   EXPECT_FALSE(instr->HasFieldWriteListeners());
491   EXPECT_FALSE(instr->HasMethodEntryListeners());
492   EXPECT_FALSE(instr->HasMethodExitListeners());
493   EXPECT_FALSE(instr->IsActive());
494 }
495 
496 // Test instrumentation listeners for each event.
TEST_F(InstrumentationTest,MethodEntryEvent)497 TEST_F(InstrumentationTest, MethodEntryEvent) {
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   ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
505   ASSERT_TRUE(klass != nullptr);
506   ArtMethod* method =
507       klass->FindClassMethod("returnReference", "()Ljava/lang/Object;", kRuntimePointerSize);
508   ASSERT_TRUE(method != nullptr);
509   ASSERT_TRUE(method->IsDirect());
510   ASSERT_TRUE(method->GetDeclaringClass() == klass);
511   TestEvent(instrumentation::Instrumentation::kMethodEntered,
512             /*event_method=*/ method,
513             /*event_field=*/ nullptr,
514             /*with_object=*/ true);
515 }
516 
TEST_F(InstrumentationTest,MethodExitObjectEvent)517 TEST_F(InstrumentationTest, MethodExitObjectEvent) {
518   ScopedObjectAccess soa(Thread::Current());
519   jobject class_loader = LoadDex("Instrumentation");
520   Runtime* const runtime = Runtime::Current();
521   ClassLinker* class_linker = runtime->GetClassLinker();
522   StackHandleScope<1> hs(soa.Self());
523   Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
524   ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
525   ASSERT_TRUE(klass != nullptr);
526   ArtMethod* method =
527       klass->FindClassMethod("returnReference", "()Ljava/lang/Object;", kRuntimePointerSize);
528   ASSERT_TRUE(method != nullptr);
529   ASSERT_TRUE(method->IsDirect());
530   ASSERT_TRUE(method->GetDeclaringClass() == klass);
531   TestEvent(instrumentation::Instrumentation::kMethodExited,
532             /*event_method=*/ method,
533             /*event_field=*/ nullptr,
534             /*with_object=*/ true);
535 }
536 
TEST_F(InstrumentationTest,MethodExitPrimEvent)537 TEST_F(InstrumentationTest, MethodExitPrimEvent) {
538   ScopedObjectAccess soa(Thread::Current());
539   jobject class_loader = LoadDex("Instrumentation");
540   Runtime* const runtime = Runtime::Current();
541   ClassLinker* class_linker = runtime->GetClassLinker();
542   StackHandleScope<1> hs(soa.Self());
543   Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
544   ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
545   ASSERT_TRUE(klass != nullptr);
546   ArtMethod* method = klass->FindClassMethod("returnPrimitive", "()I", kRuntimePointerSize);
547   ASSERT_TRUE(method != nullptr);
548   ASSERT_TRUE(method->IsDirect());
549   ASSERT_TRUE(method->GetDeclaringClass() == klass);
550   TestEvent(instrumentation::Instrumentation::kMethodExited,
551             /*event_method=*/ method,
552             /*event_field=*/ nullptr,
553             /*with_object=*/ false);
554 }
555 
TEST_F(InstrumentationTest,MethodUnwindEvent)556 TEST_F(InstrumentationTest, MethodUnwindEvent) {
557   TestEvent(instrumentation::Instrumentation::kMethodUnwind);
558 }
559 
TEST_F(InstrumentationTest,DexPcMovedEvent)560 TEST_F(InstrumentationTest, DexPcMovedEvent) {
561   TestEvent(instrumentation::Instrumentation::kDexPcMoved);
562 }
563 
TEST_F(InstrumentationTest,FieldReadEvent)564 TEST_F(InstrumentationTest, FieldReadEvent) {
565   TestEvent(instrumentation::Instrumentation::kFieldRead);
566 }
567 
TEST_F(InstrumentationTest,WatchedFramePop)568 TEST_F(InstrumentationTest, WatchedFramePop) {
569   TestEvent(instrumentation::Instrumentation::kWatchedFramePop);
570 }
571 
TEST_F(InstrumentationTest,FieldWriteObjectEvent)572 TEST_F(InstrumentationTest, FieldWriteObjectEvent) {
573   ScopedObjectAccess soa(Thread::Current());
574   jobject class_loader = LoadDex("Instrumentation");
575   Runtime* const runtime = Runtime::Current();
576   ClassLinker* class_linker = runtime->GetClassLinker();
577   StackHandleScope<1> hs(soa.Self());
578   Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
579   ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
580   ASSERT_TRUE(klass != nullptr);
581   ArtField* field = klass->FindDeclaredStaticField("referenceField", "Ljava/lang/Object;");
582   ASSERT_TRUE(field != nullptr);
583 
584   TestEvent(instrumentation::Instrumentation::kFieldWritten,
585             /*event_method=*/ nullptr,
586             /*event_field=*/ field,
587             /*with_object=*/ true);
588 }
589 
TEST_F(InstrumentationTest,FieldWritePrimEvent)590 TEST_F(InstrumentationTest, FieldWritePrimEvent) {
591   ScopedObjectAccess soa(Thread::Current());
592   jobject class_loader = LoadDex("Instrumentation");
593   Runtime* const runtime = Runtime::Current();
594   ClassLinker* class_linker = runtime->GetClassLinker();
595   StackHandleScope<1> hs(soa.Self());
596   Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
597   ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
598   ASSERT_TRUE(klass != nullptr);
599   ArtField* field = klass->FindDeclaredStaticField("primitiveField", "I");
600   ASSERT_TRUE(field != nullptr);
601 
602   TestEvent(instrumentation::Instrumentation::kFieldWritten,
603             /*event_method=*/ nullptr,
604             /*event_field=*/ field,
605             /*with_object=*/ false);
606 }
607 
TEST_F(InstrumentationTest,ExceptionHandledEvent)608 TEST_F(InstrumentationTest, ExceptionHandledEvent) {
609   TestEvent(instrumentation::Instrumentation::kExceptionHandled);
610 }
611 
TEST_F(InstrumentationTest,ExceptionThrownEvent)612 TEST_F(InstrumentationTest, ExceptionThrownEvent) {
613   TestEvent(instrumentation::Instrumentation::kExceptionThrown);
614 }
615 
TEST_F(InstrumentationTest,BranchEvent)616 TEST_F(InstrumentationTest, BranchEvent) {
617   TestEvent(instrumentation::Instrumentation::kBranch);
618 }
619 
TEST_F(InstrumentationTest,DeoptimizeDirectMethod)620 TEST_F(InstrumentationTest, DeoptimizeDirectMethod) {
621   ScopedObjectAccess soa(Thread::Current());
622   jobject class_loader = LoadDex("Instrumentation");
623   Runtime* const runtime = Runtime::Current();
624   instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
625   ClassLinker* class_linker = runtime->GetClassLinker();
626   StackHandleScope<1> hs(soa.Self());
627   Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
628   ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
629   ASSERT_TRUE(klass != nullptr);
630   ArtMethod* method_to_deoptimize =
631       klass->FindClassMethod("instanceMethod", "()V", kRuntimePointerSize);
632   ASSERT_TRUE(method_to_deoptimize != nullptr);
633   ASSERT_TRUE(method_to_deoptimize->IsDirect());
634   ASSERT_TRUE(method_to_deoptimize->GetDeclaringClass() == klass);
635 
636   EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
637   EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
638 
639   DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);
640 
641   EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
642   EXPECT_TRUE(instr->AreExitStubsInstalled());
643   EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
644 
645   constexpr const char* instrumentation_key = "DeoptimizeDirectMethod";
646   UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
647 
648   EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
649   EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
650 }
651 
TEST_F(InstrumentationTest,FullDeoptimization)652 TEST_F(InstrumentationTest, FullDeoptimization) {
653   ScopedObjectAccess soa(Thread::Current());
654   Runtime* const runtime = Runtime::Current();
655   instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
656   EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
657 
658   constexpr const char* instrumentation_key = "FullDeoptimization";
659   DeoptimizeEverything(soa.Self(), instrumentation_key, true);
660 
661   EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
662   EXPECT_TRUE(instr->AreExitStubsInstalled());
663 
664   UndeoptimizeEverything(soa.Self(), instrumentation_key, true);
665 
666   EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
667 }
668 
TEST_F(InstrumentationTest,MixedDeoptimization)669 TEST_F(InstrumentationTest, MixedDeoptimization) {
670   ScopedObjectAccess soa(Thread::Current());
671   jobject class_loader = LoadDex("Instrumentation");
672   Runtime* const runtime = Runtime::Current();
673   instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
674   ClassLinker* class_linker = runtime->GetClassLinker();
675   StackHandleScope<1> hs(soa.Self());
676   Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
677   ObjPtr<mirror::Class> klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
678   ASSERT_TRUE(klass != nullptr);
679   ArtMethod* method_to_deoptimize =
680       klass->FindClassMethod("instanceMethod", "()V", kRuntimePointerSize);
681   ASSERT_TRUE(method_to_deoptimize != nullptr);
682   ASSERT_TRUE(method_to_deoptimize->IsDirect());
683   ASSERT_TRUE(method_to_deoptimize->GetDeclaringClass() == klass);
684 
685   EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
686   EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
687 
688   DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);
689   // Deoptimizing a method does not change instrumentation level.
690   EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
691             GetCurrentInstrumentationLevel());
692   EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
693   EXPECT_TRUE(instr->AreExitStubsInstalled());
694   EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
695 
696   constexpr const char* instrumentation_key = "MixedDeoptimization";
697   DeoptimizeEverything(soa.Self(), instrumentation_key, false);
698   EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
699             GetCurrentInstrumentationLevel());
700   EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
701   EXPECT_TRUE(instr->AreExitStubsInstalled());
702   EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
703 
704   UndeoptimizeEverything(soa.Self(), instrumentation_key, false);
705   EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
706             GetCurrentInstrumentationLevel());
707   EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
708   EXPECT_TRUE(instr->AreExitStubsInstalled());
709   EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
710 
711   UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
712   EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
713             GetCurrentInstrumentationLevel());
714   EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
715   EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
716 }
717 
TEST_F(InstrumentationTest,MethodTracing_Interpreter)718 TEST_F(InstrumentationTest, MethodTracing_Interpreter) {
719   ScopedObjectAccess soa(Thread::Current());
720   Runtime* const runtime = Runtime::Current();
721   instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
722   EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
723 
724   constexpr const char* instrumentation_key = "MethodTracing";
725   EnableMethodTracing(soa.Self(), instrumentation_key, true);
726   EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
727             GetCurrentInstrumentationLevel());
728   EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
729   EXPECT_TRUE(instr->AreExitStubsInstalled());
730 
731   DisableMethodTracing(soa.Self(), instrumentation_key);
732   EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
733             GetCurrentInstrumentationLevel());
734   EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
735 }
736 
TEST_F(InstrumentationTest,MethodTracing_InstrumentationEntryExitStubs)737 TEST_F(InstrumentationTest, MethodTracing_InstrumentationEntryExitStubs) {
738   ScopedObjectAccess soa(Thread::Current());
739   Runtime* const runtime = Runtime::Current();
740   instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
741   EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
742 
743   constexpr const char* instrumentation_key = "MethodTracing";
744   EnableMethodTracing(soa.Self(), instrumentation_key, false);
745   EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
746             GetCurrentInstrumentationLevel());
747   EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
748   EXPECT_TRUE(instr->AreExitStubsInstalled());
749 
750   DisableMethodTracing(soa.Self(), instrumentation_key);
751   EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
752             GetCurrentInstrumentationLevel());
753   EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
754 }
755 
756 // We use a macro to print the line number where the test is failing.
757 #define CHECK_INSTRUMENTATION(_level, _user_count)                                      \
758   do {                                                                                  \
759     Instrumentation* const instr = Runtime::Current()->GetInstrumentation();            \
760     bool interpreter =                                                                  \
761       ((_level) == Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);  \
762     EXPECT_EQ(_level, GetCurrentInstrumentationLevel());                                \
763     EXPECT_EQ(_user_count, GetInstrumentationUserCount());                              \
764     if (instr->IsForcedInterpretOnly()) {                                               \
765       EXPECT_TRUE(instr->InterpretOnly());                                              \
766     } else if (interpreter) {                                                           \
767       EXPECT_TRUE(instr->InterpretOnly());                                              \
768     } else {                                                                            \
769       EXPECT_FALSE(instr->InterpretOnly());                                             \
770     }                                                                                   \
771     if (interpreter) {                                                                  \
772       EXPECT_TRUE(instr->AreAllMethodsDeoptimized());                                   \
773     } else {                                                                            \
774       EXPECT_FALSE(instr->AreAllMethodsDeoptimized());                                  \
775     }                                                                                   \
776   } while (false)
777 
TEST_F(InstrumentationTest,ConfigureStubs_Nothing)778 TEST_F(InstrumentationTest, ConfigureStubs_Nothing) {
779   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
780 
781   // Check no-op.
782   CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
783   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
784 }
785 
TEST_F(InstrumentationTest,ConfigureStubs_InstrumentationStubs)786 TEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubs) {
787   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
788 
789   // Check we can switch to instrumentation stubs
790   CheckConfigureStubs(kClientOneKey,
791                       Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
792   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
793                         1U);
794 
795   // Check we can disable instrumentation.
796   CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
797   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
798 }
799 
TEST_F(InstrumentationTest,ConfigureStubs_Interpreter)800 TEST_F(InstrumentationTest, ConfigureStubs_Interpreter) {
801   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
802 
803   // Check we can switch to interpreter
804   CheckConfigureStubs(kClientOneKey,
805                       Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
806   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
807 
808   // Check we can disable instrumentation.
809   CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
810   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
811 }
812 
TEST_F(InstrumentationTest,ConfigureStubs_InstrumentationStubsToInterpreter)813 TEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubsToInterpreter) {
814   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
815 
816   // Configure stubs with instrumentation stubs.
817   CheckConfigureStubs(kClientOneKey,
818                       Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
819   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
820                         1U);
821 
822   // Configure stubs with interpreter.
823   CheckConfigureStubs(kClientOneKey,
824                       Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
825   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
826 
827   // Check we can disable instrumentation.
828   CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
829   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
830 }
831 
TEST_F(InstrumentationTest,ConfigureStubs_InterpreterToInstrumentationStubs)832 TEST_F(InstrumentationTest, ConfigureStubs_InterpreterToInstrumentationStubs) {
833   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
834 
835   // Configure stubs with interpreter.
836   CheckConfigureStubs(kClientOneKey,
837                       Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
838   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
839 
840   // Configure stubs with instrumentation stubs.
841   CheckConfigureStubs(kClientOneKey,
842                       Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
843   // Make sure we are still interpreter since going from interpreter->instrumentation is dangerous.
844   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
845                         1U);
846 
847   // Check we can disable instrumentation.
848   CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
849   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
850 }
851 
TEST_F(InstrumentationTest,ConfigureStubs_InstrumentationStubsToInterpreterToInstrumentationStubs)852 TEST_F(InstrumentationTest,
853        ConfigureStubs_InstrumentationStubsToInterpreterToInstrumentationStubs) {
854   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
855 
856   // Configure stubs with instrumentation stubs.
857   CheckConfigureStubs(kClientOneKey,
858                       Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
859   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
860                         1U);
861 
862   // Configure stubs with interpreter.
863   CheckConfigureStubs(kClientOneKey,
864                       Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
865   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
866 
867   // Configure stubs with instrumentation stubs again.
868   CheckConfigureStubs(kClientOneKey,
869                       Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
870   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
871                         1U);
872 
873   // Check we can disable instrumentation.
874   CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
875   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
876 }
877 
TEST_F(InstrumentationTest,MultiConfigureStubs_Nothing)878 TEST_F(InstrumentationTest, MultiConfigureStubs_Nothing) {
879   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
880 
881   // Check kInstrumentNothing with two clients.
882   CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
883   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
884 
885   CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
886   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
887 }
888 
TEST_F(InstrumentationTest,MultiConfigureStubs_InstrumentationStubs)889 TEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubs) {
890   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
891 
892   // Configure stubs with instrumentation stubs for 1st client.
893   CheckConfigureStubs(kClientOneKey,
894                       Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
895   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
896                         1U);
897 
898   // Configure stubs with instrumentation stubs for 2nd client.
899   CheckConfigureStubs(kClientTwoKey,
900                       Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
901   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
902                         2U);
903 
904   // 1st client requests instrumentation deactivation but 2nd client still needs
905   // instrumentation stubs.
906   CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
907   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
908                         1U);
909 
910   // 2nd client requests instrumentation deactivation
911   CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
912   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
913 }
914 
TEST_F(InstrumentationTest,MultiConfigureStubs_Interpreter)915 TEST_F(InstrumentationTest, MultiConfigureStubs_Interpreter) {
916   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
917 
918   // Configure stubs with interpreter for 1st client.
919   CheckConfigureStubs(kClientOneKey,
920                       Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
921   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
922 
923   // Configure stubs with interpreter for 2nd client.
924   CheckConfigureStubs(kClientTwoKey,
925                       Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
926   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
927 
928   // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
929   CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
930   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
931 
932   // 2nd client requests instrumentation deactivation
933   CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
934   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
935 }
936 
TEST_F(InstrumentationTest,MultiConfigureStubs_InstrumentationStubsThenInterpreter)937 TEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubsThenInterpreter) {
938   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
939 
940   // Configure stubs with instrumentation stubs for 1st client.
941   CheckConfigureStubs(kClientOneKey,
942                       Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
943   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
944                         1U);
945 
946   // Configure stubs with interpreter for 2nd client.
947   CheckConfigureStubs(kClientTwoKey,
948                       Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
949   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
950 
951   // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
952   CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
953   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
954 
955   // 2nd client requests instrumentation deactivation
956   CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
957   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
958 }
959 
TEST_F(InstrumentationTest,MultiConfigureStubs_InterpreterThenInstrumentationStubs)960 TEST_F(InstrumentationTest, MultiConfigureStubs_InterpreterThenInstrumentationStubs) {
961   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
962 
963   // Configure stubs with interpreter for 1st client.
964   CheckConfigureStubs(kClientOneKey,
965                       Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
966   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
967 
968   // Configure stubs with instrumentation stubs for 2nd client.
969   CheckConfigureStubs(kClientTwoKey,
970                       Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
971   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
972 
973   // 1st client requests instrumentation deactivation but 2nd client still needs
974   // instrumentation stubs. Since we already got interpreter stubs we need to stay there.
975   CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
976   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
977                         1U);
978 
979   // 2nd client requests instrumentation deactivation
980   CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
981   CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
982 }
983 
984 }  // namespace instrumentation
985 }  // namespace art
986