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