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 
 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 = &current_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   bool        _need_clone; // THIS object is in a value object constructor
184 
185   static const jvalue _DEFAULT_VALUE;
186 
187   // It is possible to get the receiver out of a non-static native wrapper
188   // frame.  Use VM_GetReceiver to do this.
189   virtual bool getting_receiver() const { return false; }
190 
191   jvmtiError  _result;
192 
193   virtual javaVFrame* get_java_vframe() = 0;
194   bool check_slot_type_lvt(javaVFrame* vf);
195   bool check_slot_type_no_lvt(javaVFrame* vf);
196   void check_and_clone_this_value_object();
197 
198 public:
199   VM_BaseGetOrSetLocal(JavaThread* calling_thread, jint depth, jint index,
200                        BasicType type, jvalue value, bool set, bool self);
201 
202   jvalue value()         { return _value; }
203   jvmtiError result()    { return _result; }
204 
205   void doit();
206   void doit_epilogue();
207   bool allow_nested_vm_operations() const;
208   virtual const char* name() const = 0;
209 
210   // Check that the klass is assignable to a type with the given signature.
211   static bool is_assignable(const char* ty_sign, Klass* klass, Thread* thread);
212 };
213 
214 
215 class VM_GetOrSetLocal : public VM_BaseGetOrSetLocal {
216  protected:
217   JavaThread* _thread;
218   EscapeBarrier _eb;
219 
220   vframe* get_vframe();
221   javaVFrame* get_java_vframe();
222 
223 public:
224   // Constructor for non-object getter
225   VM_GetOrSetLocal(JavaThread* thread, jint depth, jint index, BasicType type, bool self);
226 
227   // Constructor for object or non-object setter
228   VM_GetOrSetLocal(JavaThread* thread, jint depth, jint index, BasicType type, jvalue value, bool self);
229 
230   // Constructor for object getter
231   VM_GetOrSetLocal(JavaThread* thread, JavaThread* calling_thread, jint depth, int index, bool self);
232 
233   VMOp_Type type() const { return VMOp_GetOrSetLocal; }
234 
235   bool doit_prologue();
236 
237   const char* name() const                       { return "get/set locals"; }
238 };
239 
240 class VM_GetReceiver : public VM_GetOrSetLocal {
241  protected:
242   virtual bool getting_receiver() const { return true; }
243 
244  public:
245   VM_GetReceiver(JavaThread* thread, JavaThread* calling_thread, jint depth, bool self);
246   const char* name() const                       { return "get receiver"; }
247 };
248 
249 // VM operation to get or set virtual thread local.
250 class VM_VirtualThreadGetOrSetLocal : public VM_BaseGetOrSetLocal {
251  protected:
252   JvmtiEnv *_env;
253   Handle _vthread_h;
254 
255   javaVFrame* get_java_vframe();
256 
257 public:
258   // Constructor for non-object getter.
259   VM_VirtualThreadGetOrSetLocal(JvmtiEnv* env, Handle vthread_h, jint depth, jint index, BasicType type, bool self);
260 
261   // Constructor for object or non-object setter.
262   VM_VirtualThreadGetOrSetLocal(JvmtiEnv* env, Handle vthread_h, jint depth,
263                                 jint index, BasicType type, jvalue value, bool self);
264 
265   // Constructor for object getter.
266   VM_VirtualThreadGetOrSetLocal(JvmtiEnv* env, Handle vthread_h, JavaThread* calling_thread,
267                                 jint depth, int index, bool self);
268 
269   VMOp_Type type() const { return VMOp_VirtualThreadGetOrSetLocal; }
270 
271   const char* name() const                       { return "virtual thread get/set locals"; }
272 };
273 
274 class VM_VirtualThreadGetReceiver : public VM_VirtualThreadGetOrSetLocal {
275  protected:
276   virtual bool getting_receiver() const { return true; }
277 
278  public:
279   VM_VirtualThreadGetReceiver(JvmtiEnv* env, Handle vthread_h, JavaThread* calling_thread, jint depth, bool self);
280   const char* name() const                       { return "virtual thread get receiver"; }
281 };
282 
283 
284 /**
285  * When a thread (such as the compiler thread or VM thread) cannot post a
286  * JVMTI event itself because the event needs to be posted from a Java
287  * thread, then it can defer the event to the Service thread for posting.
288  * The information needed to post the event is encapsulated into this class
289  * and then enqueued onto the JvmtiDeferredEventQueue, where the Service
290  * thread will pick it up and post it.
291  *
292  * This is currently only used for posting compiled-method-load and unload
293  * events, which we don't want posted from the compiler thread.
294  */
295 class JvmtiDeferredEvent {
296   friend class JvmtiDeferredEventQueue;
297  private:
298   typedef enum {
299     TYPE_NONE,
300     TYPE_COMPILED_METHOD_LOAD,
301     TYPE_COMPILED_METHOD_UNLOAD,
302     TYPE_DYNAMIC_CODE_GENERATED,
303     TYPE_CLASS_UNLOAD
304   } Type;
305 
306   Type _type;
307   union {
308     nmethod* compiled_method_load;
309     struct {
310       jmethodID method_id;
311       const void* code_begin;
312     } compiled_method_unload;
313     struct {
314       const char* name;
315       const void* code_begin;
316       const void* code_end;
317     } dynamic_code_generated;
318     struct {
319       const char* name;
320     } class_unload;
321   } _event_data;
322 
323   JvmtiDeferredEvent(Type t) : _type(t) {}
324 
325  public:
326 
327   JvmtiDeferredEvent() : _type(TYPE_NONE) {}
328 
329   // Factory methods
330   static JvmtiDeferredEvent compiled_method_load_event(nmethod* nm)
331     NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
332   static JvmtiDeferredEvent compiled_method_unload_event(
333       jmethodID id, const void* code) NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
334   static JvmtiDeferredEvent dynamic_code_generated_event(
335       const char* name, const void* begin, const void* end)
336           NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
337   static JvmtiDeferredEvent class_unload_event(
338       const char* name) NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
339 
340   // Actually posts the event.
341   void post() NOT_JVMTI_RETURN;
342   void post_compiled_method_load_event(JvmtiEnv* env) NOT_JVMTI_RETURN;
343   void run_nmethod_entry_barriers() NOT_JVMTI_RETURN;
344   // GC support to keep nmethods from unloading while in the queue.
345   void nmethods_do(NMethodClosure* cf) NOT_JVMTI_RETURN;
346   // GC support to keep nmethod from being unloaded while in the queue.
347   void oops_do(OopClosure* f, NMethodClosure* cf) NOT_JVMTI_RETURN;
348 };
349 
350 /**
351  * Events enqueued on this queue wake up the Service thread which dequeues
352  * and posts the events.  The Service_lock is required to be held
353  * when operating on the queue.
354  */
355 class JvmtiDeferredEventQueue : public CHeapObj<mtInternal> {
356   friend class JvmtiDeferredEvent;
357  private:
358   class QueueNode : public CHeapObj<mtInternal> {
359    private:
360     JvmtiDeferredEvent _event;
361     QueueNode* _next;
362 
363    public:
364     QueueNode(const JvmtiDeferredEvent& event)
365       : _event(event), _next(nullptr) {}
366 
367     JvmtiDeferredEvent& event() { return _event; }
368     QueueNode* next() const { return _next; }
369 
370     void set_next(QueueNode* next) { _next = next; }
371   };
372 
373   QueueNode* _queue_head;
374   QueueNode* _queue_tail;
375 
376  public:
377   JvmtiDeferredEventQueue() : _queue_head(nullptr), _queue_tail(nullptr) {}
378 
379   bool has_events() NOT_JVMTI_RETURN_(false);
380   JvmtiDeferredEvent dequeue() NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
381 
382   // Post all events in the queue for the current Jvmti environment
383   void post(JvmtiEnv* env) NOT_JVMTI_RETURN;
384   void enqueue(JvmtiDeferredEvent event) NOT_JVMTI_RETURN;
385   void run_nmethod_entry_barriers();
386 
387   // GC support to keep nmethods from unloading while in the queue.
388   void nmethods_do(NMethodClosure* cf) NOT_JVMTI_RETURN;
389   // GC support to keep nmethod from being unloaded while in the queue.
390   void oops_do(OopClosure* f, NMethodClosure* cf) NOT_JVMTI_RETURN;
391 };
392 
393 // Utility macro that checks for null pointers:
394 #define NULL_CHECK(X, Y) if ((X) == nullptr) { return (Y); }
395 
396 #endif // SHARE_PRIMS_JVMTIIMPL_HPP