1 /* 2 * Copyright (c) 1998, 2024, 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_JVMTIEXPORT_HPP 26 #define SHARE_PRIMS_JVMTIEXPORT_HPP 27 28 #include "jvmtifiles/jvmti.h" 29 #include "memory/allocation.hpp" 30 #include "memory/iterator.hpp" 31 #include "oops/oop.hpp" 32 #include "oops/oopHandle.hpp" 33 #include "oops/oopsHierarchy.hpp" 34 #include "runtime/frame.hpp" 35 #include "runtime/handles.hpp" 36 #include "utilities/globalDefinitions.hpp" 37 #include "utilities/growableArray.hpp" 38 #include "utilities/macros.hpp" 39 40 // Must be included after jvmti.h. 41 #include "jvmticmlr.h" 42 43 // Forward declarations 44 45 struct JvmtiCachedClassFileData; 46 class JvmtiEventControllerPrivate; 47 class JvmtiManageCapabilities; 48 class JvmtiEnv; 49 class JvmtiThreadState; 50 class OopStorage; 51 class ThreadsList; 52 53 #define JVMTI_SUPPORT_FLAG(key) \ 54 private: \ 55 static bool _##key; \ 56 public: \ 57 inline static void set_##key(bool on) { \ 58 JVMTI_ONLY(_##key = (on != 0)); \ 59 NOT_JVMTI(report_unsupported(on)); \ 60 } \ 61 inline static bool key() { \ 62 JVMTI_ONLY(return _##key); \ 63 NOT_JVMTI(return false); \ 64 } 65 66 67 // This class contains the JVMTI interface for the rest of hotspot. 68 // 69 class JvmtiExport : public AllStatic { 70 friend class VMStructs; 71 friend class CompileReplay; 72 73 private: 74 75 #if INCLUDE_JVMTI 76 static int _field_access_count; 77 static int _field_modification_count; 78 79 static bool _can_access_local_variables; 80 static bool _can_hotswap_or_post_breakpoint; 81 static bool _can_modify_any_class; 82 static bool _can_walk_any_space; 83 #endif // INCLUDE_JVMTI 84 85 JVMTI_SUPPORT_FLAG(can_get_source_debug_extension) 86 JVMTI_SUPPORT_FLAG(can_maintain_original_method_order) 87 JVMTI_SUPPORT_FLAG(can_post_interpreter_events) 88 JVMTI_SUPPORT_FLAG(can_post_on_exceptions) 89 JVMTI_SUPPORT_FLAG(can_post_breakpoint) 90 JVMTI_SUPPORT_FLAG(can_post_field_access) 91 JVMTI_SUPPORT_FLAG(can_post_field_modification) 92 JVMTI_SUPPORT_FLAG(can_post_method_entry) 93 JVMTI_SUPPORT_FLAG(can_post_method_exit) 94 JVMTI_SUPPORT_FLAG(can_post_frame_pop) 95 JVMTI_SUPPORT_FLAG(can_pop_frame) 96 JVMTI_SUPPORT_FLAG(can_force_early_return) 97 JVMTI_SUPPORT_FLAG(can_support_virtual_threads) 98 99 JVMTI_SUPPORT_FLAG(early_vmstart_recorded) 100 JVMTI_SUPPORT_FLAG(can_get_owned_monitor_info) // includes can_get_owned_monitor_stack_depth_info 101 102 friend class JvmtiEventControllerPrivate; // should only modify these flags 103 JVMTI_SUPPORT_FLAG(should_post_single_step) 104 JVMTI_SUPPORT_FLAG(should_post_field_access) 105 JVMTI_SUPPORT_FLAG(should_post_field_modification) 106 JVMTI_SUPPORT_FLAG(should_post_class_load) 107 JVMTI_SUPPORT_FLAG(should_post_class_prepare) 108 JVMTI_SUPPORT_FLAG(should_post_class_unload) 109 JVMTI_SUPPORT_FLAG(should_post_native_method_bind) 110 JVMTI_SUPPORT_FLAG(should_post_compiled_method_load) 111 JVMTI_SUPPORT_FLAG(should_post_compiled_method_unload) 112 JVMTI_SUPPORT_FLAG(should_post_dynamic_code_generated) 113 JVMTI_SUPPORT_FLAG(should_post_monitor_contended_enter) 114 JVMTI_SUPPORT_FLAG(should_post_monitor_contended_entered) 115 JVMTI_SUPPORT_FLAG(should_post_monitor_wait) 116 JVMTI_SUPPORT_FLAG(should_post_monitor_waited) 117 JVMTI_SUPPORT_FLAG(should_post_data_dump) 118 JVMTI_SUPPORT_FLAG(should_post_garbage_collection_start) 119 JVMTI_SUPPORT_FLAG(should_post_garbage_collection_finish) 120 JVMTI_SUPPORT_FLAG(should_post_on_exceptions) 121 122 // ------ the below maybe don't have to be (but are for now) 123 // fixed conditions here ------------ 124 // any events can be enabled 125 JVMTI_SUPPORT_FLAG(should_post_thread_life) 126 JVMTI_SUPPORT_FLAG(should_post_object_free) 127 JVMTI_SUPPORT_FLAG(should_post_resource_exhausted) 128 129 // we are holding objects on the heap - need to talk to GC - e.g. 130 // breakpoint info 131 JVMTI_SUPPORT_FLAG(should_clean_up_heap_objects) 132 JVMTI_SUPPORT_FLAG(should_post_vm_object_alloc) 133 JVMTI_SUPPORT_FLAG(should_post_sampled_object_alloc) 134 135 JVMTI_SUPPORT_FLAG(should_post_vthread_start) 136 JVMTI_SUPPORT_FLAG(should_post_vthread_end) 137 JVMTI_SUPPORT_FLAG(should_post_vthread_mount) 138 JVMTI_SUPPORT_FLAG(should_post_vthread_unmount) 139 140 // If flag cannot be implemented, give an error if on=true 141 static void report_unsupported(bool on); 142 143 // these should only be called by the friend class 144 friend class JvmtiManageCapabilities; 145 inline static void set_can_modify_any_class(bool on) { 146 JVMTI_ONLY(_can_modify_any_class = (on != 0);) 147 } 148 inline static void set_can_access_local_variables(bool on) { 149 JVMTI_ONLY(_can_access_local_variables = (on != 0);) 150 } 151 inline static void set_can_hotswap_or_post_breakpoint(bool on) { 152 #if INCLUDE_JVMTI 153 // Check that _can_hotswap_or_post_breakpoint is not reset once it 154 // was set to true. When _can_hotswap_or_post_breakpoint is set to true 155 // _all_dependencies_are_recorded is also set to true and never 156 // reset so we have to ensure that evol dependencies are always 157 // recorded from that point on. 158 assert(!_can_hotswap_or_post_breakpoint || on, "sanity check"); 159 _can_hotswap_or_post_breakpoint = (on != 0); 160 #endif 161 } 162 inline static void set_can_walk_any_space(bool on) { 163 JVMTI_ONLY(_can_walk_any_space = (on != 0);) 164 } 165 166 enum { 167 JVMTI_VERSION_MASK = 0x70000000, 168 JVMTI_VERSION_VALUE = 0x30000000, 169 JVMDI_VERSION_VALUE = 0x20000000 170 }; 171 172 static void post_field_modification(JavaThread *thread, Method* method, address location, 173 Klass* field_klass, Handle object, jfieldID field, 174 char sig_type, jvalue *value); 175 176 177 // posts a DynamicCodeGenerated event (internal/private implementation). 178 // The public post_dynamic_code_generated* functions make use of the 179 // internal implementation. Also called from JvmtiDeferredEvent::post() 180 static void post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) NOT_JVMTI_RETURN; 181 182 static void post_class_unload_internal(const char *name) NOT_JVMTI_RETURN; 183 184 static void initialize_oop_storage() NOT_JVMTI_RETURN; 185 static OopStorage* jvmti_oop_storage(); 186 static OopStorage* weak_tag_storage(); 187 private: 188 189 // GenerateEvents support to allow posting of CompiledMethodLoad and 190 // DynamicCodeGenerated events for a given environment. 191 friend class JvmtiCodeBlobEvents; 192 193 static void post_dynamic_code_generated(JvmtiEnv* env, const char *name, const void *code_begin, 194 const void *code_end) NOT_JVMTI_RETURN; 195 196 // This flag indicates whether RedefineClasses() has ever redefined 197 // one or more classes during the lifetime of the VM. The flag should 198 // only be set by the friend class and can be queried by other sub 199 // systems as needed to relax invariant checks. 200 static uint64_t _redefinition_count; 201 friend class VM_RedefineClasses; 202 inline static void increment_redefinition_count() { 203 JVMTI_ONLY(_redefinition_count++;) 204 } 205 // Flag to indicate if the compiler has recorded all dependencies. When the 206 // can_redefine_classes capability is enabled in the OnLoad phase then the compiler 207 // records all dependencies from startup. However if the capability is first 208 // enabled some time later then the dependencies recorded by the compiler 209 // are incomplete. This flag is used by RedefineClasses to know if the 210 // dependency information is complete or not. 211 static bool _all_dependencies_are_recorded; 212 213 static void post_method_exit_inner(JavaThread* thread, 214 methodHandle& mh, 215 JvmtiThreadState *state, 216 bool exception_exit, 217 frame current_frame, 218 jvalue& value); 219 220 public: 221 inline static bool has_redefined_a_class() { 222 JVMTI_ONLY(return _redefinition_count != 0); 223 NOT_JVMTI(return false); 224 } 225 226 // Only set in safepoint, so no memory ordering needed. 227 inline static uint64_t redefinition_count() { 228 JVMTI_ONLY(return _redefinition_count); 229 NOT_JVMTI(return 0); 230 } 231 232 inline static bool all_dependencies_are_recorded() { 233 return _all_dependencies_are_recorded; 234 } 235 236 inline static void set_all_dependencies_are_recorded(bool on) { 237 _all_dependencies_are_recorded = (on != 0); 238 } 239 240 // Add read edges to the unnamed modules of the bootstrap and app class loaders 241 static void add_default_read_edges(Handle h_module, TRAPS) NOT_JVMTI_RETURN; 242 243 // Add a read edge to the module 244 static jvmtiError add_module_reads(Handle module, Handle to_module, TRAPS); 245 246 // Updates a module to export a package 247 static jvmtiError add_module_exports(Handle module, Handle pkg_name, Handle to_module, TRAPS); 248 249 // Updates a module to open a package 250 static jvmtiError add_module_opens(Handle module, Handle pkg_name, Handle to_module, TRAPS); 251 252 // Add a used service to the module 253 static jvmtiError add_module_uses(Handle module, Handle service, TRAPS); 254 255 // Add a service provider to the module 256 static jvmtiError add_module_provides(Handle module, Handle service, Handle impl_class, TRAPS); 257 258 // let JVMTI know that the JVM_OnLoad code is running 259 static void enter_onload_phase() NOT_JVMTI_RETURN; 260 261 // let JVMTI know that the VM isn't up yet (and JVM_OnLoad code isn't running) 262 static void enter_primordial_phase() NOT_JVMTI_RETURN; 263 264 // let JVMTI know that the VM isn't up yet but JNI is live 265 static void enter_early_start_phase() NOT_JVMTI_RETURN; 266 static void enter_start_phase() NOT_JVMTI_RETURN; 267 268 // let JVMTI know that the VM is fully up and running now 269 static void enter_live_phase() NOT_JVMTI_RETURN; 270 271 // ------ can_* conditions (below) are set at OnLoad and never changed ------------ 272 inline static bool can_modify_any_class() { 273 JVMTI_ONLY(return _can_modify_any_class); 274 NOT_JVMTI(return false); 275 } 276 inline static bool can_access_local_variables() { 277 JVMTI_ONLY(return _can_access_local_variables); 278 NOT_JVMTI(return false); 279 } 280 inline static bool can_hotswap_or_post_breakpoint() { 281 JVMTI_ONLY(return _can_hotswap_or_post_breakpoint); 282 NOT_JVMTI(return false); 283 } 284 inline static bool can_walk_any_space() { 285 JVMTI_ONLY(return _can_walk_any_space); 286 NOT_JVMTI(return false); 287 } 288 289 // field access management 290 static address get_field_access_count_addr() NOT_JVMTI_RETURN_(nullptr); 291 292 // field modification management 293 static address get_field_modification_count_addr() NOT_JVMTI_RETURN_(nullptr); 294 295 // ----------------- 296 297 static bool is_jvmti_version(jint version) { 298 JVMTI_ONLY(return (version & JVMTI_VERSION_MASK) == JVMTI_VERSION_VALUE); 299 NOT_JVMTI(return false); 300 } 301 static bool is_jvmdi_version(jint version) { 302 JVMTI_ONLY(return (version & JVMTI_VERSION_MASK) == JVMDI_VERSION_VALUE); 303 NOT_JVMTI(return false); 304 } 305 static jint get_jvmti_interface(JavaVM *jvm, void **penv, jint version) NOT_JVMTI_RETURN_(0); 306 static void decode_version_values(jint version, int * major, int * minor, 307 int * micro) NOT_JVMTI_RETURN; 308 309 // If the jvmti_thread_state is absent and any thread filtered event 310 // is enabled globally then it is created. 311 // Otherwise, the thread->jvmti_thread_state() is returned. 312 static JvmtiThreadState* get_jvmti_thread_state(JavaThread *thread); 313 314 // single stepping management methods 315 static void at_single_stepping_point(JavaThread *thread, Method* method, address location) NOT_JVMTI_RETURN; 316 static void expose_single_stepping(JavaThread *thread) NOT_JVMTI_RETURN; 317 static bool hide_single_stepping(JavaThread *thread) NOT_JVMTI_RETURN_(false); 318 319 // Methods that notify the debugger that something interesting has happened in the VM. 320 static void post_early_vm_start () NOT_JVMTI_RETURN; 321 static void post_vm_start () NOT_JVMTI_RETURN; 322 static void post_vm_initialized () NOT_JVMTI_RETURN; 323 static void post_vm_death () NOT_JVMTI_RETURN; 324 325 static void post_single_step (JavaThread *thread, Method* method, address location) NOT_JVMTI_RETURN; 326 static void post_raw_breakpoint (JavaThread *thread, Method* method, address location) NOT_JVMTI_RETURN; 327 328 static void post_exception_throw (JavaThread *thread, Method* method, address location, oop exception) NOT_JVMTI_RETURN; 329 static void notice_unwind_due_to_exception (JavaThread *thread, Method* method, address location, oop exception, bool in_handler_frame) NOT_JVMTI_RETURN; 330 331 static oop jni_GetField_probe (JavaThread *thread, jobject jobj, 332 oop obj, Klass* klass, jfieldID fieldID, bool is_static) 333 NOT_JVMTI_RETURN_(nullptr); 334 static void post_field_access_by_jni (JavaThread *thread, oop obj, 335 Klass* klass, jfieldID fieldID, bool is_static) NOT_JVMTI_RETURN; 336 static void post_field_access (JavaThread *thread, Method* method, 337 address location, Klass* field_klass, Handle object, jfieldID field) NOT_JVMTI_RETURN; 338 static oop jni_SetField_probe (JavaThread *thread, jobject jobj, 339 oop obj, Klass* klass, jfieldID fieldID, bool is_static, char sig_type, 340 jvalue *value) NOT_JVMTI_RETURN_(nullptr); 341 static void post_field_modification_by_jni(JavaThread *thread, oop obj, 342 Klass* klass, jfieldID fieldID, bool is_static, char sig_type, 343 jvalue *value); 344 static void post_raw_field_modification(JavaThread *thread, Method* method, 345 address location, Klass* field_klass, Handle object, jfieldID field, 346 char sig_type, jvalue *value) NOT_JVMTI_RETURN; 347 348 static void post_method_entry (JavaThread *thread, Method* method, frame current_frame) NOT_JVMTI_RETURN; 349 static void post_method_exit (JavaThread *thread, Method* method, frame current_frame) NOT_JVMTI_RETURN; 350 351 static void post_class_load (JavaThread *thread, Klass* klass) NOT_JVMTI_RETURN; 352 static void post_class_unload (Klass* klass) NOT_JVMTI_RETURN; 353 static void post_class_prepare (JavaThread *thread, Klass* klass) NOT_JVMTI_RETURN; 354 355 static void post_thread_start (JavaThread *thread) NOT_JVMTI_RETURN; 356 static void post_thread_end (JavaThread *thread) NOT_JVMTI_RETURN; 357 358 static void post_vthread_start (jthread vthread) NOT_JVMTI_RETURN; 359 static void post_vthread_end (jthread vthread) NOT_JVMTI_RETURN; 360 static void post_vthread_mount (jthread vthread) NOT_JVMTI_RETURN; 361 static void post_vthread_unmount (jthread vthread) NOT_JVMTI_RETURN; 362 363 static void continuation_yield_cleanup (JavaThread* thread, jint continuation_frame_count) NOT_JVMTI_RETURN; 364 365 // Support for java.lang.instrument agent loading. 366 static bool _should_post_class_file_load_hook; 367 inline static void set_should_post_class_file_load_hook(bool on) { _should_post_class_file_load_hook = on; } 368 inline static bool should_post_class_file_load_hook() { 369 JVMTI_ONLY(return _should_post_class_file_load_hook); 370 NOT_JVMTI(return false;) 371 } 372 static bool is_early_phase() NOT_JVMTI_RETURN_(false); 373 static bool has_early_class_hook_env() NOT_JVMTI_RETURN_(false); 374 // Return true if the class was modified by the hook. 375 static bool post_class_file_load_hook(Symbol* h_name, Handle class_loader, 376 Handle h_protection_domain, 377 unsigned char **data_ptr, unsigned char **end_ptr, 378 JvmtiCachedClassFileData **cache_ptr) NOT_JVMTI_RETURN_(false); 379 static void post_native_method_bind(Method* method, address* function_ptr) NOT_JVMTI_RETURN; 380 static void post_compiled_method_load(JvmtiEnv* env, nmethod *nm) NOT_JVMTI_RETURN; 381 static void post_compiled_method_load(nmethod *nm) NOT_JVMTI_RETURN; 382 static void post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end) NOT_JVMTI_RETURN; 383 384 // used to post a CompiledMethodUnload event 385 static void post_compiled_method_unload(jmethodID mid, const void *code_begin) NOT_JVMTI_RETURN; 386 387 // similar to post_dynamic_code_generated except that it can be used to 388 // post a DynamicCodeGenerated event while holding locks in the VM. Any event 389 // posted using this function is recorded by the enclosing event collector 390 // -- JvmtiDynamicCodeEventCollector. 391 static void post_dynamic_code_generated_while_holding_locks(const char* name, address code_begin, address code_end) NOT_JVMTI_RETURN; 392 393 static void post_garbage_collection_finish() NOT_JVMTI_RETURN; 394 static void post_garbage_collection_start() NOT_JVMTI_RETURN; 395 static void post_data_dump() NOT_JVMTI_RETURN; 396 static void post_monitor_contended_enter(JavaThread *thread, ObjectMonitor *obj_mntr) NOT_JVMTI_RETURN; 397 static void post_monitor_contended_entered(JavaThread *thread, ObjectMonitor *obj_mntr) NOT_JVMTI_RETURN; 398 static void post_monitor_wait(JavaThread *thread, oop obj, jlong timeout) NOT_JVMTI_RETURN; 399 static void post_monitor_waited(JavaThread *thread, ObjectMonitor *obj_mntr, jboolean timed_out) NOT_JVMTI_RETURN; 400 static void post_object_free(JvmtiEnv* env, GrowableArray<jlong>* objects) NOT_JVMTI_RETURN; 401 static void post_resource_exhausted(jint resource_exhausted_flags, const char* detail) NOT_JVMTI_RETURN; 402 static void record_vm_internal_object_allocation(oop object) NOT_JVMTI_RETURN; 403 // Post objects collected by vm_object_alloc_event_collector. 404 static void post_vm_object_alloc(JavaThread *thread, oop object) NOT_JVMTI_RETURN; 405 // Collects vm internal objects for later event posting. 406 inline static void vm_object_alloc_event_collector(oop object) { 407 if (should_post_vm_object_alloc()) { 408 record_vm_internal_object_allocation(object); 409 } 410 } 411 412 // Used by C2 to deoptimize allocation intrinsics and post vm_object_alloc 413 static int _should_notify_object_alloc; 414 415 static void record_sampled_internal_object_allocation(oop object) NOT_JVMTI_RETURN; 416 // Post objects collected by sampled_object_alloc_event_collector. 417 static void post_sampled_object_alloc(JavaThread *thread, oop object) NOT_JVMTI_RETURN; 418 419 // Collects vm internal objects for later event posting. 420 inline static void sampled_object_alloc_event_collector(oop object) { 421 if (should_post_sampled_object_alloc()) { 422 record_sampled_internal_object_allocation(object); 423 } 424 } 425 426 inline static void post_array_size_exhausted() { 427 if (should_post_resource_exhausted()) { 428 post_resource_exhausted(JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR, 429 "Requested array size exceeds VM limit"); 430 } 431 } 432 433 static void cleanup_thread (JavaThread* thread) NOT_JVMTI_RETURN; 434 static void clear_detected_exception (JavaThread* thread) NOT_JVMTI_RETURN; 435 436 static void transition_pending_onload_raw_monitors() NOT_JVMTI_RETURN; 437 438 #if INCLUDE_SERVICES 439 // attach support 440 static jint load_agent_library(const char *agent, const char *absParam, const char *options, outputStream* out) NOT_JVMTI_RETURN_(JNI_ERR); 441 #endif 442 443 // SetNativeMethodPrefix support 444 static char** get_all_native_method_prefixes(int* count_ptr) NOT_JVMTI_RETURN_(nullptr); 445 446 // JavaThread lifecycle support: 447 static jvmtiError cv_external_thread_to_JavaThread(ThreadsList * t_list, 448 jthread thread, 449 JavaThread ** jt_pp, 450 oop * thread_oop_p); 451 static jvmtiError cv_oop_to_JavaThread(ThreadsList * t_list, oop thread_oop, 452 JavaThread ** jt_pp); 453 }; 454 455 // Support class used by JvmtiDynamicCodeEventCollector and others. It 456 // describes a single code blob by name and address range. 457 class JvmtiCodeBlobDesc : public CHeapObj<mtInternal> { 458 private: 459 char _name[64]; 460 address _code_begin; 461 address _code_end; 462 463 public: 464 JvmtiCodeBlobDesc(const char *name, address code_begin, address code_end) { 465 assert(name != nullptr, "all code blobs must be named"); 466 strncpy(_name, name, sizeof(_name) - 1); 467 _name[sizeof(_name)-1] = '\0'; 468 _code_begin = code_begin; 469 _code_end = code_end; 470 } 471 char* name() { return _name; } 472 address code_begin() { return _code_begin; } 473 address code_end() { return _code_end; } 474 }; 475 476 // JvmtiEventCollector is a helper class to setup thread for 477 // event collection. 478 class JvmtiEventCollector : public StackObj { 479 private: 480 JvmtiEventCollector* _prev; // Save previous one to support nested event collector. 481 bool _unset_jvmti_thread_state; 482 483 public: 484 JvmtiEventCollector() : _prev(nullptr), _unset_jvmti_thread_state(false) {} 485 486 void setup_jvmti_thread_state(); // Set this collector in current thread, returns if success. 487 void unset_jvmti_thread_state(); // Reset previous collector in current thread. 488 virtual bool is_dynamic_code_event() { return false; } 489 virtual bool is_vm_object_alloc_event(){ return false; } 490 virtual bool is_sampled_object_alloc_event(){ return false; } 491 JvmtiEventCollector *get_prev() { return _prev; } 492 }; 493 494 // A JvmtiDynamicCodeEventCollector is a helper class for the JvmtiExport 495 // interface. It collects "dynamic code generated" events that are posted 496 // while holding locks. When the event collector goes out of scope the 497 // events will be posted. 498 // 499 // Usage :- 500 // 501 // { 502 // JvmtiDynamicCodeEventCollector event_collector; 503 // : 504 // { MutexLocker ml(...) 505 // : 506 // JvmtiExport::post_dynamic_code_generated_while_holding_locks(...) 507 // } 508 // // event collector goes out of scope => post events to profiler. 509 // } 510 511 class JvmtiDynamicCodeEventCollector : public JvmtiEventCollector { 512 private: 513 GrowableArray<JvmtiCodeBlobDesc*>* _code_blobs; // collected code blob events 514 515 friend class JvmtiExport; 516 void register_stub(const char* name, address start, address end); 517 518 public: 519 JvmtiDynamicCodeEventCollector() NOT_JVMTI_RETURN; 520 ~JvmtiDynamicCodeEventCollector() NOT_JVMTI_RETURN; 521 bool is_dynamic_code_event() { return true; } 522 523 }; 524 525 // Used as a base class for object allocation collection and then posting 526 // the allocations to any event notification callbacks. 527 // 528 class JvmtiObjectAllocEventCollector : public JvmtiEventCollector { 529 protected: 530 GrowableArray<OopHandle>* _allocated; // field to record collected allocated object oop. 531 bool _enable; // This flag is enabled in constructor if set up in the thread state 532 // and disabled in destructor before posting event. To avoid 533 // collection of objects allocated while running java code inside 534 // agent post_X_object_alloc() event handler. 535 void (*_post_callback)(JavaThread*, oop); // what callback to use when destroying the collector. 536 537 friend class JvmtiExport; 538 539 // Record allocated object oop. 540 inline void record_allocation(oop obj); 541 542 public: 543 JvmtiObjectAllocEventCollector() NOT_JVMTI_RETURN; 544 545 void generate_call_for_allocated(); 546 547 bool is_enabled() { return _enable; } 548 void set_enabled(bool on) { _enable = on; } 549 }; 550 551 // Used to record vm internally allocated object oops and post 552 // vm object alloc event for objects visible to java world. 553 // Constructor enables JvmtiThreadState flag and all vm allocated 554 // objects are recorded in a growable array. When destructor is 555 // called the vm object alloc event is posted for each object 556 // visible to java world. 557 // See jvm.cpp file for its usage. 558 // 559 class JvmtiVMObjectAllocEventCollector : public JvmtiObjectAllocEventCollector { 560 public: 561 JvmtiVMObjectAllocEventCollector() NOT_JVMTI_RETURN; 562 ~JvmtiVMObjectAllocEventCollector() NOT_JVMTI_RETURN; 563 virtual bool is_vm_object_alloc_event() { return true; } 564 }; 565 566 // Used to record sampled allocated object oops and post 567 // sampled object alloc event. 568 // Constructor enables JvmtiThreadState flag and all sampled allocated 569 // objects are recorded in a growable array. When destructor is 570 // called the sampled object alloc event is posted for each sampled object. 571 // See jvm.cpp file for its usage. 572 // 573 class JvmtiSampledObjectAllocEventCollector : public JvmtiObjectAllocEventCollector { 574 public: 575 JvmtiSampledObjectAllocEventCollector(bool should_start = true) { 576 JVMTI_ONLY(if (should_start) start();) 577 } 578 ~JvmtiSampledObjectAllocEventCollector() NOT_JVMTI_RETURN; 579 bool is_sampled_object_alloc_event() { return true; } 580 void start() NOT_JVMTI_RETURN; 581 static bool object_alloc_is_safe_to_sample() NOT_JVMTI_RETURN_(false); 582 }; 583 584 // Marker class to disable the posting of VMObjectAlloc events 585 // within its scope. 586 // 587 // Usage :- 588 // 589 // { 590 // NoJvmtiVMObjectAllocMark njm; 591 // : 592 // // VMObjAlloc event will not be posted 593 // JvmtiExport::vm_object_alloc_event_collector(obj); 594 // : 595 // } 596 597 class NoJvmtiVMObjectAllocMark : public StackObj { 598 private: 599 // enclosing collector if enabled, null otherwise 600 JvmtiVMObjectAllocEventCollector *_collector; 601 602 bool was_enabled() { return _collector != nullptr; } 603 604 public: 605 NoJvmtiVMObjectAllocMark() NOT_JVMTI_RETURN; 606 ~NoJvmtiVMObjectAllocMark() NOT_JVMTI_RETURN; 607 }; 608 609 610 // Base class for reporting GC events to JVMTI. 611 class JvmtiGCMarker : public StackObj { 612 public: 613 JvmtiGCMarker() NOT_JVMTI_RETURN; 614 ~JvmtiGCMarker() NOT_JVMTI_RETURN; 615 }; 616 617 // JvmtiHideSingleStepping is a helper class for hiding 618 // internal single step events. 619 class JvmtiHideSingleStepping : public StackObj { 620 private: 621 bool _single_step_hidden; 622 JavaThread * _thread; 623 624 public: 625 JvmtiHideSingleStepping(JavaThread * thread) { 626 assert(thread != nullptr, "sanity check"); 627 628 _single_step_hidden = false; 629 _thread = thread; 630 if (JvmtiExport::should_post_single_step()) { 631 _single_step_hidden = JvmtiExport::hide_single_stepping(_thread); 632 } 633 } 634 635 ~JvmtiHideSingleStepping() { 636 if (_single_step_hidden) { 637 JvmtiExport::expose_single_stepping(_thread); 638 } 639 } 640 }; 641 642 #endif // SHARE_PRIMS_JVMTIEXPORT_HPP