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 
AddThreadLifecycleCallback(ThreadLifecycleCallback * cb)28 void RuntimeCallbacks::AddThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
29   thread_callbacks_.push_back(cb);
30 }
31 
32 template <typename T>
33 ALWAYS_INLINE
Remove(T * cb,std::vector<T * > * data)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 
RemoveThreadLifecycleCallback(ThreadLifecycleCallback * cb)41 void RuntimeCallbacks::RemoveThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
42   Remove(cb, &thread_callbacks_);
43 }
44 
ThreadStart(Thread * self)45 void RuntimeCallbacks::ThreadStart(Thread* self) {
46   for (ThreadLifecycleCallback* cb : thread_callbacks_) {
47     cb->ThreadStart(self);
48   }
49 }
50 
ThreadDeath(Thread * self)51 void RuntimeCallbacks::ThreadDeath(Thread* self) {
52   for (ThreadLifecycleCallback* cb : thread_callbacks_) {
53     cb->ThreadDeath(self);
54   }
55 }
56 
AddClassLoadCallback(ClassLoadCallback * cb)57 void RuntimeCallbacks::AddClassLoadCallback(ClassLoadCallback* cb) {
58   class_callbacks_.push_back(cb);
59 }
60 
RemoveClassLoadCallback(ClassLoadCallback * cb)61 void RuntimeCallbacks::RemoveClassLoadCallback(ClassLoadCallback* cb) {
62   Remove(cb, &class_callbacks_);
63 }
64 
ClassLoad(Handle<mirror::Class> klass)65 void RuntimeCallbacks::ClassLoad(Handle<mirror::Class> klass) {
66   for (ClassLoadCallback* cb : class_callbacks_) {
67     cb->ClassLoad(klass);
68   }
69 }
70 
ClassPreDefine(const char * descriptor,Handle<mirror::Class> temp_class,Handle<mirror::ClassLoader> loader,const DexFile & initial_dex_file,const DexFile::ClassDef & initial_class_def,DexFile const ** final_dex_file,DexFile::ClassDef const ** final_class_def)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 
ClassPrepare(Handle<mirror::Class> temp_klass,Handle<mirror::Class> klass)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 
AddRuntimeSigQuitCallback(RuntimeSigQuitCallback * cb)107 void RuntimeCallbacks::AddRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) {
108   sigquit_callbacks_.push_back(cb);
109 }
110 
RemoveRuntimeSigQuitCallback(RuntimeSigQuitCallback * cb)111 void RuntimeCallbacks::RemoveRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) {
112   Remove(cb, &sigquit_callbacks_);
113 }
114 
SigQuit()115 void RuntimeCallbacks::SigQuit() {
116   for (RuntimeSigQuitCallback* cb : sigquit_callbacks_) {
117     cb->SigQuit();
118   }
119 }
120 
AddRuntimePhaseCallback(RuntimePhaseCallback * cb)121 void RuntimeCallbacks::AddRuntimePhaseCallback(RuntimePhaseCallback* cb) {
122   phase_callbacks_.push_back(cb);
123 }
124 
RemoveRuntimePhaseCallback(RuntimePhaseCallback * cb)125 void RuntimeCallbacks::RemoveRuntimePhaseCallback(RuntimePhaseCallback* cb) {
126   Remove(cb, &phase_callbacks_);
127 }
128 
NextRuntimePhase(RuntimePhaseCallback::RuntimePhase phase)129 void RuntimeCallbacks::NextRuntimePhase(RuntimePhaseCallback::RuntimePhase phase) {
130   for (RuntimePhaseCallback* cb : phase_callbacks_) {
131     cb->NextRuntimePhase(phase);
132   }
133 }
134 
AddMethodCallback(MethodCallback * cb)135 void RuntimeCallbacks::AddMethodCallback(MethodCallback* cb) {
136   method_callbacks_.push_back(cb);
137 }
138 
RemoveMethodCallback(MethodCallback * cb)139 void RuntimeCallbacks::RemoveMethodCallback(MethodCallback* cb) {
140   Remove(cb, &method_callbacks_);
141 }
142 
RegisterNativeMethod(ArtMethod * method,const void * in_cur_method,void ** new_method)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