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