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