blob: f164f7c8ecdad89d7513739163f0538381235c0f [file] [log] [blame]
Andreas Gampe04bbb5b2017-01-19 17:49:03 +00001/*
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
Alex Lightd78ddec2017-04-18 15:20:38 -070021#include "art_method.h"
Andreas Gampea5814f92017-01-18 21:43:16 -080022#include "base/macros.h"
Andreas Gampe0f01b582017-01-18 15:22:37 -080023#include "class_linker.h"
Alex Light77fee872017-09-05 14:51:49 -070024#include "monitor.h"
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000025#include "thread.h"
26
27namespace art {
28
Andreas Gampea5814f92017-01-18 21:43:16 -080029template <typename T>
30ALWAYS_INLINE
31static 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);
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000035 }
36}
37
Alex Light21611932017-09-26 13:07:39 -070038void RuntimeCallbacks::AddMethodInspectionCallback(MethodInspectionCallback* cb) {
39 method_inspection_callbacks_.push_back(cb);
40}
41
42void RuntimeCallbacks::RemoveMethodInspectionCallback(MethodInspectionCallback* cb) {
43 Remove(cb, &method_inspection_callbacks_);
44}
45
46bool RuntimeCallbacks::IsMethodBeingInspected(ArtMethod* m) {
47 for (MethodInspectionCallback* cb : method_inspection_callbacks_) {
48 if (cb->IsMethodBeingInspected(m)) {
49 return true;
50 }
51 }
52 return false;
53}
54
55void RuntimeCallbacks::AddThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
56 thread_callbacks_.push_back(cb);
57}
58
Alex Light77fee872017-09-05 14:51:49 -070059void RuntimeCallbacks::MonitorContendedLocking(Monitor* m) {
60 for (MonitorCallback* cb : monitor_callbacks_) {
61 cb->MonitorContendedLocking(m);
62 }
63}
64
65void RuntimeCallbacks::MonitorContendedLocked(Monitor* m) {
66 for (MonitorCallback* cb : monitor_callbacks_) {
67 cb->MonitorContendedLocked(m);
68 }
69}
70
71void RuntimeCallbacks::ObjectWaitStart(Handle<mirror::Object> m, int64_t timeout) {
72 for (MonitorCallback* cb : monitor_callbacks_) {
73 cb->ObjectWaitStart(m, timeout);
74 }
75}
76
77void RuntimeCallbacks::MonitorWaitFinished(Monitor* m, bool timeout) {
78 for (MonitorCallback* cb : monitor_callbacks_) {
79 cb->MonitorWaitFinished(m, timeout);
80 }
81}
82
83void RuntimeCallbacks::AddMonitorCallback(MonitorCallback* cb) {
84 monitor_callbacks_.push_back(cb);
85}
86
87void RuntimeCallbacks::RemoveMonitorCallback(MonitorCallback* cb) {
88 Remove(cb, &monitor_callbacks_);
89}
90
Andreas Gampea5814f92017-01-18 21:43:16 -080091void RuntimeCallbacks::RemoveThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
92 Remove(cb, &thread_callbacks_);
93}
94
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000095void RuntimeCallbacks::ThreadStart(Thread* self) {
96 for (ThreadLifecycleCallback* cb : thread_callbacks_) {
97 cb->ThreadStart(self);
98 }
99}
100
101void RuntimeCallbacks::ThreadDeath(Thread* self) {
102 for (ThreadLifecycleCallback* cb : thread_callbacks_) {
103 cb->ThreadDeath(self);
104 }
105}
106
Andreas Gampe0f01b582017-01-18 15:22:37 -0800107void RuntimeCallbacks::AddClassLoadCallback(ClassLoadCallback* cb) {
108 class_callbacks_.push_back(cb);
109}
110
111void RuntimeCallbacks::RemoveClassLoadCallback(ClassLoadCallback* cb) {
Andreas Gampea5814f92017-01-18 21:43:16 -0800112 Remove(cb, &class_callbacks_);
Andreas Gampe0f01b582017-01-18 15:22:37 -0800113}
114
115void RuntimeCallbacks::ClassLoad(Handle<mirror::Class> klass) {
116 for (ClassLoadCallback* cb : class_callbacks_) {
117 cb->ClassLoad(klass);
118 }
119}
120
Alex Lightb0f11922017-01-23 14:25:17 -0800121void RuntimeCallbacks::ClassPreDefine(const char* descriptor,
122 Handle<mirror::Class> temp_class,
123 Handle<mirror::ClassLoader> loader,
124 const DexFile& initial_dex_file,
125 const DexFile::ClassDef& initial_class_def,
126 /*out*/DexFile const** final_dex_file,
127 /*out*/DexFile::ClassDef const** final_class_def) {
128 DexFile const* current_dex_file = &initial_dex_file;
129 DexFile::ClassDef const* current_class_def = &initial_class_def;
130 for (ClassLoadCallback* cb : class_callbacks_) {
131 DexFile const* new_dex_file = nullptr;
132 DexFile::ClassDef const* new_class_def = nullptr;
133 cb->ClassPreDefine(descriptor,
134 temp_class,
135 loader,
136 *current_dex_file,
137 *current_class_def,
138 &new_dex_file,
139 &new_class_def);
140 if ((new_dex_file != nullptr && new_dex_file != current_dex_file) ||
141 (new_class_def != nullptr && new_class_def != current_class_def)) {
142 DCHECK(new_dex_file != nullptr && new_class_def != nullptr);
143 current_dex_file = new_dex_file;
144 current_class_def = new_class_def;
145 }
146 }
147 *final_dex_file = current_dex_file;
148 *final_class_def = current_class_def;
149}
150
Andreas Gampe0f01b582017-01-18 15:22:37 -0800151void RuntimeCallbacks::ClassPrepare(Handle<mirror::Class> temp_klass, Handle<mirror::Class> klass) {
152 for (ClassLoadCallback* cb : class_callbacks_) {
153 cb->ClassPrepare(temp_klass, klass);
154 }
155}
156
Andreas Gampea5814f92017-01-18 21:43:16 -0800157void RuntimeCallbacks::AddRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) {
158 sigquit_callbacks_.push_back(cb);
159}
160
161void RuntimeCallbacks::RemoveRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) {
162 Remove(cb, &sigquit_callbacks_);
163}
164
165void RuntimeCallbacks::SigQuit() {
166 for (RuntimeSigQuitCallback* cb : sigquit_callbacks_) {
167 cb->SigQuit();
168 }
169}
170
Andreas Gampe48864112017-01-19 17:23:17 -0800171void RuntimeCallbacks::AddRuntimePhaseCallback(RuntimePhaseCallback* cb) {
172 phase_callbacks_.push_back(cb);
173}
174
175void RuntimeCallbacks::RemoveRuntimePhaseCallback(RuntimePhaseCallback* cb) {
176 Remove(cb, &phase_callbacks_);
177}
178
179void RuntimeCallbacks::NextRuntimePhase(RuntimePhaseCallback::RuntimePhase phase) {
180 for (RuntimePhaseCallback* cb : phase_callbacks_) {
181 cb->NextRuntimePhase(phase);
182 }
183}
184
Alex Lightd78ddec2017-04-18 15:20:38 -0700185void RuntimeCallbacks::AddMethodCallback(MethodCallback* cb) {
186 method_callbacks_.push_back(cb);
187}
188
189void RuntimeCallbacks::RemoveMethodCallback(MethodCallback* cb) {
190 Remove(cb, &method_callbacks_);
191}
192
193void RuntimeCallbacks::RegisterNativeMethod(ArtMethod* method,
194 const void* in_cur_method,
195 /*out*/void** new_method) {
196 void* cur_method = const_cast<void*>(in_cur_method);
197 *new_method = cur_method;
198 for (MethodCallback* cb : method_callbacks_) {
199 cb->RegisterNativeMethod(method, cur_method, new_method);
200 if (*new_method != nullptr) {
201 cur_method = *new_method;
202 }
203 }
204}
205
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000206} // namespace art