Home | History | Annotate | Download | only in runtime
      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:
     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:
     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:
     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 
    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 
    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 
    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:
    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