• 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 "class_linker.h"
24 #include "monitor.h"
25 #include "thread.h"
26 
27 namespace art {
28 
29 template <typename T>
30 ALWAYS_INLINE
Remove(T * cb,std::vector<T * > * data)31 static 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);
35   }
36 }
37 
AddDdmCallback(DdmCallback * cb)38 void RuntimeCallbacks::AddDdmCallback(DdmCallback* cb) {
39   ddm_callbacks_.push_back(cb);
40 }
41 
RemoveDdmCallback(DdmCallback * cb)42 void RuntimeCallbacks::RemoveDdmCallback(DdmCallback* cb) {
43   Remove(cb, &ddm_callbacks_);
44 }
45 
DdmPublishChunk(uint32_t type,const ArrayRef<const uint8_t> & data)46 void 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 
AddDebuggerControlCallback(DebuggerControlCallback * cb)52 void RuntimeCallbacks::AddDebuggerControlCallback(DebuggerControlCallback* cb) {
53   debugger_control_callbacks_.push_back(cb);
54 }
55 
RemoveDebuggerControlCallback(DebuggerControlCallback * cb)56 void RuntimeCallbacks::RemoveDebuggerControlCallback(DebuggerControlCallback* cb) {
57   Remove(cb, &debugger_control_callbacks_);
58 }
59 
IsDebuggerConfigured()60 bool RuntimeCallbacks::IsDebuggerConfigured() {
61   for (DebuggerControlCallback* cb : debugger_control_callbacks_) {
62     if (cb->IsDebuggerConfigured()) {
63       return true;
64     }
65   }
66   return false;
67 }
68 
StartDebugger()69 void RuntimeCallbacks::StartDebugger() {
70   for (DebuggerControlCallback* cb : debugger_control_callbacks_) {
71     cb->StartDebugger();
72   }
73 }
74 
StopDebugger()75 void RuntimeCallbacks::StopDebugger() {
76   for (DebuggerControlCallback* cb : debugger_control_callbacks_) {
77     cb->StopDebugger();
78   }
79 }
80 
AddMethodInspectionCallback(MethodInspectionCallback * cb)81 void RuntimeCallbacks::AddMethodInspectionCallback(MethodInspectionCallback* cb) {
82   method_inspection_callbacks_.push_back(cb);
83 }
84 
RemoveMethodInspectionCallback(MethodInspectionCallback * cb)85 void RuntimeCallbacks::RemoveMethodInspectionCallback(MethodInspectionCallback* cb) {
86   Remove(cb, &method_inspection_callbacks_);
87 }
88 
IsMethodSafeToJit(ArtMethod * m)89 bool 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 
IsMethodBeingInspected(ArtMethod * m)100 bool 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 
MethodNeedsDebugVersion(ArtMethod * m)109 bool 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 
AddThreadLifecycleCallback(ThreadLifecycleCallback * cb)118 void RuntimeCallbacks::AddThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
119   thread_callbacks_.push_back(cb);
120 }
121 
MonitorContendedLocking(Monitor * m)122 void RuntimeCallbacks::MonitorContendedLocking(Monitor* m) {
123   for (MonitorCallback* cb : monitor_callbacks_) {
124     cb->MonitorContendedLocking(m);
125   }
126 }
127 
MonitorContendedLocked(Monitor * m)128 void RuntimeCallbacks::MonitorContendedLocked(Monitor* m) {
129   for (MonitorCallback* cb : monitor_callbacks_) {
130     cb->MonitorContendedLocked(m);
131   }
132 }
133 
ObjectWaitStart(Handle<mirror::Object> m,int64_t timeout)134 void RuntimeCallbacks::ObjectWaitStart(Handle<mirror::Object> m, int64_t timeout) {
135   for (MonitorCallback* cb : monitor_callbacks_) {
136     cb->ObjectWaitStart(m, timeout);
137   }
138 }
139 
MonitorWaitFinished(Monitor * m,bool timeout)140 void RuntimeCallbacks::MonitorWaitFinished(Monitor* m, bool timeout) {
141   for (MonitorCallback* cb : monitor_callbacks_) {
142     cb->MonitorWaitFinished(m, timeout);
143   }
144 }
145 
AddMonitorCallback(MonitorCallback * cb)146 void RuntimeCallbacks::AddMonitorCallback(MonitorCallback* cb) {
147   monitor_callbacks_.push_back(cb);
148 }
149 
RemoveMonitorCallback(MonitorCallback * cb)150 void RuntimeCallbacks::RemoveMonitorCallback(MonitorCallback* cb) {
151   Remove(cb, &monitor_callbacks_);
152 }
153 
RemoveThreadLifecycleCallback(ThreadLifecycleCallback * cb)154 void RuntimeCallbacks::RemoveThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
155   Remove(cb, &thread_callbacks_);
156 }
157 
ThreadStart(Thread * self)158 void RuntimeCallbacks::ThreadStart(Thread* self) {
159   for (ThreadLifecycleCallback* cb : thread_callbacks_) {
160     cb->ThreadStart(self);
161   }
162 }
163 
ThreadDeath(Thread * self)164 void RuntimeCallbacks::ThreadDeath(Thread* self) {
165   for (ThreadLifecycleCallback* cb : thread_callbacks_) {
166     cb->ThreadDeath(self);
167   }
168 }
169 
AddClassLoadCallback(ClassLoadCallback * cb)170 void RuntimeCallbacks::AddClassLoadCallback(ClassLoadCallback* cb) {
171   class_callbacks_.push_back(cb);
172 }
173 
RemoveClassLoadCallback(ClassLoadCallback * cb)174 void RuntimeCallbacks::RemoveClassLoadCallback(ClassLoadCallback* cb) {
175   Remove(cb, &class_callbacks_);
176 }
177 
ClassLoad(Handle<mirror::Class> klass)178 void RuntimeCallbacks::ClassLoad(Handle<mirror::Class> klass) {
179   for (ClassLoadCallback* cb : class_callbacks_) {
180     cb->ClassLoad(klass);
181   }
182 }
183 
ClassPreDefine(const char * descriptor,Handle<mirror::Class> temp_class,Handle<mirror::ClassLoader> loader,const DexFile & initial_dex_file,const DexFile::ClassDef & initial_class_def,DexFile const ** final_dex_file,DexFile::ClassDef const ** final_class_def)184 void RuntimeCallbacks::ClassPreDefine(const char* descriptor,
185                                       Handle<mirror::Class> temp_class,
186                                       Handle<mirror::ClassLoader> loader,
187                                       const DexFile& initial_dex_file,
188                                       const DexFile::ClassDef& initial_class_def,
189                                       /*out*/DexFile const** final_dex_file,
190                                       /*out*/DexFile::ClassDef const** final_class_def) {
191   DexFile const* current_dex_file = &initial_dex_file;
192   DexFile::ClassDef const* current_class_def = &initial_class_def;
193   for (ClassLoadCallback* cb : class_callbacks_) {
194     DexFile const* new_dex_file = nullptr;
195     DexFile::ClassDef const* new_class_def = nullptr;
196     cb->ClassPreDefine(descriptor,
197                        temp_class,
198                        loader,
199                        *current_dex_file,
200                        *current_class_def,
201                        &new_dex_file,
202                        &new_class_def);
203     if ((new_dex_file != nullptr && new_dex_file != current_dex_file) ||
204         (new_class_def != nullptr && new_class_def != current_class_def)) {
205       DCHECK(new_dex_file != nullptr && new_class_def != nullptr);
206       current_dex_file = new_dex_file;
207       current_class_def = new_class_def;
208     }
209   }
210   *final_dex_file = current_dex_file;
211   *final_class_def = current_class_def;
212 }
213 
ClassPrepare(Handle<mirror::Class> temp_klass,Handle<mirror::Class> klass)214 void RuntimeCallbacks::ClassPrepare(Handle<mirror::Class> temp_klass, Handle<mirror::Class> klass) {
215   for (ClassLoadCallback* cb : class_callbacks_) {
216     cb->ClassPrepare(temp_klass, klass);
217   }
218 }
219 
AddRuntimeSigQuitCallback(RuntimeSigQuitCallback * cb)220 void RuntimeCallbacks::AddRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) {
221   sigquit_callbacks_.push_back(cb);
222 }
223 
RemoveRuntimeSigQuitCallback(RuntimeSigQuitCallback * cb)224 void RuntimeCallbacks::RemoveRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) {
225   Remove(cb, &sigquit_callbacks_);
226 }
227 
SigQuit()228 void RuntimeCallbacks::SigQuit() {
229   for (RuntimeSigQuitCallback* cb : sigquit_callbacks_) {
230     cb->SigQuit();
231   }
232 }
233 
AddRuntimePhaseCallback(RuntimePhaseCallback * cb)234 void RuntimeCallbacks::AddRuntimePhaseCallback(RuntimePhaseCallback* cb) {
235   phase_callbacks_.push_back(cb);
236 }
237 
RemoveRuntimePhaseCallback(RuntimePhaseCallback * cb)238 void RuntimeCallbacks::RemoveRuntimePhaseCallback(RuntimePhaseCallback* cb) {
239   Remove(cb, &phase_callbacks_);
240 }
241 
NextRuntimePhase(RuntimePhaseCallback::RuntimePhase phase)242 void RuntimeCallbacks::NextRuntimePhase(RuntimePhaseCallback::RuntimePhase phase) {
243   for (RuntimePhaseCallback* cb : phase_callbacks_) {
244     cb->NextRuntimePhase(phase);
245   }
246 }
247 
AddMethodCallback(MethodCallback * cb)248 void RuntimeCallbacks::AddMethodCallback(MethodCallback* cb) {
249   method_callbacks_.push_back(cb);
250 }
251 
RemoveMethodCallback(MethodCallback * cb)252 void RuntimeCallbacks::RemoveMethodCallback(MethodCallback* cb) {
253   Remove(cb, &method_callbacks_);
254 }
255 
RegisterNativeMethod(ArtMethod * method,const void * in_cur_method,void ** new_method)256 void RuntimeCallbacks::RegisterNativeMethod(ArtMethod* method,
257                                             const void* in_cur_method,
258                                             /*out*/void** new_method) {
259   void* cur_method = const_cast<void*>(in_cur_method);
260   *new_method = cur_method;
261   for (MethodCallback* cb : method_callbacks_) {
262     cb->RegisterNativeMethod(method, cur_method, new_method);
263     if (*new_method != nullptr) {
264       cur_method = *new_method;
265     }
266   }
267 }
268 
269 }  // namespace art
270