xref: /aosp_15_r20/art/runtime/runtime_callbacks.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include "runtime_callbacks.h"
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include <algorithm>
20*795d594fSAndroid Build Coastguard Worker 
21*795d594fSAndroid Build Coastguard Worker #include "art_method.h"
22*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
23*795d594fSAndroid Build Coastguard Worker #include "base/mutex-inl.h"
24*795d594fSAndroid Build Coastguard Worker #include "class_linker.h"
25*795d594fSAndroid Build Coastguard Worker #include "monitor.h"
26*795d594fSAndroid Build Coastguard Worker #include "thread-current-inl.h"
27*795d594fSAndroid Build Coastguard Worker 
28*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
29*795d594fSAndroid Build Coastguard Worker 
RuntimeCallbacks()30*795d594fSAndroid Build Coastguard Worker RuntimeCallbacks::RuntimeCallbacks()
31*795d594fSAndroid Build Coastguard Worker     : callback_lock_(new ReaderWriterMutex("Runtime callbacks lock",
32*795d594fSAndroid Build Coastguard Worker                                            LockLevel::kGenericBottomLock)) {}
33*795d594fSAndroid Build Coastguard Worker 
34*795d594fSAndroid Build Coastguard Worker // We don't want to be holding any locks when the actual event is called so we use this to define a
35*795d594fSAndroid Build Coastguard Worker // helper that gets a copy of the current event list and returns it.
36*795d594fSAndroid Build Coastguard Worker #define COPY(T)                                                   \
37*795d594fSAndroid Build Coastguard Worker   ([this]() -> decltype(this->T) {                                \
38*795d594fSAndroid Build Coastguard Worker     ReaderMutexLock mu(Thread::Current(), *this->callback_lock_); \
39*795d594fSAndroid Build Coastguard Worker     return std::vector<decltype(this->T)::value_type>(this->T);   \
40*795d594fSAndroid Build Coastguard Worker   })()
41*795d594fSAndroid Build Coastguard Worker 
42*795d594fSAndroid Build Coastguard Worker template <typename T>
43*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE
Remove(T * cb,std::vector<T * > * data)44*795d594fSAndroid Build Coastguard Worker static inline void Remove(T* cb, std::vector<T*>* data) {
45*795d594fSAndroid Build Coastguard Worker   auto it = std::find(data->begin(), data->end(), cb);
46*795d594fSAndroid Build Coastguard Worker   if (it != data->end()) {
47*795d594fSAndroid Build Coastguard Worker     data->erase(it);
48*795d594fSAndroid Build Coastguard Worker   }
49*795d594fSAndroid Build Coastguard Worker }
50*795d594fSAndroid Build Coastguard Worker 
AddDdmCallback(DdmCallback * cb)51*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::AddDdmCallback(DdmCallback* cb) {
52*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
53*795d594fSAndroid Build Coastguard Worker   ddm_callbacks_.push_back(cb);
54*795d594fSAndroid Build Coastguard Worker }
55*795d594fSAndroid Build Coastguard Worker 
RemoveDdmCallback(DdmCallback * cb)56*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::RemoveDdmCallback(DdmCallback* cb) {
57*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
58*795d594fSAndroid Build Coastguard Worker   Remove(cb, &ddm_callbacks_);
59*795d594fSAndroid Build Coastguard Worker }
60*795d594fSAndroid Build Coastguard Worker 
AddAppInfoCallback(AppInfoCallback * cb)61*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::AddAppInfoCallback(AppInfoCallback* cb) {
62*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
63*795d594fSAndroid Build Coastguard Worker   appinfo_callbacks_.push_back(cb);
64*795d594fSAndroid Build Coastguard Worker }
65*795d594fSAndroid Build Coastguard Worker 
RemoveAppInfoCallback(AppInfoCallback * cb)66*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::RemoveAppInfoCallback(AppInfoCallback* cb) {
67*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
68*795d594fSAndroid Build Coastguard Worker   Remove(cb, &appinfo_callbacks_);
69*795d594fSAndroid Build Coastguard Worker }
70*795d594fSAndroid Build Coastguard Worker 
DdmPublishChunk(uint32_t type,const ArrayRef<const uint8_t> & data)71*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::DdmPublishChunk(uint32_t type, const ArrayRef<const uint8_t>& data) {
72*795d594fSAndroid Build Coastguard Worker   for (DdmCallback* cb : COPY(ddm_callbacks_)) {
73*795d594fSAndroid Build Coastguard Worker     cb->DdmPublishChunk(type, data);
74*795d594fSAndroid Build Coastguard Worker   }
75*795d594fSAndroid Build Coastguard Worker }
76*795d594fSAndroid Build Coastguard Worker 
SetCurrentProcessName(const std::string & process_name)77*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::SetCurrentProcessName(const std::string& process_name) {
78*795d594fSAndroid Build Coastguard Worker   for (AppInfoCallback* cb : COPY(appinfo_callbacks_)) {
79*795d594fSAndroid Build Coastguard Worker     cb->SetCurrentProcessName(process_name);
80*795d594fSAndroid Build Coastguard Worker   }
81*795d594fSAndroid Build Coastguard Worker }
82*795d594fSAndroid Build Coastguard Worker 
AddApplication(const std::string & package_name)83*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::AddApplication(const std::string& package_name) {
84*795d594fSAndroid Build Coastguard Worker   for (AppInfoCallback* cb : COPY(appinfo_callbacks_)) {
85*795d594fSAndroid Build Coastguard Worker     cb->AddApplication(package_name);
86*795d594fSAndroid Build Coastguard Worker   }
87*795d594fSAndroid Build Coastguard Worker }
88*795d594fSAndroid Build Coastguard Worker 
RemoveApplication(const std::string & package_name)89*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::RemoveApplication(const std::string& package_name) {
90*795d594fSAndroid Build Coastguard Worker   for (AppInfoCallback* cb : COPY(appinfo_callbacks_)) {
91*795d594fSAndroid Build Coastguard Worker     cb->RemoveApplication(package_name);
92*795d594fSAndroid Build Coastguard Worker   }
93*795d594fSAndroid Build Coastguard Worker }
94*795d594fSAndroid Build Coastguard Worker 
SetWaitingForDebugger(bool waiting)95*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::SetWaitingForDebugger(bool waiting) {
96*795d594fSAndroid Build Coastguard Worker   for (AppInfoCallback* cb : COPY(appinfo_callbacks_)) {
97*795d594fSAndroid Build Coastguard Worker     cb->SetWaitingForDebugger(waiting);
98*795d594fSAndroid Build Coastguard Worker   }
99*795d594fSAndroid Build Coastguard Worker }
100*795d594fSAndroid Build Coastguard Worker 
SetUserId(int user_id)101*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::SetUserId(int user_id) {
102*795d594fSAndroid Build Coastguard Worker   for (AppInfoCallback* cb : COPY(appinfo_callbacks_)) {
103*795d594fSAndroid Build Coastguard Worker     cb->SetUserId(user_id);
104*795d594fSAndroid Build Coastguard Worker   }
105*795d594fSAndroid Build Coastguard Worker }
106*795d594fSAndroid Build Coastguard Worker 
AddDebuggerControlCallback(DebuggerControlCallback * cb)107*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::AddDebuggerControlCallback(DebuggerControlCallback* cb) {
108*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
109*795d594fSAndroid Build Coastguard Worker   debugger_control_callbacks_.push_back(cb);
110*795d594fSAndroid Build Coastguard Worker }
111*795d594fSAndroid Build Coastguard Worker 
RemoveDebuggerControlCallback(DebuggerControlCallback * cb)112*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::RemoveDebuggerControlCallback(DebuggerControlCallback* cb) {
113*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
114*795d594fSAndroid Build Coastguard Worker   Remove(cb, &debugger_control_callbacks_);
115*795d594fSAndroid Build Coastguard Worker }
116*795d594fSAndroid Build Coastguard Worker 
IsDebuggerConfigured()117*795d594fSAndroid Build Coastguard Worker bool RuntimeCallbacks::IsDebuggerConfigured() {
118*795d594fSAndroid Build Coastguard Worker   for (DebuggerControlCallback* cb : COPY(debugger_control_callbacks_)) {
119*795d594fSAndroid Build Coastguard Worker     if (cb->IsDebuggerConfigured()) {
120*795d594fSAndroid Build Coastguard Worker       return true;
121*795d594fSAndroid Build Coastguard Worker     }
122*795d594fSAndroid Build Coastguard Worker   }
123*795d594fSAndroid Build Coastguard Worker   return false;
124*795d594fSAndroid Build Coastguard Worker }
125*795d594fSAndroid Build Coastguard Worker 
StartDebugger()126*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::StartDebugger() {
127*795d594fSAndroid Build Coastguard Worker   for (DebuggerControlCallback* cb : COPY(debugger_control_callbacks_)) {
128*795d594fSAndroid Build Coastguard Worker     cb->StartDebugger();
129*795d594fSAndroid Build Coastguard Worker   }
130*795d594fSAndroid Build Coastguard Worker }
131*795d594fSAndroid Build Coastguard Worker 
StopDebugger()132*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::StopDebugger() {
133*795d594fSAndroid Build Coastguard Worker   for (DebuggerControlCallback* cb : COPY(debugger_control_callbacks_)) {
134*795d594fSAndroid Build Coastguard Worker     cb->StopDebugger();
135*795d594fSAndroid Build Coastguard Worker   }
136*795d594fSAndroid Build Coastguard Worker }
137*795d594fSAndroid Build Coastguard Worker 
AddMethodInspectionCallback(MethodInspectionCallback * cb)138*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::AddMethodInspectionCallback(MethodInspectionCallback* cb) {
139*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
140*795d594fSAndroid Build Coastguard Worker   method_inspection_callbacks_.push_back(cb);
141*795d594fSAndroid Build Coastguard Worker }
142*795d594fSAndroid Build Coastguard Worker 
RemoveMethodInspectionCallback(MethodInspectionCallback * cb)143*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::RemoveMethodInspectionCallback(MethodInspectionCallback* cb) {
144*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
145*795d594fSAndroid Build Coastguard Worker   Remove(cb, &method_inspection_callbacks_);
146*795d594fSAndroid Build Coastguard Worker }
147*795d594fSAndroid Build Coastguard Worker 
HaveLocalsChanged()148*795d594fSAndroid Build Coastguard Worker bool RuntimeCallbacks::HaveLocalsChanged() {
149*795d594fSAndroid Build Coastguard Worker   for (MethodInspectionCallback* cb : COPY(method_inspection_callbacks_)) {
150*795d594fSAndroid Build Coastguard Worker     if (cb->HaveLocalsChanged()) {
151*795d594fSAndroid Build Coastguard Worker       return true;
152*795d594fSAndroid Build Coastguard Worker     }
153*795d594fSAndroid Build Coastguard Worker   }
154*795d594fSAndroid Build Coastguard Worker   return false;
155*795d594fSAndroid Build Coastguard Worker }
156*795d594fSAndroid Build Coastguard Worker 
AddThreadLifecycleCallback(ThreadLifecycleCallback * cb)157*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::AddThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
158*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
159*795d594fSAndroid Build Coastguard Worker   thread_callbacks_.push_back(cb);
160*795d594fSAndroid Build Coastguard Worker }
161*795d594fSAndroid Build Coastguard Worker 
MonitorContendedLocking(Monitor * m)162*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::MonitorContendedLocking(Monitor* m) {
163*795d594fSAndroid Build Coastguard Worker   for (MonitorCallback* cb : COPY(monitor_callbacks_)) {
164*795d594fSAndroid Build Coastguard Worker     cb->MonitorContendedLocking(m);
165*795d594fSAndroid Build Coastguard Worker   }
166*795d594fSAndroid Build Coastguard Worker }
167*795d594fSAndroid Build Coastguard Worker 
MonitorContendedLocked(Monitor * m)168*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::MonitorContendedLocked(Monitor* m) {
169*795d594fSAndroid Build Coastguard Worker   for (MonitorCallback* cb : COPY(monitor_callbacks_)) {
170*795d594fSAndroid Build Coastguard Worker     cb->MonitorContendedLocked(m);
171*795d594fSAndroid Build Coastguard Worker   }
172*795d594fSAndroid Build Coastguard Worker }
173*795d594fSAndroid Build Coastguard Worker 
ObjectWaitStart(Handle<mirror::Object> m,int64_t timeout)174*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::ObjectWaitStart(Handle<mirror::Object> m, int64_t timeout) {
175*795d594fSAndroid Build Coastguard Worker   for (MonitorCallback* cb : COPY(monitor_callbacks_)) {
176*795d594fSAndroid Build Coastguard Worker     cb->ObjectWaitStart(m, timeout);
177*795d594fSAndroid Build Coastguard Worker   }
178*795d594fSAndroid Build Coastguard Worker }
179*795d594fSAndroid Build Coastguard Worker 
MonitorWaitFinished(Monitor * m,bool timeout)180*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::MonitorWaitFinished(Monitor* m, bool timeout) {
181*795d594fSAndroid Build Coastguard Worker   for (MonitorCallback* cb : COPY(monitor_callbacks_)) {
182*795d594fSAndroid Build Coastguard Worker     cb->MonitorWaitFinished(m, timeout);
183*795d594fSAndroid Build Coastguard Worker   }
184*795d594fSAndroid Build Coastguard Worker }
185*795d594fSAndroid Build Coastguard Worker 
AddMonitorCallback(MonitorCallback * cb)186*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::AddMonitorCallback(MonitorCallback* cb) {
187*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
188*795d594fSAndroid Build Coastguard Worker   monitor_callbacks_.push_back(cb);
189*795d594fSAndroid Build Coastguard Worker }
190*795d594fSAndroid Build Coastguard Worker 
RemoveMonitorCallback(MonitorCallback * cb)191*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::RemoveMonitorCallback(MonitorCallback* cb) {
192*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
193*795d594fSAndroid Build Coastguard Worker   Remove(cb, &monitor_callbacks_);
194*795d594fSAndroid Build Coastguard Worker }
195*795d594fSAndroid Build Coastguard Worker 
ThreadParkStart(bool is_absolute,int64_t timeout)196*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::ThreadParkStart(bool is_absolute, int64_t timeout) {
197*795d594fSAndroid Build Coastguard Worker   for (ParkCallback * cb : COPY(park_callbacks_)) {
198*795d594fSAndroid Build Coastguard Worker     cb->ThreadParkStart(is_absolute, timeout);
199*795d594fSAndroid Build Coastguard Worker   }
200*795d594fSAndroid Build Coastguard Worker }
201*795d594fSAndroid Build Coastguard Worker 
ThreadParkFinished(bool timeout)202*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::ThreadParkFinished(bool timeout) {
203*795d594fSAndroid Build Coastguard Worker   for (ParkCallback * cb : COPY(park_callbacks_)) {
204*795d594fSAndroid Build Coastguard Worker     cb->ThreadParkFinished(timeout);
205*795d594fSAndroid Build Coastguard Worker   }
206*795d594fSAndroid Build Coastguard Worker }
207*795d594fSAndroid Build Coastguard Worker 
AddParkCallback(ParkCallback * cb)208*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::AddParkCallback(ParkCallback* cb) {
209*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
210*795d594fSAndroid Build Coastguard Worker   park_callbacks_.push_back(cb);
211*795d594fSAndroid Build Coastguard Worker }
212*795d594fSAndroid Build Coastguard Worker 
RemoveParkCallback(ParkCallback * cb)213*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::RemoveParkCallback(ParkCallback* cb) {
214*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
215*795d594fSAndroid Build Coastguard Worker   Remove(cb, &park_callbacks_);
216*795d594fSAndroid Build Coastguard Worker }
217*795d594fSAndroid Build Coastguard Worker 
RemoveThreadLifecycleCallback(ThreadLifecycleCallback * cb)218*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::RemoveThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
219*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
220*795d594fSAndroid Build Coastguard Worker   Remove(cb, &thread_callbacks_);
221*795d594fSAndroid Build Coastguard Worker }
222*795d594fSAndroid Build Coastguard Worker 
ThreadStart(Thread * self)223*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::ThreadStart(Thread* self) {
224*795d594fSAndroid Build Coastguard Worker   for (ThreadLifecycleCallback* cb : COPY(thread_callbacks_)) {
225*795d594fSAndroid Build Coastguard Worker     cb->ThreadStart(self);
226*795d594fSAndroid Build Coastguard Worker   }
227*795d594fSAndroid Build Coastguard Worker }
228*795d594fSAndroid Build Coastguard Worker 
ThreadDeath(Thread * self)229*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::ThreadDeath(Thread* self) {
230*795d594fSAndroid Build Coastguard Worker   for (ThreadLifecycleCallback* cb : COPY(thread_callbacks_)) {
231*795d594fSAndroid Build Coastguard Worker     cb->ThreadDeath(self);
232*795d594fSAndroid Build Coastguard Worker   }
233*795d594fSAndroid Build Coastguard Worker }
234*795d594fSAndroid Build Coastguard Worker 
AddClassLoadCallback(ClassLoadCallback * cb)235*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::AddClassLoadCallback(ClassLoadCallback* cb) {
236*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
237*795d594fSAndroid Build Coastguard Worker   class_callbacks_.push_back(cb);
238*795d594fSAndroid Build Coastguard Worker }
239*795d594fSAndroid Build Coastguard Worker 
RemoveClassLoadCallback(ClassLoadCallback * cb)240*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::RemoveClassLoadCallback(ClassLoadCallback* cb) {
241*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
242*795d594fSAndroid Build Coastguard Worker   Remove(cb, &class_callbacks_);
243*795d594fSAndroid Build Coastguard Worker }
244*795d594fSAndroid Build Coastguard Worker 
ClassLoad(Handle<mirror::Class> klass)245*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::ClassLoad(Handle<mirror::Class> klass) {
246*795d594fSAndroid Build Coastguard Worker   for (ClassLoadCallback* cb : COPY(class_callbacks_)) {
247*795d594fSAndroid Build Coastguard Worker     cb->ClassLoad(klass);
248*795d594fSAndroid Build Coastguard Worker   }
249*795d594fSAndroid Build Coastguard Worker }
250*795d594fSAndroid Build Coastguard Worker 
EndDefineClass()251*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::EndDefineClass() {
252*795d594fSAndroid Build Coastguard Worker   for (ClassLoadCallback* cb : COPY(class_callbacks_)) {
253*795d594fSAndroid Build Coastguard Worker     cb->EndDefineClass();
254*795d594fSAndroid Build Coastguard Worker   }
255*795d594fSAndroid Build Coastguard Worker }
256*795d594fSAndroid Build Coastguard Worker 
BeginDefineClass()257*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::BeginDefineClass() {
258*795d594fSAndroid Build Coastguard Worker   for (ClassLoadCallback* cb : COPY(class_callbacks_)) {
259*795d594fSAndroid Build Coastguard Worker     cb->BeginDefineClass();
260*795d594fSAndroid Build Coastguard Worker   }
261*795d594fSAndroid Build Coastguard Worker }
262*795d594fSAndroid Build Coastguard Worker 
263*795d594fSAndroid Build Coastguard Worker 
ClassPreDefine(const char * descriptor,Handle<mirror::Class> temp_class,Handle<mirror::ClassLoader> loader,const DexFile & initial_dex_file,const dex::ClassDef & initial_class_def,DexFile const ** final_dex_file,dex::ClassDef const ** final_class_def)264*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::ClassPreDefine(const char* descriptor,
265*795d594fSAndroid Build Coastguard Worker                                       Handle<mirror::Class> temp_class,
266*795d594fSAndroid Build Coastguard Worker                                       Handle<mirror::ClassLoader> loader,
267*795d594fSAndroid Build Coastguard Worker                                       const DexFile& initial_dex_file,
268*795d594fSAndroid Build Coastguard Worker                                       const dex::ClassDef& initial_class_def,
269*795d594fSAndroid Build Coastguard Worker                                       /*out*/DexFile const** final_dex_file,
270*795d594fSAndroid Build Coastguard Worker                                       /*out*/dex::ClassDef const** final_class_def) {
271*795d594fSAndroid Build Coastguard Worker   DexFile const* current_dex_file = &initial_dex_file;
272*795d594fSAndroid Build Coastguard Worker   dex::ClassDef const* current_class_def = &initial_class_def;
273*795d594fSAndroid Build Coastguard Worker   for (ClassLoadCallback* cb : COPY(class_callbacks_)) {
274*795d594fSAndroid Build Coastguard Worker     DexFile const* new_dex_file = nullptr;
275*795d594fSAndroid Build Coastguard Worker     dex::ClassDef const* new_class_def = nullptr;
276*795d594fSAndroid Build Coastguard Worker     cb->ClassPreDefine(descriptor,
277*795d594fSAndroid Build Coastguard Worker                        temp_class,
278*795d594fSAndroid Build Coastguard Worker                        loader,
279*795d594fSAndroid Build Coastguard Worker                        *current_dex_file,
280*795d594fSAndroid Build Coastguard Worker                        *current_class_def,
281*795d594fSAndroid Build Coastguard Worker                        &new_dex_file,
282*795d594fSAndroid Build Coastguard Worker                        &new_class_def);
283*795d594fSAndroid Build Coastguard Worker     if ((new_dex_file != nullptr && new_dex_file != current_dex_file) ||
284*795d594fSAndroid Build Coastguard Worker         (new_class_def != nullptr && new_class_def != current_class_def)) {
285*795d594fSAndroid Build Coastguard Worker       DCHECK(new_dex_file != nullptr && new_class_def != nullptr);
286*795d594fSAndroid Build Coastguard Worker       current_dex_file = new_dex_file;
287*795d594fSAndroid Build Coastguard Worker       current_class_def = new_class_def;
288*795d594fSAndroid Build Coastguard Worker     }
289*795d594fSAndroid Build Coastguard Worker   }
290*795d594fSAndroid Build Coastguard Worker   *final_dex_file = current_dex_file;
291*795d594fSAndroid Build Coastguard Worker   *final_class_def = current_class_def;
292*795d594fSAndroid Build Coastguard Worker }
293*795d594fSAndroid Build Coastguard Worker 
ClassPrepare(Handle<mirror::Class> temp_klass,Handle<mirror::Class> klass)294*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::ClassPrepare(Handle<mirror::Class> temp_klass, Handle<mirror::Class> klass) {
295*795d594fSAndroid Build Coastguard Worker   for (ClassLoadCallback* cb : COPY(class_callbacks_)) {
296*795d594fSAndroid Build Coastguard Worker     cb->ClassPrepare(temp_klass, klass);
297*795d594fSAndroid Build Coastguard Worker   }
298*795d594fSAndroid Build Coastguard Worker }
299*795d594fSAndroid Build Coastguard Worker 
AddRuntimeSigQuitCallback(RuntimeSigQuitCallback * cb)300*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::AddRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) {
301*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
302*795d594fSAndroid Build Coastguard Worker   sigquit_callbacks_.push_back(cb);
303*795d594fSAndroid Build Coastguard Worker }
304*795d594fSAndroid Build Coastguard Worker 
RemoveRuntimeSigQuitCallback(RuntimeSigQuitCallback * cb)305*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::RemoveRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) {
306*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
307*795d594fSAndroid Build Coastguard Worker   Remove(cb, &sigquit_callbacks_);
308*795d594fSAndroid Build Coastguard Worker }
309*795d594fSAndroid Build Coastguard Worker 
SigQuit()310*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::SigQuit() {
311*795d594fSAndroid Build Coastguard Worker   for (RuntimeSigQuitCallback* cb : COPY(sigquit_callbacks_)) {
312*795d594fSAndroid Build Coastguard Worker     cb->SigQuit();
313*795d594fSAndroid Build Coastguard Worker   }
314*795d594fSAndroid Build Coastguard Worker }
315*795d594fSAndroid Build Coastguard Worker 
AddRuntimePhaseCallback(RuntimePhaseCallback * cb)316*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::AddRuntimePhaseCallback(RuntimePhaseCallback* cb) {
317*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
318*795d594fSAndroid Build Coastguard Worker   phase_callbacks_.push_back(cb);
319*795d594fSAndroid Build Coastguard Worker }
320*795d594fSAndroid Build Coastguard Worker 
RemoveRuntimePhaseCallback(RuntimePhaseCallback * cb)321*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::RemoveRuntimePhaseCallback(RuntimePhaseCallback* cb) {
322*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
323*795d594fSAndroid Build Coastguard Worker   Remove(cb, &phase_callbacks_);
324*795d594fSAndroid Build Coastguard Worker }
325*795d594fSAndroid Build Coastguard Worker 
NextRuntimePhase(RuntimePhaseCallback::RuntimePhase phase)326*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::NextRuntimePhase(RuntimePhaseCallback::RuntimePhase phase) {
327*795d594fSAndroid Build Coastguard Worker   for (RuntimePhaseCallback* cb : COPY(phase_callbacks_)) {
328*795d594fSAndroid Build Coastguard Worker     cb->NextRuntimePhase(phase);
329*795d594fSAndroid Build Coastguard Worker   }
330*795d594fSAndroid Build Coastguard Worker }
331*795d594fSAndroid Build Coastguard Worker 
AddMethodCallback(MethodCallback * cb)332*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::AddMethodCallback(MethodCallback* cb) {
333*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
334*795d594fSAndroid Build Coastguard Worker   method_callbacks_.push_back(cb);
335*795d594fSAndroid Build Coastguard Worker }
336*795d594fSAndroid Build Coastguard Worker 
RemoveMethodCallback(MethodCallback * cb)337*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::RemoveMethodCallback(MethodCallback* cb) {
338*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
339*795d594fSAndroid Build Coastguard Worker   Remove(cb, &method_callbacks_);
340*795d594fSAndroid Build Coastguard Worker }
341*795d594fSAndroid Build Coastguard Worker 
RegisterNativeMethod(ArtMethod * method,const void * in_cur_method,void ** new_method)342*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::RegisterNativeMethod(ArtMethod* method,
343*795d594fSAndroid Build Coastguard Worker                                             const void* in_cur_method,
344*795d594fSAndroid Build Coastguard Worker                                             /*out*/void** new_method) {
345*795d594fSAndroid Build Coastguard Worker   void* cur_method = const_cast<void*>(in_cur_method);
346*795d594fSAndroid Build Coastguard Worker   *new_method = cur_method;
347*795d594fSAndroid Build Coastguard Worker   for (MethodCallback* cb : COPY(method_callbacks_)) {
348*795d594fSAndroid Build Coastguard Worker     cb->RegisterNativeMethod(method, cur_method, new_method);
349*795d594fSAndroid Build Coastguard Worker     if (*new_method != nullptr) {
350*795d594fSAndroid Build Coastguard Worker       cur_method = *new_method;
351*795d594fSAndroid Build Coastguard Worker     }
352*795d594fSAndroid Build Coastguard Worker   }
353*795d594fSAndroid Build Coastguard Worker }
354*795d594fSAndroid Build Coastguard Worker 
AddReflectiveValueVisitCallback(ReflectiveValueVisitCallback * cb)355*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::AddReflectiveValueVisitCallback(ReflectiveValueVisitCallback *cb) {
356*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
357*795d594fSAndroid Build Coastguard Worker   reflective_value_visit_callbacks_.push_back(cb);
358*795d594fSAndroid Build Coastguard Worker }
359*795d594fSAndroid Build Coastguard Worker 
RemoveReflectiveValueVisitCallback(ReflectiveValueVisitCallback * cb)360*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::RemoveReflectiveValueVisitCallback(ReflectiveValueVisitCallback *cb) {
361*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *callback_lock_);
362*795d594fSAndroid Build Coastguard Worker   Remove(cb, &reflective_value_visit_callbacks_);
363*795d594fSAndroid Build Coastguard Worker }
364*795d594fSAndroid Build Coastguard Worker 
VisitReflectiveTargets(ReflectiveValueVisitor * visitor)365*795d594fSAndroid Build Coastguard Worker void RuntimeCallbacks::VisitReflectiveTargets(ReflectiveValueVisitor *visitor) {
366*795d594fSAndroid Build Coastguard Worker   for (ReflectiveValueVisitCallback* cb : COPY(reflective_value_visit_callbacks_)) {
367*795d594fSAndroid Build Coastguard Worker     cb->VisitReflectiveTargets(visitor);
368*795d594fSAndroid Build Coastguard Worker   }
369*795d594fSAndroid Build Coastguard Worker }
370*795d594fSAndroid Build Coastguard Worker 
371*795d594fSAndroid Build Coastguard Worker }  // namespace art
372