• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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