Home | History | Annotate | Download | only in runtime
      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:
     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 
     55   virtual ~TestInstrumentationListener() {}
     56 
     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 
     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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    202   Instrumentation::InstrumentationLevel GetCurrentInstrumentationLevel() {
    203     return Runtime::Current()->GetInstrumentation()->GetCurrentInstrumentationLevel();
    204   }
    205 
    206   size_t GetInstrumentationUserCount() {
    207     ScopedObjectAccess soa(Thread::Current());
    208     return Runtime::Current()->GetInstrumentation()->requested_instrumentation_levels_.size();
    209   }
    210 
    211   void TestEvent(uint32_t instrumentation_event) {
    212     TestEvent(instrumentation_event, nullptr, nullptr, false);
    213   }
    214 
    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 
    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 
    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 
    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 
    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 
    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 
    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:
    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 
    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 
    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 
    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.
    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 
    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 
    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 
    556 TEST_F(InstrumentationTest, MethodUnwindEvent) {
    557   TestEvent(instrumentation::Instrumentation::kMethodUnwind);
    558 }
    559 
    560 TEST_F(InstrumentationTest, DexPcMovedEvent) {
    561   TestEvent(instrumentation::Instrumentation::kDexPcMoved);
    562 }
    563 
    564 TEST_F(InstrumentationTest, FieldReadEvent) {
    565   TestEvent(instrumentation::Instrumentation::kFieldRead);
    566 }
    567 
    568 TEST_F(InstrumentationTest, WatchedFramePop) {
    569   TestEvent(instrumentation::Instrumentation::kWatchedFramePop);
    570 }
    571 
    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 
    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 
    608 TEST_F(InstrumentationTest, ExceptionHandledEvent) {
    609   TestEvent(instrumentation::Instrumentation::kExceptionHandled);
    610 }
    611 
    612 TEST_F(InstrumentationTest, ExceptionThrownEvent) {
    613   TestEvent(instrumentation::Instrumentation::kExceptionThrown);
    614 }
    615 
    616 TEST_F(InstrumentationTest, BranchEvent) {
    617   TestEvent(instrumentation::Instrumentation::kBranch);
    618 }
    619 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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