blob: 25324b52d1e3bee6403a2c652ebbc90ec8519e7e [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
Andreas Gampea5814f92017-01-18 21:43:16 -080021#include "base/macros.h"
Andreas Gampe0f01b582017-01-18 15:22:37 -080022#include "class_linker.h"
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000023#include "thread.h"
24
25namespace art {
26
27void RuntimeCallbacks::AddThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
28 thread_callbacks_.push_back(cb);
29}
30
Andreas Gampea5814f92017-01-18 21:43:16 -080031template <typename T>
32ALWAYS_INLINE
33static inline void Remove(T* cb, std::vector<T*>* data) {
34 auto it = std::find(data->begin(), data->end(), cb);
35 if (it != data->end()) {
36 data->erase(it);
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000037 }
38}
39
Andreas Gampea5814f92017-01-18 21:43:16 -080040void RuntimeCallbacks::RemoveThreadLifecycleCallback(ThreadLifecycleCallback* cb) {
41 Remove(cb, &thread_callbacks_);
42}
43
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000044void RuntimeCallbacks::ThreadStart(Thread* self) {
45 for (ThreadLifecycleCallback* cb : thread_callbacks_) {
46 cb->ThreadStart(self);
47 }
48}
49
50void RuntimeCallbacks::ThreadDeath(Thread* self) {
51 for (ThreadLifecycleCallback* cb : thread_callbacks_) {
52 cb->ThreadDeath(self);
53 }
54}
55
Andreas Gampe0f01b582017-01-18 15:22:37 -080056void RuntimeCallbacks::AddClassLoadCallback(ClassLoadCallback* cb) {
57 class_callbacks_.push_back(cb);
58}
59
60void RuntimeCallbacks::RemoveClassLoadCallback(ClassLoadCallback* cb) {
Andreas Gampea5814f92017-01-18 21:43:16 -080061 Remove(cb, &class_callbacks_);
Andreas Gampe0f01b582017-01-18 15:22:37 -080062}
63
64void RuntimeCallbacks::ClassLoad(Handle<mirror::Class> klass) {
65 for (ClassLoadCallback* cb : class_callbacks_) {
66 cb->ClassLoad(klass);
67 }
68}
69
Alex Lightb0f11922017-01-23 14:25:17 -080070void RuntimeCallbacks::ClassPreDefine(const char* descriptor,
71 Handle<mirror::Class> temp_class,
72 Handle<mirror::ClassLoader> loader,
73 const DexFile& initial_dex_file,
74 const DexFile::ClassDef& initial_class_def,
75 /*out*/DexFile const** final_dex_file,
76 /*out*/DexFile::ClassDef const** final_class_def) {
77 DexFile const* current_dex_file = &initial_dex_file;
78 DexFile::ClassDef const* current_class_def = &initial_class_def;
79 for (ClassLoadCallback* cb : class_callbacks_) {
80 DexFile const* new_dex_file = nullptr;
81 DexFile::ClassDef const* new_class_def = nullptr;
82 cb->ClassPreDefine(descriptor,
83 temp_class,
84 loader,
85 *current_dex_file,
86 *current_class_def,
87 &new_dex_file,
88 &new_class_def);
89 if ((new_dex_file != nullptr && new_dex_file != current_dex_file) ||
90 (new_class_def != nullptr && new_class_def != current_class_def)) {
91 DCHECK(new_dex_file != nullptr && new_class_def != nullptr);
92 current_dex_file = new_dex_file;
93 current_class_def = new_class_def;
94 }
95 }
96 *final_dex_file = current_dex_file;
97 *final_class_def = current_class_def;
98}
99
Andreas Gampe0f01b582017-01-18 15:22:37 -0800100void RuntimeCallbacks::ClassPrepare(Handle<mirror::Class> temp_klass, Handle<mirror::Class> klass) {
101 for (ClassLoadCallback* cb : class_callbacks_) {
102 cb->ClassPrepare(temp_klass, klass);
103 }
104}
105
Andreas Gampea5814f92017-01-18 21:43:16 -0800106void RuntimeCallbacks::AddRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) {
107 sigquit_callbacks_.push_back(cb);
108}
109
110void RuntimeCallbacks::RemoveRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb) {
111 Remove(cb, &sigquit_callbacks_);
112}
113
114void RuntimeCallbacks::SigQuit() {
115 for (RuntimeSigQuitCallback* cb : sigquit_callbacks_) {
116 cb->SigQuit();
117 }
118}
119
Andreas Gampe48864112017-01-19 17:23:17 -0800120void RuntimeCallbacks::AddRuntimePhaseCallback(RuntimePhaseCallback* cb) {
121 phase_callbacks_.push_back(cb);
122}
123
124void RuntimeCallbacks::RemoveRuntimePhaseCallback(RuntimePhaseCallback* cb) {
125 Remove(cb, &phase_callbacks_);
126}
127
128void RuntimeCallbacks::NextRuntimePhase(RuntimePhaseCallback::RuntimePhase phase) {
129 for (RuntimePhaseCallback* cb : phase_callbacks_) {
130 cb->NextRuntimePhase(phase);
131 }
132}
133
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000134} // namespace art