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