blob: 88d3f28583c08f88d1e1d0e65c391651cd1b63e5 [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
29void RuntimeCallbacks::AddThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
30 thread_callbacks_.push_back(cb);
31}
32
Andreas Gampea5814f92017-01-18 21:43:16 -080033template <typename T>
34ALWAYS_INLINE
35static inline void Remove(T* cb, std::vector<T*>* data) {
36 auto it = std::find(data->begin(), data->end(), cb);
37 if (it != data->end()) {
38 data->erase(it);
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000039 }
40}
41
Alex Light77fee872017-09-05 14:51:49 -070042void RuntimeCallbacks::MonitorContendedLocking(Monitor* m) {
43 for (MonitorCallback* cb : monitor_callbacks_) {
44 cb->MonitorContendedLocking(m);
45 }
46}
47
48void RuntimeCallbacks::MonitorContendedLocked(Monitor* m) {
49 for (MonitorCallback* cb : monitor_callbacks_) {
50 cb->MonitorContendedLocked(m);
51 }
52}
53
54void RuntimeCallbacks::ObjectWaitStart(Handle<mirror::Object> m, int64_t timeout) {
55 for (MonitorCallback* cb : monitor_callbacks_) {
56 cb->ObjectWaitStart(m, timeout);
57 }
58}
59
60void RuntimeCallbacks::MonitorWaitFinished(Monitor* m, bool timeout) {
61 for (MonitorCallback* cb : monitor_callbacks_) {
62 cb->MonitorWaitFinished(m, timeout);
63 }
64}
65
66void RuntimeCallbacks::AddMonitorCallback(MonitorCallback* cb) {
67 monitor_callbacks_.push_back(cb);
68}
69
70void RuntimeCallbacks::RemoveMonitorCallback(MonitorCallback* cb) {
71 Remove(cb, &monitor_callbacks_);
72}
73
Andreas Gampea5814f92017-01-18 21:43:16 -080074void RuntimeCallbacks::RemoveThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
75 Remove(cb, &thread_callbacks_);
76}
77
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000078void RuntimeCallbacks::ThreadStart(Thread* self) {
79 for (ThreadLifecycleCallback* cb : thread_callbacks_) {
80 cb->ThreadStart(self);
81 }
82}
83
84void RuntimeCallbacks::ThreadDeath(Thread* self) {
85 for (ThreadLifecycleCallback* cb : thread_callbacks_) {
86 cb->ThreadDeath(self);
87 }
88}
89
Andreas Gampe0f01b582017-01-18 15:22:37 -080090void RuntimeCallbacks::AddClassLoadCallback(ClassLoadCallback* cb) {
91 class_callbacks_.push_back(cb);
92}
93
94void RuntimeCallbacks::RemoveClassLoadCallback(ClassLoadCallback* cb) {
Andreas Gampea5814f92017-01-18 21:43:16 -080095 Remove(cb, &class_callbacks_);
Andreas Gampe0f01b582017-01-18 15:22:37 -080096}
97
98void RuntimeCallbacks::ClassLoad(Handle<mirror::Class> klass) {
99 for (ClassLoadCallback* cb : class_callbacks_) {
100 cb->ClassLoad(klass);
101 }
102}
103
Alex Lightb0f11922017-01-23 14:25:17 -0800104void RuntimeCallbacks::ClassPreDefine(const char* descriptor,
105 Handle<mirror::Class> temp_class,
106 Handle<mirror::ClassLoader> loader,
107 const DexFile& initial_dex_file,
108 const DexFile::ClassDef& initial_class_def,
109 /*out*/DexFile const** final_dex_file,
110 /*out*/DexFile::ClassDef const** final_class_def) {
111 DexFile const* current_dex_file = &initial_dex_file;
112 DexFile::ClassDef const* current_class_def = &initial_class_def;
113 for (ClassLoadCallback* cb : class_callbacks_) {
114 DexFile const* new_dex_file = nullptr;
115 DexFile::ClassDef const* new_class_def = nullptr;
116 cb->ClassPreDefine(descriptor,
117 temp_class,
118 loader,
119 *current_dex_file,
120 *current_class_def,
121 &new_dex_file,
122 &new_class_def);
123 if ((new_dex_file != nullptr && new_dex_file != current_dex_file) ||
124 (new_class_def != nullptr && new_class_def != current_class_def)) {
125 DCHECK(new_dex_file != nullptr && new_class_def != nullptr);
126 current_dex_file = new_dex_file;
127 current_class_def = new_class_def;
128 }
129 }
130 *final_dex_file = current_dex_file;
131 *final_class_def = current_class_def;
132}
133
Andreas Gampe0f01b582017-01-18 15:22:37 -0800134void RuntimeCallbacks::ClassPrepare(Handle<mirror::Class> temp_klass, Handle<mirror::Class> klass) {
135 for (ClassLoadCallback* cb : class_callbacks_) {
136 cb->ClassPrepare(temp_klass, klass);
137 }
138}
139
Andreas Gampea5814f92017-01-18 21:43:16 -0800140void RuntimeCallbacks::AddRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) {
141 sigquit_callbacks_.push_back(cb);
142}
143
144void RuntimeCallbacks::RemoveRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) {
145 Remove(cb, &sigquit_callbacks_);
146}
147
148void RuntimeCallbacks::SigQuit() {
149 for (RuntimeSigQuitCallback* cb : sigquit_callbacks_) {
150 cb->SigQuit();
151 }
152}
153
Andreas Gampe48864112017-01-19 17:23:17 -0800154void RuntimeCallbacks::AddRuntimePhaseCallback(RuntimePhaseCallback* cb) {
155 phase_callbacks_.push_back(cb);
156}
157
158void RuntimeCallbacks::RemoveRuntimePhaseCallback(RuntimePhaseCallback* cb) {
159 Remove(cb, &phase_callbacks_);
160}
161
162void RuntimeCallbacks::NextRuntimePhase(RuntimePhaseCallback::RuntimePhase phase) {
163 for (RuntimePhaseCallback* cb : phase_callbacks_) {
164 cb->NextRuntimePhase(phase);
165 }
166}
167
Alex Lightd78ddec2017-04-18 15:20:38 -0700168void RuntimeCallbacks::AddMethodCallback(MethodCallback* cb) {
169 method_callbacks_.push_back(cb);
170}
171
172void RuntimeCallbacks::RemoveMethodCallback(MethodCallback* cb) {
173 Remove(cb, &method_callbacks_);
174}
175
176void RuntimeCallbacks::RegisterNativeMethod(ArtMethod* method,
177 const void* in_cur_method,
178 /*out*/void** new_method) {
179 void* cur_method = const_cast<void*>(in_cur_method);
180 *new_method = cur_method;
181 for (MethodCallback* cb : method_callbacks_) {
182 cb->RegisterNativeMethod(method, cur_method, new_method);
183 if (*new_method != nullptr) {
184 cur_method = *new_method;
185 }
186 }
187}
188
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000189} // namespace art