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 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 38 void RuntimeCallbacks::AddDdmCallback(DdmCallback* cb) { 39 ddm_callbacks_.push_back(cb); 40 } 41 42 void RuntimeCallbacks::RemoveDdmCallback(DdmCallback* cb) { 43 Remove(cb, &ddm_callbacks_); 44 } 45 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 52 void RuntimeCallbacks::AddDebuggerControlCallback(DebuggerControlCallback* cb) { 53 debugger_control_callbacks_.push_back(cb); 54 } 55 56 void RuntimeCallbacks::RemoveDebuggerControlCallback(DebuggerControlCallback* cb) { 57 Remove(cb, &debugger_control_callbacks_); 58 } 59 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 69 void RuntimeCallbacks::StartDebugger() { 70 for (DebuggerControlCallback* cb : debugger_control_callbacks_) { 71 cb->StartDebugger(); 72 } 73 } 74 75 void RuntimeCallbacks::StopDebugger() { 76 for (DebuggerControlCallback* cb : debugger_control_callbacks_) { 77 cb->StopDebugger(); 78 } 79 } 80 81 void RuntimeCallbacks::AddMethodInspectionCallback(MethodInspectionCallback* cb) { 82 method_inspection_callbacks_.push_back(cb); 83 } 84 85 void RuntimeCallbacks::RemoveMethodInspectionCallback(MethodInspectionCallback* cb) { 86 Remove(cb, &method_inspection_callbacks_); 87 } 88 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 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 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 118 void RuntimeCallbacks::AddThreadLifecycleCallback(ThreadLifecycleCallback* cb) { 119 thread_callbacks_.push_back(cb); 120 } 121 122 void RuntimeCallbacks::MonitorContendedLocking(Monitor* m) { 123 for (MonitorCallback* cb : monitor_callbacks_) { 124 cb->MonitorContendedLocking(m); 125 } 126 } 127 128 void RuntimeCallbacks::MonitorContendedLocked(Monitor* m) { 129 for (MonitorCallback* cb : monitor_callbacks_) { 130 cb->MonitorContendedLocked(m); 131 } 132 } 133 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 140 void RuntimeCallbacks::MonitorWaitFinished(Monitor* m, bool timeout) { 141 for (MonitorCallback* cb : monitor_callbacks_) { 142 cb->MonitorWaitFinished(m, timeout); 143 } 144 } 145 146 void RuntimeCallbacks::AddMonitorCallback(MonitorCallback* cb) { 147 monitor_callbacks_.push_back(cb); 148 } 149 150 void RuntimeCallbacks::RemoveMonitorCallback(MonitorCallback* cb) { 151 Remove(cb, &monitor_callbacks_); 152 } 153 154 void RuntimeCallbacks::RemoveThreadLifecycleCallback(ThreadLifecycleCallback* cb) { 155 Remove(cb, &thread_callbacks_); 156 } 157 158 void RuntimeCallbacks::ThreadStart(Thread* self) { 159 for (ThreadLifecycleCallback* cb : thread_callbacks_) { 160 cb->ThreadStart(self); 161 } 162 } 163 164 void RuntimeCallbacks::ThreadDeath(Thread* self) { 165 for (ThreadLifecycleCallback* cb : thread_callbacks_) { 166 cb->ThreadDeath(self); 167 } 168 } 169 170 void RuntimeCallbacks::AddClassLoadCallback(ClassLoadCallback* cb) { 171 class_callbacks_.push_back(cb); 172 } 173 174 void RuntimeCallbacks::RemoveClassLoadCallback(ClassLoadCallback* cb) { 175 Remove(cb, &class_callbacks_); 176 } 177 178 void RuntimeCallbacks::ClassLoad(Handle<mirror::Class> klass) { 179 for (ClassLoadCallback* cb : class_callbacks_) { 180 cb->ClassLoad(klass); 181 } 182 } 183 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 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 220 void RuntimeCallbacks::AddRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) { 221 sigquit_callbacks_.push_back(cb); 222 } 223 224 void RuntimeCallbacks::RemoveRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) { 225 Remove(cb, &sigquit_callbacks_); 226 } 227 228 void RuntimeCallbacks::SigQuit() { 229 for (RuntimeSigQuitCallback* cb : sigquit_callbacks_) { 230 cb->SigQuit(); 231 } 232 } 233 234 void RuntimeCallbacks::AddRuntimePhaseCallback(RuntimePhaseCallback* cb) { 235 phase_callbacks_.push_back(cb); 236 } 237 238 void RuntimeCallbacks::RemoveRuntimePhaseCallback(RuntimePhaseCallback* cb) { 239 Remove(cb, &phase_callbacks_); 240 } 241 242 void RuntimeCallbacks::NextRuntimePhase(RuntimePhaseCallback::RuntimePhase phase) { 243 for (RuntimePhaseCallback* cb : phase_callbacks_) { 244 cb->NextRuntimePhase(phase); 245 } 246 } 247 248 void RuntimeCallbacks::AddMethodCallback(MethodCallback* cb) { 249 method_callbacks_.push_back(cb); 250 } 251 252 void RuntimeCallbacks::RemoveMethodCallback(MethodCallback* cb) { 253 Remove(cb, &method_callbacks_); 254 } 255 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