15eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz/* 25eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz * Copyright (C) 2015 The Android Open Source Project 35eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz * 45eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz * Licensed under the Apache License, Version 2.0 (the "License"); 55eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz * you may not use this file except in compliance with the License. 65eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz * You may obtain a copy of the License at 75eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz * 85eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz * http://www.apache.org/licenses/LICENSE-2.0 95eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz * 105eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz * Unless required by applicable law or agreed to in writing, software 115eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz * distributed under the License is distributed on an "AS IS" BASIS, 125eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz * See the License for the specific language governing permissions and 145eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz * limitations under the License. 155eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz */ 165eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 175eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz#include "instrumentation.h" 185eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 195eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz#include "common_runtime_test.h" 205eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz#include "common_throws.h" 215eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz#include "class_linker-inl.h" 225eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz#include "dex_file.h" 235eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz#include "handle_scope-inl.h" 245eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz#include "jvalue.h" 255eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz#include "runtime.h" 265eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz#include "scoped_thread_state_change.h" 275eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz#include "thread_list.h" 285eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz#include "thread-inl.h" 295eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 305eae455507399286c845ba54796c47087a72b3e2Sebastien Hertznamespace art { 315eae455507399286c845ba54796c47087a72b3e2Sebastien Hertznamespace instrumentation { 325eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 335eae455507399286c845ba54796c47087a72b3e2Sebastien Hertzclass TestInstrumentationListener FINAL : public instrumentation::InstrumentationListener { 345eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz public: 355eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz TestInstrumentationListener() 365eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz : received_method_enter_event(false), received_method_exit_event(false), 375eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz received_method_unwind_event(false), received_dex_pc_moved_event(false), 385eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz received_field_read_event(false), received_field_written_event(false), 395eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz received_exception_caught_event(false), received_backward_branch_event(false) {} 405eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 415eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz virtual ~TestInstrumentationListener() {} 425eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 435eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz void MethodEntered(Thread* thread ATTRIBUTE_UNUSED, 445eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz mirror::Object* this_object ATTRIBUTE_UNUSED, 453d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* method ATTRIBUTE_UNUSED, 465eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz uint32_t dex_pc ATTRIBUTE_UNUSED) 475eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 485eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz received_method_enter_event = true; 495eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 505eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 515eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz void MethodExited(Thread* thread ATTRIBUTE_UNUSED, 525eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz mirror::Object* this_object ATTRIBUTE_UNUSED, 533d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* method ATTRIBUTE_UNUSED, 545eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz uint32_t dex_pc ATTRIBUTE_UNUSED, 555eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz const JValue& return_value ATTRIBUTE_UNUSED) 565eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 575eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz received_method_exit_event = true; 585eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 595eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 605eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz void MethodUnwind(Thread* thread ATTRIBUTE_UNUSED, 615eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz mirror::Object* this_object ATTRIBUTE_UNUSED, 623d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* method ATTRIBUTE_UNUSED, 635eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz uint32_t dex_pc ATTRIBUTE_UNUSED) 645eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 655eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz received_method_unwind_event = true; 665eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 675eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 685eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz void DexPcMoved(Thread* thread ATTRIBUTE_UNUSED, 695eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz mirror::Object* this_object ATTRIBUTE_UNUSED, 703d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* method ATTRIBUTE_UNUSED, 715eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz uint32_t new_dex_pc ATTRIBUTE_UNUSED) 725eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 735eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz received_dex_pc_moved_event = true; 745eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 755eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 765eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz void FieldRead(Thread* thread ATTRIBUTE_UNUSED, 775eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz mirror::Object* this_object ATTRIBUTE_UNUSED, 783d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* method ATTRIBUTE_UNUSED, 795eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz uint32_t dex_pc ATTRIBUTE_UNUSED, 805eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz ArtField* field ATTRIBUTE_UNUSED) 815eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 825eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz received_field_read_event = true; 835eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 845eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 855eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz void FieldWritten(Thread* thread ATTRIBUTE_UNUSED, 865eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz mirror::Object* this_object ATTRIBUTE_UNUSED, 873d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* method ATTRIBUTE_UNUSED, 885eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz uint32_t dex_pc ATTRIBUTE_UNUSED, 895eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz ArtField* field ATTRIBUTE_UNUSED, 905eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz const JValue& field_value ATTRIBUTE_UNUSED) 915eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 925eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz received_field_written_event = true; 935eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 945eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 955eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz void ExceptionCaught(Thread* thread ATTRIBUTE_UNUSED, 965eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz mirror::Throwable* exception_object ATTRIBUTE_UNUSED) 975eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 985eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz received_exception_caught_event = true; 995eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 1005eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1015eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz void BackwardBranch(Thread* thread ATTRIBUTE_UNUSED, 1023d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* method ATTRIBUTE_UNUSED, 1035eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz int32_t dex_pc_offset ATTRIBUTE_UNUSED) 1045eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 1055eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz received_backward_branch_event = true; 1065eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 1075eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1085eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz void Reset() { 1095eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz received_method_enter_event = false; 1105eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz received_method_exit_event = false; 1115eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz received_method_unwind_event = false; 1125eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz received_dex_pc_moved_event = false; 1135eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz received_field_read_event = false; 1145eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz received_field_written_event = false; 1155eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz received_exception_caught_event = false; 1165eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz received_backward_branch_event = false; 1175eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 1185eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1195eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz bool received_method_enter_event; 1205eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz bool received_method_exit_event; 1215eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz bool received_method_unwind_event; 1225eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz bool received_dex_pc_moved_event; 1235eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz bool received_field_read_event; 1245eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz bool received_field_written_event; 1255eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz bool received_exception_caught_event; 1265eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz bool received_backward_branch_event; 1275eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1285eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz private: 1295eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz DISALLOW_COPY_AND_ASSIGN(TestInstrumentationListener); 1305eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz}; 1315eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1325eae455507399286c845ba54796c47087a72b3e2Sebastien Hertzclass InstrumentationTest : public CommonRuntimeTest { 1335eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz public: 1345eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Unique keys used to test Instrumentation::ConfigureStubs. 1355eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz static constexpr const char* kClientOneKey = "TestClient1"; 1365eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz static constexpr const char* kClientTwoKey = "TestClient2"; 1375eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1385eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz void CheckConfigureStubs(const char* key, Instrumentation::InstrumentationLevel level) { 1395eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz ScopedObjectAccess soa(Thread::Current()); 1405eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation(); 1415eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz { 1425eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz soa.Self()->TransitionFromRunnableToSuspended(kSuspended); 1435eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Runtime* runtime = Runtime::Current(); 1445eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz runtime->GetThreadList()->SuspendAll("Instrumentation::ConfigureStubs"); 1455eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instr->ConfigureStubs(key, level); 1465eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz runtime->GetThreadList()->ResumeAll(); 1475eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz soa.Self()->TransitionFromSuspendedToRunnable(); 1485eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 1495eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 1505eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1515eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Instrumentation::InstrumentationLevel GetCurrentInstrumentationLevel() { 1525eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz return Runtime::Current()->GetInstrumentation()->GetCurrentInstrumentationLevel(); 1535eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 1545eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1555eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz size_t GetInstrumentationUserCount() { 1565eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz ScopedObjectAccess soa(Thread::Current()); 1575eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz return Runtime::Current()->GetInstrumentation()->requested_instrumentation_levels_.size(); 1585eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 1595eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1605eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz void TestEvent(uint32_t instrumentation_event) { 1615eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz ScopedObjectAccess soa(Thread::Current()); 1625eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation(); 1635eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz TestInstrumentationListener listener; 1645eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz { 1655eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz soa.Self()->TransitionFromRunnableToSuspended(kSuspended); 1665eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Runtime* runtime = Runtime::Current(); 1675eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz runtime->GetThreadList()->SuspendAll("Add instrumentation listener"); 1685eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instr->AddListener(&listener, instrumentation_event); 1695eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz runtime->GetThreadList()->ResumeAll(); 1705eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz soa.Self()->TransitionFromSuspendedToRunnable(); 1715eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 1725eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1733d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* const event_method = nullptr; 1745eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz mirror::Object* const event_obj = nullptr; 1755eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz const uint32_t event_dex_pc = 0; 1765eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1775eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Check the listener is registered and is notified of the event. 1785eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_TRUE(HasEventListener(instr, instrumentation_event)); 1795eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event)); 1805eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz ReportEvent(instr, instrumentation_event, soa.Self(), event_method, event_obj, event_dex_pc); 1815eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_TRUE(DidListenerReceiveEvent(listener, instrumentation_event)); 1825eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1835eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz listener.Reset(); 1845eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz { 1855eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz soa.Self()->TransitionFromRunnableToSuspended(kSuspended); 1865eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Runtime* runtime = Runtime::Current(); 1875eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz runtime->GetThreadList()->SuspendAll("Remove instrumentation listener"); 1885eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instr->RemoveListener(&listener, instrumentation_event); 1895eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz runtime->GetThreadList()->ResumeAll(); 1905eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz soa.Self()->TransitionFromSuspendedToRunnable(); 1915eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 1925eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1935eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Check the listener is not registered and is not notified of the event. 1945eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(HasEventListener(instr, instrumentation_event)); 1955eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event)); 1965eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz ReportEvent(instr, instrumentation_event, soa.Self(), event_method, event_obj, event_dex_pc); 1975eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event)); 1985eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 1995eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 2003d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier void DeoptimizeMethod(Thread* self, ArtMethod* method, bool enable_deoptimization) 2015eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2025eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Runtime* runtime = Runtime::Current(); 2035eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); 2045eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz self->TransitionFromRunnableToSuspended(kSuspended); 2055eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz runtime->GetThreadList()->SuspendAll("Single method deoptimization"); 2065eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz if (enable_deoptimization) { 2075eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation->EnableDeoptimization(); 2085eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 2093d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier instrumentation->Deoptimize(method); 2105eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz runtime->GetThreadList()->ResumeAll(); 2115eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz self->TransitionFromSuspendedToRunnable(); 2125eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 2135eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 2143d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier void UndeoptimizeMethod(Thread* self, ArtMethod* method, 2155eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz const char* key, bool disable_deoptimization) 2165eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2175eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Runtime* runtime = Runtime::Current(); 2185eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); 2195eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz self->TransitionFromRunnableToSuspended(kSuspended); 2205eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz runtime->GetThreadList()->SuspendAll("Single method undeoptimization"); 2213d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier instrumentation->Undeoptimize(method); 2225eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz if (disable_deoptimization) { 2235eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation->DisableDeoptimization(key); 2245eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 2255eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz runtime->GetThreadList()->ResumeAll(); 2265eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz self->TransitionFromSuspendedToRunnable(); 2275eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 2285eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 2295eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz void DeoptimizeEverything(Thread* self, const char* key, bool enable_deoptimization) 2305eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2315eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Runtime* runtime = Runtime::Current(); 2325eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); 2335eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz self->TransitionFromRunnableToSuspended(kSuspended); 2345eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz runtime->GetThreadList()->SuspendAll("Full deoptimization"); 2355eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz if (enable_deoptimization) { 2365eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation->EnableDeoptimization(); 2375eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 2385eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation->DeoptimizeEverything(key); 2395eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz runtime->GetThreadList()->ResumeAll(); 2405eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz self->TransitionFromSuspendedToRunnable(); 2415eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 2425eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 2435eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz void UndeoptimizeEverything(Thread* self, const char* key, bool disable_deoptimization) 2445eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2455eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Runtime* runtime = Runtime::Current(); 2465eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); 2475eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz self->TransitionFromRunnableToSuspended(kSuspended); 2485eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz runtime->GetThreadList()->SuspendAll("Full undeoptimization"); 2495eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation->UndeoptimizeEverything(key); 2505eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz if (disable_deoptimization) { 2515eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation->DisableDeoptimization(key); 2525eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 2535eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz runtime->GetThreadList()->ResumeAll(); 2545eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz self->TransitionFromSuspendedToRunnable(); 2555eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 2565eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 2575eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz void EnableMethodTracing(Thread* self, const char* key, bool needs_interpreter) 2585eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2595eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Runtime* runtime = Runtime::Current(); 2605eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); 2615eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz self->TransitionFromRunnableToSuspended(kSuspended); 2625eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz runtime->GetThreadList()->SuspendAll("EnableMethodTracing"); 2635eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation->EnableMethodTracing(key, needs_interpreter); 2645eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz runtime->GetThreadList()->ResumeAll(); 2655eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz self->TransitionFromSuspendedToRunnable(); 2665eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 2675eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 2685eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz void DisableMethodTracing(Thread* self, const char* key) 2695eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2705eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Runtime* runtime = Runtime::Current(); 2715eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); 2725eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz self->TransitionFromRunnableToSuspended(kSuspended); 2735eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz runtime->GetThreadList()->SuspendAll("EnableMethodTracing"); 2745eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation->DisableMethodTracing(key); 2755eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz runtime->GetThreadList()->ResumeAll(); 2765eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz self->TransitionFromSuspendedToRunnable(); 2775eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 2785eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 2795eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz private: 2805eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz static bool HasEventListener(const instrumentation::Instrumentation* instr, uint32_t event_type) 2815eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2825eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz switch (event_type) { 2835eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kMethodEntered: 2845eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz return instr->HasMethodEntryListeners(); 2855eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kMethodExited: 2865eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz return instr->HasMethodExitListeners(); 2875eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kMethodUnwind: 2885eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz return instr->HasMethodUnwindListeners(); 2895eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kDexPcMoved: 2905eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz return instr->HasDexPcListeners(); 2915eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kFieldRead: 2925eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz return instr->HasFieldReadListeners(); 2935eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kFieldWritten: 2945eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz return instr->HasFieldWriteListeners(); 2955eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kExceptionCaught: 2965eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz return instr->HasExceptionCaughtListeners(); 2975eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kBackwardBranch: 2985eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz return instr->HasBackwardBranchListeners(); 2995eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz default: 3005eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz LOG(FATAL) << "Unknown instrumentation event " << event_type; 3015eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz UNREACHABLE(); 3025eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 3035eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 3045eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 3055eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz static void ReportEvent(const instrumentation::Instrumentation* instr, uint32_t event_type, 3063d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier Thread* self, ArtMethod* method, mirror::Object* obj, 3075eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz uint32_t dex_pc) 3085eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 3095eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz switch (event_type) { 3105eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kMethodEntered: 3115eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instr->MethodEnterEvent(self, obj, method, dex_pc); 3125eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz break; 3135eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kMethodExited: { 3145eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz JValue value; 3155eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instr->MethodExitEvent(self, obj, method, dex_pc, value); 3165eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz break; 3175eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 3185eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kMethodUnwind: 3195eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instr->MethodUnwindEvent(self, obj, method, dex_pc); 3205eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz break; 3215eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kDexPcMoved: 3225eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instr->DexPcMovedEvent(self, obj, method, dex_pc); 3235eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz break; 3245eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kFieldRead: 3255eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instr->FieldReadEvent(self, obj, method, dex_pc, nullptr); 3265eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz break; 3275eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kFieldWritten: { 3285eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz JValue value; 3295eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instr->FieldWriteEvent(self, obj, method, dex_pc, nullptr, value); 3305eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz break; 3315eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 3325eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kExceptionCaught: { 3335eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz ThrowArithmeticExceptionDivideByZero(); 3345eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz mirror::Throwable* event_exception = self->GetException(); 3355eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instr->ExceptionCaughtEvent(self, event_exception); 3365eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz self->ClearException(); 3375eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz break; 3385eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 3395eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kBackwardBranch: 3405eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instr->BackwardBranch(self, method, dex_pc); 3415eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz break; 3425eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz default: 3435eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz LOG(FATAL) << "Unknown instrumentation event " << event_type; 3445eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz UNREACHABLE(); 3455eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 3465eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 3475eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 3485eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz static bool DidListenerReceiveEvent(const TestInstrumentationListener& listener, 3495eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz uint32_t event_type) { 3505eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz switch (event_type) { 3515eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kMethodEntered: 3525eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz return listener.received_method_enter_event; 3535eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kMethodExited: 3545eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz return listener.received_method_exit_event; 3555eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kMethodUnwind: 3565eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz return listener.received_method_unwind_event; 3575eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kDexPcMoved: 3585eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz return listener.received_dex_pc_moved_event; 3595eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kFieldRead: 3605eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz return listener.received_field_read_event; 3615eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kFieldWritten: 3625eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz return listener.received_field_written_event; 3635eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kExceptionCaught: 3645eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz return listener.received_exception_caught_event; 3655eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz case instrumentation::Instrumentation::kBackwardBranch: 3665eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz return listener.received_backward_branch_event; 3675eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz default: 3685eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz LOG(FATAL) << "Unknown instrumentation event " << event_type; 3695eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz UNREACHABLE(); 3705eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 3715eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } 3725eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz}; 3735eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 3745eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, NoInstrumentation) { 3755eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz ScopedObjectAccess soa(Thread::Current()); 3765eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation(); 3775eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz ASSERT_NE(instr, nullptr); 3785eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 3795eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->AreExitStubsInstalled()); 3805eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); 3815eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->IsActive()); 3825eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->ShouldNotifyMethodEnterExitEvents()); 3835eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 3845eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Test interpreter table is the default one. 3855eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_EQ(instrumentation::kMainHandlerTable, instr->GetInterpreterHandlerTable()); 3865eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 3875eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Check there is no registered listener. 3885eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->HasDexPcListeners()); 3895eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->HasExceptionCaughtListeners()); 3905eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->HasFieldReadListeners()); 3915eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->HasFieldWriteListeners()); 3925eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->HasMethodEntryListeners()); 3935eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->HasMethodExitListeners()); 3945eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->IsActive()); 3955eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 3965eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 3975eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz// Test instrumentation listeners for each event. 3985eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, MethodEntryEvent) { 3995eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz TestEvent(instrumentation::Instrumentation::kMethodEntered); 4005eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 4015eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4025eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, MethodExitEvent) { 4035eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz TestEvent(instrumentation::Instrumentation::kMethodExited); 4045eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 4055eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4065eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, MethodUnwindEvent) { 4075eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz TestEvent(instrumentation::Instrumentation::kMethodUnwind); 4085eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 4095eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4105eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, DexPcMovedEvent) { 4115eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz TestEvent(instrumentation::Instrumentation::kDexPcMoved); 4125eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 4135eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4145eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, FieldReadEvent) { 4155eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz TestEvent(instrumentation::Instrumentation::kFieldRead); 4165eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 4175eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4185eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, FieldWriteEvent) { 4195eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz TestEvent(instrumentation::Instrumentation::kFieldWritten); 4205eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 4215eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4225eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, ExceptionCaughtEvent) { 4235eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz TestEvent(instrumentation::Instrumentation::kExceptionCaught); 4245eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 4255eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4265eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, BackwardBranchEvent) { 4275eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz TestEvent(instrumentation::Instrumentation::kBackwardBranch); 4285eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 4295eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4305eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, DeoptimizeDirectMethod) { 4315eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz ScopedObjectAccess soa(Thread::Current()); 4325eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz jobject class_loader = LoadDex("Instrumentation"); 4335eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Runtime* const runtime = Runtime::Current(); 4345eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation::Instrumentation* instr = runtime->GetInstrumentation(); 4355eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz ClassLinker* class_linker = runtime->GetClassLinker(); 4363d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier StackHandleScope<1> hs(soa.Self()); 4375eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader*>(class_loader))); 4385eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader); 4395eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz ASSERT_TRUE(klass != nullptr); 4403d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* method_to_deoptimize = klass->FindDeclaredDirectMethod("instanceMethod", "()V", 4413d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier sizeof(void*)); 4423d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ASSERT_TRUE(method_to_deoptimize != nullptr); 4435eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4445eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); 4453d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize)); 4465eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4475eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz DeoptimizeMethod(soa.Self(), method_to_deoptimize, true); 4485eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4495eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); 4505eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_TRUE(instr->AreExitStubsInstalled()); 4513d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize)); 4525eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4535eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz constexpr const char* instrumentation_key = "DeoptimizeDirectMethod"; 4545eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true); 4555eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4565eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); 4573d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize)); 4585eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 4595eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4605eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, FullDeoptimization) { 4615eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz ScopedObjectAccess soa(Thread::Current()); 4625eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Runtime* const runtime = Runtime::Current(); 4635eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation::Instrumentation* instr = runtime->GetInstrumentation(); 4645eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); 4655eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4665eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz constexpr const char* instrumentation_key = "FullDeoptimization"; 4675eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz DeoptimizeEverything(soa.Self(), instrumentation_key, true); 4685eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4695eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_TRUE(instr->AreAllMethodsDeoptimized()); 4705eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_TRUE(instr->AreExitStubsInstalled()); 4715eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4725eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz UndeoptimizeEverything(soa.Self(), instrumentation_key, true); 4735eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4745eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); 4755eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 4765eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4775eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, MixedDeoptimization) { 4785eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz ScopedObjectAccess soa(Thread::Current()); 4795eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz jobject class_loader = LoadDex("Instrumentation"); 4805eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Runtime* const runtime = Runtime::Current(); 4815eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation::Instrumentation* instr = runtime->GetInstrumentation(); 4825eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz ClassLinker* class_linker = runtime->GetClassLinker(); 4833d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier StackHandleScope<1> hs(soa.Self()); 4845eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader*>(class_loader))); 4855eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader); 4865eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz ASSERT_TRUE(klass != nullptr); 4873d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod* method_to_deoptimize = klass->FindDeclaredDirectMethod("instanceMethod", "()V", 4883d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier sizeof(void*)); 4893d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ASSERT_TRUE(method_to_deoptimize != nullptr); 4905eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4915eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); 4923d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize)); 4935eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 4945eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz DeoptimizeMethod(soa.Self(), method_to_deoptimize, true); 4955eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Deoptimizing a method does not change instrumentation level. 4965eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing, 4975eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz GetCurrentInstrumentationLevel()); 4985eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); 4995eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_TRUE(instr->AreExitStubsInstalled()); 5003d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize)); 5015eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 5025eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz constexpr const char* instrumentation_key = "MixedDeoptimization"; 5035eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz DeoptimizeEverything(soa.Self(), instrumentation_key, false); 5045eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 5055eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz GetCurrentInstrumentationLevel()); 5065eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_TRUE(instr->AreAllMethodsDeoptimized()); 5075eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_TRUE(instr->AreExitStubsInstalled()); 5083d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize)); 5095eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 5105eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz UndeoptimizeEverything(soa.Self(), instrumentation_key, false); 5115eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing, 5125eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz GetCurrentInstrumentationLevel()); 5135eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); 5145eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_TRUE(instr->AreExitStubsInstalled()); 5153d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize)); 5165eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 5175eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true); 5185eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing, 5195eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz GetCurrentInstrumentationLevel()); 5205eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); 5213d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize)); 5225eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 5235eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 5245eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, MethodTracing_Interpreter) { 5255eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz ScopedObjectAccess soa(Thread::Current()); 5265eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Runtime* const runtime = Runtime::Current(); 5275eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation::Instrumentation* instr = runtime->GetInstrumentation(); 5285eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); 5295eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 5305eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz constexpr const char* instrumentation_key = "MethodTracing"; 5315eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EnableMethodTracing(soa.Self(), instrumentation_key, true); 5325eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 5335eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz GetCurrentInstrumentationLevel()); 5345eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_TRUE(instr->AreAllMethodsDeoptimized()); 5355eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_TRUE(instr->AreExitStubsInstalled()); 5365eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 5375eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz DisableMethodTracing(soa.Self(), instrumentation_key); 5385eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing, 5395eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz GetCurrentInstrumentationLevel()); 5405eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); 5415eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 5425eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 5435eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, MethodTracing_InstrumentationEntryExitStubs) { 5445eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz ScopedObjectAccess soa(Thread::Current()); 5455eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Runtime* const runtime = Runtime::Current(); 5465eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz instrumentation::Instrumentation* instr = runtime->GetInstrumentation(); 5475eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); 5485eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 5495eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz constexpr const char* instrumentation_key = "MethodTracing"; 5505eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EnableMethodTracing(soa.Self(), instrumentation_key, false); 5515eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs, 5525eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz GetCurrentInstrumentationLevel()); 5535eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); 5545eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_TRUE(instr->AreExitStubsInstalled()); 5555eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 5565eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz DisableMethodTracing(soa.Self(), instrumentation_key); 5575eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing, 5585eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz GetCurrentInstrumentationLevel()); 5595eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); 5605eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 5615eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 5625eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz// We use a macro to print the line number where the test is failing. 5635eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz#define CHECK_INSTRUMENTATION(_level, _user_count) \ 5645eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz do { \ 5655eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Instrumentation* const instr = Runtime::Current()->GetInstrumentation(); \ 5665eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz bool interpreter = \ 5675eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz (_level == Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter); \ 5685eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_EQ(_level, GetCurrentInstrumentationLevel()); \ 5695eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_EQ(_user_count, GetInstrumentationUserCount()); \ 5705eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz if (instr->IsForcedInterpretOnly()) { \ 5715eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_TRUE(instr->InterpretOnly()); \ 5725eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } else if (interpreter) { \ 5735eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_TRUE(instr->InterpretOnly()); \ 5745eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } else { \ 5755eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->InterpretOnly()); \ 5765eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } \ 5775eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz if (interpreter) { \ 5785eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_TRUE(instr->AreAllMethodsDeoptimized()); \ 5795eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } else { \ 5805eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); \ 5815eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } \ 5825eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz } while (false) 5835eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 5845eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, ConfigureStubs_Nothing) { 5855eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 5865eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 5875eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Check no-op. 5885eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing); 5895eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 5905eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 5915eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 5925eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubs) { 5935eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 5945eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 5955eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Check we can switch to instrumentation stubs 5965eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, 5975eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs); 5985eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs, 5995eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1U); 6005eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6015eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Check we can disable instrumentation. 6025eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing); 6035eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 6045eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 6055eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6065eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, ConfigureStubs_Interpreter) { 6075eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 6085eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6095eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Check we can switch to interpreter 6105eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, 6115eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter); 6125eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U); 6135eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6145eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Check we can disable instrumentation. 6155eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing); 6165eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 6175eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 6185eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6195eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubsToInterpreter) { 6205eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 6215eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6225eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Configure stubs with instrumentation stubs. 6235eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, 6245eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs); 6255eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs, 6265eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1U); 6275eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6285eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Configure stubs with interpreter. 6295eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, 6305eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter); 6315eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U); 6325eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6335eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Check we can disable instrumentation. 6345eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing); 6355eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 6365eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 6375eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6385eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, ConfigureStubs_InterpreterToInstrumentationStubs) { 6395eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 6405eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6415eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Configure stubs with interpreter. 6425eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, 6435eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter); 6445eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U); 6455eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6465eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Configure stubs with instrumentation stubs. 6475eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, 6485eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs); 6495eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs, 6505eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1U); 6515eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6525eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Check we can disable instrumentation. 6535eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing); 6545eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 6555eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 6565eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6575eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, 6585eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz ConfigureStubs_InstrumentationStubsToInterpreterToInstrumentationStubs) { 6595eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 6605eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6615eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Configure stubs with instrumentation stubs. 6625eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, 6635eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs); 6645eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs, 6655eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1U); 6665eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6675eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Configure stubs with interpreter. 6685eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, 6695eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter); 6705eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U); 6715eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6725eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Configure stubs with instrumentation stubs again. 6735eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, 6745eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs); 6755eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs, 6765eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1U); 6775eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6785eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Check we can disable instrumentation. 6795eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing); 6805eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 6815eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 6825eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6835eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, MultiConfigureStubs_Nothing) { 6845eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 6855eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6865eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Check kInstrumentNothing with two clients. 6875eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing); 6885eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 6895eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6905eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing); 6915eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 6925eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 6935eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6945eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubs) { 6955eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 6965eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 6975eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Configure stubs with instrumentation stubs for 1st client. 6985eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, 6995eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs); 7005eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs, 7015eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1U); 7025eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 7035eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Configure stubs with instrumentation stubs for 2nd client. 7045eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientTwoKey, 7055eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs); 7065eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs, 7075eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 2U); 7085eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 7095eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // 1st client requests instrumentation deactivation but 2nd client still needs 7105eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // instrumentation stubs. 7115eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing); 7125eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs, 7135eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1U); 7145eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 7155eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // 2nd client requests instrumentation deactivation 7165eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing); 7175eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 7185eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 7195eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 7205eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, MultiConfigureStubs_Interpreter) { 7215eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 7225eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 7235eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Configure stubs with interpreter for 1st client. 7245eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, 7255eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter); 7265eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U); 7275eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 7285eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Configure stubs with interpreter for 2nd client. 7295eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientTwoKey, 7305eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter); 7315eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U); 7325eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 7335eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // 1st client requests instrumentation deactivation but 2nd client still needs interpreter. 7345eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing); 7355eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U); 7365eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 7375eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // 2nd client requests instrumentation deactivation 7385eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing); 7395eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 7405eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 7415eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 7425eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubsThenInterpreter) { 7435eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 7445eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 7455eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Configure stubs with instrumentation stubs for 1st client. 7465eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, 7475eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs); 7485eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs, 7495eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1U); 7505eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 7515eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Configure stubs with interpreter for 2nd client. 7525eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientTwoKey, 7535eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter); 7545eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U); 7555eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 7565eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // 1st client requests instrumentation deactivation but 2nd client still needs interpreter. 7575eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing); 7585eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U); 7595eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 7605eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // 2nd client requests instrumentation deactivation 7615eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing); 7625eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 7635eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 7645eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 7655eae455507399286c845ba54796c47087a72b3e2Sebastien HertzTEST_F(InstrumentationTest, MultiConfigureStubs_InterpreterThenInstrumentationStubs) { 7665eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 7675eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 7685eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Configure stubs with interpreter for 1st client. 7695eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, 7705eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter); 7715eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U); 7725eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 7735eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // Configure stubs with instrumentation stubs for 2nd client. 7745eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientTwoKey, 7755eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs); 7765eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U); 7775eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 7785eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // 1st client requests instrumentation deactivation but 2nd client still needs 7795eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // instrumentation stubs. 7805eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing); 7815eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs, 7825eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 1U); 7835eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 7845eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz // 2nd client requests instrumentation deactivation 7855eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing); 7865eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U); 7875eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} 7885eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz 7895eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} // namespace instrumentation 7905eae455507399286c845ba54796c47087a72b3e2Sebastien Hertz} // namespace art 791