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 "thread.h" 25 26 namespace art { 27 28 void RuntimeCallbacks::AddThreadLifecycleCallback(ThreadLifecycleCallback* cb) { 29 thread_callbacks_.push_back(cb); 30 } 31 32 template <typename T> 33 ALWAYS_INLINE 34 static inline void Remove(T* cb, std::vector<T*>* data) { 35 auto it = std::find(data->begin(), data->end(), cb); 36 if (it != data->end()) { 37 data->erase(it); 38 } 39 } 40 41 void RuntimeCallbacks::RemoveThreadLifecycleCallback(ThreadLifecycleCallback* cb) { 42 Remove(cb, &thread_callbacks_); 43 } 44 45 void RuntimeCallbacks::ThreadStart(Thread* self) { 46 for (ThreadLifecycleCallback* cb : thread_callbacks_) { 47 cb->ThreadStart(self); 48 } 49 } 50 51 void RuntimeCallbacks::ThreadDeath(Thread* self) { 52 for (ThreadLifecycleCallback* cb : thread_callbacks_) { 53 cb->ThreadDeath(self); 54 } 55 } 56 57 void RuntimeCallbacks::AddClassLoadCallback(ClassLoadCallback* cb) { 58 class_callbacks_.push_back(cb); 59 } 60 61 void RuntimeCallbacks::RemoveClassLoadCallback(ClassLoadCallback* cb) { 62 Remove(cb, &class_callbacks_); 63 } 64 65 void RuntimeCallbacks::ClassLoad(Handle<mirror::Class> klass) { 66 for (ClassLoadCallback* cb : class_callbacks_) { 67 cb->ClassLoad(klass); 68 } 69 } 70 71 void RuntimeCallbacks::ClassPreDefine(const char* descriptor, 72 Handle<mirror::Class> temp_class, 73 Handle<mirror::ClassLoader> loader, 74 const DexFile& initial_dex_file, 75 const DexFile::ClassDef& initial_class_def, 76 /*out*/DexFile const** final_dex_file, 77 /*out*/DexFile::ClassDef const** final_class_def) { 78 DexFile const* current_dex_file = &initial_dex_file; 79 DexFile::ClassDef const* current_class_def = &initial_class_def; 80 for (ClassLoadCallback* cb : class_callbacks_) { 81 DexFile const* new_dex_file = nullptr; 82 DexFile::ClassDef const* new_class_def = nullptr; 83 cb->ClassPreDefine(descriptor, 84 temp_class, 85 loader, 86 *current_dex_file, 87 *current_class_def, 88 &new_dex_file, 89 &new_class_def); 90 if ((new_dex_file != nullptr && new_dex_file != current_dex_file) || 91 (new_class_def != nullptr && new_class_def != current_class_def)) { 92 DCHECK(new_dex_file != nullptr && new_class_def != nullptr); 93 current_dex_file = new_dex_file; 94 current_class_def = new_class_def; 95 } 96 } 97 *final_dex_file = current_dex_file; 98 *final_class_def = current_class_def; 99 } 100 101 void RuntimeCallbacks::ClassPrepare(Handle<mirror::Class> temp_klass, Handle<mirror::Class> klass) { 102 for (ClassLoadCallback* cb : class_callbacks_) { 103 cb->ClassPrepare(temp_klass, klass); 104 } 105 } 106 107 void RuntimeCallbacks::AddRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) { 108 sigquit_callbacks_.push_back(cb); 109 } 110 111 void RuntimeCallbacks::RemoveRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) { 112 Remove(cb, &sigquit_callbacks_); 113 } 114 115 void RuntimeCallbacks::SigQuit() { 116 for (RuntimeSigQuitCallback* cb : sigquit_callbacks_) { 117 cb->SigQuit(); 118 } 119 } 120 121 void RuntimeCallbacks::AddRuntimePhaseCallback(RuntimePhaseCallback* cb) { 122 phase_callbacks_.push_back(cb); 123 } 124 125 void RuntimeCallbacks::RemoveRuntimePhaseCallback(RuntimePhaseCallback* cb) { 126 Remove(cb, &phase_callbacks_); 127 } 128 129 void RuntimeCallbacks::NextRuntimePhase(RuntimePhaseCallback::RuntimePhase phase) { 130 for (RuntimePhaseCallback* cb : phase_callbacks_) { 131 cb->NextRuntimePhase(phase); 132 } 133 } 134 135 void RuntimeCallbacks::AddMethodCallback(MethodCallback* cb) { 136 method_callbacks_.push_back(cb); 137 } 138 139 void RuntimeCallbacks::RemoveMethodCallback(MethodCallback* cb) { 140 Remove(cb, &method_callbacks_); 141 } 142 143 void RuntimeCallbacks::RegisterNativeMethod(ArtMethod* method, 144 const void* in_cur_method, 145 /*out*/void** new_method) { 146 void* cur_method = const_cast<void*>(in_cur_method); 147 *new_method = cur_method; 148 for (MethodCallback* cb : method_callbacks_) { 149 cb->RegisterNativeMethod(method, cur_method, new_method); 150 if (*new_method != nullptr) { 151 cur_method = *new_method; 152 } 153 } 154 } 155 156 } // namespace art 157