1 /*
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
21 #include "art_method.h"
22 #include "base/macros.h"
23 #include "base/mutex-inl.h"
24 #include "class_linker.h"
25 #include "monitor.h"
26 #include "thread-current-inl.h"
27
28 namespace art HIDDEN {
29
RuntimeCallbacks()30 RuntimeCallbacks::RuntimeCallbacks()
31 : callback_lock_(new ReaderWriterMutex("Runtime callbacks lock",
32 LockLevel::kGenericBottomLock)) {}
33
34 // We don't want to be holding any locks when the actual event is called so we use this to define a
35 // helper that gets a copy of the current event list and returns it.
36 #define COPY(T) \
37 ([this]() -> decltype(this->T) { \
38 ReaderMutexLock mu(Thread::Current(), *this->callback_lock_); \
39 return std::vector<decltype(this->T)::value_type>(this->T); \
40 })()
41
42 template <typename T>
43 ALWAYS_INLINE
Remove(T * cb,std::vector<T * > * data)44 static inline void Remove(T* cb, std::vector<T*>* data) {
45 auto it = std::find(data->begin(), data->end(), cb);
46 if (it != data->end()) {
47 data->erase(it);
48 }
49 }
50
AddDdmCallback(DdmCallback * cb)51 void RuntimeCallbacks::AddDdmCallback(DdmCallback* cb) {
52 WriterMutexLock mu(Thread::Current(), *callback_lock_);
53 ddm_callbacks_.push_back(cb);
54 }
55
RemoveDdmCallback(DdmCallback * cb)56 void RuntimeCallbacks::RemoveDdmCallback(DdmCallback* cb) {
57 WriterMutexLock mu(Thread::Current(), *callback_lock_);
58 Remove(cb, &ddm_callbacks_);
59 }
60
AddAppInfoCallback(AppInfoCallback * cb)61 void RuntimeCallbacks::AddAppInfoCallback(AppInfoCallback* cb) {
62 WriterMutexLock mu(Thread::Current(), *callback_lock_);
63 appinfo_callbacks_.push_back(cb);
64 }
65
RemoveAppInfoCallback(AppInfoCallback * cb)66 void RuntimeCallbacks::RemoveAppInfoCallback(AppInfoCallback* cb) {
67 WriterMutexLock mu(Thread::Current(), *callback_lock_);
68 Remove(cb, &appinfo_callbacks_);
69 }
70
DdmPublishChunk(uint32_t type,const ArrayRef<const uint8_t> & data)71 void RuntimeCallbacks::DdmPublishChunk(uint32_t type, const ArrayRef<const uint8_t>& data) {
72 for (DdmCallback* cb : COPY(ddm_callbacks_)) {
73 cb->DdmPublishChunk(type, data);
74 }
75 }
76
SetCurrentProcessName(const std::string & process_name)77 void RuntimeCallbacks::SetCurrentProcessName(const std::string& process_name) {
78 for (AppInfoCallback* cb : COPY(appinfo_callbacks_)) {
79 cb->SetCurrentProcessName(process_name);
80 }
81 }
82
AddApplication(const std::string & package_name)83 void RuntimeCallbacks::AddApplication(const std::string& package_name) {
84 for (AppInfoCallback* cb : COPY(appinfo_callbacks_)) {
85 cb->AddApplication(package_name);
86 }
87 }
88
RemoveApplication(const std::string & package_name)89 void RuntimeCallbacks::RemoveApplication(const std::string& package_name) {
90 for (AppInfoCallback* cb : COPY(appinfo_callbacks_)) {
91 cb->RemoveApplication(package_name);
92 }
93 }
94
SetWaitingForDebugger(bool waiting)95 void RuntimeCallbacks::SetWaitingForDebugger(bool waiting) {
96 for (AppInfoCallback* cb : COPY(appinfo_callbacks_)) {
97 cb->SetWaitingForDebugger(waiting);
98 }
99 }
100
SetUserId(int user_id)101 void RuntimeCallbacks::SetUserId(int user_id) {
102 for (AppInfoCallback* cb : COPY(appinfo_callbacks_)) {
103 cb->SetUserId(user_id);
104 }
105 }
106
AddDebuggerControlCallback(DebuggerControlCallback * cb)107 void RuntimeCallbacks::AddDebuggerControlCallback(DebuggerControlCallback* cb) {
108 WriterMutexLock mu(Thread::Current(), *callback_lock_);
109 debugger_control_callbacks_.push_back(cb);
110 }
111
RemoveDebuggerControlCallback(DebuggerControlCallback * cb)112 void RuntimeCallbacks::RemoveDebuggerControlCallback(DebuggerControlCallback* cb) {
113 WriterMutexLock mu(Thread::Current(), *callback_lock_);
114 Remove(cb, &debugger_control_callbacks_);
115 }
116
IsDebuggerConfigured()117 bool RuntimeCallbacks::IsDebuggerConfigured() {
118 for (DebuggerControlCallback* cb : COPY(debugger_control_callbacks_)) {
119 if (cb->IsDebuggerConfigured()) {
120 return true;
121 }
122 }
123 return false;
124 }
125
StartDebugger()126 void RuntimeCallbacks::StartDebugger() {
127 for (DebuggerControlCallback* cb : COPY(debugger_control_callbacks_)) {
128 cb->StartDebugger();
129 }
130 }
131
StopDebugger()132 void RuntimeCallbacks::StopDebugger() {
133 for (DebuggerControlCallback* cb : COPY(debugger_control_callbacks_)) {
134 cb->StopDebugger();
135 }
136 }
137
AddMethodInspectionCallback(MethodInspectionCallback * cb)138 void RuntimeCallbacks::AddMethodInspectionCallback(MethodInspectionCallback* cb) {
139 WriterMutexLock mu(Thread::Current(), *callback_lock_);
140 method_inspection_callbacks_.push_back(cb);
141 }
142
RemoveMethodInspectionCallback(MethodInspectionCallback * cb)143 void RuntimeCallbacks::RemoveMethodInspectionCallback(MethodInspectionCallback* cb) {
144 WriterMutexLock mu(Thread::Current(), *callback_lock_);
145 Remove(cb, &method_inspection_callbacks_);
146 }
147
HaveLocalsChanged()148 bool RuntimeCallbacks::HaveLocalsChanged() {
149 for (MethodInspectionCallback* cb : COPY(method_inspection_callbacks_)) {
150 if (cb->HaveLocalsChanged()) {
151 return true;
152 }
153 }
154 return false;
155 }
156
AddThreadLifecycleCallback(ThreadLifecycleCallback * cb)157 void RuntimeCallbacks::AddThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
158 WriterMutexLock mu(Thread::Current(), *callback_lock_);
159 thread_callbacks_.push_back(cb);
160 }
161
MonitorContendedLocking(Monitor * m)162 void RuntimeCallbacks::MonitorContendedLocking(Monitor* m) {
163 for (MonitorCallback* cb : COPY(monitor_callbacks_)) {
164 cb->MonitorContendedLocking(m);
165 }
166 }
167
MonitorContendedLocked(Monitor * m)168 void RuntimeCallbacks::MonitorContendedLocked(Monitor* m) {
169 for (MonitorCallback* cb : COPY(monitor_callbacks_)) {
170 cb->MonitorContendedLocked(m);
171 }
172 }
173
ObjectWaitStart(Handle<mirror::Object> m,int64_t timeout)174 void RuntimeCallbacks::ObjectWaitStart(Handle<mirror::Object> m, int64_t timeout) {
175 for (MonitorCallback* cb : COPY(monitor_callbacks_)) {
176 cb->ObjectWaitStart(m, timeout);
177 }
178 }
179
MonitorWaitFinished(Monitor * m,bool timeout)180 void RuntimeCallbacks::MonitorWaitFinished(Monitor* m, bool timeout) {
181 for (MonitorCallback* cb : COPY(monitor_callbacks_)) {
182 cb->MonitorWaitFinished(m, timeout);
183 }
184 }
185
AddMonitorCallback(MonitorCallback * cb)186 void RuntimeCallbacks::AddMonitorCallback(MonitorCallback* cb) {
187 WriterMutexLock mu(Thread::Current(), *callback_lock_);
188 monitor_callbacks_.push_back(cb);
189 }
190
RemoveMonitorCallback(MonitorCallback * cb)191 void RuntimeCallbacks::RemoveMonitorCallback(MonitorCallback* cb) {
192 WriterMutexLock mu(Thread::Current(), *callback_lock_);
193 Remove(cb, &monitor_callbacks_);
194 }
195
ThreadParkStart(bool is_absolute,int64_t timeout)196 void RuntimeCallbacks::ThreadParkStart(bool is_absolute, int64_t timeout) {
197 for (ParkCallback * cb : COPY(park_callbacks_)) {
198 cb->ThreadParkStart(is_absolute, timeout);
199 }
200 }
201
ThreadParkFinished(bool timeout)202 void RuntimeCallbacks::ThreadParkFinished(bool timeout) {
203 for (ParkCallback * cb : COPY(park_callbacks_)) {
204 cb->ThreadParkFinished(timeout);
205 }
206 }
207
AddParkCallback(ParkCallback * cb)208 void RuntimeCallbacks::AddParkCallback(ParkCallback* cb) {
209 WriterMutexLock mu(Thread::Current(), *callback_lock_);
210 park_callbacks_.push_back(cb);
211 }
212
RemoveParkCallback(ParkCallback * cb)213 void RuntimeCallbacks::RemoveParkCallback(ParkCallback* cb) {
214 WriterMutexLock mu(Thread::Current(), *callback_lock_);
215 Remove(cb, &park_callbacks_);
216 }
217
RemoveThreadLifecycleCallback(ThreadLifecycleCallback * cb)218 void RuntimeCallbacks::RemoveThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
219 WriterMutexLock mu(Thread::Current(), *callback_lock_);
220 Remove(cb, &thread_callbacks_);
221 }
222
ThreadStart(Thread * self)223 void RuntimeCallbacks::ThreadStart(Thread* self) {
224 for (ThreadLifecycleCallback* cb : COPY(thread_callbacks_)) {
225 cb->ThreadStart(self);
226 }
227 }
228
ThreadDeath(Thread * self)229 void RuntimeCallbacks::ThreadDeath(Thread* self) {
230 for (ThreadLifecycleCallback* cb : COPY(thread_callbacks_)) {
231 cb->ThreadDeath(self);
232 }
233 }
234
AddClassLoadCallback(ClassLoadCallback * cb)235 void RuntimeCallbacks::AddClassLoadCallback(ClassLoadCallback* cb) {
236 WriterMutexLock mu(Thread::Current(), *callback_lock_);
237 class_callbacks_.push_back(cb);
238 }
239
RemoveClassLoadCallback(ClassLoadCallback * cb)240 void RuntimeCallbacks::RemoveClassLoadCallback(ClassLoadCallback* cb) {
241 WriterMutexLock mu(Thread::Current(), *callback_lock_);
242 Remove(cb, &class_callbacks_);
243 }
244
ClassLoad(Handle<mirror::Class> klass)245 void RuntimeCallbacks::ClassLoad(Handle<mirror::Class> klass) {
246 for (ClassLoadCallback* cb : COPY(class_callbacks_)) {
247 cb->ClassLoad(klass);
248 }
249 }
250
EndDefineClass()251 void RuntimeCallbacks::EndDefineClass() {
252 for (ClassLoadCallback* cb : COPY(class_callbacks_)) {
253 cb->EndDefineClass();
254 }
255 }
256
BeginDefineClass()257 void RuntimeCallbacks::BeginDefineClass() {
258 for (ClassLoadCallback* cb : COPY(class_callbacks_)) {
259 cb->BeginDefineClass();
260 }
261 }
262
263
ClassPreDefine(const char * descriptor,Handle<mirror::Class> temp_class,Handle<mirror::ClassLoader> loader,const DexFile & initial_dex_file,const dex::ClassDef & initial_class_def,DexFile const ** final_dex_file,dex::ClassDef const ** final_class_def)264 void RuntimeCallbacks::ClassPreDefine(const char* descriptor,
265 Handle<mirror::Class> temp_class,
266 Handle<mirror::ClassLoader> loader,
267 const DexFile& initial_dex_file,
268 const dex::ClassDef& initial_class_def,
269 /*out*/DexFile const** final_dex_file,
270 /*out*/dex::ClassDef const** final_class_def) {
271 DexFile const* current_dex_file = &initial_dex_file;
272 dex::ClassDef const* current_class_def = &initial_class_def;
273 for (ClassLoadCallback* cb : COPY(class_callbacks_)) {
274 DexFile const* new_dex_file = nullptr;
275 dex::ClassDef const* new_class_def = nullptr;
276 cb->ClassPreDefine(descriptor,
277 temp_class,
278 loader,
279 *current_dex_file,
280 *current_class_def,
281 &new_dex_file,
282 &new_class_def);
283 if ((new_dex_file != nullptr && new_dex_file != current_dex_file) ||
284 (new_class_def != nullptr && new_class_def != current_class_def)) {
285 DCHECK(new_dex_file != nullptr && new_class_def != nullptr);
286 current_dex_file = new_dex_file;
287 current_class_def = new_class_def;
288 }
289 }
290 *final_dex_file = current_dex_file;
291 *final_class_def = current_class_def;
292 }
293
ClassPrepare(Handle<mirror::Class> temp_klass,Handle<mirror::Class> klass)294 void RuntimeCallbacks::ClassPrepare(Handle<mirror::Class> temp_klass, Handle<mirror::Class> klass) {
295 for (ClassLoadCallback* cb : COPY(class_callbacks_)) {
296 cb->ClassPrepare(temp_klass, klass);
297 }
298 }
299
AddRuntimeSigQuitCallback(RuntimeSigQuitCallback * cb)300 void RuntimeCallbacks::AddRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) {
301 WriterMutexLock mu(Thread::Current(), *callback_lock_);
302 sigquit_callbacks_.push_back(cb);
303 }
304
RemoveRuntimeSigQuitCallback(RuntimeSigQuitCallback * cb)305 void RuntimeCallbacks::RemoveRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) {
306 WriterMutexLock mu(Thread::Current(), *callback_lock_);
307 Remove(cb, &sigquit_callbacks_);
308 }
309
SigQuit()310 void RuntimeCallbacks::SigQuit() {
311 for (RuntimeSigQuitCallback* cb : COPY(sigquit_callbacks_)) {
312 cb->SigQuit();
313 }
314 }
315
AddRuntimePhaseCallback(RuntimePhaseCallback * cb)316 void RuntimeCallbacks::AddRuntimePhaseCallback(RuntimePhaseCallback* cb) {
317 WriterMutexLock mu(Thread::Current(), *callback_lock_);
318 phase_callbacks_.push_back(cb);
319 }
320
RemoveRuntimePhaseCallback(RuntimePhaseCallback * cb)321 void RuntimeCallbacks::RemoveRuntimePhaseCallback(RuntimePhaseCallback* cb) {
322 WriterMutexLock mu(Thread::Current(), *callback_lock_);
323 Remove(cb, &phase_callbacks_);
324 }
325
NextRuntimePhase(RuntimePhaseCallback::RuntimePhase phase)326 void RuntimeCallbacks::NextRuntimePhase(RuntimePhaseCallback::RuntimePhase phase) {
327 for (RuntimePhaseCallback* cb : COPY(phase_callbacks_)) {
328 cb->NextRuntimePhase(phase);
329 }
330 }
331
AddMethodCallback(MethodCallback * cb)332 void RuntimeCallbacks::AddMethodCallback(MethodCallback* cb) {
333 WriterMutexLock mu(Thread::Current(), *callback_lock_);
334 method_callbacks_.push_back(cb);
335 }
336
RemoveMethodCallback(MethodCallback * cb)337 void RuntimeCallbacks::RemoveMethodCallback(MethodCallback* cb) {
338 WriterMutexLock mu(Thread::Current(), *callback_lock_);
339 Remove(cb, &method_callbacks_);
340 }
341
RegisterNativeMethod(ArtMethod * method,const void * in_cur_method,void ** new_method)342 void RuntimeCallbacks::RegisterNativeMethod(ArtMethod* method,
343 const void* in_cur_method,
344 /*out*/void** new_method) {
345 void* cur_method = const_cast<void*>(in_cur_method);
346 *new_method = cur_method;
347 for (MethodCallback* cb : COPY(method_callbacks_)) {
348 cb->RegisterNativeMethod(method, cur_method, new_method);
349 if (*new_method != nullptr) {
350 cur_method = *new_method;
351 }
352 }
353 }
354
AddReflectiveValueVisitCallback(ReflectiveValueVisitCallback * cb)355 void RuntimeCallbacks::AddReflectiveValueVisitCallback(ReflectiveValueVisitCallback *cb) {
356 WriterMutexLock mu(Thread::Current(), *callback_lock_);
357 reflective_value_visit_callbacks_.push_back(cb);
358 }
359
RemoveReflectiveValueVisitCallback(ReflectiveValueVisitCallback * cb)360 void RuntimeCallbacks::RemoveReflectiveValueVisitCallback(ReflectiveValueVisitCallback *cb) {
361 WriterMutexLock mu(Thread::Current(), *callback_lock_);
362 Remove(cb, &reflective_value_visit_callbacks_);
363 }
364
VisitReflectiveTargets(ReflectiveValueVisitor * visitor)365 void RuntimeCallbacks::VisitReflectiveTargets(ReflectiveValueVisitor *visitor) {
366 for (ReflectiveValueVisitCallback* cb : COPY(reflective_value_visit_callbacks_)) {
367 cb->VisitReflectiveTargets(visitor);
368 }
369 }
370
371 } // namespace art
372