blob: 9e9fa71e60ebe1ca299a09aa2de346f103f994b1 [file] [log] [blame]
Sebastien Hertz0462c4c2015-04-01 16:34:17 +02001/*
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
Vladimir Markoba118822017-06-12 15:41:56 +010019#include "art_method-inl.h"
Andreas Gampe542451c2016-07-26 09:02:02 -070020#include "base/enums.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020021#include "common_runtime_test.h"
22#include "common_throws.h"
23#include "class_linker-inl.h"
24#include "dex_file.h"
Mathieu Chartieraa516822015-10-02 15:53:37 -070025#include "gc/scoped_gc_critical_section.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020026#include "handle_scope-inl.h"
Alex Lightd7661582017-05-01 13:48:16 -070027#include "jni_internal.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020028#include "jvalue.h"
29#include "runtime.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070030#include "scoped_thread_state_change-inl.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020031#include "thread_list.h"
Alex Lightd7661582017-05-01 13:48:16 -070032#include "thread-inl.h"
33#include "well_known_classes.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020034
35namespace art {
36namespace instrumentation {
37
38class TestInstrumentationListener FINAL : public instrumentation::InstrumentationListener {
39 public:
40 TestInstrumentationListener()
Alex Lightd7661582017-05-01 13:48:16 -070041 : received_method_enter_event(false),
42 received_method_exit_event(false),
43 received_method_exit_object_event(false),
44 received_method_unwind_event(false),
45 received_dex_pc_moved_event(false),
46 received_field_read_event(false),
47 received_field_written_event(false),
48 received_field_written_object_event(false),
49 received_exception_caught_event(false),
50 received_branch_event(false),
Nicolas Geoffray5550ca82015-08-21 18:38:30 +010051 received_invoke_virtual_or_interface_event(false) {}
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020052
53 virtual ~TestInstrumentationListener() {}
54
55 void MethodEntered(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070056 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070057 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020058 uint32_t dex_pc ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070059 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020060 received_method_enter_event = true;
61 }
62
63 void MethodExited(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070064 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
65 ArtMethod* method ATTRIBUTE_UNUSED,
66 uint32_t dex_pc ATTRIBUTE_UNUSED,
67 Handle<mirror::Object> return_value ATTRIBUTE_UNUSED)
68 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
69 received_method_exit_object_event = true;
70 }
71
72 void MethodExited(Thread* thread ATTRIBUTE_UNUSED,
73 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070074 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020075 uint32_t dex_pc ATTRIBUTE_UNUSED,
76 const JValue& return_value ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070077 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020078 received_method_exit_event = true;
79 }
80
81 void MethodUnwind(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070082 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070083 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020084 uint32_t dex_pc ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070085 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020086 received_method_unwind_event = true;
87 }
88
89 void DexPcMoved(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070090 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070091 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020092 uint32_t new_dex_pc ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070093 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020094 received_dex_pc_moved_event = true;
95 }
96
97 void FieldRead(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070098 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070099 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200100 uint32_t dex_pc ATTRIBUTE_UNUSED,
101 ArtField* field ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700102 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200103 received_field_read_event = true;
104 }
105
106 void FieldWritten(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -0700107 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
108 ArtMethod* method ATTRIBUTE_UNUSED,
109 uint32_t dex_pc ATTRIBUTE_UNUSED,
110 ArtField* field ATTRIBUTE_UNUSED,
111 Handle<mirror::Object> field_value ATTRIBUTE_UNUSED)
112 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
113 received_field_written_object_event = true;
114 }
115
116 void FieldWritten(Thread* thread ATTRIBUTE_UNUSED,
117 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700118 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200119 uint32_t dex_pc ATTRIBUTE_UNUSED,
120 ArtField* field ATTRIBUTE_UNUSED,
121 const JValue& field_value ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700122 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200123 received_field_written_event = true;
124 }
125
126 void ExceptionCaught(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -0700127 Handle<mirror::Throwable> exception_object ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700128 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200129 received_exception_caught_event = true;
130 }
131
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000132 void Branch(Thread* thread ATTRIBUTE_UNUSED,
133 ArtMethod* method ATTRIBUTE_UNUSED,
134 uint32_t dex_pc ATTRIBUTE_UNUSED,
135 int32_t dex_pc_offset ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700136 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000137 received_branch_event = true;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200138 }
139
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100140 void InvokeVirtualOrInterface(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -0700141 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100142 ArtMethod* caller ATTRIBUTE_UNUSED,
143 uint32_t dex_pc ATTRIBUTE_UNUSED,
144 ArtMethod* callee ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700145 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100146 received_invoke_virtual_or_interface_event = true;
147 }
148
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200149 void Reset() {
150 received_method_enter_event = false;
151 received_method_exit_event = false;
Alex Lightd7661582017-05-01 13:48:16 -0700152 received_method_exit_object_event = false;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200153 received_method_unwind_event = false;
154 received_dex_pc_moved_event = false;
155 received_field_read_event = false;
156 received_field_written_event = false;
Alex Lightd7661582017-05-01 13:48:16 -0700157 received_field_written_object_event = false;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200158 received_exception_caught_event = false;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000159 received_branch_event = false;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100160 received_invoke_virtual_or_interface_event = false;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200161 }
162
163 bool received_method_enter_event;
164 bool received_method_exit_event;
Alex Lightd7661582017-05-01 13:48:16 -0700165 bool received_method_exit_object_event;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200166 bool received_method_unwind_event;
167 bool received_dex_pc_moved_event;
168 bool received_field_read_event;
169 bool received_field_written_event;
Alex Lightd7661582017-05-01 13:48:16 -0700170 bool received_field_written_object_event;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200171 bool received_exception_caught_event;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000172 bool received_branch_event;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100173 bool received_invoke_virtual_or_interface_event;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200174
175 private:
176 DISALLOW_COPY_AND_ASSIGN(TestInstrumentationListener);
177};
178
179class InstrumentationTest : public CommonRuntimeTest {
180 public:
181 // Unique keys used to test Instrumentation::ConfigureStubs.
182 static constexpr const char* kClientOneKey = "TestClient1";
183 static constexpr const char* kClientTwoKey = "TestClient2";
184
185 void CheckConfigureStubs(const char* key, Instrumentation::InstrumentationLevel level) {
186 ScopedObjectAccess soa(Thread::Current());
187 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700188 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700189 gc::ScopedGCCriticalSection gcs(soa.Self(),
190 gc::kGcCauseInstrumentation,
191 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700192 ScopedSuspendAll ssa("Instrumentation::ConfigureStubs");
193 instr->ConfigureStubs(key, level);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200194 }
195
196 Instrumentation::InstrumentationLevel GetCurrentInstrumentationLevel() {
197 return Runtime::Current()->GetInstrumentation()->GetCurrentInstrumentationLevel();
198 }
199
200 size_t GetInstrumentationUserCount() {
201 ScopedObjectAccess soa(Thread::Current());
202 return Runtime::Current()->GetInstrumentation()->requested_instrumentation_levels_.size();
203 }
204
205 void TestEvent(uint32_t instrumentation_event) {
Alex Lightd7661582017-05-01 13:48:16 -0700206 TestEvent(instrumentation_event, nullptr, nullptr, false);
207 }
208
209 void TestEvent(uint32_t instrumentation_event,
210 ArtMethod* event_method,
211 ArtField* event_field,
212 bool with_object) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200213 ScopedObjectAccess soa(Thread::Current());
214 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
215 TestInstrumentationListener listener;
216 {
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700217 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700218 ScopedSuspendAll ssa("Add instrumentation listener");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200219 instr->AddListener(&listener, instrumentation_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200220 }
221
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200222 mirror::Object* const event_obj = nullptr;
223 const uint32_t event_dex_pc = 0;
224
225 // Check the listener is registered and is notified of the event.
226 EXPECT_TRUE(HasEventListener(instr, instrumentation_event));
Alex Lightd7661582017-05-01 13:48:16 -0700227 EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
228 ReportEvent(instr,
229 instrumentation_event,
230 soa.Self(),
231 event_method,
232 event_obj,
233 event_field,
234 event_dex_pc);
235 EXPECT_TRUE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200236
237 listener.Reset();
238 {
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700239 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700240 ScopedSuspendAll ssa("Remove instrumentation listener");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200241 instr->RemoveListener(&listener, instrumentation_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200242 }
243
244 // Check the listener is not registered and is not notified of the event.
245 EXPECT_FALSE(HasEventListener(instr, instrumentation_event));
Alex Lightd7661582017-05-01 13:48:16 -0700246 EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
247 ReportEvent(instr,
248 instrumentation_event,
249 soa.Self(),
250 event_method,
251 event_obj,
252 event_field,
253 event_dex_pc);
254 EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200255 }
256
Mathieu Chartiere401d142015-04-22 13:56:20 -0700257 void DeoptimizeMethod(Thread* self, ArtMethod* method, bool enable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700258 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200259 Runtime* runtime = Runtime::Current();
260 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700261 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700262 gc::ScopedGCCriticalSection gcs(self,
263 gc::kGcCauseInstrumentation,
264 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700265 ScopedSuspendAll ssa("Single method deoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200266 if (enable_deoptimization) {
267 instrumentation->EnableDeoptimization();
268 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700269 instrumentation->Deoptimize(method);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200270 }
271
Mathieu Chartiere401d142015-04-22 13:56:20 -0700272 void UndeoptimizeMethod(Thread* self, ArtMethod* method,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200273 const char* key, bool disable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700274 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200275 Runtime* runtime = Runtime::Current();
276 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700277 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700278 gc::ScopedGCCriticalSection gcs(self,
279 gc::kGcCauseInstrumentation,
280 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700281 ScopedSuspendAll ssa("Single method undeoptimization");
Mathieu Chartiere401d142015-04-22 13:56:20 -0700282 instrumentation->Undeoptimize(method);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200283 if (disable_deoptimization) {
284 instrumentation->DisableDeoptimization(key);
285 }
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200286 }
287
288 void DeoptimizeEverything(Thread* self, const char* key, bool enable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700289 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200290 Runtime* runtime = Runtime::Current();
291 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700292 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700293 gc::ScopedGCCriticalSection gcs(self,
294 gc::kGcCauseInstrumentation,
295 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700296 ScopedSuspendAll ssa("Full deoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200297 if (enable_deoptimization) {
298 instrumentation->EnableDeoptimization();
299 }
300 instrumentation->DeoptimizeEverything(key);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200301 }
302
303 void UndeoptimizeEverything(Thread* self, const char* key, bool disable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700304 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200305 Runtime* runtime = Runtime::Current();
306 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700307 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700308 gc::ScopedGCCriticalSection gcs(self,
309 gc::kGcCauseInstrumentation,
310 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700311 ScopedSuspendAll ssa("Full undeoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200312 instrumentation->UndeoptimizeEverything(key);
313 if (disable_deoptimization) {
314 instrumentation->DisableDeoptimization(key);
315 }
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200316 }
317
318 void EnableMethodTracing(Thread* self, const char* key, bool needs_interpreter)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700319 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200320 Runtime* runtime = Runtime::Current();
321 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700322 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700323 gc::ScopedGCCriticalSection gcs(self,
324 gc::kGcCauseInstrumentation,
325 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700326 ScopedSuspendAll ssa("EnableMethodTracing");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200327 instrumentation->EnableMethodTracing(key, needs_interpreter);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200328 }
329
330 void DisableMethodTracing(Thread* self, const char* key)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700331 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200332 Runtime* runtime = Runtime::Current();
333 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700334 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700335 gc::ScopedGCCriticalSection gcs(self,
336 gc::kGcCauseInstrumentation,
337 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700338 ScopedSuspendAll ssa("EnableMethodTracing");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200339 instrumentation->DisableMethodTracing(key);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200340 }
341
342 private:
343 static bool HasEventListener(const instrumentation::Instrumentation* instr, uint32_t event_type)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700344 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200345 switch (event_type) {
346 case instrumentation::Instrumentation::kMethodEntered:
347 return instr->HasMethodEntryListeners();
348 case instrumentation::Instrumentation::kMethodExited:
349 return instr->HasMethodExitListeners();
350 case instrumentation::Instrumentation::kMethodUnwind:
351 return instr->HasMethodUnwindListeners();
352 case instrumentation::Instrumentation::kDexPcMoved:
353 return instr->HasDexPcListeners();
354 case instrumentation::Instrumentation::kFieldRead:
355 return instr->HasFieldReadListeners();
356 case instrumentation::Instrumentation::kFieldWritten:
357 return instr->HasFieldWriteListeners();
358 case instrumentation::Instrumentation::kExceptionCaught:
359 return instr->HasExceptionCaughtListeners();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000360 case instrumentation::Instrumentation::kBranch:
361 return instr->HasBranchListeners();
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100362 case instrumentation::Instrumentation::kInvokeVirtualOrInterface:
363 return instr->HasInvokeVirtualOrInterfaceListeners();
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200364 default:
365 LOG(FATAL) << "Unknown instrumentation event " << event_type;
366 UNREACHABLE();
367 }
368 }
369
Alex Lightd7661582017-05-01 13:48:16 -0700370 static void ReportEvent(const instrumentation::Instrumentation* instr,
371 uint32_t event_type,
372 Thread* self,
373 ArtMethod* method,
374 mirror::Object* obj,
375 ArtField* field,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200376 uint32_t dex_pc)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700377 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200378 switch (event_type) {
379 case instrumentation::Instrumentation::kMethodEntered:
380 instr->MethodEnterEvent(self, obj, method, dex_pc);
381 break;
382 case instrumentation::Instrumentation::kMethodExited: {
383 JValue value;
384 instr->MethodExitEvent(self, obj, method, dex_pc, value);
385 break;
386 }
387 case instrumentation::Instrumentation::kMethodUnwind:
388 instr->MethodUnwindEvent(self, obj, method, dex_pc);
389 break;
390 case instrumentation::Instrumentation::kDexPcMoved:
391 instr->DexPcMovedEvent(self, obj, method, dex_pc);
392 break;
393 case instrumentation::Instrumentation::kFieldRead:
Alex Lightd7661582017-05-01 13:48:16 -0700394 instr->FieldReadEvent(self, obj, method, dex_pc, field);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200395 break;
396 case instrumentation::Instrumentation::kFieldWritten: {
397 JValue value;
Alex Lightd7661582017-05-01 13:48:16 -0700398 instr->FieldWriteEvent(self, obj, method, dex_pc, field, value);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200399 break;
400 }
401 case instrumentation::Instrumentation::kExceptionCaught: {
402 ThrowArithmeticExceptionDivideByZero();
403 mirror::Throwable* event_exception = self->GetException();
404 instr->ExceptionCaughtEvent(self, event_exception);
405 self->ClearException();
406 break;
407 }
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000408 case instrumentation::Instrumentation::kBranch:
409 instr->Branch(self, method, dex_pc, -1);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200410 break;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100411 case instrumentation::Instrumentation::kInvokeVirtualOrInterface:
412 instr->InvokeVirtualOrInterface(self, obj, method, dex_pc, method);
413 break;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200414 default:
415 LOG(FATAL) << "Unknown instrumentation event " << event_type;
416 UNREACHABLE();
417 }
418 }
419
420 static bool DidListenerReceiveEvent(const TestInstrumentationListener& listener,
Alex Lightd7661582017-05-01 13:48:16 -0700421 uint32_t event_type,
422 bool with_object) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200423 switch (event_type) {
424 case instrumentation::Instrumentation::kMethodEntered:
425 return listener.received_method_enter_event;
426 case instrumentation::Instrumentation::kMethodExited:
Alex Lightd7661582017-05-01 13:48:16 -0700427 return (!with_object && listener.received_method_exit_event) ||
428 (with_object && listener.received_method_exit_object_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200429 case instrumentation::Instrumentation::kMethodUnwind:
430 return listener.received_method_unwind_event;
431 case instrumentation::Instrumentation::kDexPcMoved:
432 return listener.received_dex_pc_moved_event;
433 case instrumentation::Instrumentation::kFieldRead:
434 return listener.received_field_read_event;
435 case instrumentation::Instrumentation::kFieldWritten:
Alex Lightd7661582017-05-01 13:48:16 -0700436 return (!with_object && listener.received_field_written_event) ||
437 (with_object && listener.received_field_written_object_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200438 case instrumentation::Instrumentation::kExceptionCaught:
439 return listener.received_exception_caught_event;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000440 case instrumentation::Instrumentation::kBranch:
441 return listener.received_branch_event;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100442 case instrumentation::Instrumentation::kInvokeVirtualOrInterface:
443 return listener.received_invoke_virtual_or_interface_event;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200444 default:
445 LOG(FATAL) << "Unknown instrumentation event " << event_type;
446 UNREACHABLE();
447 }
448 }
449};
450
451TEST_F(InstrumentationTest, NoInstrumentation) {
452 ScopedObjectAccess soa(Thread::Current());
453 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
454 ASSERT_NE(instr, nullptr);
455
456 EXPECT_FALSE(instr->AreExitStubsInstalled());
457 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
458 EXPECT_FALSE(instr->IsActive());
459 EXPECT_FALSE(instr->ShouldNotifyMethodEnterExitEvents());
460
461 // Test interpreter table is the default one.
462 EXPECT_EQ(instrumentation::kMainHandlerTable, instr->GetInterpreterHandlerTable());
463
464 // Check there is no registered listener.
465 EXPECT_FALSE(instr->HasDexPcListeners());
466 EXPECT_FALSE(instr->HasExceptionCaughtListeners());
467 EXPECT_FALSE(instr->HasFieldReadListeners());
468 EXPECT_FALSE(instr->HasFieldWriteListeners());
469 EXPECT_FALSE(instr->HasMethodEntryListeners());
470 EXPECT_FALSE(instr->HasMethodExitListeners());
471 EXPECT_FALSE(instr->IsActive());
472}
473
474// Test instrumentation listeners for each event.
475TEST_F(InstrumentationTest, MethodEntryEvent) {
476 TestEvent(instrumentation::Instrumentation::kMethodEntered);
477}
478
Alex Lightd7661582017-05-01 13:48:16 -0700479TEST_F(InstrumentationTest, MethodExitObjectEvent) {
480 ScopedObjectAccess soa(Thread::Current());
481 jobject class_loader = LoadDex("Instrumentation");
482 Runtime* const runtime = Runtime::Current();
483 ClassLinker* class_linker = runtime->GetClassLinker();
484 StackHandleScope<1> hs(soa.Self());
485 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
486 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
487 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100488 ArtMethod* method =
489 klass->FindClassMethod("returnReference", "()Ljava/lang/Object;", kRuntimePointerSize);
Alex Lightd7661582017-05-01 13:48:16 -0700490 ASSERT_TRUE(method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100491 ASSERT_TRUE(method->IsDirect());
492 ASSERT_TRUE(method->GetDeclaringClass() == klass);
Alex Lightd7661582017-05-01 13:48:16 -0700493 TestEvent(instrumentation::Instrumentation::kMethodExited,
494 /*event_method*/ method,
495 /*event_field*/ nullptr,
496 /*with_object*/ true);
497}
498
499TEST_F(InstrumentationTest, MethodExitPrimEvent) {
500 ScopedObjectAccess soa(Thread::Current());
501 jobject class_loader = LoadDex("Instrumentation");
502 Runtime* const runtime = Runtime::Current();
503 ClassLinker* class_linker = runtime->GetClassLinker();
504 StackHandleScope<1> hs(soa.Self());
505 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
506 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
507 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100508 ArtMethod* method = klass->FindClassMethod("returnPrimitive", "()I", kRuntimePointerSize);
Alex Lightd7661582017-05-01 13:48:16 -0700509 ASSERT_TRUE(method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100510 ASSERT_TRUE(method->IsDirect());
511 ASSERT_TRUE(method->GetDeclaringClass() == klass);
Alex Lightd7661582017-05-01 13:48:16 -0700512 TestEvent(instrumentation::Instrumentation::kMethodExited,
513 /*event_method*/ method,
514 /*event_field*/ nullptr,
515 /*with_object*/ false);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200516}
517
518TEST_F(InstrumentationTest, MethodUnwindEvent) {
519 TestEvent(instrumentation::Instrumentation::kMethodUnwind);
520}
521
522TEST_F(InstrumentationTest, DexPcMovedEvent) {
523 TestEvent(instrumentation::Instrumentation::kDexPcMoved);
524}
525
526TEST_F(InstrumentationTest, FieldReadEvent) {
527 TestEvent(instrumentation::Instrumentation::kFieldRead);
528}
529
Alex Lightd7661582017-05-01 13:48:16 -0700530TEST_F(InstrumentationTest, FieldWriteObjectEvent) {
531 ScopedObjectAccess soa(Thread::Current());
532 jobject class_loader = LoadDex("Instrumentation");
533 Runtime* const runtime = Runtime::Current();
534 ClassLinker* class_linker = runtime->GetClassLinker();
535 StackHandleScope<1> hs(soa.Self());
536 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
537 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
538 ASSERT_TRUE(klass != nullptr);
539 ArtField* field = klass->FindDeclaredStaticField("referenceField", "Ljava/lang/Object;");
540 ASSERT_TRUE(field != nullptr);
541
542 TestEvent(instrumentation::Instrumentation::kFieldWritten,
543 /*event_method*/ nullptr,
544 /*event_field*/ field,
545 /*with_object*/ true);
546}
547
548TEST_F(InstrumentationTest, FieldWritePrimEvent) {
549 ScopedObjectAccess soa(Thread::Current());
550 jobject class_loader = LoadDex("Instrumentation");
551 Runtime* const runtime = Runtime::Current();
552 ClassLinker* class_linker = runtime->GetClassLinker();
553 StackHandleScope<1> hs(soa.Self());
554 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
555 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
556 ASSERT_TRUE(klass != nullptr);
557 ArtField* field = klass->FindDeclaredStaticField("primitiveField", "I");
558 ASSERT_TRUE(field != nullptr);
559
560 TestEvent(instrumentation::Instrumentation::kFieldWritten,
561 /*event_method*/ nullptr,
562 /*event_field*/ field,
563 /*with_object*/ false);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200564}
565
566TEST_F(InstrumentationTest, ExceptionCaughtEvent) {
567 TestEvent(instrumentation::Instrumentation::kExceptionCaught);
568}
569
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000570TEST_F(InstrumentationTest, BranchEvent) {
571 TestEvent(instrumentation::Instrumentation::kBranch);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200572}
573
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100574TEST_F(InstrumentationTest, InvokeVirtualOrInterfaceEvent) {
575 TestEvent(instrumentation::Instrumentation::kInvokeVirtualOrInterface);
576}
577
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200578TEST_F(InstrumentationTest, DeoptimizeDirectMethod) {
579 ScopedObjectAccess soa(Thread::Current());
580 jobject class_loader = LoadDex("Instrumentation");
581 Runtime* const runtime = Runtime::Current();
582 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
583 ClassLinker* class_linker = runtime->GetClassLinker();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700584 StackHandleScope<1> hs(soa.Self());
Mathieu Chartier0795f232016-09-27 18:43:30 -0700585 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200586 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
587 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100588 ArtMethod* method_to_deoptimize =
589 klass->FindClassMethod("instanceMethod", "()V", kRuntimePointerSize);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700590 ASSERT_TRUE(method_to_deoptimize != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100591 ASSERT_TRUE(method_to_deoptimize->IsDirect());
592 ASSERT_TRUE(method_to_deoptimize->GetDeclaringClass() == klass);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200593
594 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700595 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200596
597 DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);
598
599 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
600 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700601 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200602
603 constexpr const char* instrumentation_key = "DeoptimizeDirectMethod";
604 UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
605
606 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700607 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200608}
609
610TEST_F(InstrumentationTest, FullDeoptimization) {
611 ScopedObjectAccess soa(Thread::Current());
612 Runtime* const runtime = Runtime::Current();
613 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
614 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
615
616 constexpr const char* instrumentation_key = "FullDeoptimization";
617 DeoptimizeEverything(soa.Self(), instrumentation_key, true);
618
619 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
620 EXPECT_TRUE(instr->AreExitStubsInstalled());
621
622 UndeoptimizeEverything(soa.Self(), instrumentation_key, true);
623
624 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
625}
626
627TEST_F(InstrumentationTest, MixedDeoptimization) {
628 ScopedObjectAccess soa(Thread::Current());
629 jobject class_loader = LoadDex("Instrumentation");
630 Runtime* const runtime = Runtime::Current();
631 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
632 ClassLinker* class_linker = runtime->GetClassLinker();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700633 StackHandleScope<1> hs(soa.Self());
Mathieu Chartier0795f232016-09-27 18:43:30 -0700634 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200635 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
636 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100637 ArtMethod* method_to_deoptimize =
638 klass->FindClassMethod("instanceMethod", "()V", kRuntimePointerSize);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700639 ASSERT_TRUE(method_to_deoptimize != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100640 ASSERT_TRUE(method_to_deoptimize->IsDirect());
641 ASSERT_TRUE(method_to_deoptimize->GetDeclaringClass() == klass);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200642
643 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700644 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200645
646 DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);
647 // Deoptimizing a method does not change instrumentation level.
648 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
649 GetCurrentInstrumentationLevel());
650 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
651 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700652 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200653
654 constexpr const char* instrumentation_key = "MixedDeoptimization";
655 DeoptimizeEverything(soa.Self(), instrumentation_key, false);
656 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
657 GetCurrentInstrumentationLevel());
658 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
659 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700660 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200661
662 UndeoptimizeEverything(soa.Self(), instrumentation_key, false);
663 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
664 GetCurrentInstrumentationLevel());
665 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
666 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700667 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200668
669 UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
670 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
671 GetCurrentInstrumentationLevel());
672 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700673 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200674}
675
676TEST_F(InstrumentationTest, MethodTracing_Interpreter) {
677 ScopedObjectAccess soa(Thread::Current());
678 Runtime* const runtime = Runtime::Current();
679 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
680 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
681
682 constexpr const char* instrumentation_key = "MethodTracing";
683 EnableMethodTracing(soa.Self(), instrumentation_key, true);
684 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
685 GetCurrentInstrumentationLevel());
686 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
687 EXPECT_TRUE(instr->AreExitStubsInstalled());
688
689 DisableMethodTracing(soa.Self(), instrumentation_key);
690 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
691 GetCurrentInstrumentationLevel());
692 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
693}
694
695TEST_F(InstrumentationTest, MethodTracing_InstrumentationEntryExitStubs) {
696 ScopedObjectAccess soa(Thread::Current());
697 Runtime* const runtime = Runtime::Current();
698 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
699 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
700
701 constexpr const char* instrumentation_key = "MethodTracing";
702 EnableMethodTracing(soa.Self(), instrumentation_key, false);
703 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
704 GetCurrentInstrumentationLevel());
705 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
706 EXPECT_TRUE(instr->AreExitStubsInstalled());
707
708 DisableMethodTracing(soa.Self(), instrumentation_key);
709 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
710 GetCurrentInstrumentationLevel());
711 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
712}
713
714// We use a macro to print the line number where the test is failing.
715#define CHECK_INSTRUMENTATION(_level, _user_count) \
716 do { \
717 Instrumentation* const instr = Runtime::Current()->GetInstrumentation(); \
718 bool interpreter = \
Chih-Hung Hsieh1a0de6a2016-08-26 15:06:11 -0700719 ((_level) == Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter); \
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200720 EXPECT_EQ(_level, GetCurrentInstrumentationLevel()); \
721 EXPECT_EQ(_user_count, GetInstrumentationUserCount()); \
722 if (instr->IsForcedInterpretOnly()) { \
723 EXPECT_TRUE(instr->InterpretOnly()); \
724 } else if (interpreter) { \
725 EXPECT_TRUE(instr->InterpretOnly()); \
726 } else { \
727 EXPECT_FALSE(instr->InterpretOnly()); \
728 } \
729 if (interpreter) { \
730 EXPECT_TRUE(instr->AreAllMethodsDeoptimized()); \
731 } else { \
732 EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); \
733 } \
734 } while (false)
735
736TEST_F(InstrumentationTest, ConfigureStubs_Nothing) {
737 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
738
739 // Check no-op.
740 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
741 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
742}
743
744TEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubs) {
745 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
746
747 // Check we can switch to instrumentation stubs
748 CheckConfigureStubs(kClientOneKey,
749 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
750 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
751 1U);
752
753 // Check we can disable instrumentation.
754 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
755 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
756}
757
758TEST_F(InstrumentationTest, ConfigureStubs_Interpreter) {
759 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
760
761 // Check we can switch to interpreter
762 CheckConfigureStubs(kClientOneKey,
763 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
764 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
765
766 // Check we can disable instrumentation.
767 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
768 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
769}
770
771TEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubsToInterpreter) {
772 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
773
774 // Configure stubs with instrumentation stubs.
775 CheckConfigureStubs(kClientOneKey,
776 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
777 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
778 1U);
779
780 // Configure stubs with interpreter.
781 CheckConfigureStubs(kClientOneKey,
782 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
783 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
784
785 // Check we can disable instrumentation.
786 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
787 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
788}
789
790TEST_F(InstrumentationTest, ConfigureStubs_InterpreterToInstrumentationStubs) {
791 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
792
793 // Configure stubs with interpreter.
794 CheckConfigureStubs(kClientOneKey,
795 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
796 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
797
798 // Configure stubs with instrumentation stubs.
799 CheckConfigureStubs(kClientOneKey,
800 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
801 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
802 1U);
803
804 // Check we can disable instrumentation.
805 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
806 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
807}
808
809TEST_F(InstrumentationTest,
810 ConfigureStubs_InstrumentationStubsToInterpreterToInstrumentationStubs) {
811 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
812
813 // Configure stubs with instrumentation stubs.
814 CheckConfigureStubs(kClientOneKey,
815 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
816 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
817 1U);
818
819 // Configure stubs with interpreter.
820 CheckConfigureStubs(kClientOneKey,
821 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
822 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
823
824 // Configure stubs with instrumentation stubs again.
825 CheckConfigureStubs(kClientOneKey,
826 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
827 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
828 1U);
829
830 // Check we can disable instrumentation.
831 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
832 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
833}
834
835TEST_F(InstrumentationTest, MultiConfigureStubs_Nothing) {
836 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
837
838 // Check kInstrumentNothing with two clients.
839 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
840 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
841
842 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
843 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
844}
845
846TEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubs) {
847 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
848
849 // Configure stubs with instrumentation stubs for 1st client.
850 CheckConfigureStubs(kClientOneKey,
851 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
852 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
853 1U);
854
855 // Configure stubs with instrumentation stubs for 2nd client.
856 CheckConfigureStubs(kClientTwoKey,
857 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
858 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
859 2U);
860
861 // 1st client requests instrumentation deactivation but 2nd client still needs
862 // instrumentation stubs.
863 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
864 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
865 1U);
866
867 // 2nd client requests instrumentation deactivation
868 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
869 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
870}
871
872TEST_F(InstrumentationTest, MultiConfigureStubs_Interpreter) {
873 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
874
875 // Configure stubs with interpreter for 1st client.
876 CheckConfigureStubs(kClientOneKey,
877 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
878 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
879
880 // Configure stubs with interpreter for 2nd client.
881 CheckConfigureStubs(kClientTwoKey,
882 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
883 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
884
885 // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
886 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
887 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
888
889 // 2nd client requests instrumentation deactivation
890 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
891 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
892}
893
894TEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubsThenInterpreter) {
895 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
896
897 // Configure stubs with instrumentation stubs for 1st client.
898 CheckConfigureStubs(kClientOneKey,
899 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
900 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
901 1U);
902
903 // Configure stubs with interpreter for 2nd client.
904 CheckConfigureStubs(kClientTwoKey,
905 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
906 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
907
908 // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
909 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
910 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
911
912 // 2nd client requests instrumentation deactivation
913 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
914 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
915}
916
917TEST_F(InstrumentationTest, MultiConfigureStubs_InterpreterThenInstrumentationStubs) {
918 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
919
920 // Configure stubs with interpreter for 1st client.
921 CheckConfigureStubs(kClientOneKey,
922 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
923 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
924
925 // Configure stubs with instrumentation stubs for 2nd client.
926 CheckConfigureStubs(kClientTwoKey,
927 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
928 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
929
930 // 1st client requests instrumentation deactivation but 2nd client still needs
931 // instrumentation stubs.
932 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
933 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
934 1U);
935
936 // 2nd client requests instrumentation deactivation
937 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
938 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
939}
940
941} // namespace instrumentation
942} // namespace art