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