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