blob: bf74816f2417819de0fe3d3a18833ecab026a2d9 [file] [log] [blame]
Andreas Gampe04bbb5b2017-01-19 17:49:03 +00001/*
2 * Copyright (C) 2017 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 "runtime_callbacks.h"
18
19#include <algorithm>
20
Alex Lightd78ddec2017-04-18 15:20:38 -070021#include "art_method.h"
Andreas Gampea5814f92017-01-18 21:43:16 -080022#include "base/macros.h"
Andreas Gampe0f01b582017-01-18 15:22:37 -080023#include "class_linker.h"
Alex Light77fee872017-09-05 14:51:49 -070024#include "monitor.h"
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000025#include "thread.h"
26
27namespace art {
28
Andreas Gampea5814f92017-01-18 21:43:16 -080029template <typename T>
30ALWAYS_INLINE
31static inline void Remove(T* cb, std::vector<T*>* data) {
32 auto it = std::find(data->begin(), data->end(), cb);
33 if (it != data->end()) {
34 data->erase(it);
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000035 }
36}
37
Alex Light8c2b9292017-11-09 13:21:01 -080038void RuntimeCallbacks::AddDdmCallback(DdmCallback* cb) {
39 ddm_callbacks_.push_back(cb);
40}
41
42void RuntimeCallbacks::RemoveDdmCallback(DdmCallback* cb) {
43 Remove(cb, &ddm_callbacks_);
44}
45
46void RuntimeCallbacks::DdmPublishChunk(uint32_t type, const ArrayRef<const uint8_t>& data) {
47 for (DdmCallback* cb : ddm_callbacks_) {
48 cb->DdmPublishChunk(type, data);
49 }
50}
51
Alex Light40320712017-12-14 11:52:04 -080052void RuntimeCallbacks::AddDebuggerControlCallback(DebuggerControlCallback* cb) {
53 debugger_control_callbacks_.push_back(cb);
54}
55
56void RuntimeCallbacks::RemoveDebuggerControlCallback(DebuggerControlCallback* cb) {
57 Remove(cb, &debugger_control_callbacks_);
58}
59
60bool RuntimeCallbacks::IsDebuggerConfigured() {
61 for (DebuggerControlCallback* cb : debugger_control_callbacks_) {
62 if (cb->IsDebuggerConfigured()) {
63 return true;
64 }
65 }
66 return false;
67}
68
69void RuntimeCallbacks::StartDebugger() {
70 for (DebuggerControlCallback* cb : debugger_control_callbacks_) {
71 cb->StartDebugger();
72 }
73}
74
75void RuntimeCallbacks::StopDebugger() {
76 for (DebuggerControlCallback* cb : debugger_control_callbacks_) {
77 cb->StopDebugger();
78 }
79}
80
Alex Light21611932017-09-26 13:07:39 -070081void RuntimeCallbacks::AddMethodInspectionCallback(MethodInspectionCallback* cb) {
82 method_inspection_callbacks_.push_back(cb);
83}
84
85void RuntimeCallbacks::RemoveMethodInspectionCallback(MethodInspectionCallback* cb) {
86 Remove(cb, &method_inspection_callbacks_);
87}
88
Alex Light0fa17862017-10-24 13:43:05 -070089bool RuntimeCallbacks::IsMethodSafeToJit(ArtMethod* m) {
90 for (MethodInspectionCallback* cb : method_inspection_callbacks_) {
91 if (!cb->IsMethodSafeToJit(m)) {
92 DCHECK(cb->IsMethodBeingInspected(m))
93 << "Contract requires that !IsMethodSafeToJit(m) -> IsMethodBeingInspected(m)";
94 return false;
95 }
96 }
97 return true;
98}
99
Alex Light21611932017-09-26 13:07:39 -0700100bool RuntimeCallbacks::IsMethodBeingInspected(ArtMethod* m) {
101 for (MethodInspectionCallback* cb : method_inspection_callbacks_) {
102 if (cb->IsMethodBeingInspected(m)) {
103 return true;
104 }
105 }
106 return false;
107}
108
Alex Lightf2858632018-04-02 11:28:50 -0700109bool RuntimeCallbacks::MethodNeedsDebugVersion(ArtMethod* m) {
110 for (MethodInspectionCallback* cb : method_inspection_callbacks_) {
111 if (cb->MethodNeedsDebugVersion(m)) {
112 return true;
113 }
114 }
115 return false;
116}
117
Alex Light21611932017-09-26 13:07:39 -0700118void RuntimeCallbacks::AddThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
119 thread_callbacks_.push_back(cb);
120}
121
Alex Light77fee872017-09-05 14:51:49 -0700122void RuntimeCallbacks::MonitorContendedLocking(Monitor* m) {
123 for (MonitorCallback* cb : monitor_callbacks_) {
124 cb->MonitorContendedLocking(m);
125 }
126}
127
128void RuntimeCallbacks::MonitorContendedLocked(Monitor* m) {
129 for (MonitorCallback* cb : monitor_callbacks_) {
130 cb->MonitorContendedLocked(m);
131 }
132}
133
134void RuntimeCallbacks::ObjectWaitStart(Handle<mirror::Object> m, int64_t timeout) {
135 for (MonitorCallback* cb : monitor_callbacks_) {
136 cb->ObjectWaitStart(m, timeout);
137 }
138}
139
140void RuntimeCallbacks::MonitorWaitFinished(Monitor* m, bool timeout) {
141 for (MonitorCallback* cb : monitor_callbacks_) {
142 cb->MonitorWaitFinished(m, timeout);
143 }
144}
145
146void RuntimeCallbacks::AddMonitorCallback(MonitorCallback* cb) {
147 monitor_callbacks_.push_back(cb);
148}
149
150void RuntimeCallbacks::RemoveMonitorCallback(MonitorCallback* cb) {
151 Remove(cb, &monitor_callbacks_);
152}
153
Charles Munger5cc0e752018-11-09 12:30:46 -0800154void RuntimeCallbacks::ThreadParkStart(bool is_absolute, int64_t timeout) {
155 for (ParkCallback * cb : park_callbacks_) {
156 cb->ThreadParkStart(is_absolute, timeout);
157 }
158}
159
160void RuntimeCallbacks::ThreadParkFinished(bool timeout) {
161 for (ParkCallback * cb : park_callbacks_) {
162 cb->ThreadParkFinished(timeout);
163 }
164}
165
166void RuntimeCallbacks::AddParkCallback(ParkCallback* cb) {
167 park_callbacks_.push_back(cb);
168}
169
170void RuntimeCallbacks::RemoveParkCallback(ParkCallback* cb) {
171 Remove(cb, &park_callbacks_);
172}
173
Andreas Gampea5814f92017-01-18 21:43:16 -0800174void RuntimeCallbacks::RemoveThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
175 Remove(cb, &thread_callbacks_);
176}
177
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000178void RuntimeCallbacks::ThreadStart(Thread* self) {
179 for (ThreadLifecycleCallback* cb : thread_callbacks_) {
180 cb->ThreadStart(self);
181 }
182}
183
184void RuntimeCallbacks::ThreadDeath(Thread* self) {
185 for (ThreadLifecycleCallback* cb : thread_callbacks_) {
186 cb->ThreadDeath(self);
187 }
188}
189
Andreas Gampe0f01b582017-01-18 15:22:37 -0800190void RuntimeCallbacks::AddClassLoadCallback(ClassLoadCallback* cb) {
191 class_callbacks_.push_back(cb);
192}
193
194void RuntimeCallbacks::RemoveClassLoadCallback(ClassLoadCallback* cb) {
Andreas Gampea5814f92017-01-18 21:43:16 -0800195 Remove(cb, &class_callbacks_);
Andreas Gampe0f01b582017-01-18 15:22:37 -0800196}
197
198void RuntimeCallbacks::ClassLoad(Handle<mirror::Class> klass) {
199 for (ClassLoadCallback* cb : class_callbacks_) {
200 cb->ClassLoad(klass);
201 }
202}
203
Alex Lightb0f11922017-01-23 14:25:17 -0800204void RuntimeCallbacks::ClassPreDefine(const char* descriptor,
205 Handle<mirror::Class> temp_class,
206 Handle<mirror::ClassLoader> loader,
207 const DexFile& initial_dex_file,
208 const DexFile::ClassDef& initial_class_def,
209 /*out*/DexFile const** final_dex_file,
210 /*out*/DexFile::ClassDef const** final_class_def) {
211 DexFile const* current_dex_file = &initial_dex_file;
212 DexFile::ClassDef const* current_class_def = &initial_class_def;
213 for (ClassLoadCallback* cb : class_callbacks_) {
214 DexFile const* new_dex_file = nullptr;
215 DexFile::ClassDef const* new_class_def = nullptr;
216 cb->ClassPreDefine(descriptor,
217 temp_class,
218 loader,
219 *current_dex_file,
220 *current_class_def,
221 &new_dex_file,
222 &new_class_def);
223 if ((new_dex_file != nullptr && new_dex_file != current_dex_file) ||
224 (new_class_def != nullptr && new_class_def != current_class_def)) {
225 DCHECK(new_dex_file != nullptr && new_class_def != nullptr);
226 current_dex_file = new_dex_file;
227 current_class_def = new_class_def;
228 }
229 }
230 *final_dex_file = current_dex_file;
231 *final_class_def = current_class_def;
232}
233
Andreas Gampe0f01b582017-01-18 15:22:37 -0800234void RuntimeCallbacks::ClassPrepare(Handle<mirror::Class> temp_klass, Handle<mirror::Class> klass) {
235 for (ClassLoadCallback* cb : class_callbacks_) {
236 cb->ClassPrepare(temp_klass, klass);
237 }
238}
239
Andreas Gampea5814f92017-01-18 21:43:16 -0800240void RuntimeCallbacks::AddRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) {
241 sigquit_callbacks_.push_back(cb);
242}
243
244void RuntimeCallbacks::RemoveRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) {
245 Remove(cb, &sigquit_callbacks_);
246}
247
248void RuntimeCallbacks::SigQuit() {
249 for (RuntimeSigQuitCallback* cb : sigquit_callbacks_) {
250 cb->SigQuit();
251 }
252}
253
Andreas Gampe48864112017-01-19 17:23:17 -0800254void RuntimeCallbacks::AddRuntimePhaseCallback(RuntimePhaseCallback* cb) {
255 phase_callbacks_.push_back(cb);
256}
257
258void RuntimeCallbacks::RemoveRuntimePhaseCallback(RuntimePhaseCallback* cb) {
259 Remove(cb, &phase_callbacks_);
260}
261
262void RuntimeCallbacks::NextRuntimePhase(RuntimePhaseCallback::RuntimePhase phase) {
263 for (RuntimePhaseCallback* cb : phase_callbacks_) {
264 cb->NextRuntimePhase(phase);
265 }
266}
267
Alex Lightd78ddec2017-04-18 15:20:38 -0700268void RuntimeCallbacks::AddMethodCallback(MethodCallback* cb) {
269 method_callbacks_.push_back(cb);
270}
271
272void RuntimeCallbacks::RemoveMethodCallback(MethodCallback* cb) {
273 Remove(cb, &method_callbacks_);
274}
275
276void RuntimeCallbacks::RegisterNativeMethod(ArtMethod* method,
277 const void* in_cur_method,
278 /*out*/void** new_method) {
279 void* cur_method = const_cast<void*>(in_cur_method);
280 *new_method = cur_method;
281 for (MethodCallback* cb : method_callbacks_) {
282 cb->RegisterNativeMethod(method, cur_method, new_method);
283 if (*new_method != nullptr) {
284 cur_method = *new_method;
285 }
286 }
287}
288
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000289} // namespace art