blob: bfd36cc11cbe9db16b4f316e24fdc94b10e8eddf [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"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070021#include "class_linker-inl.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020022#include "common_runtime_test.h"
23#include "common_throws.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020024#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"
Alex Lightd7661582017-05-01 13:48:16 -070031#include "thread-inl.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070032#include "thread_list.h"
Alex Lightd7661582017-05-01 13:48:16 -070033#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) {
Mingyao Yangedeba102017-04-12 13:43:15 -0700476 ScopedObjectAccess soa(Thread::Current());
477 jobject class_loader = LoadDex("Instrumentation");
478 Runtime* const runtime = Runtime::Current();
479 ClassLinker* class_linker = runtime->GetClassLinker();
480 StackHandleScope<1> hs(soa.Self());
481 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
482 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
483 ASSERT_TRUE(klass != nullptr);
484 ArtMethod* method =
485 klass->FindClassMethod("returnReference", "()Ljava/lang/Object;", kRuntimePointerSize);
486 ASSERT_TRUE(method != nullptr);
487 ASSERT_TRUE(method->IsDirect());
488 ASSERT_TRUE(method->GetDeclaringClass() == klass);
489 TestEvent(instrumentation::Instrumentation::kMethodEntered,
490 /*event_method*/ method,
491 /*event_field*/ nullptr,
492 /*with_object*/ true);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200493}
494
Alex Lightd7661582017-05-01 13:48:16 -0700495TEST_F(InstrumentationTest, MethodExitObjectEvent) {
496 ScopedObjectAccess soa(Thread::Current());
497 jobject class_loader = LoadDex("Instrumentation");
498 Runtime* const runtime = Runtime::Current();
499 ClassLinker* class_linker = runtime->GetClassLinker();
500 StackHandleScope<1> hs(soa.Self());
501 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
502 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
503 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100504 ArtMethod* method =
505 klass->FindClassMethod("returnReference", "()Ljava/lang/Object;", kRuntimePointerSize);
Alex Lightd7661582017-05-01 13:48:16 -0700506 ASSERT_TRUE(method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100507 ASSERT_TRUE(method->IsDirect());
508 ASSERT_TRUE(method->GetDeclaringClass() == klass);
Alex Lightd7661582017-05-01 13:48:16 -0700509 TestEvent(instrumentation::Instrumentation::kMethodExited,
510 /*event_method*/ method,
511 /*event_field*/ nullptr,
512 /*with_object*/ true);
513}
514
515TEST_F(InstrumentationTest, MethodExitPrimEvent) {
516 ScopedObjectAccess soa(Thread::Current());
517 jobject class_loader = LoadDex("Instrumentation");
518 Runtime* const runtime = Runtime::Current();
519 ClassLinker* class_linker = runtime->GetClassLinker();
520 StackHandleScope<1> hs(soa.Self());
521 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
522 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
523 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100524 ArtMethod* method = klass->FindClassMethod("returnPrimitive", "()I", kRuntimePointerSize);
Alex Lightd7661582017-05-01 13:48:16 -0700525 ASSERT_TRUE(method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100526 ASSERT_TRUE(method->IsDirect());
527 ASSERT_TRUE(method->GetDeclaringClass() == klass);
Alex Lightd7661582017-05-01 13:48:16 -0700528 TestEvent(instrumentation::Instrumentation::kMethodExited,
529 /*event_method*/ method,
530 /*event_field*/ nullptr,
531 /*with_object*/ false);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200532}
533
534TEST_F(InstrumentationTest, MethodUnwindEvent) {
535 TestEvent(instrumentation::Instrumentation::kMethodUnwind);
536}
537
538TEST_F(InstrumentationTest, DexPcMovedEvent) {
539 TestEvent(instrumentation::Instrumentation::kDexPcMoved);
540}
541
542TEST_F(InstrumentationTest, FieldReadEvent) {
543 TestEvent(instrumentation::Instrumentation::kFieldRead);
544}
545
Alex Lightd7661582017-05-01 13:48:16 -0700546TEST_F(InstrumentationTest, FieldWriteObjectEvent) {
547 ScopedObjectAccess soa(Thread::Current());
548 jobject class_loader = LoadDex("Instrumentation");
549 Runtime* const runtime = Runtime::Current();
550 ClassLinker* class_linker = runtime->GetClassLinker();
551 StackHandleScope<1> hs(soa.Self());
552 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
553 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
554 ASSERT_TRUE(klass != nullptr);
555 ArtField* field = klass->FindDeclaredStaticField("referenceField", "Ljava/lang/Object;");
556 ASSERT_TRUE(field != nullptr);
557
558 TestEvent(instrumentation::Instrumentation::kFieldWritten,
559 /*event_method*/ nullptr,
560 /*event_field*/ field,
561 /*with_object*/ true);
562}
563
564TEST_F(InstrumentationTest, FieldWritePrimEvent) {
565 ScopedObjectAccess soa(Thread::Current());
566 jobject class_loader = LoadDex("Instrumentation");
567 Runtime* const runtime = Runtime::Current();
568 ClassLinker* class_linker = runtime->GetClassLinker();
569 StackHandleScope<1> hs(soa.Self());
570 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
571 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
572 ASSERT_TRUE(klass != nullptr);
573 ArtField* field = klass->FindDeclaredStaticField("primitiveField", "I");
574 ASSERT_TRUE(field != nullptr);
575
576 TestEvent(instrumentation::Instrumentation::kFieldWritten,
577 /*event_method*/ nullptr,
578 /*event_field*/ field,
579 /*with_object*/ false);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200580}
581
582TEST_F(InstrumentationTest, ExceptionCaughtEvent) {
583 TestEvent(instrumentation::Instrumentation::kExceptionCaught);
584}
585
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000586TEST_F(InstrumentationTest, BranchEvent) {
587 TestEvent(instrumentation::Instrumentation::kBranch);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200588}
589
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100590TEST_F(InstrumentationTest, InvokeVirtualOrInterfaceEvent) {
591 TestEvent(instrumentation::Instrumentation::kInvokeVirtualOrInterface);
592}
593
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200594TEST_F(InstrumentationTest, DeoptimizeDirectMethod) {
595 ScopedObjectAccess soa(Thread::Current());
596 jobject class_loader = LoadDex("Instrumentation");
597 Runtime* const runtime = Runtime::Current();
598 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
599 ClassLinker* class_linker = runtime->GetClassLinker();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700600 StackHandleScope<1> hs(soa.Self());
Mathieu Chartier0795f232016-09-27 18:43:30 -0700601 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200602 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
603 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100604 ArtMethod* method_to_deoptimize =
605 klass->FindClassMethod("instanceMethod", "()V", kRuntimePointerSize);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700606 ASSERT_TRUE(method_to_deoptimize != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100607 ASSERT_TRUE(method_to_deoptimize->IsDirect());
608 ASSERT_TRUE(method_to_deoptimize->GetDeclaringClass() == klass);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200609
610 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700611 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200612
613 DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);
614
615 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
616 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700617 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200618
619 constexpr const char* instrumentation_key = "DeoptimizeDirectMethod";
620 UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
621
622 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700623 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200624}
625
626TEST_F(InstrumentationTest, FullDeoptimization) {
627 ScopedObjectAccess soa(Thread::Current());
628 Runtime* const runtime = Runtime::Current();
629 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
630 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
631
632 constexpr const char* instrumentation_key = "FullDeoptimization";
633 DeoptimizeEverything(soa.Self(), instrumentation_key, true);
634
635 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
636 EXPECT_TRUE(instr->AreExitStubsInstalled());
637
638 UndeoptimizeEverything(soa.Self(), instrumentation_key, true);
639
640 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
641}
642
643TEST_F(InstrumentationTest, MixedDeoptimization) {
644 ScopedObjectAccess soa(Thread::Current());
645 jobject class_loader = LoadDex("Instrumentation");
646 Runtime* const runtime = Runtime::Current();
647 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
648 ClassLinker* class_linker = runtime->GetClassLinker();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700649 StackHandleScope<1> hs(soa.Self());
Mathieu Chartier0795f232016-09-27 18:43:30 -0700650 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200651 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
652 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100653 ArtMethod* method_to_deoptimize =
654 klass->FindClassMethod("instanceMethod", "()V", kRuntimePointerSize);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700655 ASSERT_TRUE(method_to_deoptimize != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100656 ASSERT_TRUE(method_to_deoptimize->IsDirect());
657 ASSERT_TRUE(method_to_deoptimize->GetDeclaringClass() == klass);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200658
659 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700660 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200661
662 DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);
663 // Deoptimizing a method does not change instrumentation level.
664 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
665 GetCurrentInstrumentationLevel());
666 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
667 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700668 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200669
670 constexpr const char* instrumentation_key = "MixedDeoptimization";
671 DeoptimizeEverything(soa.Self(), instrumentation_key, false);
672 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
673 GetCurrentInstrumentationLevel());
674 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
675 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700676 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200677
678 UndeoptimizeEverything(soa.Self(), instrumentation_key, false);
679 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
680 GetCurrentInstrumentationLevel());
681 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
682 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700683 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200684
685 UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
686 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
687 GetCurrentInstrumentationLevel());
688 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700689 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200690}
691
692TEST_F(InstrumentationTest, MethodTracing_Interpreter) {
693 ScopedObjectAccess soa(Thread::Current());
694 Runtime* const runtime = Runtime::Current();
695 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
696 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
697
698 constexpr const char* instrumentation_key = "MethodTracing";
699 EnableMethodTracing(soa.Self(), instrumentation_key, true);
700 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
701 GetCurrentInstrumentationLevel());
702 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
703 EXPECT_TRUE(instr->AreExitStubsInstalled());
704
705 DisableMethodTracing(soa.Self(), instrumentation_key);
706 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
707 GetCurrentInstrumentationLevel());
708 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
709}
710
711TEST_F(InstrumentationTest, MethodTracing_InstrumentationEntryExitStubs) {
712 ScopedObjectAccess soa(Thread::Current());
713 Runtime* const runtime = Runtime::Current();
714 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
715 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
716
717 constexpr const char* instrumentation_key = "MethodTracing";
718 EnableMethodTracing(soa.Self(), instrumentation_key, false);
719 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
720 GetCurrentInstrumentationLevel());
721 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
722 EXPECT_TRUE(instr->AreExitStubsInstalled());
723
724 DisableMethodTracing(soa.Self(), instrumentation_key);
725 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
726 GetCurrentInstrumentationLevel());
727 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
728}
729
730// We use a macro to print the line number where the test is failing.
731#define CHECK_INSTRUMENTATION(_level, _user_count) \
732 do { \
733 Instrumentation* const instr = Runtime::Current()->GetInstrumentation(); \
734 bool interpreter = \
Chih-Hung Hsieh1a0de6a2016-08-26 15:06:11 -0700735 ((_level) == Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter); \
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200736 EXPECT_EQ(_level, GetCurrentInstrumentationLevel()); \
737 EXPECT_EQ(_user_count, GetInstrumentationUserCount()); \
738 if (instr->IsForcedInterpretOnly()) { \
739 EXPECT_TRUE(instr->InterpretOnly()); \
740 } else if (interpreter) { \
741 EXPECT_TRUE(instr->InterpretOnly()); \
742 } else { \
743 EXPECT_FALSE(instr->InterpretOnly()); \
744 } \
745 if (interpreter) { \
746 EXPECT_TRUE(instr->AreAllMethodsDeoptimized()); \
747 } else { \
748 EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); \
749 } \
750 } while (false)
751
752TEST_F(InstrumentationTest, ConfigureStubs_Nothing) {
753 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
754
755 // Check no-op.
756 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
757 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
758}
759
760TEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubs) {
761 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
762
763 // Check we can switch to instrumentation stubs
764 CheckConfigureStubs(kClientOneKey,
765 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
766 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
767 1U);
768
769 // Check we can disable instrumentation.
770 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
771 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
772}
773
774TEST_F(InstrumentationTest, ConfigureStubs_Interpreter) {
775 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
776
777 // Check we can switch to interpreter
778 CheckConfigureStubs(kClientOneKey,
779 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
780 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
781
782 // Check we can disable instrumentation.
783 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
784 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
785}
786
787TEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubsToInterpreter) {
788 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
789
790 // Configure stubs with instrumentation stubs.
791 CheckConfigureStubs(kClientOneKey,
792 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
793 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
794 1U);
795
796 // Configure stubs with interpreter.
797 CheckConfigureStubs(kClientOneKey,
798 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
799 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
800
801 // Check we can disable instrumentation.
802 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
803 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
804}
805
806TEST_F(InstrumentationTest, ConfigureStubs_InterpreterToInstrumentationStubs) {
807 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
808
809 // Configure stubs with interpreter.
810 CheckConfigureStubs(kClientOneKey,
811 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
812 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
813
814 // Configure stubs with instrumentation stubs.
815 CheckConfigureStubs(kClientOneKey,
816 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
817 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
818 1U);
819
820 // Check we can disable instrumentation.
821 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
822 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
823}
824
825TEST_F(InstrumentationTest,
826 ConfigureStubs_InstrumentationStubsToInterpreterToInstrumentationStubs) {
827 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
828
829 // Configure stubs with instrumentation stubs.
830 CheckConfigureStubs(kClientOneKey,
831 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
832 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
833 1U);
834
835 // Configure stubs with interpreter.
836 CheckConfigureStubs(kClientOneKey,
837 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
838 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
839
840 // Configure stubs with instrumentation stubs again.
841 CheckConfigureStubs(kClientOneKey,
842 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
843 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
844 1U);
845
846 // Check we can disable instrumentation.
847 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
848 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
849}
850
851TEST_F(InstrumentationTest, MultiConfigureStubs_Nothing) {
852 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
853
854 // Check kInstrumentNothing with two clients.
855 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
856 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
857
858 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
859 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
860}
861
862TEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubs) {
863 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
864
865 // Configure stubs with instrumentation stubs for 1st client.
866 CheckConfigureStubs(kClientOneKey,
867 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
868 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
869 1U);
870
871 // Configure stubs with instrumentation stubs for 2nd client.
872 CheckConfigureStubs(kClientTwoKey,
873 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
874 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
875 2U);
876
877 // 1st client requests instrumentation deactivation but 2nd client still needs
878 // instrumentation stubs.
879 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
880 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
881 1U);
882
883 // 2nd client requests instrumentation deactivation
884 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
885 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
886}
887
888TEST_F(InstrumentationTest, MultiConfigureStubs_Interpreter) {
889 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
890
891 // Configure stubs with interpreter for 1st client.
892 CheckConfigureStubs(kClientOneKey,
893 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
894 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
895
896 // Configure stubs with interpreter for 2nd client.
897 CheckConfigureStubs(kClientTwoKey,
898 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
899 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
900
901 // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
902 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
903 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
904
905 // 2nd client requests instrumentation deactivation
906 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
907 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
908}
909
910TEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubsThenInterpreter) {
911 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
912
913 // Configure stubs with instrumentation stubs for 1st client.
914 CheckConfigureStubs(kClientOneKey,
915 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
916 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
917 1U);
918
919 // Configure stubs with interpreter for 2nd client.
920 CheckConfigureStubs(kClientTwoKey,
921 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
922 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
923
924 // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
925 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
926 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
927
928 // 2nd client requests instrumentation deactivation
929 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
930 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
931}
932
933TEST_F(InstrumentationTest, MultiConfigureStubs_InterpreterThenInstrumentationStubs) {
934 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
935
936 // Configure stubs with interpreter for 1st client.
937 CheckConfigureStubs(kClientOneKey,
938 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
939 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
940
941 // Configure stubs with instrumentation stubs for 2nd client.
942 CheckConfigureStubs(kClientTwoKey,
943 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
944 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
945
946 // 1st client requests instrumentation deactivation but 2nd client still needs
947 // instrumentation stubs.
948 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
949 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
950 1U);
951
952 // 2nd client requests instrumentation deactivation
953 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
954 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
955}
956
957} // namespace instrumentation
958} // namespace art