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 #include "runtime_callbacks.h"
     18 
     19 #include <algorithm>
     20 
     21 #include "art_method.h"
     22 #include "base/macros.h"
     23 #include "class_linker.h"
     24 #include "monitor.h"
     25 #include "thread.h"
     26 
     27 namespace art {
     28 
     29 template <typename T>
     30 ALWAYS_INLINE
     31 static inline void Remove(T* cb, std::vector<T*>* data) {
     32   auto it = std::find(data->begin(), data->end(), cb);
     33   if (it != data->end()) {
     34     data->erase(it);
     35   }
     36 }
     37 
     38 void RuntimeCallbacks::AddDdmCallback(DdmCallback* cb) {
     39   ddm_callbacks_.push_back(cb);
     40 }
     41 
     42 void RuntimeCallbacks::RemoveDdmCallback(DdmCallback* cb) {
     43   Remove(cb, &ddm_callbacks_);
     44 }
     45 
     46 void RuntimeCallbacks::DdmPublishChunk(uint32_t type, const ArrayRef<const uint8_t>& data) {
     47   for (DdmCallback* cb : ddm_callbacks_) {
     48     cb->DdmPublishChunk(type, data);
     49   }
     50 }
     51 
     52 void RuntimeCallbacks::AddDebuggerControlCallback(DebuggerControlCallback* cb) {
     53   debugger_control_callbacks_.push_back(cb);
     54 }
     55 
     56 void RuntimeCallbacks::RemoveDebuggerControlCallback(DebuggerControlCallback* cb) {
     57   Remove(cb, &debugger_control_callbacks_);
     58 }
     59 
     60 bool RuntimeCallbacks::IsDebuggerConfigured() {
     61   for (DebuggerControlCallback* cb : debugger_control_callbacks_) {
     62     if (cb->IsDebuggerConfigured()) {
     63       return true;
     64     }
     65   }
     66   return false;
     67 }
     68 
     69 void RuntimeCallbacks::StartDebugger() {
     70   for (DebuggerControlCallback* cb : debugger_control_callbacks_) {
     71     cb->StartDebugger();
     72   }
     73 }
     74 
     75 void RuntimeCallbacks::StopDebugger() {
     76   for (DebuggerControlCallback* cb : debugger_control_callbacks_) {
     77     cb->StopDebugger();
     78   }
     79 }
     80 
     81 void RuntimeCallbacks::AddMethodInspectionCallback(MethodInspectionCallback* cb) {
     82   method_inspection_callbacks_.push_back(cb);
     83 }
     84 
     85 void RuntimeCallbacks::RemoveMethodInspectionCallback(MethodInspectionCallback* cb) {
     86   Remove(cb, &method_inspection_callbacks_);
     87 }
     88 
     89 bool RuntimeCallbacks::IsMethodSafeToJit(ArtMethod* m) {
     90   for (MethodInspectionCallback* cb : method_inspection_callbacks_) {
     91     if (!cb->IsMethodSafeToJit(m)) {
     92       DCHECK(cb->IsMethodBeingInspected(m))
     93           << "Contract requires that !IsMethodSafeToJit(m) -> IsMethodBeingInspected(m)";
     94       return false;
     95     }
     96   }
     97   return true;
     98 }
     99 
    100 bool RuntimeCallbacks::IsMethodBeingInspected(ArtMethod* m) {
    101   for (MethodInspectionCallback* cb : method_inspection_callbacks_) {
    102     if (cb->IsMethodBeingInspected(m)) {
    103       return true;
    104     }
    105   }
    106   return false;
    107 }
    108 
    109 bool RuntimeCallbacks::MethodNeedsDebugVersion(ArtMethod* m) {
    110   for (MethodInspectionCallback* cb : method_inspection_callbacks_) {
    111     if (cb->MethodNeedsDebugVersion(m)) {
    112       return true;
    113     }
    114   }
    115   return false;
    116 }
    117 
    118 void RuntimeCallbacks::AddThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
    119   thread_callbacks_.push_back(cb);
    120 }
    121 
    122 void RuntimeCallbacks::MonitorContendedLocking(Monitor* m) {
    123   for (MonitorCallback* cb : monitor_callbacks_) {
    124     cb->MonitorContendedLocking(m);
    125   }
    126 }
    127 
    128 void RuntimeCallbacks::MonitorContendedLocked(Monitor* m) {
    129   for (MonitorCallback* cb : monitor_callbacks_) {
    130     cb->MonitorContendedLocked(m);
    131   }
    132 }
    133 
    134 void RuntimeCallbacks::ObjectWaitStart(Handle<mirror::Object> m, int64_t timeout) {
    135   for (MonitorCallback* cb : monitor_callbacks_) {
    136     cb->ObjectWaitStart(m, timeout);
    137   }
    138 }
    139 
    140 void RuntimeCallbacks::MonitorWaitFinished(Monitor* m, bool timeout) {
    141   for (MonitorCallback* cb : monitor_callbacks_) {
    142     cb->MonitorWaitFinished(m, timeout);
    143   }
    144 }
    145 
    146 void RuntimeCallbacks::AddMonitorCallback(MonitorCallback* cb) {
    147   monitor_callbacks_.push_back(cb);
    148 }
    149 
    150 void RuntimeCallbacks::RemoveMonitorCallback(MonitorCallback* cb) {
    151   Remove(cb, &monitor_callbacks_);
    152 }
    153 
    154 void RuntimeCallbacks::RemoveThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
    155   Remove(cb, &thread_callbacks_);
    156 }
    157 
    158 void RuntimeCallbacks::ThreadStart(Thread* self) {
    159   for (ThreadLifecycleCallback* cb : thread_callbacks_) {
    160     cb->ThreadStart(self);
    161   }
    162 }
    163 
    164 void RuntimeCallbacks::ThreadDeath(Thread* self) {
    165   for (ThreadLifecycleCallback* cb : thread_callbacks_) {
    166     cb->ThreadDeath(self);
    167   }
    168 }
    169 
    170 void RuntimeCallbacks::AddClassLoadCallback(ClassLoadCallback* cb) {
    171   class_callbacks_.push_back(cb);
    172 }
    173 
    174 void RuntimeCallbacks::RemoveClassLoadCallback(ClassLoadCallback* cb) {
    175   Remove(cb, &class_callbacks_);
    176 }
    177 
    178 void RuntimeCallbacks::ClassLoad(Handle<mirror::Class> klass) {
    179   for (ClassLoadCallback* cb : class_callbacks_) {
    180     cb->ClassLoad(klass);
    181   }
    182 }
    183 
    184 void RuntimeCallbacks::ClassPreDefine(const char* descriptor,
    185                                       Handle<mirror::Class> temp_class,
    186                                       Handle<mirror::ClassLoader> loader,
    187                                       const DexFile& initial_dex_file,
    188                                       const DexFile::ClassDef& initial_class_def,
    189                                       /*out*/DexFile const** final_dex_file,
    190                                       /*out*/DexFile::ClassDef const** final_class_def) {
    191   DexFile const* current_dex_file = &initial_dex_file;
    192   DexFile::ClassDef const* current_class_def = &initial_class_def;
    193   for (ClassLoadCallback* cb : class_callbacks_) {
    194     DexFile const* new_dex_file = nullptr;
    195     DexFile::ClassDef const* new_class_def = nullptr;
    196     cb->ClassPreDefine(descriptor,
    197                        temp_class,
    198                        loader,
    199                        *current_dex_file,
    200                        *current_class_def,
    201                        &new_dex_file,
    202                        &new_class_def);
    203     if ((new_dex_file != nullptr && new_dex_file != current_dex_file) ||
    204         (new_class_def != nullptr && new_class_def != current_class_def)) {
    205       DCHECK(new_dex_file != nullptr && new_class_def != nullptr);
    206       current_dex_file = new_dex_file;
    207       current_class_def = new_class_def;
    208     }
    209   }
    210   *final_dex_file = current_dex_file;
    211   *final_class_def = current_class_def;
    212 }
    213 
    214 void RuntimeCallbacks::ClassPrepare(Handle<mirror::Class> temp_klass, Handle<mirror::Class> klass) {
    215   for (ClassLoadCallback* cb : class_callbacks_) {
    216     cb->ClassPrepare(temp_klass, klass);
    217   }
    218 }
    219 
    220 void RuntimeCallbacks::AddRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) {
    221   sigquit_callbacks_.push_back(cb);
    222 }
    223 
    224 void RuntimeCallbacks::RemoveRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) {
    225   Remove(cb, &sigquit_callbacks_);
    226 }
    227 
    228 void RuntimeCallbacks::SigQuit() {
    229   for (RuntimeSigQuitCallback* cb : sigquit_callbacks_) {
    230     cb->SigQuit();
    231   }
    232 }
    233 
    234 void RuntimeCallbacks::AddRuntimePhaseCallback(RuntimePhaseCallback* cb) {
    235   phase_callbacks_.push_back(cb);
    236 }
    237 
    238 void RuntimeCallbacks::RemoveRuntimePhaseCallback(RuntimePhaseCallback* cb) {
    239   Remove(cb, &phase_callbacks_);
    240 }
    241 
    242 void RuntimeCallbacks::NextRuntimePhase(RuntimePhaseCallback::RuntimePhase phase) {
    243   for (RuntimePhaseCallback* cb : phase_callbacks_) {
    244     cb->NextRuntimePhase(phase);
    245   }
    246 }
    247 
    248 void RuntimeCallbacks::AddMethodCallback(MethodCallback* cb) {
    249   method_callbacks_.push_back(cb);
    250 }
    251 
    252 void RuntimeCallbacks::RemoveMethodCallback(MethodCallback* cb) {
    253   Remove(cb, &method_callbacks_);
    254 }
    255 
    256 void RuntimeCallbacks::RegisterNativeMethod(ArtMethod* method,
    257                                             const void* in_cur_method,
    258                                             /*out*/void** new_method) {
    259   void* cur_method = const_cast<void*>(in_cur_method);
    260   *new_method = cur_method;
    261   for (MethodCallback* cb : method_callbacks_) {
    262     cb->RegisterNativeMethod(method, cur_method, new_method);
    263     if (*new_method != nullptr) {
    264       cur_method = *new_method;
    265     }
    266   }
    267 }
    268 
    269 }  // namespace art
    270