• 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 #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