blob: fe7bb0c1cde98f0d0f44bd179e46f6aebedd9d1c [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 Gampe7fbc4a52018-11-28 08:26:47 -080023#include "base/locks.h"
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000024#include "base/macros.h"
Andreas Gampe0f01b582017-01-18 15:22:37 -080025#include "handle.h"
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000026
27namespace art {
28
Andreas Gampe3f1dcd32018-12-28 09:39:56 -080029namespace dex {
30struct ClassDef;
31} // namespace dex
32
Andreas Gampe0f01b582017-01-18 15:22:37 -080033namespace mirror {
34class Class;
Alex Lightb0f11922017-01-23 14:25:17 -080035class ClassLoader;
Alex Light77fee872017-09-05 14:51:49 -070036class Object;
Andreas Gampe0f01b582017-01-18 15:22:37 -080037} // namespace mirror
38
Alex Lightd78ddec2017-04-18 15:20:38 -070039class ArtMethod;
Andreas Gampe0f01b582017-01-18 15:22:37 -080040class ClassLoadCallback;
Andreas Gampe3f1dcd32018-12-28 09:39:56 -080041class DexFile;
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000042class Thread;
Alex Lightd78ddec2017-04-18 15:20:38 -070043class MethodCallback;
Alex Light77fee872017-09-05 14:51:49 -070044class Monitor;
Alex Light51d5a302019-04-09 11:22:17 -070045class ReaderWriterMutex;
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000046class ThreadLifecycleCallback;
47
48// Note: RuntimeCallbacks uses the mutator lock to synchronize the callback lists. A thread must
49// hold the exclusive lock to add or remove a listener. A thread must hold the shared lock
50// to dispatch an event. This setup is chosen as some clients may want to suspend the
51// dispatching thread or all threads.
52//
53// To make this safe, the following restrictions apply:
54// * Only the owner of a listener may ever add or remove said listener.
55// * A listener must never add or remove itself or any other listener while running.
56// * It is the responsibility of the owner to not remove the listener while it is running
57// (and suspended).
Alex Light51d5a302019-04-09 11:22:17 -070058// * The owner should never deallocate a listener once it has been registered, even if it has
59// been removed.
Andreas Gampe04bbb5b2017-01-19 17:49:03 +000060//
61// The simplest way to satisfy these restrictions is to never remove a listener, and to do
62// any state checking (is the listener enabled) in the listener itself. For an example, see
63// Dbg.
64
Alex Light8c2b9292017-11-09 13:21:01 -080065class DdmCallback {
66 public:
67 virtual ~DdmCallback() {}
68 virtual void DdmPublishChunk(uint32_t type, const ArrayRef<const uint8_t>& data)
69 REQUIRES_SHARED(Locks::mutator_lock_) = 0;
70};
71
Alex Light40320712017-12-14 11:52:04 -080072class DebuggerControlCallback {
73 public:
74 virtual ~DebuggerControlCallback() {}
75
76 // Begin running the debugger.
77 virtual void StartDebugger() = 0;
78 // The debugger should begin shutting down since the runtime is ending. This is just advisory
79 virtual void StopDebugger() = 0;
80
81 // This allows the debugger to tell the runtime if it is configured.
82 virtual bool IsDebuggerConfigured() = 0;
83};
84
Andreas Gampea5814f92017-01-18 21:43:16 -080085class RuntimeSigQuitCallback {
86 public:
87 virtual ~RuntimeSigQuitCallback() {}
88
89 virtual void SigQuit() REQUIRES_SHARED(Locks::mutator_lock_) = 0;
90};
91
Andreas Gampe48864112017-01-19 17:23:17 -080092class RuntimePhaseCallback {
93 public:
94 enum RuntimePhase {
Andreas Gampe96eca782017-01-19 19:45:30 -080095 kInitialAgents, // Initial agent loading is done.
96 kStart, // The runtime is started.
97 kInit, // The runtime is initialized (and will run user code soon).
98 kDeath, // The runtime just died.
Andreas Gampe48864112017-01-19 17:23:17 -080099 };
100
101 virtual ~RuntimePhaseCallback() {}
102
103 virtual void NextRuntimePhase(RuntimePhase phase) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
104};
105
Alex Light77fee872017-09-05 14:51:49 -0700106class MonitorCallback {
107 public:
108 // Called just before the thread goes to sleep to wait for the monitor to become unlocked.
109 virtual void MonitorContendedLocking(Monitor* mon) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
110 // Called just after the monitor has been successfully acquired when it was already locked.
111 virtual void MonitorContendedLocked(Monitor* mon) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
112 // Called on entry to the Object#wait method regardless of whether or not the call is valid.
113 virtual void ObjectWaitStart(Handle<mirror::Object> obj, int64_t millis_timeout)
114 REQUIRES_SHARED(Locks::mutator_lock_) = 0;
115
116 // Called just after the monitor has woken up from going to sleep for a wait(). At this point the
117 // thread does not possess a lock on the monitor. This will only be called for threads wait calls
118 // where the thread did (or at least could have) gone to sleep.
119 virtual void MonitorWaitFinished(Monitor* m, bool timed_out)
120 REQUIRES_SHARED(Locks::mutator_lock_) = 0;
121
122 virtual ~MonitorCallback() {}
123};
124
Charles Munger5cc0e752018-11-09 12:30:46 -0800125class ParkCallback {
126 public:
127 // Called on entry to the Unsafe.#park method
128 virtual void ThreadParkStart(bool is_absolute, int64_t millis_timeout)
129 REQUIRES_SHARED(Locks::mutator_lock_) = 0;
130
131 // Called just after the thread has woken up from going to sleep for a park(). This will only be
132 // called for Unsafe.park() calls where the thread did (or at least could have) gone to sleep.
133 virtual void ThreadParkFinished(bool timed_out) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
134
135 virtual ~ParkCallback() {}
136};
137
Alex Light21611932017-09-26 13:07:39 -0700138// A callback to let parts of the runtime note that they are currently relying on a particular
139// method remaining in it's current state. Users should not rely on always being called. If multiple
140// callbacks are added the runtime will short-circuit when the first one returns 'true'.
141class MethodInspectionCallback {
142 public:
143 virtual ~MethodInspectionCallback() {}
144
145 // Returns true if the method is being inspected currently and the runtime should not modify it in
146 // potentially dangerous ways (i.e. replace with compiled version, JIT it, etc).
147 virtual bool IsMethodBeingInspected(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
Alex Light0fa17862017-10-24 13:43:05 -0700148
149 // Returns true if the method is safe to Jit, false otherwise.
150 // Note that '!IsMethodSafeToJit(m) implies IsMethodBeingInspected(m)'. That is that if this
151 // method returns false IsMethodBeingInspected must return true.
152 virtual bool IsMethodSafeToJit(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
Alex Lightf2858632018-04-02 11:28:50 -0700153
154 // Returns true if we expect the method to be debuggable but are not doing anything unusual with
155 // it currently.
156 virtual bool MethodNeedsDebugVersion(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
Alex Light21611932017-09-26 13:07:39 -0700157};
158
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000159class RuntimeCallbacks {
160 public:
Alex Light51d5a302019-04-09 11:22:17 -0700161 RuntimeCallbacks();
162
Andreas Gampe0f01b582017-01-18 15:22:37 -0800163 void AddThreadLifecycleCallback(ThreadLifecycleCallback* cb) REQUIRES(Locks::mutator_lock_);
164 void RemoveThreadLifecycleCallback(ThreadLifecycleCallback* cb) REQUIRES(Locks::mutator_lock_);
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000165
Andreas Gampe0f01b582017-01-18 15:22:37 -0800166 void ThreadStart(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);
167 void ThreadDeath(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);
168
169 void AddClassLoadCallback(ClassLoadCallback* cb) REQUIRES(Locks::mutator_lock_);
170 void RemoveClassLoadCallback(ClassLoadCallback* cb) REQUIRES(Locks::mutator_lock_);
171
172 void ClassLoad(Handle<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
173 void ClassPrepare(Handle<mirror::Class> temp_klass, Handle<mirror::Class> klass)
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000174 REQUIRES_SHARED(Locks::mutator_lock_);
175
Andreas Gampea5814f92017-01-18 21:43:16 -0800176 void AddRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb)
177 REQUIRES(Locks::mutator_lock_);
178 void RemoveRuntimeSigQuitCallback(RuntimeSigQuitCallback* cb)
179 REQUIRES(Locks::mutator_lock_);
180
181 void SigQuit() REQUIRES_SHARED(Locks::mutator_lock_);
182
Andreas Gampe48864112017-01-19 17:23:17 -0800183 void AddRuntimePhaseCallback(RuntimePhaseCallback* cb)
184 REQUIRES(Locks::mutator_lock_);
185 void RemoveRuntimePhaseCallback(RuntimePhaseCallback* cb)
186 REQUIRES(Locks::mutator_lock_);
187
188 void NextRuntimePhase(RuntimePhaseCallback::RuntimePhase phase)
189 REQUIRES_SHARED(Locks::mutator_lock_);
190
Alex Lightb0f11922017-01-23 14:25:17 -0800191 void ClassPreDefine(const char* descriptor,
192 Handle<mirror::Class> temp_class,
193 Handle<mirror::ClassLoader> loader,
194 const DexFile& initial_dex_file,
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800195 const dex::ClassDef& initial_class_def,
Alex Lightb0f11922017-01-23 14:25:17 -0800196 /*out*/DexFile const** final_dex_file,
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800197 /*out*/dex::ClassDef const** final_class_def)
Alex Lightb0f11922017-01-23 14:25:17 -0800198 REQUIRES_SHARED(Locks::mutator_lock_);
199
Alex Lightd78ddec2017-04-18 15:20:38 -0700200 void AddMethodCallback(MethodCallback* cb) REQUIRES(Locks::mutator_lock_);
201 void RemoveMethodCallback(MethodCallback* cb) REQUIRES(Locks::mutator_lock_);
202
203 void RegisterNativeMethod(ArtMethod* method,
204 const void* original_implementation,
205 /*out*/void** new_implementation)
206 REQUIRES_SHARED(Locks::mutator_lock_);
207
Alex Light77fee872017-09-05 14:51:49 -0700208 void MonitorContendedLocking(Monitor* m) REQUIRES_SHARED(Locks::mutator_lock_);
209 void MonitorContendedLocked(Monitor* m) REQUIRES_SHARED(Locks::mutator_lock_);
210 void ObjectWaitStart(Handle<mirror::Object> m, int64_t timeout)
211 REQUIRES_SHARED(Locks::mutator_lock_);
212 void MonitorWaitFinished(Monitor* m, bool timed_out)
213 REQUIRES_SHARED(Locks::mutator_lock_);
214
215 void AddMonitorCallback(MonitorCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_);
216 void RemoveMonitorCallback(MonitorCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_);
217
Charles Munger5cc0e752018-11-09 12:30:46 -0800218 void ThreadParkStart(bool is_absolute, int64_t timeout) REQUIRES_SHARED(Locks::mutator_lock_);
219 void ThreadParkFinished(bool timed_out) REQUIRES_SHARED(Locks::mutator_lock_);
220 void AddParkCallback(ParkCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_);
221 void RemoveParkCallback(ParkCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_);
222
Alex Light21611932017-09-26 13:07:39 -0700223 // Returns true if some MethodInspectionCallback indicates the method is being inspected/depended
224 // on by some code.
225 bool IsMethodBeingInspected(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
226
Alex Light0fa17862017-10-24 13:43:05 -0700227 // Returns false if some MethodInspectionCallback indicates the method cannot be safetly jitted
228 // (which implies that it is being Inspected). Returns true otherwise. If it returns false the
229 // entrypoint should not be changed to JITed code.
230 bool IsMethodSafeToJit(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
231
Alex Lightf2858632018-04-02 11:28:50 -0700232 // Returns true if some MethodInspectionCallback indicates the method needs to use a debug
233 // version. This allows later code to set breakpoints or perform other actions that could be
234 // broken by some optimizations.
235 bool MethodNeedsDebugVersion(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
236
Alex Light21611932017-09-26 13:07:39 -0700237 void AddMethodInspectionCallback(MethodInspectionCallback* cb)
238 REQUIRES_SHARED(Locks::mutator_lock_);
239 void RemoveMethodInspectionCallback(MethodInspectionCallback* cb)
240 REQUIRES_SHARED(Locks::mutator_lock_);
241
Alex Light8c2b9292017-11-09 13:21:01 -0800242 // DDMS callbacks
243 void DdmPublishChunk(uint32_t type, const ArrayRef<const uint8_t>& data)
244 REQUIRES_SHARED(Locks::mutator_lock_);
245
246 void AddDdmCallback(DdmCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_);
247 void RemoveDdmCallback(DdmCallback* cb) REQUIRES_SHARED(Locks::mutator_lock_);
248
Alex Light40320712017-12-14 11:52:04 -0800249 void StartDebugger() REQUIRES_SHARED(Locks::mutator_lock_);
250 // NO_THREAD_SAFETY_ANALYSIS since this is only called when we are in the middle of shutting down
251 // and the mutator_lock_ is no longer acquirable.
252 void StopDebugger() NO_THREAD_SAFETY_ANALYSIS;
253 bool IsDebuggerConfigured() REQUIRES_SHARED(Locks::mutator_lock_);
254
255 void AddDebuggerControlCallback(DebuggerControlCallback* cb)
256 REQUIRES_SHARED(Locks::mutator_lock_);
257 void RemoveDebuggerControlCallback(DebuggerControlCallback* cb)
258 REQUIRES_SHARED(Locks::mutator_lock_);
259
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000260 private:
Alex Light51d5a302019-04-09 11:22:17 -0700261 std::unique_ptr<ReaderWriterMutex> callback_lock_ BOTTOM_MUTEX_ACQUIRED_AFTER;
262
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000263 std::vector<ThreadLifecycleCallback*> thread_callbacks_
Alex Light51d5a302019-04-09 11:22:17 -0700264 GUARDED_BY(callback_lock_);
Andreas Gampe0f01b582017-01-18 15:22:37 -0800265 std::vector<ClassLoadCallback*> class_callbacks_
Alex Light51d5a302019-04-09 11:22:17 -0700266 GUARDED_BY(callback_lock_);
Andreas Gampea5814f92017-01-18 21:43:16 -0800267 std::vector<RuntimeSigQuitCallback*> sigquit_callbacks_
Alex Light51d5a302019-04-09 11:22:17 -0700268 GUARDED_BY(callback_lock_);
Andreas Gampe48864112017-01-19 17:23:17 -0800269 std::vector<RuntimePhaseCallback*> phase_callbacks_
Alex Light51d5a302019-04-09 11:22:17 -0700270 GUARDED_BY(callback_lock_);
Alex Lightd78ddec2017-04-18 15:20:38 -0700271 std::vector<MethodCallback*> method_callbacks_
Alex Light51d5a302019-04-09 11:22:17 -0700272 GUARDED_BY(callback_lock_);
Alex Light77fee872017-09-05 14:51:49 -0700273 std::vector<MonitorCallback*> monitor_callbacks_
Alex Light51d5a302019-04-09 11:22:17 -0700274 GUARDED_BY(callback_lock_);
Charles Munger5cc0e752018-11-09 12:30:46 -0800275 std::vector<ParkCallback*> park_callbacks_
Alex Light51d5a302019-04-09 11:22:17 -0700276 GUARDED_BY(callback_lock_);
Alex Light21611932017-09-26 13:07:39 -0700277 std::vector<MethodInspectionCallback*> method_inspection_callbacks_
Alex Light51d5a302019-04-09 11:22:17 -0700278 GUARDED_BY(callback_lock_);
Alex Light8c2b9292017-11-09 13:21:01 -0800279 std::vector<DdmCallback*> ddm_callbacks_
Alex Light51d5a302019-04-09 11:22:17 -0700280 GUARDED_BY(callback_lock_);
Alex Light40320712017-12-14 11:52:04 -0800281 std::vector<DebuggerControlCallback*> debugger_control_callbacks_
Alex Light51d5a302019-04-09 11:22:17 -0700282 GUARDED_BY(callback_lock_);
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000283};
284
285} // namespace art
286
287#endif // ART_RUNTIME_RUNTIME_CALLBACKS_H_