blob: 16d6c13722d6ddc9beec824770ff552452047bea [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"
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000024#include "thread.h"
25
26namespace art {
27
28void RuntimeCallbacks::AddThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
29 thread_callbacks_.push_back(cb);
30}
31
Andreas Gampea5814f92017-01-18 21:43:16 -080032template <typename T>
33ALWAYS_INLINE
34static 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);
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000038 }
39}
40
Andreas Gampea5814f92017-01-18 21:43:16 -080041void RuntimeCallbacks::RemoveThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
42 Remove(cb, &thread_callbacks_);
43}
44
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000045void RuntimeCallbacks::ThreadStart(Thread* self) {
46 for (ThreadLifecycleCallback* cb : thread_callbacks_) {
47 cb->ThreadStart(self);
48 }
49}
50
51void RuntimeCallbacks::ThreadDeath(Thread* self) {
52 for (ThreadLifecycleCallback* cb : thread_callbacks_) {
53 cb->ThreadDeath(self);
54 }
55}
56
Andreas Gampe0f01b582017-01-18 15:22:37 -080057void RuntimeCallbacks::AddClassLoadCallback(ClassLoadCallback* cb) {
58 class_callbacks_.push_back(cb);
59}
60
61void RuntimeCallbacks::RemoveClassLoadCallback(ClassLoadCallback* cb) {
Andreas Gampea5814f92017-01-18 21:43:16 -080062 Remove(cb, &class_callbacks_);
Andreas Gampe0f01b582017-01-18 15:22:37 -080063}
64
65void RuntimeCallbacks::ClassLoad(Handle<mirror::Class> klass) {
66 for (ClassLoadCallback* cb : class_callbacks_) {
67 cb->ClassLoad(klass);
68 }
69}
70
Alex Lightb0f11922017-01-23 14:25:17 -080071void 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
Andreas Gampe0f01b582017-01-18 15:22:37 -0800101void 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
Andreas Gampea5814f92017-01-18 21:43:16 -0800107void RuntimeCallbacks::AddRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) {
108 sigquit_callbacks_.push_back(cb);
109}
110
111void RuntimeCallbacks::RemoveRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) {
112 Remove(cb, &sigquit_callbacks_);
113}
114
115void RuntimeCallbacks::SigQuit() {
116 for (RuntimeSigQuitCallback* cb : sigquit_callbacks_) {
117 cb->SigQuit();
118 }
119}
120
Andreas Gampe48864112017-01-19 17:23:17 -0800121void RuntimeCallbacks::AddRuntimePhaseCallback(RuntimePhaseCallback* cb) {
122 phase_callbacks_.push_back(cb);
123}
124
125void RuntimeCallbacks::RemoveRuntimePhaseCallback(RuntimePhaseCallback* cb) {
126 Remove(cb, &phase_callbacks_);
127}
128
129void RuntimeCallbacks::NextRuntimePhase(RuntimePhaseCallback::RuntimePhase phase) {
130 for (RuntimePhaseCallback* cb : phase_callbacks_) {
131 cb->NextRuntimePhase(phase);
132 }
133}
134
Alex Lightd78ddec2017-04-18 15:20:38 -0700135void RuntimeCallbacks::AddMethodCallback(MethodCallback* cb) {
136 method_callbacks_.push_back(cb);
137}
138
139void RuntimeCallbacks::RemoveMethodCallback(MethodCallback* cb) {
140 Remove(cb, &method_callbacks_);
141}
142
143void 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
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000156} // namespace art