10462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz/*
20462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz * Copyright (C) 2015 The Android Open Source Project
30462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz *
40462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz * Licensed under the Apache License, Version 2.0 (the "License");
50462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz * you may not use this file except in compliance with the License.
60462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz * You may obtain a copy of the License at
70462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz *
80462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz *      http://www.apache.org/licenses/LICENSE-2.0
90462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz *
100462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz * Unless required by applicable law or agreed to in writing, software
110462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz * distributed under the License is distributed on an "AS IS" BASIS,
120462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz * See the License for the specific language governing permissions and
140462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz * limitations under the License.
150462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz */
160462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
170462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz#include "instrumentation.h"
180462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
190462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz#include "common_runtime_test.h"
200462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz#include "common_throws.h"
210462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz#include "class_linker-inl.h"
220462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz#include "dex_file.h"
23aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier#include "gc/scoped_gc_critical_section.h"
240462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz#include "handle_scope-inl.h"
250462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz#include "jvalue.h"
260462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz#include "runtime.h"
270462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz#include "scoped_thread_state_change.h"
280462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz#include "thread_list.h"
290462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz#include "thread-inl.h"
300462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
310462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertznamespace art {
320462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertznamespace instrumentation {
330462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
340462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertzclass TestInstrumentationListener FINAL : public instrumentation::InstrumentationListener {
350462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz public:
360462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  TestInstrumentationListener()
370462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    : received_method_enter_event(false), received_method_exit_event(false),
380462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      received_method_unwind_event(false), received_dex_pc_moved_event(false),
390462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      received_field_read_event(false), received_field_written_event(false),
4081f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray      received_exception_caught_event(false), received_branch_event(false),
415550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray      received_invoke_virtual_or_interface_event(false) {}
420462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
430462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  virtual ~TestInstrumentationListener() {}
440462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
450462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void MethodEntered(Thread* thread ATTRIBUTE_UNUSED,
460462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                     mirror::Object* this_object ATTRIBUTE_UNUSED,
47e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                     ArtMethod* method ATTRIBUTE_UNUSED,
480462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                     uint32_t dex_pc ATTRIBUTE_UNUSED)
4990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) {
500462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    received_method_enter_event = true;
510462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
520462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
530462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void MethodExited(Thread* thread ATTRIBUTE_UNUSED,
540462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                    mirror::Object* this_object ATTRIBUTE_UNUSED,
55e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                    ArtMethod* method ATTRIBUTE_UNUSED,
560462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                    uint32_t dex_pc ATTRIBUTE_UNUSED,
570462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                    const JValue& return_value ATTRIBUTE_UNUSED)
5890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) {
590462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    received_method_exit_event = true;
600462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
610462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
620462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void MethodUnwind(Thread* thread ATTRIBUTE_UNUSED,
630462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                    mirror::Object* this_object ATTRIBUTE_UNUSED,
64e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                    ArtMethod* method ATTRIBUTE_UNUSED,
650462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                    uint32_t dex_pc ATTRIBUTE_UNUSED)
6690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) {
670462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    received_method_unwind_event = true;
680462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
690462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
700462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void DexPcMoved(Thread* thread ATTRIBUTE_UNUSED,
710462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                  mirror::Object* this_object ATTRIBUTE_UNUSED,
72e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                  ArtMethod* method ATTRIBUTE_UNUSED,
730462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                  uint32_t new_dex_pc ATTRIBUTE_UNUSED)
7490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) {
750462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    received_dex_pc_moved_event = true;
760462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
770462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
780462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void FieldRead(Thread* thread ATTRIBUTE_UNUSED,
790462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                 mirror::Object* this_object ATTRIBUTE_UNUSED,
80e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                 ArtMethod* method ATTRIBUTE_UNUSED,
810462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                 uint32_t dex_pc ATTRIBUTE_UNUSED,
820462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                 ArtField* field ATTRIBUTE_UNUSED)
8390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) {
840462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    received_field_read_event = true;
850462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
860462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
870462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void FieldWritten(Thread* thread ATTRIBUTE_UNUSED,
880462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                    mirror::Object* this_object ATTRIBUTE_UNUSED,
89e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                    ArtMethod* method ATTRIBUTE_UNUSED,
900462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                    uint32_t dex_pc ATTRIBUTE_UNUSED,
910462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                    ArtField* field ATTRIBUTE_UNUSED,
920462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                    const JValue& field_value ATTRIBUTE_UNUSED)
9390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) {
940462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    received_field_written_event = true;
950462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
960462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
970462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void ExceptionCaught(Thread* thread ATTRIBUTE_UNUSED,
980462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                       mirror::Throwable* exception_object ATTRIBUTE_UNUSED)
9990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) {
1000462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    received_exception_caught_event = true;
1010462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
1020462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
10381f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray  void Branch(Thread* thread ATTRIBUTE_UNUSED,
10481f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray              ArtMethod* method ATTRIBUTE_UNUSED,
10581f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray              uint32_t dex_pc ATTRIBUTE_UNUSED,
10681f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray              int32_t dex_pc_offset ATTRIBUTE_UNUSED)
10790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) {
10881f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray    received_branch_event = true;
1090462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
1100462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
1115550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  void InvokeVirtualOrInterface(Thread* thread ATTRIBUTE_UNUSED,
1125550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                mirror::Object* this_object ATTRIBUTE_UNUSED,
1135550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                ArtMethod* caller ATTRIBUTE_UNUSED,
1145550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                uint32_t dex_pc ATTRIBUTE_UNUSED,
1155550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                ArtMethod* callee ATTRIBUTE_UNUSED)
1165550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray      OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) {
1175550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray    received_invoke_virtual_or_interface_event = true;
1185550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  }
1195550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray
1200462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void Reset() {
1210462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    received_method_enter_event = false;
1220462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    received_method_exit_event = false;
1230462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    received_method_unwind_event = false;
1240462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    received_dex_pc_moved_event = false;
1250462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    received_field_read_event = false;
1260462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    received_field_written_event = false;
1270462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    received_exception_caught_event = false;
12881f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray    received_branch_event = false;
1295550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray    received_invoke_virtual_or_interface_event = false;
1300462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
1310462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
1320462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  bool received_method_enter_event;
1330462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  bool received_method_exit_event;
1340462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  bool received_method_unwind_event;
1350462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  bool received_dex_pc_moved_event;
1360462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  bool received_field_read_event;
1370462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  bool received_field_written_event;
1380462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  bool received_exception_caught_event;
13981f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray  bool received_branch_event;
1405550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  bool received_invoke_virtual_or_interface_event;
1410462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
1420462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz private:
1430462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  DISALLOW_COPY_AND_ASSIGN(TestInstrumentationListener);
1440462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz};
1450462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
1460462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertzclass InstrumentationTest : public CommonRuntimeTest {
1470462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz public:
1480462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Unique keys used to test Instrumentation::ConfigureStubs.
1490462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  static constexpr const char* kClientOneKey = "TestClient1";
1500462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  static constexpr const char* kClientTwoKey = "TestClient2";
1510462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
1520462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void CheckConfigureStubs(const char* key, Instrumentation::InstrumentationLevel level) {
1530462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    ScopedObjectAccess soa(Thread::Current());
1540462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
1554f55e22630d99ca0edd9e951e5ee96b57bb9b980Mathieu Chartier    ScopedThreadSuspension sts(soa.Self(), kSuspended);
156aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier    gc::ScopedGCCriticalSection gcs(soa.Self(),
157aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier                                    gc::kGcCauseInstrumentation,
158aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier                                    gc::kCollectorTypeInstrumentation);
1594f55e22630d99ca0edd9e951e5ee96b57bb9b980Mathieu Chartier    ScopedSuspendAll ssa("Instrumentation::ConfigureStubs");
1604f55e22630d99ca0edd9e951e5ee96b57bb9b980Mathieu Chartier    instr->ConfigureStubs(key, level);
1610462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
1620462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
1630462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  Instrumentation::InstrumentationLevel GetCurrentInstrumentationLevel() {
1640462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    return Runtime::Current()->GetInstrumentation()->GetCurrentInstrumentationLevel();
1650462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
1660462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
1670462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  size_t GetInstrumentationUserCount() {
1680462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    ScopedObjectAccess soa(Thread::Current());
1690462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    return Runtime::Current()->GetInstrumentation()->requested_instrumentation_levels_.size();
1700462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
1710462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
1720462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void TestEvent(uint32_t instrumentation_event) {
1730462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    ScopedObjectAccess soa(Thread::Current());
1740462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
1750462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    TestInstrumentationListener listener;
1760462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    {
177f1d666e1b48f8070ef1177fce156c08827f08eb8Mathieu Chartier      ScopedThreadSuspension sts(soa.Self(), kSuspended);
1784f55e22630d99ca0edd9e951e5ee96b57bb9b980Mathieu Chartier      ScopedSuspendAll ssa("Add instrumentation listener");
1790462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      instr->AddListener(&listener, instrumentation_event);
1800462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    }
1810462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
182e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier    ArtMethod* const event_method = nullptr;
1830462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    mirror::Object* const event_obj = nullptr;
1840462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    const uint32_t event_dex_pc = 0;
1850462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
1860462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    // Check the listener is registered and is notified of the event.
1870462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    EXPECT_TRUE(HasEventListener(instr, instrumentation_event));
1880462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event));
1890462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    ReportEvent(instr, instrumentation_event, soa.Self(), event_method, event_obj, event_dex_pc);
1900462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    EXPECT_TRUE(DidListenerReceiveEvent(listener, instrumentation_event));
1910462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
1920462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    listener.Reset();
1930462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    {
194f1d666e1b48f8070ef1177fce156c08827f08eb8Mathieu Chartier      ScopedThreadSuspension sts(soa.Self(), kSuspended);
1954f55e22630d99ca0edd9e951e5ee96b57bb9b980Mathieu Chartier      ScopedSuspendAll ssa("Remove instrumentation listener");
1960462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      instr->RemoveListener(&listener, instrumentation_event);
1970462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    }
1980462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
1990462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    // Check the listener is not registered and is not notified of the event.
2000462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    EXPECT_FALSE(HasEventListener(instr, instrumentation_event));
2010462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event));
2020462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    ReportEvent(instr, instrumentation_event, soa.Self(), event_method, event_obj, event_dex_pc);
2030462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event));
2040462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
2050462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
206e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  void DeoptimizeMethod(Thread* self, ArtMethod* method, bool enable_deoptimization)
20790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) {
2080462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    Runtime* runtime = Runtime::Current();
2090462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
210f1d666e1b48f8070ef1177fce156c08827f08eb8Mathieu Chartier    ScopedThreadSuspension sts(self, kSuspended);
211aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier    gc::ScopedGCCriticalSection gcs(self,
212aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier                                    gc::kGcCauseInstrumentation,
213aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier                                    gc::kCollectorTypeInstrumentation);
2144f55e22630d99ca0edd9e951e5ee96b57bb9b980Mathieu Chartier    ScopedSuspendAll ssa("Single method deoptimization");
2150462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    if (enable_deoptimization) {
2160462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      instrumentation->EnableDeoptimization();
2170462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    }
218e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier    instrumentation->Deoptimize(method);
2190462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
2200462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
221e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  void UndeoptimizeMethod(Thread* self, ArtMethod* method,
2220462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                          const char* key, bool disable_deoptimization)
22390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) {
2240462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    Runtime* runtime = Runtime::Current();
2250462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
226f1d666e1b48f8070ef1177fce156c08827f08eb8Mathieu Chartier    ScopedThreadSuspension sts(self, kSuspended);
227aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier    gc::ScopedGCCriticalSection gcs(self,
228aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier                                    gc::kGcCauseInstrumentation,
229aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier                                    gc::kCollectorTypeInstrumentation);
2304f55e22630d99ca0edd9e951e5ee96b57bb9b980Mathieu Chartier    ScopedSuspendAll ssa("Single method undeoptimization");
231e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier    instrumentation->Undeoptimize(method);
2320462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    if (disable_deoptimization) {
2330462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      instrumentation->DisableDeoptimization(key);
2340462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    }
2350462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
2360462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
2370462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void DeoptimizeEverything(Thread* self, const char* key, bool enable_deoptimization)
23890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier        SHARED_REQUIRES(Locks::mutator_lock_) {
2390462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    Runtime* runtime = Runtime::Current();
2400462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
241f1d666e1b48f8070ef1177fce156c08827f08eb8Mathieu Chartier    ScopedThreadSuspension sts(self, kSuspended);
242aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier    gc::ScopedGCCriticalSection gcs(self,
243aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier                                    gc::kGcCauseInstrumentation,
244aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier                                    gc::kCollectorTypeInstrumentation);
2454f55e22630d99ca0edd9e951e5ee96b57bb9b980Mathieu Chartier    ScopedSuspendAll ssa("Full deoptimization");
2460462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    if (enable_deoptimization) {
2470462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      instrumentation->EnableDeoptimization();
2480462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    }
2490462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    instrumentation->DeoptimizeEverything(key);
2500462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
2510462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
2520462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void UndeoptimizeEverything(Thread* self, const char* key, bool disable_deoptimization)
25390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier        SHARED_REQUIRES(Locks::mutator_lock_) {
2540462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    Runtime* runtime = Runtime::Current();
2550462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
256f1d666e1b48f8070ef1177fce156c08827f08eb8Mathieu Chartier    ScopedThreadSuspension sts(self, kSuspended);
257aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier    gc::ScopedGCCriticalSection gcs(self,
258aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier                                    gc::kGcCauseInstrumentation,
259aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier                                    gc::kCollectorTypeInstrumentation);
2604f55e22630d99ca0edd9e951e5ee96b57bb9b980Mathieu Chartier    ScopedSuspendAll ssa("Full undeoptimization");
2610462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    instrumentation->UndeoptimizeEverything(key);
2620462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    if (disable_deoptimization) {
2630462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      instrumentation->DisableDeoptimization(key);
2640462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    }
2650462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
2660462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
2670462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void EnableMethodTracing(Thread* self, const char* key, bool needs_interpreter)
26890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier        SHARED_REQUIRES(Locks::mutator_lock_) {
2690462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    Runtime* runtime = Runtime::Current();
2700462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
271f1d666e1b48f8070ef1177fce156c08827f08eb8Mathieu Chartier    ScopedThreadSuspension sts(self, kSuspended);
272aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier    gc::ScopedGCCriticalSection gcs(self,
273aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier                                    gc::kGcCauseInstrumentation,
274aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier                                    gc::kCollectorTypeInstrumentation);
2754f55e22630d99ca0edd9e951e5ee96b57bb9b980Mathieu Chartier    ScopedSuspendAll ssa("EnableMethodTracing");
2760462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    instrumentation->EnableMethodTracing(key, needs_interpreter);
2770462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
2780462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
2790462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void DisableMethodTracing(Thread* self, const char* key)
28090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier        SHARED_REQUIRES(Locks::mutator_lock_) {
2810462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    Runtime* runtime = Runtime::Current();
2820462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
283f1d666e1b48f8070ef1177fce156c08827f08eb8Mathieu Chartier    ScopedThreadSuspension sts(self, kSuspended);
284aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier    gc::ScopedGCCriticalSection gcs(self,
285aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier                                    gc::kGcCauseInstrumentation,
286aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier                                    gc::kCollectorTypeInstrumentation);
2874f55e22630d99ca0edd9e951e5ee96b57bb9b980Mathieu Chartier    ScopedSuspendAll ssa("EnableMethodTracing");
2880462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    instrumentation->DisableMethodTracing(key);
2890462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
2900462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
2910462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz private:
2920462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  static bool HasEventListener(const instrumentation::Instrumentation* instr, uint32_t event_type)
29390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) {
2940462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    switch (event_type) {
2950462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kMethodEntered:
2960462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        return instr->HasMethodEntryListeners();
2970462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kMethodExited:
2980462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        return instr->HasMethodExitListeners();
2990462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kMethodUnwind:
3000462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        return instr->HasMethodUnwindListeners();
3010462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kDexPcMoved:
3020462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        return instr->HasDexPcListeners();
3030462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kFieldRead:
3040462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        return instr->HasFieldReadListeners();
3050462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kFieldWritten:
3060462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        return instr->HasFieldWriteListeners();
3070462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kExceptionCaught:
3080462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        return instr->HasExceptionCaughtListeners();
30981f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray      case instrumentation::Instrumentation::kBranch:
31081f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray        return instr->HasBranchListeners();
3115550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray      case instrumentation::Instrumentation::kInvokeVirtualOrInterface:
3125550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray        return instr->HasInvokeVirtualOrInterfaceListeners();
3130462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      default:
3140462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        LOG(FATAL) << "Unknown instrumentation event " << event_type;
3150462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        UNREACHABLE();
3160462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    }
3170462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
3180462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
3190462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  static void ReportEvent(const instrumentation::Instrumentation* instr, uint32_t event_type,
320e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                          Thread* self, ArtMethod* method, mirror::Object* obj,
3210462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                          uint32_t dex_pc)
32290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) {
3230462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    switch (event_type) {
3240462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kMethodEntered:
3250462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        instr->MethodEnterEvent(self, obj, method, dex_pc);
3260462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        break;
3270462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kMethodExited: {
3280462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        JValue value;
3290462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        instr->MethodExitEvent(self, obj, method, dex_pc, value);
3300462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        break;
3310462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      }
3320462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kMethodUnwind:
3330462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        instr->MethodUnwindEvent(self, obj, method, dex_pc);
3340462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        break;
3350462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kDexPcMoved:
3360462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        instr->DexPcMovedEvent(self, obj, method, dex_pc);
3370462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        break;
3380462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kFieldRead:
3390462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        instr->FieldReadEvent(self, obj, method, dex_pc, nullptr);
3400462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        break;
3410462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kFieldWritten: {
3420462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        JValue value;
3430462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        instr->FieldWriteEvent(self, obj, method, dex_pc, nullptr, value);
3440462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        break;
3450462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      }
3460462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kExceptionCaught: {
3470462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        ThrowArithmeticExceptionDivideByZero();
3480462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        mirror::Throwable* event_exception = self->GetException();
3490462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        instr->ExceptionCaughtEvent(self, event_exception);
3500462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        self->ClearException();
3510462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        break;
3520462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      }
35381f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray      case instrumentation::Instrumentation::kBranch:
35481f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray        instr->Branch(self, method, dex_pc, -1);
3550462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        break;
3565550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray      case instrumentation::Instrumentation::kInvokeVirtualOrInterface:
3575550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray        instr->InvokeVirtualOrInterface(self, obj, method, dex_pc, method);
3585550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray        break;
3590462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      default:
3600462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        LOG(FATAL) << "Unknown instrumentation event " << event_type;
3610462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        UNREACHABLE();
3620462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    }
3630462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
3640462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
3650462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  static bool DidListenerReceiveEvent(const TestInstrumentationListener& listener,
3660462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                                      uint32_t event_type) {
3670462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    switch (event_type) {
3680462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kMethodEntered:
3690462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        return listener.received_method_enter_event;
3700462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kMethodExited:
3710462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        return listener.received_method_exit_event;
3720462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kMethodUnwind:
3730462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        return listener.received_method_unwind_event;
3740462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kDexPcMoved:
3750462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        return listener.received_dex_pc_moved_event;
3760462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kFieldRead:
3770462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        return listener.received_field_read_event;
3780462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kFieldWritten:
3790462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        return listener.received_field_written_event;
3800462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      case instrumentation::Instrumentation::kExceptionCaught:
3810462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        return listener.received_exception_caught_event;
38281f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray      case instrumentation::Instrumentation::kBranch:
38381f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray        return listener.received_branch_event;
3845550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray      case instrumentation::Instrumentation::kInvokeVirtualOrInterface:
3855550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray        return listener.received_invoke_virtual_or_interface_event;
3860462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      default:
3870462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        LOG(FATAL) << "Unknown instrumentation event " << event_type;
3880462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz        UNREACHABLE();
3890462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    }
3900462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
3910462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz};
3920462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
3930462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, NoInstrumentation) {
3940462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  ScopedObjectAccess soa(Thread::Current());
3950462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
3960462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  ASSERT_NE(instr, nullptr);
3970462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
3980462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->AreExitStubsInstalled());
3990462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
4000462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->IsActive());
4010462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->ShouldNotifyMethodEnterExitEvents());
4020462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
4030462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Test interpreter table is the default one.
4040462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_EQ(instrumentation::kMainHandlerTable, instr->GetInterpreterHandlerTable());
4050462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
4060462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Check there is no registered listener.
4070462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->HasDexPcListeners());
4080462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->HasExceptionCaughtListeners());
4090462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->HasFieldReadListeners());
4100462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->HasFieldWriteListeners());
4110462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->HasMethodEntryListeners());
4120462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->HasMethodExitListeners());
4130462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->IsActive());
4140462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
4150462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
4160462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz// Test instrumentation listeners for each event.
4170462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, MethodEntryEvent) {
4180462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  TestEvent(instrumentation::Instrumentation::kMethodEntered);
4190462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
4200462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
4210462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, MethodExitEvent) {
4220462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  TestEvent(instrumentation::Instrumentation::kMethodExited);
4230462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
4240462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
4250462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, MethodUnwindEvent) {
4260462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  TestEvent(instrumentation::Instrumentation::kMethodUnwind);
4270462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
4280462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
4290462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, DexPcMovedEvent) {
4300462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  TestEvent(instrumentation::Instrumentation::kDexPcMoved);
4310462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
4320462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
4330462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, FieldReadEvent) {
4340462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  TestEvent(instrumentation::Instrumentation::kFieldRead);
4350462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
4360462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
4370462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, FieldWriteEvent) {
4380462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  TestEvent(instrumentation::Instrumentation::kFieldWritten);
4390462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
4400462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
4410462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, ExceptionCaughtEvent) {
4420462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  TestEvent(instrumentation::Instrumentation::kExceptionCaught);
4430462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
4440462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
44581f0f953c4bb159997046c962d44cb1898b1778dNicolas GeoffrayTEST_F(InstrumentationTest, BranchEvent) {
44681f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray  TestEvent(instrumentation::Instrumentation::kBranch);
4470462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
4480462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
4495550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas GeoffrayTEST_F(InstrumentationTest, InvokeVirtualOrInterfaceEvent) {
4505550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  TestEvent(instrumentation::Instrumentation::kInvokeVirtualOrInterface);
4515550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray}
4525550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray
4530462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, DeoptimizeDirectMethod) {
4540462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  ScopedObjectAccess soa(Thread::Current());
4550462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  jobject class_loader = LoadDex("Instrumentation");
4560462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  Runtime* const runtime = Runtime::Current();
4570462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
4580462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  ClassLinker* class_linker = runtime->GetClassLinker();
459e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  StackHandleScope<1> hs(soa.Self());
4600462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader*>(class_loader)));
4610462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
4620462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  ASSERT_TRUE(klass != nullptr);
463e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  ArtMethod* method_to_deoptimize = klass->FindDeclaredDirectMethod("instanceMethod", "()V",
464e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                                                                    sizeof(void*));
465e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  ASSERT_TRUE(method_to_deoptimize != nullptr);
4660462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
4670462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
468e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
4690462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
4700462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);
4710462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
4720462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
4730462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_TRUE(instr->AreExitStubsInstalled());
474e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
4750462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
4760462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  constexpr const char* instrumentation_key = "DeoptimizeDirectMethod";
4770462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
4780462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
4790462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
480e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
4810462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
4820462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
4830462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, FullDeoptimization) {
4840462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  ScopedObjectAccess soa(Thread::Current());
4850462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  Runtime* const runtime = Runtime::Current();
4860462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
4870462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
4880462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
4890462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  constexpr const char* instrumentation_key = "FullDeoptimization";
4900462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  DeoptimizeEverything(soa.Self(), instrumentation_key, true);
4910462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
4920462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
4930462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_TRUE(instr->AreExitStubsInstalled());
4940462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
4950462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  UndeoptimizeEverything(soa.Self(), instrumentation_key, true);
4960462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
4970462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
4980462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
4990462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
5000462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, MixedDeoptimization) {
5010462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  ScopedObjectAccess soa(Thread::Current());
5020462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  jobject class_loader = LoadDex("Instrumentation");
5030462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  Runtime* const runtime = Runtime::Current();
5040462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
5050462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  ClassLinker* class_linker = runtime->GetClassLinker();
506e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  StackHandleScope<1> hs(soa.Self());
5070462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader*>(class_loader)));
5080462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
5090462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  ASSERT_TRUE(klass != nullptr);
510e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  ArtMethod* method_to_deoptimize = klass->FindDeclaredDirectMethod("instanceMethod", "()V",
511e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                                                                    sizeof(void*));
512e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  ASSERT_TRUE(method_to_deoptimize != nullptr);
5130462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
5140462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
515e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
5160462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
5170462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);
5180462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Deoptimizing a method does not change instrumentation level.
5190462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
5200462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz            GetCurrentInstrumentationLevel());
5210462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
5220462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_TRUE(instr->AreExitStubsInstalled());
523e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
5240462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
5250462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  constexpr const char* instrumentation_key = "MixedDeoptimization";
5260462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  DeoptimizeEverything(soa.Self(), instrumentation_key, false);
5270462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
5280462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz            GetCurrentInstrumentationLevel());
5290462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
5300462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_TRUE(instr->AreExitStubsInstalled());
531e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
5320462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
5330462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  UndeoptimizeEverything(soa.Self(), instrumentation_key, false);
5340462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
5350462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz            GetCurrentInstrumentationLevel());
5360462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
5370462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_TRUE(instr->AreExitStubsInstalled());
538e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
5390462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
5400462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
5410462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
5420462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz            GetCurrentInstrumentationLevel());
5430462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
544e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
5450462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
5460462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
5470462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, MethodTracing_Interpreter) {
5480462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  ScopedObjectAccess soa(Thread::Current());
5490462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  Runtime* const runtime = Runtime::Current();
5500462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
5510462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
5520462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
5530462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  constexpr const char* instrumentation_key = "MethodTracing";
5540462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EnableMethodTracing(soa.Self(), instrumentation_key, true);
5550462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
5560462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz            GetCurrentInstrumentationLevel());
5570462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
5580462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_TRUE(instr->AreExitStubsInstalled());
5590462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
5600462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  DisableMethodTracing(soa.Self(), instrumentation_key);
5610462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
5620462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz            GetCurrentInstrumentationLevel());
5630462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
5640462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
5650462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
5660462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, MethodTracing_InstrumentationEntryExitStubs) {
5670462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  ScopedObjectAccess soa(Thread::Current());
5680462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  Runtime* const runtime = Runtime::Current();
5690462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
5700462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
5710462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
5720462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  constexpr const char* instrumentation_key = "MethodTracing";
5730462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EnableMethodTracing(soa.Self(), instrumentation_key, false);
5740462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
5750462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz            GetCurrentInstrumentationLevel());
5760462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
5770462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_TRUE(instr->AreExitStubsInstalled());
5780462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
5790462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  DisableMethodTracing(soa.Self(), instrumentation_key);
5800462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
5810462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz            GetCurrentInstrumentationLevel());
5820462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
5830462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
5840462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
5850462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz// We use a macro to print the line number where the test is failing.
5860462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz#define CHECK_INSTRUMENTATION(_level, _user_count)                                      \
5870462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  do {                                                                                  \
5880462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    Instrumentation* const instr = Runtime::Current()->GetInstrumentation();            \
5890462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    bool interpreter =                                                                  \
5900462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      (_level == Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);    \
5910462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    EXPECT_EQ(_level, GetCurrentInstrumentationLevel());                                \
5920462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    EXPECT_EQ(_user_count, GetInstrumentationUserCount());                              \
5930462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    if (instr->IsForcedInterpretOnly()) {                                               \
5940462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      EXPECT_TRUE(instr->InterpretOnly());                                              \
5950462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    } else if (interpreter) {                                                           \
5960462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      EXPECT_TRUE(instr->InterpretOnly());                                              \
5970462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    } else {                                                                            \
5980462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      EXPECT_FALSE(instr->InterpretOnly());                                             \
5990462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    }                                                                                   \
6000462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    if (interpreter) {                                                                  \
6010462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      EXPECT_TRUE(instr->AreAllMethodsDeoptimized());                                   \
6020462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    } else {                                                                            \
6030462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz      EXPECT_FALSE(instr->AreAllMethodsDeoptimized());                                  \
6040462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    }                                                                                   \
6050462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  } while (false)
6060462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
6070462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, ConfigureStubs_Nothing) {
6080462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
6090462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
6100462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Check no-op.
6110462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
6120462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
6130462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
6140462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
6150462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubs) {
6160462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
6170462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
6180462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Check we can switch to instrumentation stubs
6190462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey,
6200462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                      Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
6210462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
6220462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                        1U);
6230462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
6240462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Check we can disable instrumentation.
6250462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
6260462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
6270462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
6280462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
6290462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, ConfigureStubs_Interpreter) {
6300462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
6310462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
6320462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Check we can switch to interpreter
6330462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey,
6340462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                      Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
6350462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
6360462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
6370462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Check we can disable instrumentation.
6380462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
6390462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
6400462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
6410462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
6420462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubsToInterpreter) {
6430462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
6440462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
6450462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Configure stubs with instrumentation stubs.
6460462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey,
6470462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                      Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
6480462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
6490462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                        1U);
6500462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
6510462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Configure stubs with interpreter.
6520462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey,
6530462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                      Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
6540462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
6550462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
6560462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Check we can disable instrumentation.
6570462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
6580462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
6590462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
6600462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
6610462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, ConfigureStubs_InterpreterToInstrumentationStubs) {
6620462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
6630462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
6640462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Configure stubs with interpreter.
6650462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey,
6660462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                      Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
6670462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
6680462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
6690462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Configure stubs with instrumentation stubs.
6700462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey,
6710462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                      Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
6720462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
6730462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                        1U);
6740462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
6750462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Check we can disable instrumentation.
6760462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
6770462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
6780462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
6790462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
6800462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest,
6810462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz       ConfigureStubs_InstrumentationStubsToInterpreterToInstrumentationStubs) {
6820462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
6830462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
6840462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Configure stubs with instrumentation stubs.
6850462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey,
6860462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                      Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
6870462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
6880462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                        1U);
6890462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
6900462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Configure stubs with interpreter.
6910462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey,
6920462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                      Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
6930462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
6940462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
6950462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Configure stubs with instrumentation stubs again.
6960462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey,
6970462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                      Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
6980462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
6990462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                        1U);
7000462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7010462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Check we can disable instrumentation.
7020462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
7030462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
7040462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
7050462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7060462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, MultiConfigureStubs_Nothing) {
7070462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
7080462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7090462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Check kInstrumentNothing with two clients.
7100462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
7110462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
7120462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7130462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
7140462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
7150462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
7160462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7170462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubs) {
7180462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
7190462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7200462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Configure stubs with instrumentation stubs for 1st client.
7210462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey,
7220462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                      Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
7230462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
7240462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                        1U);
7250462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7260462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Configure stubs with instrumentation stubs for 2nd client.
7270462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientTwoKey,
7280462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                      Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
7290462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
7300462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                        2U);
7310462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7320462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // 1st client requests instrumentation deactivation but 2nd client still needs
7330462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // instrumentation stubs.
7340462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
7350462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
7360462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                        1U);
7370462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7380462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // 2nd client requests instrumentation deactivation
7390462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
7400462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
7410462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
7420462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7430462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, MultiConfigureStubs_Interpreter) {
7440462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
7450462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7460462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Configure stubs with interpreter for 1st client.
7470462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey,
7480462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                      Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
7490462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
7500462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7510462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Configure stubs with interpreter for 2nd client.
7520462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientTwoKey,
7530462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                      Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
7540462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
7550462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7560462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
7570462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
7580462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
7590462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7600462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // 2nd client requests instrumentation deactivation
7610462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
7620462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
7630462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
7640462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7650462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubsThenInterpreter) {
7660462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
7670462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7680462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Configure stubs with instrumentation stubs for 1st client.
7690462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey,
7700462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                      Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
7710462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
7720462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                        1U);
7730462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7740462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Configure stubs with interpreter for 2nd client.
7750462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientTwoKey,
7760462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                      Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
7770462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
7780462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7790462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
7800462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
7810462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
7820462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7830462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // 2nd client requests instrumentation deactivation
7840462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
7850462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
7860462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
7870462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7880462c4c87c39db6cfcd338f323844738109ac3c9Sebastien HertzTEST_F(InstrumentationTest, MultiConfigureStubs_InterpreterThenInstrumentationStubs) {
7890462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
7900462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7910462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Configure stubs with interpreter for 1st client.
7920462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey,
7930462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                      Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
7940462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
7950462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
7960462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Configure stubs with instrumentation stubs for 2nd client.
7970462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientTwoKey,
7980462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                      Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
7990462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
8000462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
8010462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // 1st client requests instrumentation deactivation but 2nd client still needs
8020462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // instrumentation stubs.
8030462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
8040462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
8050462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                        1U);
8060462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
8070462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // 2nd client requests instrumentation deactivation
8080462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
8090462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
8100462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}
8110462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
8120462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}  // namespace instrumentation
8130462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz}  // namespace art
814