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