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