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