blob: 9f0410d102e9ea78005d231a7f941b0b714f5590 [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#ifndef ART_RUNTIME_RUNTIME_CALLBACKS_H_
18#define ART_RUNTIME_RUNTIME_CALLBACKS_H_
19
20#include <vector>
21
Alex Light8c2b9292017-11-09 13:21:01 -080022#include "base/array_ref.h"
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000023#include "base/macros.h"
24#include "base/mutex.h"
David Sehr9e734c72018-01-04 17:56:19 -080025#include "dex/dex_file.h"
Andreas Gampe0f01b582017-01-18 15:22:37 -080026#include "handle.h"
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000027
28namespace art {
29
Andreas Gampe0f01b582017-01-18 15:22:37 -080030namespace mirror {
31class Class;
Alex Lightb0f11922017-01-23 14:25:17 -080032class ClassLoader;
Alex Light77fee872017-09-05 14:51:49 -070033class Object;
Andreas Gampe0f01b582017-01-18 15:22:37 -080034} // namespace mirror
35
Alex Lightd78ddec2017-04-18 15:20:38 -070036class ArtMethod;
Andreas Gampe0f01b582017-01-18 15:22:37 -080037class ClassLoadCallback;
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000038class Thread;
Alex Lightd78ddec2017-04-18 15:20:38 -070039class MethodCallback;
Alex Light77fee872017-09-05 14:51:49 -070040class Monitor;
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000041class ThreadLifecycleCallback;
42
43// Note: RuntimeCallbacks uses the mutator lock to synchronize the callback lists. A thread must
44// hold the exclusive lock to add or remove a listener. A thread must hold the shared lock
45// to dispatch an event. This setup is chosen as some clients may want to suspend the
46// dispatching thread or all threads.
47//
48// To make this safe, the following restrictions apply:
49// * Only the owner of a listener may ever add or remove said listener.
50// * A listener must never add or remove itself or any other listener while running.
51// * It is the responsibility of the owner to not remove the listener while it is running
52// (and suspended).
53//
54// The simplest way to satisfy these restrictions is to never remove a listener, and to do
55// any state checking (is the listener enabled) in the listener itself. For an example, see
56// Dbg.
57
Alex Light8c2b9292017-11-09 13:21:01 -080058class DdmCallback {
59 public:
60 virtual ~DdmCallback() {}
61 virtual void DdmPublishChunk(uint32_t type, const ArrayRef<const uint8_t>& data)
62 REQUIRES_SHARED(Locks::mutator_lock_) = 0;
63};
64
Alex Light40320712017-12-14 11:52:04 -080065class DebuggerControlCallback {
66 public:
67 virtual ~DebuggerControlCallback() {}
68
69 // Begin running the debugger.
70 virtual void StartDebugger() = 0;
71 // The debugger should begin shutting down since the runtime is ending. This is just advisory
72 virtual void StopDebugger() = 0;
73
74 // This allows the debugger to tell the runtime if it is configured.
75 virtual bool IsDebuggerConfigured() = 0;
76};
77
Andreas Gampea5814f92017-01-18 21:43:16 -080078class RuntimeSigQuitCallback {
79 public:
80 virtual ~RuntimeSigQuitCallback() {}
81
82 virtual void SigQuit() REQUIRES_SHARED(Locks::mutator_lock_) = 0;
83};
84
Andreas Gampe48864112017-01-19 17:23:17 -080085class RuntimePhaseCallback {
86 public:
87 enum RuntimePhase {
Andreas Gampe96eca782017-01-19 19:45:30 -080088 kInitialAgents, // Initial agent loading is done.
89 kStart, // The runtime is started.
90 kInit, // The runtime is initialized (and will run user code soon).
91 kDeath, // The runtime just died.
Andreas Gampe48864112017-01-19 17:23:17 -080092 };
93
94 virtual ~RuntimePhaseCallback() {}
95
96 virtual void NextRuntimePhase(RuntimePhase phase) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
97};
98
Alex Light77fee872017-09-05 14:51:49 -070099class MonitorCallback {
100 public:
101 // Called just before the thread goes to sleep to wait for the monitor to become unlocked.
102 virtual void MonitorContendedLocking(Monitor* mon) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
103 // Called just after the monitor has been successfully acquired when it was already locked.
104 virtual void MonitorContendedLocked(Monitor* mon) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
105 // Called on entry to the Object#wait method regardless of whether or not the call is valid.
106 virtual void ObjectWaitStart(Handle<mirror::Object> obj, int64_t millis_timeout)
107 REQUIRES_SHARED(Locks::mutator_lock_) = 0;
108
109 // Called just after the monitor has woken up from going to sleep for a wait(). At this point the
110 // thread does not possess a lock on the monitor. This will only be called for threads wait calls
111 // where the thread did (or at least could have) gone to sleep.
112 virtual void MonitorWaitFinished(Monitor* m, bool timed_out)
113 REQUIRES_SHARED(Locks::mutator_lock_) = 0;
114
115 virtual ~MonitorCallback() {}
116};
117
Alex Light21611932017-09-26 13:07:39 -0700118// A callback to let parts of the runtime note that they are currently relying on a particular
119// method remaining in it's current state. Users should not rely on always being called. If multiple
120// callbacks are added the runtime will short-circuit when the first one returns 'true'.
121class MethodInspectionCallback {
122 public:
123 virtual ~MethodInspectionCallback() {}
124
125 // Returns true if the method is being inspected currently and the runtime should not modify it in
126 // potentially dangerous ways (i.e. replace with compiled version, JIT it, etc).
127 virtual bool IsMethodBeingInspected(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
Alex Light0fa17862017-10-24 13:43:05 -0700128
129 // Returns true if the method is safe to Jit, false otherwise.
130 // Note that '!IsMethodSafeToJit(m) implies IsMethodBeingInspected(m)'. That is that if this
131 // method returns false IsMethodBeingInspected must return true.
132 virtual bool IsMethodSafeToJit(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
Alex Lightd698ef52018-04-02 11:28:50 -0700133
134 // Returns true if we expect the method to be debuggable but are not doing anything unusual with
135 // it currently.
136 virtual bool MethodNeedsDebugVersion(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
Alex Light21611932017-09-26 13:07:39 -0700137};
138
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000139class RuntimeCallbacks {
140 public:
Andreas Gampe0f01b582017-01-18 15:22:37 -0800141 void AddThreadLifecycleCallback(ThreadLifecycleCallback* cb) REQUIRES(Locks::mutator_lock_);
142 void RemoveThreadLifecycleCallback(ThreadLifecycleCallback* cb) REQUIRES(Locks::mutator_lock_);
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000143
Andreas Gampe0f01b582017-01-18 15:22:37 -0800144 void ThreadStart(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);
145 void ThreadDeath(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);
146
147 void AddClassLoadCallback(ClassLoadCallback* cb) REQUIRES(Locks::mutator_lock_);
148 void RemoveClassLoadCallback(ClassLoadCallback* cb) REQUIRES(Locks::mutator_lock_);
149
150 void ClassLoad(Handle<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
151 void ClassPrepare(Handle<mirror::Class> temp_klass, Handle<mirror::Class> klass)
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000152 REQUIRES_SHARED(Locks::mutator_lock_);
153
Andreas Gampea5814f92017-01-18 21:43:16 -0800154 void AddRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb)
155 REQUIRES(Locks::mutator_lock_);
156 void RemoveRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb)
157 REQUIRES(Locks::mutator_lock_);
158
159 void SigQuit() REQUIRES_SHARED(Locks::mutator_lock_);
160
Andreas Gampe48864112017-01-19 17:23:17 -0800161 void AddRuntimePhaseCallback(RuntimePhaseCallback* cb)
162 REQUIRES(Locks::mutator_lock_);
163 void RemoveRuntimePhaseCallback(RuntimePhaseCallback* cb)
164 REQUIRES(Locks::mutator_lock_);
165
166 void NextRuntimePhase(RuntimePhaseCallback::RuntimePhase phase)
167 REQUIRES_SHARED(Locks::mutator_lock_);
168
Alex Lightb0f11922017-01-23 14:25:17 -0800169 void ClassPreDefine(const char* descriptor,
170 Handle<mirror::Class> temp_class,
171 Handle<mirror::ClassLoader> loader,
172 const DexFile& initial_dex_file,
173 const DexFile::ClassDef& initial_class_def,
174 /*out*/DexFile const** final_dex_file,
175 /*out*/DexFile::ClassDef const** final_class_def)
176 REQUIRES_SHARED(Locks::mutator_lock_);
177
Alex Lightd78ddec2017-04-18 15:20:38 -0700178 void AddMethodCallback(MethodCallback* cb) REQUIRES(Locks::mutator_lock_);
179 void RemoveMethodCallback(MethodCallback* cb) REQUIRES(Locks::mutator_lock_);
180
181 void RegisterNativeMethod(ArtMethod* method,
182 const void* original_implementation,
183 /*out*/void** new_implementation)
184 REQUIRES_SHARED(Locks::mutator_lock_);
185
Alex Light77fee872017-09-05 14:51:49 -0700186 void MonitorContendedLocking(Monitor* m) REQUIRES_SHARED(Locks::mutator_lock_);
187 void MonitorContendedLocked(Monitor* m) REQUIRES_SHARED(Locks::mutator_lock_);
188 void ObjectWaitStart(Handle<mirror::Object> m, int64_t timeout)
189 REQUIRES_SHARED(Locks::mutator_lock_);
190 void MonitorWaitFinished(Monitor* m, bool timed_out)
191 REQUIRES_SHARED(Locks::mutator_lock_);
192
193 void AddMonitorCallback(MonitorCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_);
194 void RemoveMonitorCallback(MonitorCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_);
195
Alex Light21611932017-09-26 13:07:39 -0700196 // Returns true if some MethodInspectionCallback indicates the method is being inspected/depended
197 // on by some code.
198 bool IsMethodBeingInspected(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
199
Alex Light0fa17862017-10-24 13:43:05 -0700200 // Returns false if some MethodInspectionCallback indicates the method cannot be safetly jitted
201 // (which implies that it is being Inspected). Returns true otherwise. If it returns false the
202 // entrypoint should not be changed to JITed code.
203 bool IsMethodSafeToJit(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
204
Alex Lightd698ef52018-04-02 11:28:50 -0700205 // Returns true if some MethodInspectionCallback indicates the method needs to use a debug
206 // version. This allows later code to set breakpoints or perform other actions that could be
207 // broken by some optimizations.
208 bool MethodNeedsDebugVersion(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
209
Alex Light21611932017-09-26 13:07:39 -0700210 void AddMethodInspectionCallback(MethodInspectionCallback* cb)
211 REQUIRES_SHARED(Locks::mutator_lock_);
212 void RemoveMethodInspectionCallback(MethodInspectionCallback* cb)
213 REQUIRES_SHARED(Locks::mutator_lock_);
214
Alex Light8c2b9292017-11-09 13:21:01 -0800215 // DDMS callbacks
216 void DdmPublishChunk(uint32_t type, const ArrayRef<const uint8_t>& data)
217 REQUIRES_SHARED(Locks::mutator_lock_);
218
219 void AddDdmCallback(DdmCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_);
220 void RemoveDdmCallback(DdmCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_);
221
Alex Light40320712017-12-14 11:52:04 -0800222 void StartDebugger() REQUIRES_SHARED(Locks::mutator_lock_);
223 // NO_THREAD_SAFETY_ANALYSIS since this is only called when we are in the middle of shutting down
224 // and the mutator_lock_ is no longer acquirable.
225 void StopDebugger() NO_THREAD_SAFETY_ANALYSIS;
226 bool IsDebuggerConfigured() REQUIRES_SHARED(Locks::mutator_lock_);
227
228 void AddDebuggerControlCallback(DebuggerControlCallback* cb)
229 REQUIRES_SHARED(Locks::mutator_lock_);
230 void RemoveDebuggerControlCallback(DebuggerControlCallback* cb)
231 REQUIRES_SHARED(Locks::mutator_lock_);
232
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000233 private:
234 std::vector<ThreadLifecycleCallback*> thread_callbacks_
235 GUARDED_BY(Locks::mutator_lock_);
Andreas Gampe0f01b582017-01-18 15:22:37 -0800236 std::vector<ClassLoadCallback*> class_callbacks_
237 GUARDED_BY(Locks::mutator_lock_);
Andreas Gampea5814f92017-01-18 21:43:16 -0800238 std::vector<RuntimeSigQuitCallback*> sigquit_callbacks_
239 GUARDED_BY(Locks::mutator_lock_);
Andreas Gampe48864112017-01-19 17:23:17 -0800240 std::vector<RuntimePhaseCallback*> phase_callbacks_
Alex Lightd78ddec2017-04-18 15:20:38 -0700241 GUARDED_BY(Locks::mutator_lock_);
242 std::vector<MethodCallback*> method_callbacks_
243 GUARDED_BY(Locks::mutator_lock_);
Alex Light77fee872017-09-05 14:51:49 -0700244 std::vector<MonitorCallback*> monitor_callbacks_
245 GUARDED_BY(Locks::mutator_lock_);
Alex Light21611932017-09-26 13:07:39 -0700246 std::vector<MethodInspectionCallback*> method_inspection_callbacks_
247 GUARDED_BY(Locks::mutator_lock_);
Alex Light8c2b9292017-11-09 13:21:01 -0800248 std::vector<DdmCallback*> ddm_callbacks_
249 GUARDED_BY(Locks::mutator_lock_);
Alex Light40320712017-12-14 11:52:04 -0800250 std::vector<DebuggerControlCallback*> debugger_control_callbacks_
251 GUARDED_BY(Locks::mutator_lock_);
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000252};
253
254} // namespace art
255
256#endif // ART_RUNTIME_RUNTIME_CALLBACKS_H_