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 #ifndef ART_RUNTIME_RUNTIME_CALLBACKS_H_ 18 #define ART_RUNTIME_RUNTIME_CALLBACKS_H_ 19 20 #include <vector> 21 22 #include "base/array_ref.h" 23 #include "base/locks.h" 24 #include "base/macros.h" 25 #include "handle.h" 26 27 namespace art { 28 29 namespace dex { 30 struct ClassDef; 31 } // namespace dex 32 33 namespace mirror { 34 class Class; 35 class ClassLoader; 36 class Object; 37 } // namespace mirror 38 39 class ArtMethod; 40 class ClassLoadCallback; 41 class DexFile; 42 class Thread; 43 class MethodCallback; 44 class Monitor; 45 class ReaderWriterMutex; 46 class ThreadLifecycleCallback; 47 48 // Note: RuntimeCallbacks uses the mutator lock to synchronize the callback lists. A thread must 49 // hold the exclusive lock to add or remove a listener. A thread must hold the shared lock 50 // to dispatch an event. This setup is chosen as some clients may want to suspend the 51 // dispatching thread or all threads. 52 // 53 // To make this safe, the following restrictions apply: 54 // * Only the owner of a listener may ever add or remove said listener. 55 // * A listener must never add or remove itself or any other listener while running. 56 // * It is the responsibility of the owner to not remove the listener while it is running 57 // (and suspended). 58 // * The owner should never deallocate a listener once it has been registered, even if it has 59 // been removed. 60 // 61 // The simplest way to satisfy these restrictions is to never remove a listener, and to do 62 // any state checking (is the listener enabled) in the listener itself. For an example, see 63 // Dbg. 64 65 class DdmCallback { 66 public: ~DdmCallback()67 virtual ~DdmCallback() {} 68 virtual void DdmPublishChunk(uint32_t type, const ArrayRef<const uint8_t>& data) 69 REQUIRES_SHARED(Locks::mutator_lock_) = 0; 70 }; 71 72 class DebuggerControlCallback { 73 public: ~DebuggerControlCallback()74 virtual ~DebuggerControlCallback() {} 75 76 // Begin running the debugger. 77 virtual void StartDebugger() = 0; 78 // The debugger should begin shutting down since the runtime is ending. This is just advisory 79 virtual void StopDebugger() = 0; 80 81 // This allows the debugger to tell the runtime if it is configured. 82 virtual bool IsDebuggerConfigured() = 0; 83 }; 84 85 class RuntimeSigQuitCallback { 86 public: ~RuntimeSigQuitCallback()87 virtual ~RuntimeSigQuitCallback() {} 88 89 virtual void SigQuit() REQUIRES_SHARED(Locks::mutator_lock_) = 0; 90 }; 91 92 class RuntimePhaseCallback { 93 public: 94 enum RuntimePhase { 95 kInitialAgents, // Initial agent loading is done. 96 kStart, // The runtime is started. 97 kInit, // The runtime is initialized (and will run user code soon). 98 kDeath, // The runtime just died. 99 }; 100 ~RuntimePhaseCallback()101 virtual ~RuntimePhaseCallback() {} 102 103 virtual void NextRuntimePhase(RuntimePhase phase) REQUIRES_SHARED(Locks::mutator_lock_) = 0; 104 }; 105 106 class MonitorCallback { 107 public: 108 // Called just before the thread goes to sleep to wait for the monitor to become unlocked. 109 virtual void MonitorContendedLocking(Monitor* mon) REQUIRES_SHARED(Locks::mutator_lock_) = 0; 110 // Called just after the monitor has been successfully acquired when it was already locked. 111 virtual void MonitorContendedLocked(Monitor* mon) REQUIRES_SHARED(Locks::mutator_lock_) = 0; 112 // Called on entry to the Object#wait method regardless of whether or not the call is valid. 113 virtual void ObjectWaitStart(Handle<mirror::Object> obj, int64_t millis_timeout) 114 REQUIRES_SHARED(Locks::mutator_lock_) = 0; 115 116 // Called just after the monitor has woken up from going to sleep for a wait(). At this point the 117 // thread does not possess a lock on the monitor. This will only be called for threads wait calls 118 // where the thread did (or at least could have) gone to sleep. 119 virtual void MonitorWaitFinished(Monitor* m, bool timed_out) 120 REQUIRES_SHARED(Locks::mutator_lock_) = 0; 121 ~MonitorCallback()122 virtual ~MonitorCallback() {} 123 }; 124 125 class ParkCallback { 126 public: 127 // Called on entry to the Unsafe.#park method 128 virtual void ThreadParkStart(bool is_absolute, int64_t millis_timeout) 129 REQUIRES_SHARED(Locks::mutator_lock_) = 0; 130 131 // Called just after the thread has woken up from going to sleep for a park(). This will only be 132 // called for Unsafe.park() calls where the thread did (or at least could have) gone to sleep. 133 virtual void ThreadParkFinished(bool timed_out) REQUIRES_SHARED(Locks::mutator_lock_) = 0; 134 ~ParkCallback()135 virtual ~ParkCallback() {} 136 }; 137 138 // A callback to let parts of the runtime note that they are currently relying on a particular 139 // method remaining in it's current state. Users should not rely on always being called. If multiple 140 // callbacks are added the runtime will short-circuit when the first one returns 'true'. 141 class MethodInspectionCallback { 142 public: ~MethodInspectionCallback()143 virtual ~MethodInspectionCallback() {} 144 145 // Returns true if the method is being inspected currently and the runtime should not modify it in 146 // potentially dangerous ways (i.e. replace with compiled version, JIT it, etc). 147 virtual bool IsMethodBeingInspected(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) = 0; 148 149 // Returns true if the method is safe to Jit, false otherwise. 150 // Note that '!IsMethodSafeToJit(m) implies IsMethodBeingInspected(m)'. That is that if this 151 // method returns false IsMethodBeingInspected must return true. 152 virtual bool IsMethodSafeToJit(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) = 0; 153 154 // Returns true if we expect the method to be debuggable but are not doing anything unusual with 155 // it currently. 156 virtual bool MethodNeedsDebugVersion(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) = 0; 157 }; 158 159 class RuntimeCallbacks { 160 public: 161 RuntimeCallbacks(); 162 163 void AddThreadLifecycleCallback(ThreadLifecycleCallback* cb) REQUIRES(Locks::mutator_lock_); 164 void RemoveThreadLifecycleCallback(ThreadLifecycleCallback* cb) REQUIRES(Locks::mutator_lock_); 165 166 void ThreadStart(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_); 167 void ThreadDeath(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_); 168 169 void AddClassLoadCallback(ClassLoadCallback* cb) REQUIRES(Locks::mutator_lock_); 170 void RemoveClassLoadCallback(ClassLoadCallback* cb) REQUIRES(Locks::mutator_lock_); 171 172 void ClassLoad(Handle<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_); 173 void ClassPrepare(Handle<mirror::Class> temp_klass, Handle<mirror::Class> klass) 174 REQUIRES_SHARED(Locks::mutator_lock_); 175 176 void AddRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) 177 REQUIRES(Locks::mutator_lock_); 178 void RemoveRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) 179 REQUIRES(Locks::mutator_lock_); 180 181 void SigQuit() REQUIRES_SHARED(Locks::mutator_lock_); 182 183 void AddRuntimePhaseCallback(RuntimePhaseCallback* cb) 184 REQUIRES(Locks::mutator_lock_); 185 void RemoveRuntimePhaseCallback(RuntimePhaseCallback* cb) 186 REQUIRES(Locks::mutator_lock_); 187 188 void NextRuntimePhase(RuntimePhaseCallback::RuntimePhase phase) 189 REQUIRES_SHARED(Locks::mutator_lock_); 190 191 void ClassPreDefine(const char* descriptor, 192 Handle<mirror::Class> temp_class, 193 Handle<mirror::ClassLoader> loader, 194 const DexFile& initial_dex_file, 195 const dex::ClassDef& initial_class_def, 196 /*out*/DexFile const** final_dex_file, 197 /*out*/dex::ClassDef const** final_class_def) 198 REQUIRES_SHARED(Locks::mutator_lock_); 199 200 void AddMethodCallback(MethodCallback* cb) REQUIRES(Locks::mutator_lock_); 201 void RemoveMethodCallback(MethodCallback* cb) REQUIRES(Locks::mutator_lock_); 202 203 void RegisterNativeMethod(ArtMethod* method, 204 const void* original_implementation, 205 /*out*/void** new_implementation) 206 REQUIRES_SHARED(Locks::mutator_lock_); 207 208 void MonitorContendedLocking(Monitor* m) REQUIRES_SHARED(Locks::mutator_lock_); 209 void MonitorContendedLocked(Monitor* m) REQUIRES_SHARED(Locks::mutator_lock_); 210 void ObjectWaitStart(Handle<mirror::Object> m, int64_t timeout) 211 REQUIRES_SHARED(Locks::mutator_lock_); 212 void MonitorWaitFinished(Monitor* m, bool timed_out) 213 REQUIRES_SHARED(Locks::mutator_lock_); 214 215 void AddMonitorCallback(MonitorCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_); 216 void RemoveMonitorCallback(MonitorCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_); 217 218 void ThreadParkStart(bool is_absolute, int64_t timeout) REQUIRES_SHARED(Locks::mutator_lock_); 219 void ThreadParkFinished(bool timed_out) REQUIRES_SHARED(Locks::mutator_lock_); 220 void AddParkCallback(ParkCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_); 221 void RemoveParkCallback(ParkCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_); 222 223 // Returns true if some MethodInspectionCallback indicates the method is being inspected/depended 224 // on by some code. 225 bool IsMethodBeingInspected(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_); 226 227 // Returns false if some MethodInspectionCallback indicates the method cannot be safetly jitted 228 // (which implies that it is being Inspected). Returns true otherwise. If it returns false the 229 // entrypoint should not be changed to JITed code. 230 bool IsMethodSafeToJit(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_); 231 232 // Returns true if some MethodInspectionCallback indicates the method needs to use a debug 233 // version. This allows later code to set breakpoints or perform other actions that could be 234 // broken by some optimizations. 235 bool MethodNeedsDebugVersion(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_); 236 237 void AddMethodInspectionCallback(MethodInspectionCallback* cb) 238 REQUIRES_SHARED(Locks::mutator_lock_); 239 void RemoveMethodInspectionCallback(MethodInspectionCallback* cb) 240 REQUIRES_SHARED(Locks::mutator_lock_); 241 242 // DDMS callbacks 243 void DdmPublishChunk(uint32_t type, const ArrayRef<const uint8_t>& data) 244 REQUIRES_SHARED(Locks::mutator_lock_); 245 246 void AddDdmCallback(DdmCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_); 247 void RemoveDdmCallback(DdmCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_); 248 249 void StartDebugger() REQUIRES_SHARED(Locks::mutator_lock_); 250 // NO_THREAD_SAFETY_ANALYSIS since this is only called when we are in the middle of shutting down 251 // and the mutator_lock_ is no longer acquirable. 252 void StopDebugger() NO_THREAD_SAFETY_ANALYSIS; 253 bool IsDebuggerConfigured() REQUIRES_SHARED(Locks::mutator_lock_); 254 255 void AddDebuggerControlCallback(DebuggerControlCallback* cb) 256 REQUIRES_SHARED(Locks::mutator_lock_); 257 void RemoveDebuggerControlCallback(DebuggerControlCallback* cb) 258 REQUIRES_SHARED(Locks::mutator_lock_); 259 260 private: 261 std::unique_ptr<ReaderWriterMutex> callback_lock_ BOTTOM_MUTEX_ACQUIRED_AFTER; 262 263 std::vector<ThreadLifecycleCallback*> thread_callbacks_ 264 GUARDED_BY(callback_lock_); 265 std::vector<ClassLoadCallback*> class_callbacks_ 266 GUARDED_BY(callback_lock_); 267 std::vector<RuntimeSigQuitCallback*> sigquit_callbacks_ 268 GUARDED_BY(callback_lock_); 269 std::vector<RuntimePhaseCallback*> phase_callbacks_ 270 GUARDED_BY(callback_lock_); 271 std::vector<MethodCallback*> method_callbacks_ 272 GUARDED_BY(callback_lock_); 273 std::vector<MonitorCallback*> monitor_callbacks_ 274 GUARDED_BY(callback_lock_); 275 std::vector<ParkCallback*> park_callbacks_ 276 GUARDED_BY(callback_lock_); 277 std::vector<MethodInspectionCallback*> method_inspection_callbacks_ 278 GUARDED_BY(callback_lock_); 279 std::vector<DdmCallback*> ddm_callbacks_ 280 GUARDED_BY(callback_lock_); 281 std::vector<DebuggerControlCallback*> debugger_control_callbacks_ 282 GUARDED_BY(callback_lock_); 283 }; 284 285 } // namespace art 286 287 #endif // ART_RUNTIME_RUNTIME_CALLBACKS_H_ 288