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