blob: 1aa4e91eda78d199541d0455be708af2410e8a00 [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 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 Lightd7661582017-05-01 13:48:16 -070051 received_branch_event(false),
Alex Lighte814f9d2017-07-31 16:14:39 -070052 received_invoke_virtual_or_interface_event(false),
53 received_watched_frame_pop(false) {}
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020054
55 virtual ~TestInstrumentationListener() {}
56
57 void MethodEntered(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070058 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070059 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020060 uint32_t dex_pc ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070061 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020062 received_method_enter_event = true;
63 }
64
65 void MethodExited(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070066 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
67 ArtMethod* method ATTRIBUTE_UNUSED,
68 uint32_t dex_pc ATTRIBUTE_UNUSED,
69 Handle<mirror::Object> return_value ATTRIBUTE_UNUSED)
70 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
71 received_method_exit_object_event = true;
72 }
73
74 void MethodExited(Thread* thread ATTRIBUTE_UNUSED,
75 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070076 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020077 uint32_t dex_pc ATTRIBUTE_UNUSED,
78 const JValue& return_value ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070079 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020080 received_method_exit_event = true;
81 }
82
83 void MethodUnwind(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070084 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070085 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020086 uint32_t dex_pc ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070087 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020088 received_method_unwind_event = true;
89 }
90
91 void DexPcMoved(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -070092 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -070093 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020094 uint32_t new_dex_pc ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070095 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +020096 received_dex_pc_moved_event = true;
97 }
98
99 void FieldRead(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -0700100 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700101 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200102 uint32_t dex_pc ATTRIBUTE_UNUSED,
103 ArtField* field ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700104 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200105 received_field_read_event = true;
106 }
107
108 void FieldWritten(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -0700109 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
110 ArtMethod* method ATTRIBUTE_UNUSED,
111 uint32_t dex_pc ATTRIBUTE_UNUSED,
112 ArtField* field ATTRIBUTE_UNUSED,
113 Handle<mirror::Object> field_value ATTRIBUTE_UNUSED)
114 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
115 received_field_written_object_event = true;
116 }
117
118 void FieldWritten(Thread* thread ATTRIBUTE_UNUSED,
119 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700120 ArtMethod* method ATTRIBUTE_UNUSED,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200121 uint32_t dex_pc ATTRIBUTE_UNUSED,
122 ArtField* field ATTRIBUTE_UNUSED,
123 const JValue& field_value ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700124 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200125 received_field_written_event = true;
126 }
127
Alex Light6e1607e2017-08-23 10:06:18 -0700128 void ExceptionThrown(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -0700129 Handle<mirror::Throwable> exception_object ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700130 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Alex Light6e1607e2017-08-23 10:06:18 -0700131 received_exception_thrown_event = true;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200132 }
133
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000134 void Branch(Thread* thread ATTRIBUTE_UNUSED,
135 ArtMethod* method ATTRIBUTE_UNUSED,
136 uint32_t dex_pc ATTRIBUTE_UNUSED,
137 int32_t dex_pc_offset ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700138 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000139 received_branch_event = true;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200140 }
141
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100142 void InvokeVirtualOrInterface(Thread* thread ATTRIBUTE_UNUSED,
Alex Lightd7661582017-05-01 13:48:16 -0700143 Handle<mirror::Object> this_object ATTRIBUTE_UNUSED,
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100144 ArtMethod* caller ATTRIBUTE_UNUSED,
145 uint32_t dex_pc ATTRIBUTE_UNUSED,
146 ArtMethod* callee ATTRIBUTE_UNUSED)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700147 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100148 received_invoke_virtual_or_interface_event = true;
149 }
150
Alex Lighte814f9d2017-07-31 16:14:39 -0700151 void WatchedFramePop(Thread* thread ATTRIBUTE_UNUSED, const ShadowFrame& frame ATTRIBUTE_UNUSED)
152 OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
153 received_watched_frame_pop = true;
154 }
155
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200156 void Reset() {
157 received_method_enter_event = false;
158 received_method_exit_event = false;
Alex Lightd7661582017-05-01 13:48:16 -0700159 received_method_exit_object_event = false;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200160 received_method_unwind_event = false;
161 received_dex_pc_moved_event = false;
162 received_field_read_event = false;
163 received_field_written_event = false;
Alex Lightd7661582017-05-01 13:48:16 -0700164 received_field_written_object_event = false;
Alex Light6e1607e2017-08-23 10:06:18 -0700165 received_exception_thrown_event = false;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000166 received_branch_event = false;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100167 received_invoke_virtual_or_interface_event = false;
Alex Lighte814f9d2017-07-31 16:14:39 -0700168 received_watched_frame_pop = false;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200169 }
170
171 bool received_method_enter_event;
172 bool received_method_exit_event;
Alex Lightd7661582017-05-01 13:48:16 -0700173 bool received_method_exit_object_event;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200174 bool received_method_unwind_event;
175 bool received_dex_pc_moved_event;
176 bool received_field_read_event;
177 bool received_field_written_event;
Alex Lightd7661582017-05-01 13:48:16 -0700178 bool received_field_written_object_event;
Alex Light6e1607e2017-08-23 10:06:18 -0700179 bool received_exception_thrown_event;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000180 bool received_branch_event;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100181 bool received_invoke_virtual_or_interface_event;
Alex Lighte814f9d2017-07-31 16:14:39 -0700182 bool received_watched_frame_pop;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200183
184 private:
185 DISALLOW_COPY_AND_ASSIGN(TestInstrumentationListener);
186};
187
188class InstrumentationTest : public CommonRuntimeTest {
189 public:
190 // Unique keys used to test Instrumentation::ConfigureStubs.
191 static constexpr const char* kClientOneKey = "TestClient1";
192 static constexpr const char* kClientTwoKey = "TestClient2";
193
194 void CheckConfigureStubs(const char* key, Instrumentation::InstrumentationLevel level) {
195 ScopedObjectAccess soa(Thread::Current());
196 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700197 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700198 gc::ScopedGCCriticalSection gcs(soa.Self(),
199 gc::kGcCauseInstrumentation,
200 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700201 ScopedSuspendAll ssa("Instrumentation::ConfigureStubs");
202 instr->ConfigureStubs(key, level);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200203 }
204
205 Instrumentation::InstrumentationLevel GetCurrentInstrumentationLevel() {
206 return Runtime::Current()->GetInstrumentation()->GetCurrentInstrumentationLevel();
207 }
208
209 size_t GetInstrumentationUserCount() {
210 ScopedObjectAccess soa(Thread::Current());
211 return Runtime::Current()->GetInstrumentation()->requested_instrumentation_levels_.size();
212 }
213
214 void TestEvent(uint32_t instrumentation_event) {
Alex Lightd7661582017-05-01 13:48:16 -0700215 TestEvent(instrumentation_event, nullptr, nullptr, false);
216 }
217
218 void TestEvent(uint32_t instrumentation_event,
219 ArtMethod* event_method,
220 ArtField* event_field,
221 bool with_object) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200222 ScopedObjectAccess soa(Thread::Current());
223 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
224 TestInstrumentationListener listener;
225 {
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700226 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700227 ScopedSuspendAll ssa("Add instrumentation listener");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200228 instr->AddListener(&listener, instrumentation_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200229 }
230
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200231 mirror::Object* const event_obj = nullptr;
232 const uint32_t event_dex_pc = 0;
Alex Lighte814f9d2017-07-31 16:14:39 -0700233 ShadowFrameAllocaUniquePtr test_frame = CREATE_SHADOW_FRAME(0, nullptr, event_method, 0);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200234
235 // Check the listener is registered and is notified of the event.
236 EXPECT_TRUE(HasEventListener(instr, instrumentation_event));
Alex Lightd7661582017-05-01 13:48:16 -0700237 EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
238 ReportEvent(instr,
239 instrumentation_event,
240 soa.Self(),
241 event_method,
242 event_obj,
243 event_field,
Alex Lighte814f9d2017-07-31 16:14:39 -0700244 event_dex_pc,
245 *test_frame);
Alex Lightd7661582017-05-01 13:48:16 -0700246 EXPECT_TRUE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200247
248 listener.Reset();
249 {
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700250 ScopedThreadSuspension sts(soa.Self(), kSuspended);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700251 ScopedSuspendAll ssa("Remove instrumentation listener");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200252 instr->RemoveListener(&listener, instrumentation_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200253 }
254
255 // Check the listener is not registered and is not notified of the event.
256 EXPECT_FALSE(HasEventListener(instr, instrumentation_event));
Alex Lightd7661582017-05-01 13:48:16 -0700257 EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
258 ReportEvent(instr,
259 instrumentation_event,
260 soa.Self(),
261 event_method,
262 event_obj,
263 event_field,
Alex Lighte814f9d2017-07-31 16:14:39 -0700264 event_dex_pc,
265 *test_frame);
Alex Lightd7661582017-05-01 13:48:16 -0700266 EXPECT_FALSE(DidListenerReceiveEvent(listener, instrumentation_event, with_object));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200267 }
268
Mathieu Chartiere401d142015-04-22 13:56:20 -0700269 void DeoptimizeMethod(Thread* self, ArtMethod* method, bool enable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700270 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200271 Runtime* runtime = Runtime::Current();
272 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700273 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700274 gc::ScopedGCCriticalSection gcs(self,
275 gc::kGcCauseInstrumentation,
276 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700277 ScopedSuspendAll ssa("Single method deoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200278 if (enable_deoptimization) {
279 instrumentation->EnableDeoptimization();
280 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700281 instrumentation->Deoptimize(method);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200282 }
283
Mathieu Chartiere401d142015-04-22 13:56:20 -0700284 void UndeoptimizeMethod(Thread* self, ArtMethod* method,
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200285 const char* key, bool disable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700286 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200287 Runtime* runtime = Runtime::Current();
288 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700289 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700290 gc::ScopedGCCriticalSection gcs(self,
291 gc::kGcCauseInstrumentation,
292 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700293 ScopedSuspendAll ssa("Single method undeoptimization");
Mathieu Chartiere401d142015-04-22 13:56:20 -0700294 instrumentation->Undeoptimize(method);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200295 if (disable_deoptimization) {
296 instrumentation->DisableDeoptimization(key);
297 }
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200298 }
299
300 void DeoptimizeEverything(Thread* self, const char* key, bool enable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700301 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200302 Runtime* runtime = Runtime::Current();
303 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700304 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700305 gc::ScopedGCCriticalSection gcs(self,
306 gc::kGcCauseInstrumentation,
307 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700308 ScopedSuspendAll ssa("Full deoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200309 if (enable_deoptimization) {
310 instrumentation->EnableDeoptimization();
311 }
312 instrumentation->DeoptimizeEverything(key);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200313 }
314
315 void UndeoptimizeEverything(Thread* self, const char* key, bool disable_deoptimization)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700316 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200317 Runtime* runtime = Runtime::Current();
318 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700319 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700320 gc::ScopedGCCriticalSection gcs(self,
321 gc::kGcCauseInstrumentation,
322 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700323 ScopedSuspendAll ssa("Full undeoptimization");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200324 instrumentation->UndeoptimizeEverything(key);
325 if (disable_deoptimization) {
326 instrumentation->DisableDeoptimization(key);
327 }
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200328 }
329
330 void EnableMethodTracing(Thread* self, const char* key, bool needs_interpreter)
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->EnableMethodTracing(key, needs_interpreter);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200340 }
341
342 void DisableMethodTracing(Thread* self, const char* key)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700343 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200344 Runtime* runtime = Runtime::Current();
345 instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
Mathieu Chartierf1d666e2015-09-03 16:13:34 -0700346 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartieraa516822015-10-02 15:53:37 -0700347 gc::ScopedGCCriticalSection gcs(self,
348 gc::kGcCauseInstrumentation,
349 gc::kCollectorTypeInstrumentation);
Mathieu Chartier4f55e222015-09-04 13:26:21 -0700350 ScopedSuspendAll ssa("EnableMethodTracing");
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200351 instrumentation->DisableMethodTracing(key);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200352 }
353
354 private:
355 static bool HasEventListener(const instrumentation::Instrumentation* instr, uint32_t event_type)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700356 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200357 switch (event_type) {
358 case instrumentation::Instrumentation::kMethodEntered:
359 return instr->HasMethodEntryListeners();
360 case instrumentation::Instrumentation::kMethodExited:
361 return instr->HasMethodExitListeners();
362 case instrumentation::Instrumentation::kMethodUnwind:
363 return instr->HasMethodUnwindListeners();
364 case instrumentation::Instrumentation::kDexPcMoved:
365 return instr->HasDexPcListeners();
366 case instrumentation::Instrumentation::kFieldRead:
367 return instr->HasFieldReadListeners();
368 case instrumentation::Instrumentation::kFieldWritten:
369 return instr->HasFieldWriteListeners();
Alex Light6e1607e2017-08-23 10:06:18 -0700370 case instrumentation::Instrumentation::kExceptionThrown:
371 return instr->HasExceptionThrownListeners();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000372 case instrumentation::Instrumentation::kBranch:
373 return instr->HasBranchListeners();
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100374 case instrumentation::Instrumentation::kInvokeVirtualOrInterface:
375 return instr->HasInvokeVirtualOrInterfaceListeners();
Alex Lighte814f9d2017-07-31 16:14:39 -0700376 case instrumentation::Instrumentation::kWatchedFramePop:
377 return instr->HasWatchedFramePopListeners();
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200378 default:
379 LOG(FATAL) << "Unknown instrumentation event " << event_type;
380 UNREACHABLE();
381 }
382 }
383
Alex Lightd7661582017-05-01 13:48:16 -0700384 static void ReportEvent(const instrumentation::Instrumentation* instr,
385 uint32_t event_type,
386 Thread* self,
387 ArtMethod* method,
388 mirror::Object* obj,
389 ArtField* field,
Alex Lighte814f9d2017-07-31 16:14:39 -0700390 uint32_t dex_pc,
391 const ShadowFrame& frame)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700392 REQUIRES_SHARED(Locks::mutator_lock_) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200393 switch (event_type) {
394 case instrumentation::Instrumentation::kMethodEntered:
395 instr->MethodEnterEvent(self, obj, method, dex_pc);
396 break;
397 case instrumentation::Instrumentation::kMethodExited: {
398 JValue value;
399 instr->MethodExitEvent(self, obj, method, dex_pc, value);
400 break;
401 }
402 case instrumentation::Instrumentation::kMethodUnwind:
403 instr->MethodUnwindEvent(self, obj, method, dex_pc);
404 break;
405 case instrumentation::Instrumentation::kDexPcMoved:
406 instr->DexPcMovedEvent(self, obj, method, dex_pc);
407 break;
408 case instrumentation::Instrumentation::kFieldRead:
Alex Lightd7661582017-05-01 13:48:16 -0700409 instr->FieldReadEvent(self, obj, method, dex_pc, field);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200410 break;
411 case instrumentation::Instrumentation::kFieldWritten: {
412 JValue value;
Alex Lightd7661582017-05-01 13:48:16 -0700413 instr->FieldWriteEvent(self, obj, method, dex_pc, field, value);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200414 break;
415 }
Alex Light6e1607e2017-08-23 10:06:18 -0700416 case instrumentation::Instrumentation::kExceptionThrown: {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200417 ThrowArithmeticExceptionDivideByZero();
418 mirror::Throwable* event_exception = self->GetException();
Alex Light6e1607e2017-08-23 10:06:18 -0700419 instr->ExceptionThrownEvent(self, event_exception);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200420 self->ClearException();
421 break;
422 }
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000423 case instrumentation::Instrumentation::kBranch:
424 instr->Branch(self, method, dex_pc, -1);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200425 break;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100426 case instrumentation::Instrumentation::kInvokeVirtualOrInterface:
427 instr->InvokeVirtualOrInterface(self, obj, method, dex_pc, method);
428 break;
Alex Lighte814f9d2017-07-31 16:14:39 -0700429 case instrumentation::Instrumentation::kWatchedFramePop:
430 instr->WatchedFramePopped(self, frame);
431 break;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200432 default:
433 LOG(FATAL) << "Unknown instrumentation event " << event_type;
434 UNREACHABLE();
435 }
436 }
437
438 static bool DidListenerReceiveEvent(const TestInstrumentationListener& listener,
Alex Lightd7661582017-05-01 13:48:16 -0700439 uint32_t event_type,
440 bool with_object) {
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200441 switch (event_type) {
442 case instrumentation::Instrumentation::kMethodEntered:
443 return listener.received_method_enter_event;
444 case instrumentation::Instrumentation::kMethodExited:
Alex Lightd7661582017-05-01 13:48:16 -0700445 return (!with_object && listener.received_method_exit_event) ||
446 (with_object && listener.received_method_exit_object_event);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200447 case instrumentation::Instrumentation::kMethodUnwind:
448 return listener.received_method_unwind_event;
449 case instrumentation::Instrumentation::kDexPcMoved:
450 return listener.received_dex_pc_moved_event;
451 case instrumentation::Instrumentation::kFieldRead:
452 return listener.received_field_read_event;
453 case instrumentation::Instrumentation::kFieldWritten:
Alex Lightd7661582017-05-01 13:48:16 -0700454 return (!with_object && listener.received_field_written_event) ||
455 (with_object && listener.received_field_written_object_event);
Alex Light6e1607e2017-08-23 10:06:18 -0700456 case instrumentation::Instrumentation::kExceptionThrown:
457 return listener.received_exception_thrown_event;
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000458 case instrumentation::Instrumentation::kBranch:
459 return listener.received_branch_event;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100460 case instrumentation::Instrumentation::kInvokeVirtualOrInterface:
461 return listener.received_invoke_virtual_or_interface_event;
Alex Lighte814f9d2017-07-31 16:14:39 -0700462 case instrumentation::Instrumentation::kWatchedFramePop:
463 return listener.received_watched_frame_pop;
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200464 default:
465 LOG(FATAL) << "Unknown instrumentation event " << event_type;
466 UNREACHABLE();
467 }
468 }
469};
470
471TEST_F(InstrumentationTest, NoInstrumentation) {
472 ScopedObjectAccess soa(Thread::Current());
473 instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation();
474 ASSERT_NE(instr, nullptr);
475
476 EXPECT_FALSE(instr->AreExitStubsInstalled());
477 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
478 EXPECT_FALSE(instr->IsActive());
479 EXPECT_FALSE(instr->ShouldNotifyMethodEnterExitEvents());
480
481 // Test interpreter table is the default one.
482 EXPECT_EQ(instrumentation::kMainHandlerTable, instr->GetInterpreterHandlerTable());
483
484 // Check there is no registered listener.
485 EXPECT_FALSE(instr->HasDexPcListeners());
Alex Light6e1607e2017-08-23 10:06:18 -0700486 EXPECT_FALSE(instr->HasExceptionThrownListeners());
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200487 EXPECT_FALSE(instr->HasFieldReadListeners());
488 EXPECT_FALSE(instr->HasFieldWriteListeners());
489 EXPECT_FALSE(instr->HasMethodEntryListeners());
490 EXPECT_FALSE(instr->HasMethodExitListeners());
491 EXPECT_FALSE(instr->IsActive());
492}
493
494// Test instrumentation listeners for each event.
495TEST_F(InstrumentationTest, MethodEntryEvent) {
Mingyao Yang2ee17902017-08-30 11:37:08 -0700496 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);
504 ArtMethod* method =
505 klass->FindClassMethod("returnReference", "()Ljava/lang/Object;", kRuntimePointerSize);
506 ASSERT_TRUE(method != nullptr);
507 ASSERT_TRUE(method->IsDirect());
508 ASSERT_TRUE(method->GetDeclaringClass() == klass);
509 TestEvent(instrumentation::Instrumentation::kMethodEntered,
510 /*event_method*/ method,
511 /*event_field*/ nullptr,
512 /*with_object*/ true);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200513}
514
Alex Lightd7661582017-05-01 13:48:16 -0700515TEST_F(InstrumentationTest, MethodExitObjectEvent) {
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 =
525 klass->FindClassMethod("returnReference", "()Ljava/lang/Object;", kRuntimePointerSize);
Alex Lightd7661582017-05-01 13:48:16 -0700526 ASSERT_TRUE(method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100527 ASSERT_TRUE(method->IsDirect());
528 ASSERT_TRUE(method->GetDeclaringClass() == klass);
Alex Lightd7661582017-05-01 13:48:16 -0700529 TestEvent(instrumentation::Instrumentation::kMethodExited,
530 /*event_method*/ method,
531 /*event_field*/ nullptr,
532 /*with_object*/ true);
533}
534
535TEST_F(InstrumentationTest, MethodExitPrimEvent) {
536 ScopedObjectAccess soa(Thread::Current());
537 jobject class_loader = LoadDex("Instrumentation");
538 Runtime* const runtime = Runtime::Current();
539 ClassLinker* class_linker = runtime->GetClassLinker();
540 StackHandleScope<1> hs(soa.Self());
541 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
542 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
543 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100544 ArtMethod* method = klass->FindClassMethod("returnPrimitive", "()I", kRuntimePointerSize);
Alex Lightd7661582017-05-01 13:48:16 -0700545 ASSERT_TRUE(method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100546 ASSERT_TRUE(method->IsDirect());
547 ASSERT_TRUE(method->GetDeclaringClass() == klass);
Alex Lightd7661582017-05-01 13:48:16 -0700548 TestEvent(instrumentation::Instrumentation::kMethodExited,
549 /*event_method*/ method,
550 /*event_field*/ nullptr,
551 /*with_object*/ false);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200552}
553
554TEST_F(InstrumentationTest, MethodUnwindEvent) {
555 TestEvent(instrumentation::Instrumentation::kMethodUnwind);
556}
557
558TEST_F(InstrumentationTest, DexPcMovedEvent) {
559 TestEvent(instrumentation::Instrumentation::kDexPcMoved);
560}
561
562TEST_F(InstrumentationTest, FieldReadEvent) {
563 TestEvent(instrumentation::Instrumentation::kFieldRead);
564}
565
Alex Lighte814f9d2017-07-31 16:14:39 -0700566TEST_F(InstrumentationTest, WatchedFramePop) {
567 TestEvent(instrumentation::Instrumentation::kWatchedFramePop);
568}
569
Alex Lightd7661582017-05-01 13:48:16 -0700570TEST_F(InstrumentationTest, FieldWriteObjectEvent) {
571 ScopedObjectAccess soa(Thread::Current());
572 jobject class_loader = LoadDex("Instrumentation");
573 Runtime* const runtime = Runtime::Current();
574 ClassLinker* class_linker = runtime->GetClassLinker();
575 StackHandleScope<1> hs(soa.Self());
576 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
577 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
578 ASSERT_TRUE(klass != nullptr);
579 ArtField* field = klass->FindDeclaredStaticField("referenceField", "Ljava/lang/Object;");
580 ASSERT_TRUE(field != nullptr);
581
582 TestEvent(instrumentation::Instrumentation::kFieldWritten,
583 /*event_method*/ nullptr,
584 /*event_field*/ field,
585 /*with_object*/ true);
586}
587
588TEST_F(InstrumentationTest, FieldWritePrimEvent) {
589 ScopedObjectAccess soa(Thread::Current());
590 jobject class_loader = LoadDex("Instrumentation");
591 Runtime* const runtime = Runtime::Current();
592 ClassLinker* class_linker = runtime->GetClassLinker();
593 StackHandleScope<1> hs(soa.Self());
594 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
595 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
596 ASSERT_TRUE(klass != nullptr);
597 ArtField* field = klass->FindDeclaredStaticField("primitiveField", "I");
598 ASSERT_TRUE(field != nullptr);
599
600 TestEvent(instrumentation::Instrumentation::kFieldWritten,
601 /*event_method*/ nullptr,
602 /*event_field*/ field,
603 /*with_object*/ false);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200604}
605
Alex Light6e1607e2017-08-23 10:06:18 -0700606TEST_F(InstrumentationTest, ExceptionThrownEvent) {
607 TestEvent(instrumentation::Instrumentation::kExceptionThrown);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200608}
609
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000610TEST_F(InstrumentationTest, BranchEvent) {
611 TestEvent(instrumentation::Instrumentation::kBranch);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200612}
613
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100614TEST_F(InstrumentationTest, InvokeVirtualOrInterfaceEvent) {
615 TestEvent(instrumentation::Instrumentation::kInvokeVirtualOrInterface);
616}
617
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200618TEST_F(InstrumentationTest, DeoptimizeDirectMethod) {
619 ScopedObjectAccess soa(Thread::Current());
620 jobject class_loader = LoadDex("Instrumentation");
621 Runtime* const runtime = Runtime::Current();
622 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
623 ClassLinker* class_linker = runtime->GetClassLinker();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700624 StackHandleScope<1> hs(soa.Self());
Mathieu Chartier0795f232016-09-27 18:43:30 -0700625 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200626 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
627 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100628 ArtMethod* method_to_deoptimize =
629 klass->FindClassMethod("instanceMethod", "()V", kRuntimePointerSize);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700630 ASSERT_TRUE(method_to_deoptimize != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100631 ASSERT_TRUE(method_to_deoptimize->IsDirect());
632 ASSERT_TRUE(method_to_deoptimize->GetDeclaringClass() == klass);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200633
634 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700635 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200636
637 DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);
638
639 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
640 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700641 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200642
643 constexpr const char* instrumentation_key = "DeoptimizeDirectMethod";
644 UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
645
646 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700647 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200648}
649
650TEST_F(InstrumentationTest, FullDeoptimization) {
651 ScopedObjectAccess soa(Thread::Current());
652 Runtime* const runtime = Runtime::Current();
653 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
654 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
655
656 constexpr const char* instrumentation_key = "FullDeoptimization";
657 DeoptimizeEverything(soa.Self(), instrumentation_key, true);
658
659 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
660 EXPECT_TRUE(instr->AreExitStubsInstalled());
661
662 UndeoptimizeEverything(soa.Self(), instrumentation_key, true);
663
664 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
665}
666
667TEST_F(InstrumentationTest, MixedDeoptimization) {
668 ScopedObjectAccess soa(Thread::Current());
669 jobject class_loader = LoadDex("Instrumentation");
670 Runtime* const runtime = Runtime::Current();
671 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
672 ClassLinker* class_linker = runtime->GetClassLinker();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700673 StackHandleScope<1> hs(soa.Self());
Mathieu Chartier0795f232016-09-27 18:43:30 -0700674 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200675 mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader);
676 ASSERT_TRUE(klass != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100677 ArtMethod* method_to_deoptimize =
678 klass->FindClassMethod("instanceMethod", "()V", kRuntimePointerSize);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700679 ASSERT_TRUE(method_to_deoptimize != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100680 ASSERT_TRUE(method_to_deoptimize->IsDirect());
681 ASSERT_TRUE(method_to_deoptimize->GetDeclaringClass() == klass);
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200682
683 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700684 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200685
686 DeoptimizeMethod(soa.Self(), method_to_deoptimize, true);
687 // Deoptimizing a method does not change instrumentation level.
688 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
689 GetCurrentInstrumentationLevel());
690 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
691 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700692 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200693
694 constexpr const char* instrumentation_key = "MixedDeoptimization";
695 DeoptimizeEverything(soa.Self(), instrumentation_key, false);
696 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
697 GetCurrentInstrumentationLevel());
698 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
699 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700700 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200701
702 UndeoptimizeEverything(soa.Self(), instrumentation_key, false);
703 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
704 GetCurrentInstrumentationLevel());
705 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
706 EXPECT_TRUE(instr->AreExitStubsInstalled());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700707 EXPECT_TRUE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200708
709 UndeoptimizeMethod(soa.Self(), method_to_deoptimize, instrumentation_key, true);
710 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
711 GetCurrentInstrumentationLevel());
712 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700713 EXPECT_FALSE(instr->IsDeoptimized(method_to_deoptimize));
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200714}
715
716TEST_F(InstrumentationTest, MethodTracing_Interpreter) {
717 ScopedObjectAccess soa(Thread::Current());
718 Runtime* const runtime = Runtime::Current();
719 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
720 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
721
722 constexpr const char* instrumentation_key = "MethodTracing";
723 EnableMethodTracing(soa.Self(), instrumentation_key, true);
724 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter,
725 GetCurrentInstrumentationLevel());
726 EXPECT_TRUE(instr->AreAllMethodsDeoptimized());
727 EXPECT_TRUE(instr->AreExitStubsInstalled());
728
729 DisableMethodTracing(soa.Self(), instrumentation_key);
730 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
731 GetCurrentInstrumentationLevel());
732 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
733}
734
735TEST_F(InstrumentationTest, MethodTracing_InstrumentationEntryExitStubs) {
736 ScopedObjectAccess soa(Thread::Current());
737 Runtime* const runtime = Runtime::Current();
738 instrumentation::Instrumentation* instr = runtime->GetInstrumentation();
739 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
740
741 constexpr const char* instrumentation_key = "MethodTracing";
742 EnableMethodTracing(soa.Self(), instrumentation_key, false);
743 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
744 GetCurrentInstrumentationLevel());
745 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
746 EXPECT_TRUE(instr->AreExitStubsInstalled());
747
748 DisableMethodTracing(soa.Self(), instrumentation_key);
749 EXPECT_EQ(Instrumentation::InstrumentationLevel::kInstrumentNothing,
750 GetCurrentInstrumentationLevel());
751 EXPECT_FALSE(instr->AreAllMethodsDeoptimized());
752}
753
754// We use a macro to print the line number where the test is failing.
755#define CHECK_INSTRUMENTATION(_level, _user_count) \
756 do { \
757 Instrumentation* const instr = Runtime::Current()->GetInstrumentation(); \
758 bool interpreter = \
Chih-Hung Hsieh1a0de6a2016-08-26 15:06:11 -0700759 ((_level) == Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter); \
Sebastien Hertz0462c4c2015-04-01 16:34:17 +0200760 EXPECT_EQ(_level, GetCurrentInstrumentationLevel()); \
761 EXPECT_EQ(_user_count, GetInstrumentationUserCount()); \
762 if (instr->IsForcedInterpretOnly()) { \
763 EXPECT_TRUE(instr->InterpretOnly()); \
764 } else if (interpreter) { \
765 EXPECT_TRUE(instr->InterpretOnly()); \
766 } else { \
767 EXPECT_FALSE(instr->InterpretOnly()); \
768 } \
769 if (interpreter) { \
770 EXPECT_TRUE(instr->AreAllMethodsDeoptimized()); \
771 } else { \
772 EXPECT_FALSE(instr->AreAllMethodsDeoptimized()); \
773 } \
774 } while (false)
775
776TEST_F(InstrumentationTest, ConfigureStubs_Nothing) {
777 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
778
779 // Check no-op.
780 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
781 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
782}
783
784TEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubs) {
785 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
786
787 // Check we can switch to instrumentation stubs
788 CheckConfigureStubs(kClientOneKey,
789 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
790 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
791 1U);
792
793 // Check we can disable instrumentation.
794 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
795 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
796}
797
798TEST_F(InstrumentationTest, ConfigureStubs_Interpreter) {
799 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
800
801 // Check we can switch to interpreter
802 CheckConfigureStubs(kClientOneKey,
803 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
804 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
805
806 // Check we can disable instrumentation.
807 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
808 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
809}
810
811TEST_F(InstrumentationTest, ConfigureStubs_InstrumentationStubsToInterpreter) {
812 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
813
814 // Configure stubs with instrumentation stubs.
815 CheckConfigureStubs(kClientOneKey,
816 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
817 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
818 1U);
819
820 // Configure stubs with interpreter.
821 CheckConfigureStubs(kClientOneKey,
822 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
823 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
824
825 // Check we can disable instrumentation.
826 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
827 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
828}
829
830TEST_F(InstrumentationTest, ConfigureStubs_InterpreterToInstrumentationStubs) {
831 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
832
833 // Configure stubs with interpreter.
834 CheckConfigureStubs(kClientOneKey,
835 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
836 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
837
838 // Configure stubs with instrumentation stubs.
839 CheckConfigureStubs(kClientOneKey,
840 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
841 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
842 1U);
843
844 // Check we can disable instrumentation.
845 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
846 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
847}
848
849TEST_F(InstrumentationTest,
850 ConfigureStubs_InstrumentationStubsToInterpreterToInstrumentationStubs) {
851 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
852
853 // Configure stubs with instrumentation stubs.
854 CheckConfigureStubs(kClientOneKey,
855 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
856 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
857 1U);
858
859 // Configure stubs with interpreter.
860 CheckConfigureStubs(kClientOneKey,
861 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
862 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
863
864 // Configure stubs with instrumentation stubs again.
865 CheckConfigureStubs(kClientOneKey,
866 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
867 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
868 1U);
869
870 // Check we can disable instrumentation.
871 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
872 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
873}
874
875TEST_F(InstrumentationTest, MultiConfigureStubs_Nothing) {
876 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
877
878 // Check kInstrumentNothing with two clients.
879 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
880 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
881
882 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
883 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
884}
885
886TEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubs) {
887 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
888
889 // Configure stubs with instrumentation stubs for 1st client.
890 CheckConfigureStubs(kClientOneKey,
891 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
892 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
893 1U);
894
895 // Configure stubs with instrumentation stubs for 2nd client.
896 CheckConfigureStubs(kClientTwoKey,
897 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
898 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
899 2U);
900
901 // 1st client requests instrumentation deactivation but 2nd client still needs
902 // instrumentation stubs.
903 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
904 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
905 1U);
906
907 // 2nd client requests instrumentation deactivation
908 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
909 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
910}
911
912TEST_F(InstrumentationTest, MultiConfigureStubs_Interpreter) {
913 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
914
915 // Configure stubs with interpreter for 1st client.
916 CheckConfigureStubs(kClientOneKey,
917 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
918 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
919
920 // Configure stubs with interpreter for 2nd client.
921 CheckConfigureStubs(kClientTwoKey,
922 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
923 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
924
925 // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
926 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
927 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
928
929 // 2nd client requests instrumentation deactivation
930 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
931 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
932}
933
934TEST_F(InstrumentationTest, MultiConfigureStubs_InstrumentationStubsThenInterpreter) {
935 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
936
937 // Configure stubs with instrumentation stubs for 1st client.
938 CheckConfigureStubs(kClientOneKey,
939 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
940 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
941 1U);
942
943 // Configure stubs with interpreter for 2nd client.
944 CheckConfigureStubs(kClientTwoKey,
945 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
946 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
947
948 // 1st client requests instrumentation deactivation but 2nd client still needs interpreter.
949 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
950 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
951
952 // 2nd client requests instrumentation deactivation
953 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
954 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
955}
956
957TEST_F(InstrumentationTest, MultiConfigureStubs_InterpreterThenInstrumentationStubs) {
958 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
959
960 // Configure stubs with interpreter for 1st client.
961 CheckConfigureStubs(kClientOneKey,
962 Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter);
963 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 1U);
964
965 // Configure stubs with instrumentation stubs for 2nd client.
966 CheckConfigureStubs(kClientTwoKey,
967 Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs);
968 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter, 2U);
969
970 // 1st client requests instrumentation deactivation but 2nd client still needs
971 // instrumentation stubs.
972 CheckConfigureStubs(kClientOneKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
973 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentWithInstrumentationStubs,
974 1U);
975
976 // 2nd client requests instrumentation deactivation
977 CheckConfigureStubs(kClientTwoKey, Instrumentation::InstrumentationLevel::kInstrumentNothing);
978 CHECK_INSTRUMENTATION(Instrumentation::InstrumentationLevel::kInstrumentNothing, 0U);
979}
980
981} // namespace instrumentation
982} // namespace art