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 = &current_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