blob: 836bbe711fc9f59337a6ad20060a4f2380238cca [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"
David Sehr9e734c72018-01-04 17:56:19 -080024#include "dex/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 Lighte814f9d2017-07-31 16:14:39 -070031#include "interpreter/shadow_frame.h"
Alex Lightd7661582017-05-01 13:48:16 -070032#include "thread-inl.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070033#include "thread_list.h"
Alex Lightd7661582017-05-01 13:48:16 -070034#include "well_known_classes.h"
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020035
36namespace art {
37namespace instrumentation {
38
39class TestInstrumentationListener FINAL : public instrumentation::InstrumentationListener {
40 public:
41 TestInstrumentationListener()
Alex Lightd7661582017-05-01 13:48:16 -070042 : received_method_enter_event(false),
43 received_method_exit_event(false),
44 received_method_exit_object_event(false),
45 received_method_unwind_event(false),
46 received_dex_pc_moved_event(false),
47 received_field_read_event(false),
48 received_field_written_event(false),
49 received_field_written_object_event(false),
Alex Light6e1607e2017-08-23 10:06:18 -070050 received_exception_thrown_event(false),
Alex Light9fb1ab12017-09-05 09:32:49 -070051 received_exception_handled_event(false),
Alex Lightd7661582017-05-01 13:48:16 -070052 received_branch_event(false),
Alex Lighte814f9d2017-07-31 16:14:39 -070053 received_invoke_virtual_or_interface_event(false),
54 received_watched_frame_pop(false) {}
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020055
56 virtual ~TestInstrumentationListener() {}
57
58 void MethodEntered(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070059 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070060 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020061 uint32_t dex_pc ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070062 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020063 received_method_enter_event = true;
64 }
65
66 void MethodExited(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070067 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
68 ArtMethod* method ATTRIBUTE_UNUSED,
69 uint32_t dex_pc ATTRIBUTE_UNUSED,
70 Handle<mirror::Object> return_value ATTRIBUTE_UNUSED)
71 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
72 received_method_exit_object_event = true;
73 }
74
75 void MethodExited(Thread* thread ATTRIBUTE_UNUSED,
76 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070077 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020078 uint32_t dex_pc ATTRIBUTE_UNUSED,
79 const JValue& return_value ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070080 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020081 received_method_exit_event = true;
82 }
83
84 void MethodUnwind(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070085 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070086 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020087 uint32_t dex_pc ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070088 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020089 received_method_unwind_event = true;
90 }
91
92 void DexPcMoved(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070093 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070094 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020095 uint32_t new_dex_pc ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070096 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020097 received_dex_pc_moved_event = true;
98 }
99
100 void FieldRead(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -0700101 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700102 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200103 uint32_t dex_pc ATTRIBUTE_UNUSED,
104 ArtField* field ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700105 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200106 received_field_read_event = true;
107 }
108
109 void FieldWritten(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -0700110 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
111 ArtMethod* method ATTRIBUTE_UNUSED,
112 uint32_t dex_pc ATTRIBUTE_UNUSED,
113 ArtField* field ATTRIBUTE_UNUSED,
114 Handle<mirror::Object> field_value ATTRIBUTE_UNUSED)
115 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
116 received_field_written_object_event = true;
117 }
118
119 void FieldWritten(Thread* thread ATTRIBUTE_UNUSED,
120 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700121 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200122 uint32_t dex_pc ATTRIBUTE_UNUSED,
123 ArtField* field ATTRIBUTE_UNUSED,
124 const JValue& field_value ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700125 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200126 received_field_written_event = true;
127 }
128
Alex Light6e1607e2017-08-23 10:06:18 -0700129 void ExceptionThrown(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -0700130 Handle<mirror::Throwable> exception_object ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700131 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Alex Light6e1607e2017-08-23 10:06:18 -0700132 received_exception_thrown_event = true;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200133 }
134
Alex Light9fb1ab12017-09-05 09:32:49 -0700135 void ExceptionHandled(Thread* self ATTRIBUTE_UNUSED,
136 Handle<mirror::Throwable> throwable ATTRIBUTE_UNUSED)
137 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
138 received_exception_handled_event = true;
139 }
140
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000141 void Branch(Thread* thread ATTRIBUTE_UNUSED,
142 ArtMethod* method ATTRIBUTE_UNUSED,
143 uint32_t dex_pc ATTRIBUTE_UNUSED,
144 int32_t dex_pc_offset ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700145 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000146 received_branch_event = true;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200147 }
148
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100149 void InvokeVirtualOrInterface(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -0700150 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100151 ArtMethod* caller ATTRIBUTE_UNUSED,
152 uint32_t dex_pc ATTRIBUTE_UNUSED,
153 ArtMethod* callee ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700154 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100155 received_invoke_virtual_or_interface_event = true;
156 }
157
Alex Lighte814f9d2017-07-31 16:14:39 -0700158 void WatchedFramePop(Thread* thread ATTRIBUTE_UNUSED, const ShadowFrame& frame ATTRIBUTE_UNUSED)
159 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
160 received_watched_frame_pop = true;
161 }
162
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200163 void Reset() {
164 received_method_enter_event = false;
165 received_method_exit_event = false;
Alex Lightd7661582017-05-01 13:48:16 -0700166 received_method_exit_object_event = false;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200167 received_method_unwind_event = false;
168 received_dex_pc_moved_event = false;
169 received_field_read_event = false;
170 received_field_written_event = false;
Alex Lightd7661582017-05-01 13:48:16 -0700171 received_field_written_object_event = false;
Alex Light6e1607e2017-08-23 10:06:18 -0700172 received_exception_thrown_event = false;
Alex Light9fb1ab12017-09-05 09:32:49 -0700173 received_exception_handled_event = false;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000174 received_branch_event = false;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100175 received_invoke_virtual_or_interface_event = false;
Alex Lighte814f9d2017-07-31 16:14:39 -0700176 received_watched_frame_pop = false;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200177 }
178
179 bool received_method_enter_event;
180 bool received_method_exit_event;
Alex Lightd7661582017-05-01 13:48:16 -0700181 bool received_method_exit_object_event;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200182 bool received_method_unwind_event;
183 bool received_dex_pc_moved_event;
184 bool received_field_read_event;
185 bool received_field_written_event;
Alex Lightd7661582017-05-01 13:48:16 -0700186 bool received_field_written_object_event;
Alex Light6e1607e2017-08-23 10:06:18 -0700187 bool received_exception_thrown_event;
Alex Light9fb1ab12017-09-05 09:32:49 -0700188 bool received_exception_handled_event;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000189 bool received_branch_event;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100190 bool received_invoke_virtual_or_interface_event;
Alex Lighte814f9d2017-07-31 16:14:39 -0700191 bool received_watched_frame_pop;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200192
193 private:
194 DISALLOW_COPY_AND_ASSIGN(TestInstrumentationListener);
195};
196
197class InstrumentationTest : public CommonRuntimeTest {
198 public:
199 // Unique keys used to test Instrumentation::ConfigureStubs.
200 static constexpr const char* kClientOneKey = "TestClient1";
201 static constexpr const char* kClientTwoKey = "TestClient2";
202
203 void CheckConfigureStubs(const char* key, Instrumentation::InstrumentationLevel level) {
204 ScopedObjectAccess soa(Thread::Current());
205 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700206 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700207 gc::ScopedGCCriticalSection gcs(soa.Self(),
208 gc::kGcCauseInstrumentation,
209 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700210 ScopedSuspendAll ssa("Instrumentation::ConfigureStubs");
211 instr->ConfigureStubs(key, level);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200212 }
213
214 Instrumentation::InstrumentationLevel GetCurrentInstrumentationLevel() {
215 return Runtime::Current()->GetInstrumentation()->GetCurrentInstrumentationLevel();
216 }
217
218 size_t GetInstrumentationUserCount() {
219 ScopedObjectAccess soa(Thread::Current());
220 return Runtime::Current()->GetInstrumentation()->requested_instrumentation_levels_.size();
221 }
222
223 void TestEvent(uint32_t instrumentation_event) {
Alex Lightd7661582017-05-01 13:48:16 -0700224 TestEvent(instrumentation_event, nullptr, nullptr, false);
225 }
226
227 void TestEvent(uint32_t instrumentation_event,
228 ArtMethod* event_method,
229 ArtField* event_field,
230 bool with_object) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200231 ScopedObjectAccess soa(Thread::Current());
232 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
233 TestInstrumentationListener listener;
234 {
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700235 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700236 ScopedSuspendAll ssa("Add instrumentation listener");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200237 instr->AddListener(&listener, instrumentation_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200238 }
239
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200240 mirror::Object* const event_obj = nullptr;
241 const uint32_t event_dex_pc = 0;
Alex Lighte814f9d2017-07-31 16:14:39 -0700242 ShadowFrameAllocaUniquePtr test_frame = CREATE_SHADOW_FRAME(0, nullptr, event_method, 0);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200243
244 // Check the listener is registered and is notified of the event.
245 EXPECT_TRUE(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,
Alex Lighte814f9d2017-07-31 16:14:39 -0700253 event_dex_pc,
254 *test_frame);
Alex Lightd7661582017-05-01 13:48:16 -0700255 EXPECT_TRUE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200256
257 listener.Reset();
258 {
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700259 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700260 ScopedSuspendAll ssa("Remove instrumentation listener");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200261 instr->RemoveListener(&listener, instrumentation_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200262 }
263
264 // Check the listener is not registered and is not notified of the event.
265 EXPECT_FALSE(HasEventListener(instr, instrumentation_event));
Alex Lightd7661582017-05-01 13:48:16 -0700266 EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
267 ReportEvent(instr,
268 instrumentation_event,
269 soa.Self(),
270 event_method,
271 event_obj,
272 event_field,
Alex Lighte814f9d2017-07-31 16:14:39 -0700273 event_dex_pc,
274 *test_frame);
Alex Lightd7661582017-05-01 13:48:16 -0700275 EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200276 }
277
Mathieu Chartiere401d142015-04-22 13:56:20 -0700278 void DeoptimizeMethod(Thread* self, ArtMethod* method, bool enable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700279 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200280 Runtime* runtime = Runtime::Current();
281 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700282 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700283 gc::ScopedGCCriticalSection gcs(self,
284 gc::kGcCauseInstrumentation,
285 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700286 ScopedSuspendAll ssa("Single method deoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200287 if (enable_deoptimization) {
288 instrumentation->EnableDeoptimization();
289 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700290 instrumentation->Deoptimize(method);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200291 }
292
Mathieu Chartiere401d142015-04-22 13:56:20 -0700293 void UndeoptimizeMethod(Thread* self, ArtMethod* method,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200294 const char* key, bool disable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700295 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200296 Runtime* runtime = Runtime::Current();
297 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700298 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700299 gc::ScopedGCCriticalSection gcs(self,
300 gc::kGcCauseInstrumentation,
301 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700302 ScopedSuspendAll ssa("Single method undeoptimization");
Mathieu Chartiere401d142015-04-22 13:56:20 -0700303 instrumentation->Undeoptimize(method);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200304 if (disable_deoptimization) {
305 instrumentation->DisableDeoptimization(key);
306 }
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200307 }
308
309 void DeoptimizeEverything(Thread* self, const char* key, bool enable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700310 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200311 Runtime* runtime = Runtime::Current();
312 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700313 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700314 gc::ScopedGCCriticalSection gcs(self,
315 gc::kGcCauseInstrumentation,
316 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700317 ScopedSuspendAll ssa("Full deoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200318 if (enable_deoptimization) {
319 instrumentation->EnableDeoptimization();
320 }
321 instrumentation->DeoptimizeEverything(key);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200322 }
323
324 void UndeoptimizeEverything(Thread* self, const char* key, bool disable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700325 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200326 Runtime* runtime = Runtime::Current();
327 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700328 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700329 gc::ScopedGCCriticalSection gcs(self,
330 gc::kGcCauseInstrumentation,
331 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700332 ScopedSuspendAll ssa("Full undeoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200333 instrumentation->UndeoptimizeEverything(key);
334 if (disable_deoptimization) {
335 instrumentation->DisableDeoptimization(key);
336 }
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200337 }
338
339 void EnableMethodTracing(Thread* self, const char* key, bool needs_interpreter)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700340 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200341 Runtime* runtime = Runtime::Current();
342 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700343 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700344 gc::ScopedGCCriticalSection gcs(self,
345 gc::kGcCauseInstrumentation,
346 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700347 ScopedSuspendAll ssa("EnableMethodTracing");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200348 instrumentation->EnableMethodTracing(key, needs_interpreter);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200349 }
350
351 void DisableMethodTracing(Thread* self, const char* key)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700352 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200353 Runtime* runtime = Runtime::Current();
354 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700355 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700356 gc::ScopedGCCriticalSection gcs(self,
357 gc::kGcCauseInstrumentation,
358 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700359 ScopedSuspendAll ssa("EnableMethodTracing");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200360 instrumentation->DisableMethodTracing(key);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200361 }
362
363 private:
364 static bool HasEventListener(const instrumentation::Instrumentation* instr, uint32_t event_type)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700365 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200366 switch (event_type) {
367 case instrumentation::Instrumentation::kMethodEntered:
368 return instr->HasMethodEntryListeners();
369 case instrumentation::Instrumentation::kMethodExited:
370 return instr->HasMethodExitListeners();
371 case instrumentation::Instrumentation::kMethodUnwind:
372 return instr->HasMethodUnwindListeners();
373 case instrumentation::Instrumentation::kDexPcMoved:
374 return instr->HasDexPcListeners();
375 case instrumentation::Instrumentation::kFieldRead:
376 return instr->HasFieldReadListeners();
377 case instrumentation::Instrumentation::kFieldWritten:
378 return instr->HasFieldWriteListeners();
Alex Light6e1607e2017-08-23 10:06:18 -0700379 case instrumentation::Instrumentation::kExceptionThrown:
380 return instr->HasExceptionThrownListeners();
Alex Light9fb1ab12017-09-05 09:32:49 -0700381 case instrumentation::Instrumentation::kExceptionHandled:
382 return instr->HasExceptionHandledListeners();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000383 case instrumentation::Instrumentation::kBranch:
384 return instr->HasBranchListeners();
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100385 case instrumentation::Instrumentation::kInvokeVirtualOrInterface:
386 return instr->HasInvokeVirtualOrInterfaceListeners();
Alex Lighte814f9d2017-07-31 16:14:39 -0700387 case instrumentation::Instrumentation::kWatchedFramePop:
388 return instr->HasWatchedFramePopListeners();
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200389 default:
390 LOG(FATAL) << "Unknown instrumentation event " << event_type;
391 UNREACHABLE();
392 }
393 }
394
Alex Lightd7661582017-05-01 13:48:16 -0700395 static void ReportEvent(const instrumentation::Instrumentation* instr,
396 uint32_t event_type,
397 Thread* self,
398 ArtMethod* method,
399 mirror::Object* obj,
400 ArtField* field,
Alex Lighte814f9d2017-07-31 16:14:39 -0700401 uint32_t dex_pc,
402 const ShadowFrame& frame)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700403 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200404 switch (event_type) {
405 case instrumentation::Instrumentation::kMethodEntered:
406 instr->MethodEnterEvent(self, obj, method, dex_pc);
407 break;
408 case instrumentation::Instrumentation::kMethodExited: {
409 JValue value;
410 instr->MethodExitEvent(self, obj, method, dex_pc, value);
411 break;
412 }
413 case instrumentation::Instrumentation::kMethodUnwind:
414 instr->MethodUnwindEvent(self, obj, method, dex_pc);
415 break;
416 case instrumentation::Instrumentation::kDexPcMoved:
417 instr->DexPcMovedEvent(self, obj, method, dex_pc);
418 break;
419 case instrumentation::Instrumentation::kFieldRead:
Alex Lightd7661582017-05-01 13:48:16 -0700420 instr->FieldReadEvent(self, obj, method, dex_pc, field);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200421 break;
422 case instrumentation::Instrumentation::kFieldWritten: {
423 JValue value;
Alex Lightd7661582017-05-01 13:48:16 -0700424 instr->FieldWriteEvent(self, obj, method, dex_pc, field, value);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200425 break;
426 }
Alex Light6e1607e2017-08-23 10:06:18 -0700427 case instrumentation::Instrumentation::kExceptionThrown: {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200428 ThrowArithmeticExceptionDivideByZero();
429 mirror::Throwable* event_exception = self->GetException();
Alex Light6e1607e2017-08-23 10:06:18 -0700430 instr->ExceptionThrownEvent(self, event_exception);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200431 self->ClearException();
432 break;
433 }
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000434 case instrumentation::Instrumentation::kBranch:
435 instr->Branch(self, method, dex_pc, -1);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200436 break;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100437 case instrumentation::Instrumentation::kInvokeVirtualOrInterface:
438 instr->InvokeVirtualOrInterface(self, obj, method, dex_pc, method);
439 break;
Alex Lighte814f9d2017-07-31 16:14:39 -0700440 case instrumentation::Instrumentation::kWatchedFramePop:
441 instr->WatchedFramePopped(self, frame);
442 break;
Alex Light9fb1ab12017-09-05 09:32:49 -0700443 case instrumentation::Instrumentation::kExceptionHandled: {
444 ThrowArithmeticExceptionDivideByZero();
445 mirror::Throwable* event_exception = self->GetException();
446 self->ClearException();
447 instr->ExceptionHandledEvent(self, event_exception);
448 break;
449 }
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200450 default:
451 LOG(FATAL) << "Unknown instrumentation event " << event_type;
452 UNREACHABLE();
453 }
454 }
455
456 static bool DidListenerReceiveEvent(const TestInstrumentationListener& listener,
Alex Lightd7661582017-05-01 13:48:16 -0700457 uint32_t event_type,
458 bool with_object) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200459 switch (event_type) {
460 case instrumentation::Instrumentation::kMethodEntered:
461 return listener.received_method_enter_event;
462 case instrumentation::Instrumentation::kMethodExited:
Alex Lightd7661582017-05-01 13:48:16 -0700463 return (!with_object && listener.received_method_exit_event) ||
464 (with_object && listener.received_method_exit_object_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200465 case instrumentation::Instrumentation::kMethodUnwind:
466 return listener.received_method_unwind_event;
467 case instrumentation::Instrumentation::kDexPcMoved:
468 return listener.received_dex_pc_moved_event;
469 case instrumentation::Instrumentation::kFieldRead:
470 return listener.received_field_read_event;
471 case instrumentation::Instrumentation::kFieldWritten:
Alex Lightd7661582017-05-01 13:48:16 -0700472 return (!with_object && listener.received_field_written_event) ||
473 (with_object && listener.received_field_written_object_event);
Alex Light6e1607e2017-08-23 10:06:18 -0700474 case instrumentation::Instrumentation::kExceptionThrown:
475 return listener.received_exception_thrown_event;
Alex Light9fb1ab12017-09-05 09:32:49 -0700476 case instrumentation::Instrumentation::kExceptionHandled:
477 return listener.received_exception_handled_event;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000478 case instrumentation::Instrumentation::kBranch:
479 return listener.received_branch_event;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100480 case instrumentation::Instrumentation::kInvokeVirtualOrInterface:
481 return listener.received_invoke_virtual_or_interface_event;
Alex Lighte814f9d2017-07-31 16:14:39 -0700482 case instrumentation::Instrumentation::kWatchedFramePop:
483 return listener.received_watched_frame_pop;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200484 default:
485 LOG(FATAL) << "Unknown instrumentation event " << event_type;
486 UNREACHABLE();
487 }
488 }
489};
490
491TEST_F(InstrumentationTest, NoInstrumentation) {
492 ScopedObjectAccess soa(Thread::Current());
493 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
494 ASSERT_NE(instr, nullptr);
495
496 EXPECT_FALSE(instr->AreExitStubsInstalled());
497 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
498 EXPECT_FALSE(instr->IsActive());
499 EXPECT_FALSE(instr->ShouldNotifyMethodEnterExitEvents());
500
501 // Test interpreter table is the default one.
502 EXPECT_EQ(instrumentation::kMainHandlerTable, instr->GetInterpreterHandlerTable());
503
504 // Check there is no registered listener.
505 EXPECT_FALSE(instr->HasDexPcListeners());
Alex Light6e1607e2017-08-23 10:06:18 -0700506 EXPECT_FALSE(instr->HasExceptionThrownListeners());
Alex Light9fb1ab12017-09-05 09:32:49 -0700507 EXPECT_FALSE(instr->HasExceptionHandledListeners());
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200508 EXPECT_FALSE(instr->HasFieldReadListeners());
509 EXPECT_FALSE(instr->HasFieldWriteListeners());
510 EXPECT_FALSE(instr->HasMethodEntryListeners());
511 EXPECT_FALSE(instr->HasMethodExitListeners());
512 EXPECT_FALSE(instr->IsActive());
513}
514
515// Test instrumentation listeners for each event.
516TEST_F(InstrumentationTest, MethodEntryEvent) {
Mingyao Yang2ee17902017-08-30 11:37:08 -0700517 ScopedObjectAccess soa(Thread::Current());
518 jobject class_loader = LoadDex("Instrumentation");
519 Runtime* const runtime = Runtime::Current();
520 ClassLinker* class_linker = runtime->GetClassLinker();
521 StackHandleScope<1> hs(soa.Self());
522 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
523 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
524 ASSERT_TRUE(klass != nullptr);
525 ArtMethod* method =
526 klass->FindClassMethod("returnReference", "()Ljava/lang/Object;", kRuntimePointerSize);
527 ASSERT_TRUE(method != nullptr);
528 ASSERT_TRUE(method->IsDirect());
529 ASSERT_TRUE(method->GetDeclaringClass() == klass);
530 TestEvent(instrumentation::Instrumentation::kMethodEntered,
531 /*event_method*/ method,
532 /*event_field*/ nullptr,
533 /*with_object*/ true);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200534}
535
Alex Lightd7661582017-05-01 13:48:16 -0700536TEST_F(InstrumentationTest, MethodExitObjectEvent) {
537 ScopedObjectAccess soa(Thread::Current());
538 jobject class_loader = LoadDex("Instrumentation");
539 Runtime* const runtime = Runtime::Current();
540 ClassLinker* class_linker = runtime->GetClassLinker();
541 StackHandleScope<1> hs(soa.Self());
542 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
543 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
544 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100545 ArtMethod* method =
546 klass->FindClassMethod("returnReference", "()Ljava/lang/Object;", kRuntimePointerSize);
Alex Lightd7661582017-05-01 13:48:16 -0700547 ASSERT_TRUE(method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100548 ASSERT_TRUE(method->IsDirect());
549 ASSERT_TRUE(method->GetDeclaringClass() == klass);
Alex Lightd7661582017-05-01 13:48:16 -0700550 TestEvent(instrumentation::Instrumentation::kMethodExited,
551 /*event_method*/ method,
552 /*event_field*/ nullptr,
553 /*with_object*/ true);
554}
555
556TEST_F(InstrumentationTest, MethodExitPrimEvent) {
557 ScopedObjectAccess soa(Thread::Current());
558 jobject class_loader = LoadDex("Instrumentation");
559 Runtime* const runtime = Runtime::Current();
560 ClassLinker* class_linker = runtime->GetClassLinker();
561 StackHandleScope<1> hs(soa.Self());
562 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
563 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
564 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100565 ArtMethod* method = klass->FindClassMethod("returnPrimitive", "()I", kRuntimePointerSize);
Alex Lightd7661582017-05-01 13:48:16 -0700566 ASSERT_TRUE(method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100567 ASSERT_TRUE(method->IsDirect());
568 ASSERT_TRUE(method->GetDeclaringClass() == klass);
Alex Lightd7661582017-05-01 13:48:16 -0700569 TestEvent(instrumentation::Instrumentation::kMethodExited,
570 /*event_method*/ method,
571 /*event_field*/ nullptr,
572 /*with_object*/ false);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200573}
574
575TEST_F(InstrumentationTest, MethodUnwindEvent) {
576 TestEvent(instrumentation::Instrumentation::kMethodUnwind);
577}
578
579TEST_F(InstrumentationTest, DexPcMovedEvent) {
580 TestEvent(instrumentation::Instrumentation::kDexPcMoved);
581}
582
583TEST_F(InstrumentationTest, FieldReadEvent) {
584 TestEvent(instrumentation::Instrumentation::kFieldRead);
585}
586
Alex Lighte814f9d2017-07-31 16:14:39 -0700587TEST_F(InstrumentationTest, WatchedFramePop) {
588 TestEvent(instrumentation::Instrumentation::kWatchedFramePop);
589}
590
Alex Lightd7661582017-05-01 13:48:16 -0700591TEST_F(InstrumentationTest, FieldWriteObjectEvent) {
592 ScopedObjectAccess soa(Thread::Current());
593 jobject class_loader = LoadDex("Instrumentation");
594 Runtime* const runtime = Runtime::Current();
595 ClassLinker* class_linker = runtime->GetClassLinker();
596 StackHandleScope<1> hs(soa.Self());
597 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
598 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
599 ASSERT_TRUE(klass != nullptr);
600 ArtField* field = klass->FindDeclaredStaticField("referenceField", "Ljava/lang/Object;");
601 ASSERT_TRUE(field != nullptr);
602
603 TestEvent(instrumentation::Instrumentation::kFieldWritten,
604 /*event_method*/ nullptr,
605 /*event_field*/ field,
606 /*with_object*/ true);
607}
608
609TEST_F(InstrumentationTest, FieldWritePrimEvent) {
610 ScopedObjectAccess soa(Thread::Current());
611 jobject class_loader = LoadDex("Instrumentation");
612 Runtime* const runtime = Runtime::Current();
613 ClassLinker* class_linker = runtime->GetClassLinker();
614 StackHandleScope<1> hs(soa.Self());
615 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
616 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
617 ASSERT_TRUE(klass != nullptr);
618 ArtField* field = klass->FindDeclaredStaticField("primitiveField", "I");
619 ASSERT_TRUE(field != nullptr);
620
621 TestEvent(instrumentation::Instrumentation::kFieldWritten,
622 /*event_method*/ nullptr,
623 /*event_field*/ field,
624 /*with_object*/ false);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200625}
626
Alex Light9fb1ab12017-09-05 09:32:49 -0700627TEST_F(InstrumentationTest, ExceptionHandledEvent) {
628 TestEvent(instrumentation::Instrumentation::kExceptionHandled);
629}
630
Alex Light6e1607e2017-08-23 10:06:18 -0700631TEST_F(InstrumentationTest, ExceptionThrownEvent) {
632 TestEvent(instrumentation::Instrumentation::kExceptionThrown);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200633}
634
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000635TEST_F(InstrumentationTest, BranchEvent) {
636 TestEvent(instrumentation::Instrumentation::kBranch);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200637}
638
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100639TEST_F(InstrumentationTest, InvokeVirtualOrInterfaceEvent) {
640 TestEvent(instrumentation::Instrumentation::kInvokeVirtualOrInterface);
641}
642
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200643TEST_F(InstrumentationTest, DeoptimizeDirectMethod) {
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
664 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
665 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700666 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200667
668 constexpr const char* instrumentation_key = "DeoptimizeDirectMethod";
669 UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
670
671 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700672 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200673}
674
675TEST_F(InstrumentationTest, FullDeoptimization) {
676 ScopedObjectAccess soa(Thread::Current());
677 Runtime* const runtime = Runtime::Current();
678 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
679 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
680
681 constexpr const char* instrumentation_key = "FullDeoptimization";
682 DeoptimizeEverything(soa.Self(), instrumentation_key, true);
683
684 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
685 EXPECT_TRUE(instr->AreExitStubsInstalled());
686
687 UndeoptimizeEverything(soa.Self(), instrumentation_key, true);
688
689 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
690}
691
692TEST_F(InstrumentationTest, MixedDeoptimization) {
693 ScopedObjectAccess soa(Thread::Current());
694 jobject class_loader = LoadDex("Instrumentation");
695 Runtime* const runtime = Runtime::Current();
696 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
697 ClassLinker* class_linker = runtime->GetClassLinker();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700698 StackHandleScope<1> hs(soa.Self());
Mathieu Chartier0795f232016-09-27 18:43:30 -0700699 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200700 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
701 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100702 ArtMethod* method_to_deoptimize =
703 klass->FindClassMethod("instanceMethod", "()V", kRuntimePointerSize);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700704 ASSERT_TRUE(method_to_deoptimize != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100705 ASSERT_TRUE(method_to_deoptimize->IsDirect());
706 ASSERT_TRUE(method_to_deoptimize->GetDeclaringClass() == klass);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200707
708 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700709 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200710
711 DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);
712 // Deoptimizing a method does not change instrumentation level.
713 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
714 GetCurrentInstrumentationLevel());
715 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
716 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700717 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200718
719 constexpr const char* instrumentation_key = "MixedDeoptimization";
720 DeoptimizeEverything(soa.Self(), instrumentation_key, false);
721 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
722 GetCurrentInstrumentationLevel());
723 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
724 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700725 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200726
727 UndeoptimizeEverything(soa.Self(), instrumentation_key, false);
728 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
729 GetCurrentInstrumentationLevel());
730 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
731 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700732 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200733
734 UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
735 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
736 GetCurrentInstrumentationLevel());
737 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700738 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200739}
740
741TEST_F(InstrumentationTest, MethodTracing_Interpreter) {
742 ScopedObjectAccess soa(Thread::Current());
743 Runtime* const runtime = Runtime::Current();
744 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
745 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
746
747 constexpr const char* instrumentation_key = "MethodTracing";
748 EnableMethodTracing(soa.Self(), instrumentation_key, true);
749 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
750 GetCurrentInstrumentationLevel());
751 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
752 EXPECT_TRUE(instr->AreExitStubsInstalled());
753
754 DisableMethodTracing(soa.Self(), instrumentation_key);
755 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
756 GetCurrentInstrumentationLevel());
757 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
758}
759
760TEST_F(InstrumentationTest, MethodTracing_InstrumentationEntryExitStubs) {
761 ScopedObjectAccess soa(Thread::Current());
762 Runtime* const runtime = Runtime::Current();
763 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
764 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
765
766 constexpr const char* instrumentation_key = "MethodTracing";
767 EnableMethodTracing(soa.Self(), instrumentation_key, false);
768 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
769 GetCurrentInstrumentationLevel());
770 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
771 EXPECT_TRUE(instr->AreExitStubsInstalled());
772
773 DisableMethodTracing(soa.Self(), instrumentation_key);
774 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
775 GetCurrentInstrumentationLevel());
776 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
777}
778
779// We use a macro to print the line number where the test is failing.
780#define CHECK_INSTRUMENTATION(_level, _user_count) \
781 do { \
782 Instrumentation* const instr = Runtime::Current()->GetInstrumentation(); \
783 bool interpreter = \
Chih-Hung Hsieh1a0de6a2016-08-26 15:06:11 -0700784 ((_level) == Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter); \
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200785 EXPECT_EQ(_level, GetCurrentInstrumentationLevel()); \
786 EXPECT_EQ(_user_count, GetInstrumentationUserCount()); \
787 if (instr->IsForcedInterpretOnly()) { \
788 EXPECT_TRUE(instr->InterpretOnly()); \
789 } else if (interpreter) { \
790 EXPECT_TRUE(instr->InterpretOnly()); \
791 } else { \
792 EXPECT_FALSE(instr->InterpretOnly()); \
793 } \
794 if (interpreter) { \
795 EXPECT_TRUE(instr->AreAllMethodsDeoptimized()); \
796 } else { \
797 EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); \
798 } \
799 } while (false)
800
801TEST_F(InstrumentationTest, ConfigureStubs_Nothing) {
802 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
803
804 // Check no-op.
805 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
806 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
807}
808
809TEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubs) {
810 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
811
812 // Check we can switch to instrumentation stubs
813 CheckConfigureStubs(kClientOneKey,
814 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
815 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
816 1U);
817
818 // Check we can disable instrumentation.
819 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
820 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
821}
822
823TEST_F(InstrumentationTest, ConfigureStubs_Interpreter) {
824 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
825
826 // Check we can switch to interpreter
827 CheckConfigureStubs(kClientOneKey,
828 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
829 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
830
831 // Check we can disable instrumentation.
832 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
833 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
834}
835
836TEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubsToInterpreter) {
837 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
838
839 // Configure stubs with instrumentation stubs.
840 CheckConfigureStubs(kClientOneKey,
841 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
842 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
843 1U);
844
845 // Configure stubs with interpreter.
846 CheckConfigureStubs(kClientOneKey,
847 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
848 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
849
850 // Check we can disable instrumentation.
851 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
852 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
853}
854
855TEST_F(InstrumentationTest, ConfigureStubs_InterpreterToInstrumentationStubs) {
856 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
857
858 // Configure stubs with interpreter.
859 CheckConfigureStubs(kClientOneKey,
860 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
861 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
862
863 // Configure stubs with instrumentation stubs.
864 CheckConfigureStubs(kClientOneKey,
865 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
866 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
867 1U);
868
869 // Check we can disable instrumentation.
870 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
871 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
872}
873
874TEST_F(InstrumentationTest,
875 ConfigureStubs_InstrumentationStubsToInterpreterToInstrumentationStubs) {
876 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
877
878 // Configure stubs with instrumentation stubs.
879 CheckConfigureStubs(kClientOneKey,
880 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
881 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
882 1U);
883
884 // Configure stubs with interpreter.
885 CheckConfigureStubs(kClientOneKey,
886 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
887 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
888
889 // Configure stubs with instrumentation stubs again.
890 CheckConfigureStubs(kClientOneKey,
891 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
892 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
893 1U);
894
895 // Check we can disable instrumentation.
896 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
897 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
898}
899
900TEST_F(InstrumentationTest, MultiConfigureStubs_Nothing) {
901 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
902
903 // Check kInstrumentNothing with two clients.
904 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
905 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
906
907 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
908 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
909}
910
911TEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubs) {
912 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
913
914 // Configure stubs with instrumentation stubs for 1st client.
915 CheckConfigureStubs(kClientOneKey,
916 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
917 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
918 1U);
919
920 // Configure stubs with instrumentation stubs for 2nd client.
921 CheckConfigureStubs(kClientTwoKey,
922 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
923 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
924 2U);
925
926 // 1st client requests instrumentation deactivation but 2nd client still needs
927 // instrumentation stubs.
928 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
929 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
930 1U);
931
932 // 2nd client requests instrumentation deactivation
933 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
934 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
935}
936
937TEST_F(InstrumentationTest, MultiConfigureStubs_Interpreter) {
938 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
939
940 // Configure stubs with interpreter for 1st client.
941 CheckConfigureStubs(kClientOneKey,
942 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
943 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
944
945 // Configure stubs with interpreter for 2nd client.
946 CheckConfigureStubs(kClientTwoKey,
947 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
948 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
949
950 // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
951 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
952 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
953
954 // 2nd client requests instrumentation deactivation
955 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
956 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
957}
958
959TEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubsThenInterpreter) {
960 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
961
962 // Configure stubs with instrumentation stubs for 1st client.
963 CheckConfigureStubs(kClientOneKey,
964 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
965 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
966 1U);
967
968 // Configure stubs with interpreter for 2nd client.
969 CheckConfigureStubs(kClientTwoKey,
970 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
971 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
972
973 // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
974 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
975 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
976
977 // 2nd client requests instrumentation deactivation
978 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
979 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
980}
981
982TEST_F(InstrumentationTest, MultiConfigureStubs_InterpreterThenInstrumentationStubs) {
983 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
984
985 // Configure stubs with interpreter for 1st client.
986 CheckConfigureStubs(kClientOneKey,
987 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
988 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
989
990 // Configure stubs with instrumentation stubs for 2nd client.
991 CheckConfigureStubs(kClientTwoKey,
992 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
993 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
994
995 // 1st client requests instrumentation deactivation but 2nd client still needs
996 // instrumentation stubs.
997 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
998 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
999 1U);
1000
1001 // 2nd client requests instrumentation deactivation
1002 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
1003 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
1004}
1005
1006} // namespace instrumentation
1007} // namespace art