1 /*
2 * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_PRIMS_JVMTIIMPL_HPP
26 #define SHARE_PRIMS_JVMTIIMPL_HPP
27
28 #include "jvmtifiles/jvmti.h"
29 #include "oops/objArrayOop.hpp"
30 #include "prims/jvmtiEnvThreadState.hpp"
31 #include "prims/jvmtiEventController.hpp"
32 #include "prims/jvmtiTrace.hpp"
33 #include "prims/jvmtiUtil.hpp"
34 #include "runtime/escapeBarrier.hpp"
35 #include "runtime/stackValueCollection.hpp"
36 #include "runtime/vmOperations.hpp"
37 #include "utilities/ostream.hpp"
38
39
40 ///////////////////////////////////////////////////////////////
41 //
42 // class JvmtiBreakpoint
43 //
44 // A JvmtiBreakpoint describes a location (class, method, bci) to break at.
45 //
46
47 typedef void (Method::*method_action)(int _bci);
48
49 class JvmtiBreakpoint : public CHeapObj<mtInternal> {
50 private:
51 Method* _method;
52 int _bci;
53 OopHandle _class_holder; // keeps _method memory from being deallocated
54
55 public:
56 JvmtiBreakpoint(Method* m_method, jlocation location);
57 JvmtiBreakpoint(const JvmtiBreakpoint& bp);
58 virtual ~JvmtiBreakpoint();
59 bool equals(const JvmtiBreakpoint& bp) const;
60 address getBcp() const;
61 void each_method_version_do(method_action meth_act);
62 void set();
63 void clear();
64 void print_on(outputStream* out) const;
65
66 Method* method() const { return _method; }
67 };
68
69 ///////////////////////////////////////////////////////////////
70 //
71 // class JvmtiBreakpoints
72 //
73 // Contains growable array of JvmtiBreakpoint.
74 // All changes to the array occur at a safepoint.
75 //
76
77 class JvmtiBreakpoints : public CHeapObj<mtInternal> {
78 private:
79 GrowableArray<JvmtiBreakpoint*> _elements;
80
81 int length() { return _elements.length(); }
82 JvmtiBreakpoint& at(int index) { return *_elements.at(index); }
83 int find(JvmtiBreakpoint& e) {
84 return _elements.find_if([&](const JvmtiBreakpoint * other_e) { return e.equals(*other_e); });
85 }
86 void append(JvmtiBreakpoint& e) {
87 JvmtiBreakpoint* new_e = new JvmtiBreakpoint(e);
88 _elements.append(new_e);
89 }
90 void remove(int index) {
91 JvmtiBreakpoint* e = _elements.at(index);
92 assert(e != nullptr, "e != nullptr");
93 _elements.remove_at(index);
94 delete e;
95 }
96
97 friend class JvmtiCurrentBreakpoints;
98 JvmtiBreakpoints(); // accessible only for JvmtiCurrentBreakpoints
99
100 public:
101 ~JvmtiBreakpoints();
102
103 void print();
104
105 int set(JvmtiBreakpoint& bp);
106 int clear(JvmtiBreakpoint& bp);
107
108 // used by VM_ChangeBreakpoints
109 void set_at_safepoint(JvmtiBreakpoint& bp);
110 void clear_at_safepoint(JvmtiBreakpoint& bp);
111 // used by VM_RedefineClasses
112 void clearall_in_class_at_safepoint(Klass* klass);
113 };
114
115 ///////////////////////////////////////////////////////////////
116 //
117 // class JvmtiCurrentBreakpoints
118 //
119 // A static wrapper class for the JvmtiBreakpoints that provides
120 // a function for lazily creating the JvmtiBreakpoints class.
121 //
122
123 class JvmtiCurrentBreakpoints : public AllStatic {
124 private:
125 // Current breakpoints, lazily initialized by get_jvmti_breakpoints();
126 static JvmtiBreakpoints *_jvmti_breakpoints;
127
128 public:
129 // lazily create _jvmti_breakpoints
130 static JvmtiBreakpoints& get_jvmti_breakpoints();
131 };
132
133 ///////////////////////////////////////////////////////////////
134 //
135 // VM_ChangeBreakpoints implements a VM_Operation for ALL modifications to the JvmtiBreakpoints class.
136 //
137
138 class VM_ChangeBreakpoints : public VM_Operation {
139 private:
140 JvmtiBreakpoints* _breakpoints;
141 int _operation;
142 JvmtiBreakpoint* _bp;
143
144 public:
145 enum { SET_BREAKPOINT=0, CLEAR_BREAKPOINT=1 };
146
147 VM_ChangeBreakpoints(int operation, JvmtiBreakpoint *bp) {
148 JvmtiBreakpoints& current_bps = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();
149 _breakpoints = ¤t_bps;
150 _bp = bp;
151 _operation = operation;
152 assert(bp != nullptr, "bp != null");
153 }
154
155 VMOp_Type type() const { return VMOp_ChangeBreakpoints; }
156 void doit();
157 };
158
159
160 ///////////////////////////////////////////////////////////////
161 // The get/set local operations must only be done by the VM thread
162 // because the interpreter version needs to access oop maps, which can
163 // only safely be done by the VM thread
164 //
165 // I'm told that in 1.5 oop maps are now protected by a lock and
166 // we could get rid of the VM op
167 // However if the VM op is removed then the target thread must
168 // be suspended AND a lock will be needed to prevent concurrent
169 // setting of locals to the same java thread. This lock is needed
170 // to prevent compiledVFrames from trying to add deferred updates
171 // to the thread simultaneously.
172 //
173 class VM_BaseGetOrSetLocal : public VM_Operation {
174 protected:
175 JavaThread* _calling_thread;
176 jint _depth;
177 jint _index;
178 BasicType _type;
179 jvalue _value;
180 javaVFrame* _jvf;
181 bool _set;
182 bool _self;
183
184 static const jvalue _DEFAULT_VALUE;
185
186 // It is possible to get the receiver out of a non-static native wrapper
187 // frame. Use VM_GetReceiver to do this.
188 virtual bool getting_receiver() const { return false; }
189
190 jvmtiError _result;
191
192 virtual javaVFrame* get_java_vframe() = 0;
193 bool check_slot_type_lvt(javaVFrame* vf);
194 bool check_slot_type_no_lvt(javaVFrame* vf);
195
196 public:
197 VM_BaseGetOrSetLocal(JavaThread* calling_thread, jint depth, jint index,
198 BasicType type, jvalue value, bool set, bool self);
199
200 jvalue value() { return _value; }
201 jvmtiError result() { return _result; }
202
203 void doit();
204 bool allow_nested_vm_operations() const;
205 virtual const char* name() const = 0;
206
207 // Check that the klass is assignable to a type with the given signature.
208 static bool is_assignable(const char* ty_sign, Klass* klass, Thread* thread);
209 };
210
211
212 class VM_GetOrSetLocal : public VM_BaseGetOrSetLocal {
213 protected:
214 JavaThread* _thread;
215 EscapeBarrier _eb;
216
217 vframe* get_vframe();
218 javaVFrame* get_java_vframe();
219
220 public:
221 // Constructor for non-object getter
222 VM_GetOrSetLocal(JavaThread* thread, jint depth, jint index, BasicType type, bool self);
223
224 // Constructor for object or non-object setter
225 VM_GetOrSetLocal(JavaThread* thread, jint depth, jint index, BasicType type, jvalue value, bool self);
226
227 // Constructor for object getter
228 VM_GetOrSetLocal(JavaThread* thread, JavaThread* calling_thread, jint depth, int index, bool self);
229
230 VMOp_Type type() const { return VMOp_GetOrSetLocal; }
231
232 bool doit_prologue();
233
234 const char* name() const { return "get/set locals"; }
235 };
236
237 class VM_GetReceiver : public VM_GetOrSetLocal {
238 protected:
239 virtual bool getting_receiver() const { return true; }
240
241 public:
242 VM_GetReceiver(JavaThread* thread, JavaThread* calling_thread, jint depth, bool self);
243 const char* name() const { return "get receiver"; }
244 };
245
246 // VM operation to get or set virtual thread local.
247 class VM_VirtualThreadGetOrSetLocal : public VM_BaseGetOrSetLocal {
248 protected:
249 JvmtiEnv *_env;
250 Handle _vthread_h;
251
252 javaVFrame* get_java_vframe();
253
254 public:
255 // Constructor for non-object getter.
256 VM_VirtualThreadGetOrSetLocal(JvmtiEnv* env, Handle vthread_h, jint depth, jint index, BasicType type, bool self);
257
258 // Constructor for object or non-object setter.
259 VM_VirtualThreadGetOrSetLocal(JvmtiEnv* env, Handle vthread_h, jint depth,
260 jint index, BasicType type, jvalue value, bool self);
261
262 // Constructor for object getter.
263 VM_VirtualThreadGetOrSetLocal(JvmtiEnv* env, Handle vthread_h, JavaThread* calling_thread,
264 jint depth, int index, bool self);
265
266 VMOp_Type type() const { return VMOp_VirtualThreadGetOrSetLocal; }
267
268 const char* name() const { return "virtual thread get/set locals"; }
269 };
270
271 class VM_VirtualThreadGetReceiver : public VM_VirtualThreadGetOrSetLocal {
272 protected:
273 virtual bool getting_receiver() const { return true; }
274
275 public:
276 VM_VirtualThreadGetReceiver(JvmtiEnv* env, Handle vthread_h, JavaThread* calling_thread, jint depth, bool self);
277 const char* name() const { return "virtual thread get receiver"; }
278 };
279
280
281 /**
282 * When a thread (such as the compiler thread or VM thread) cannot post a
283 * JVMTI event itself because the event needs to be posted from a Java
284 * thread, then it can defer the event to the Service thread for posting.
285 * The information needed to post the event is encapsulated into this class
286 * and then enqueued onto the JvmtiDeferredEventQueue, where the Service
287 * thread will pick it up and post it.
288 *
289 * This is currently only used for posting compiled-method-load and unload
290 * events, which we don't want posted from the compiler thread.
291 */
292 class JvmtiDeferredEvent {
293 friend class JvmtiDeferredEventQueue;
294 private:
295 typedef enum {
296 TYPE_NONE,
297 TYPE_COMPILED_METHOD_LOAD,
298 TYPE_COMPILED_METHOD_UNLOAD,
299 TYPE_DYNAMIC_CODE_GENERATED,
300 TYPE_CLASS_UNLOAD
301 } Type;
302
303 Type _type;
304 union {
305 nmethod* compiled_method_load;
306 struct {
307 jmethodID method_id;
308 const void* code_begin;
309 } compiled_method_unload;
310 struct {
311 const char* name;
312 const void* code_begin;
313 const void* code_end;
314 } dynamic_code_generated;
315 struct {
316 const char* name;
317 } class_unload;
318 } _event_data;
319
320 JvmtiDeferredEvent(Type t) : _type(t) {}
321
322 public:
323
324 JvmtiDeferredEvent() : _type(TYPE_NONE) {}
325
326 // Factory methods
327 static JvmtiDeferredEvent compiled_method_load_event(nmethod* nm)
328 NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
329 static JvmtiDeferredEvent compiled_method_unload_event(
330 jmethodID id, const void* code) NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
331 static JvmtiDeferredEvent dynamic_code_generated_event(
332 const char* name, const void* begin, const void* end)
333 NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
334 static JvmtiDeferredEvent class_unload_event(
335 const char* name) NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
336
337 // Actually posts the event.
338 void post() NOT_JVMTI_RETURN;
339 void post_compiled_method_load_event(JvmtiEnv* env) NOT_JVMTI_RETURN;
340 void run_nmethod_entry_barriers() NOT_JVMTI_RETURN;
341 // GC support to keep nmethods from unloading while in the queue.
342 void nmethods_do(NMethodClosure* cf) NOT_JVMTI_RETURN;
343 // GC support to keep nmethod from being unloaded while in the queue.
344 void oops_do(OopClosure* f, NMethodClosure* cf) NOT_JVMTI_RETURN;
345 };
346
347 /**
348 * Events enqueued on this queue wake up the Service thread which dequeues
349 * and posts the events. The Service_lock is required to be held
350 * when operating on the queue.
351 */
352 class JvmtiDeferredEventQueue : public CHeapObj<mtInternal> {
353 friend class JvmtiDeferredEvent;
354 private:
355 class QueueNode : public CHeapObj<mtInternal> {
356 private:
357 JvmtiDeferredEvent _event;
358 QueueNode* _next;
359
360 public:
361 QueueNode(const JvmtiDeferredEvent& event)
362 : _event(event), _next(nullptr) {}
363
364 JvmtiDeferredEvent& event() { return _event; }
365 QueueNode* next() const { return _next; }
366
367 void set_next(QueueNode* next) { _next = next; }
368 };
369
370 QueueNode* _queue_head;
371 QueueNode* _queue_tail;
372
373 public:
374 JvmtiDeferredEventQueue() : _queue_head(nullptr), _queue_tail(nullptr) {}
375
376 bool has_events() NOT_JVMTI_RETURN_(false);
377 JvmtiDeferredEvent dequeue() NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
378
379 // Post all events in the queue for the current Jvmti environment
380 void post(JvmtiEnv* env) NOT_JVMTI_RETURN;
381 void enqueue(JvmtiDeferredEvent event) NOT_JVMTI_RETURN;
382 void run_nmethod_entry_barriers();
383
384 // GC support to keep nmethods from unloading while in the queue.
385 void nmethods_do(NMethodClosure* cf) NOT_JVMTI_RETURN;
386 // GC support to keep nmethod from being unloaded while in the queue.
387 void oops_do(OopClosure* f, NMethodClosure* cf) NOT_JVMTI_RETURN;
388 };
389
390 // Utility macro that checks for null pointers:
391 #define NULL_CHECK(X, Y) if ((X) == nullptr) { return (Y); }
392
393 #endif // SHARE_PRIMS_JVMTIIMPL_HPP