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