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/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:
     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:
     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:
     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 
     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 
    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:
    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