Path: blob/master/src/hotspot/share/prims/jvmtiExport.hpp
41144 views
/*1* Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_PRIMS_JVMTIEXPORT_HPP25#define SHARE_PRIMS_JVMTIEXPORT_HPP2627#include "jvmtifiles/jvmti.h"28#include "memory/allocation.hpp"29#include "memory/iterator.hpp"30#include "oops/oop.hpp"31#include "oops/oopHandle.hpp"32#include "oops/oopsHierarchy.hpp"33#include "runtime/frame.hpp"34#include "runtime/handles.hpp"35#include "utilities/globalDefinitions.hpp"36#include "utilities/growableArray.hpp"37#include "utilities/macros.hpp"3839// Must be included after jvmti.h.40#include "jvmticmlr.h"4142// Forward declarations4344struct JvmtiCachedClassFileData;45class JvmtiEventControllerPrivate;46class JvmtiManageCapabilities;47class JvmtiEnv;48class JvmtiThreadState;4950class OopStorage;5152#define JVMTI_SUPPORT_FLAG(key) \53private: \54static bool _##key; \55public: \56inline static void set_##key(bool on) { \57JVMTI_ONLY(_##key = (on != 0)); \58NOT_JVMTI(report_unsupported(on)); \59} \60inline static bool key() { \61JVMTI_ONLY(return _##key); \62NOT_JVMTI(return false); \63}646566// This class contains the JVMTI interface for the rest of hotspot.67//68class JvmtiExport : public AllStatic {69friend class VMStructs;70friend class CompileReplay;7172private:7374#if INCLUDE_JVMTI75static int _field_access_count;76static int _field_modification_count;7778static bool _can_access_local_variables;79static bool _can_hotswap_or_post_breakpoint;80static bool _can_modify_any_class;81static bool _can_walk_any_space;82#endif // INCLUDE_JVMTI8384JVMTI_SUPPORT_FLAG(can_get_source_debug_extension)85JVMTI_SUPPORT_FLAG(can_maintain_original_method_order)86JVMTI_SUPPORT_FLAG(can_post_interpreter_events)87JVMTI_SUPPORT_FLAG(can_post_on_exceptions)88JVMTI_SUPPORT_FLAG(can_post_breakpoint)89JVMTI_SUPPORT_FLAG(can_post_field_access)90JVMTI_SUPPORT_FLAG(can_post_field_modification)91JVMTI_SUPPORT_FLAG(can_post_method_entry)92JVMTI_SUPPORT_FLAG(can_post_method_exit)93JVMTI_SUPPORT_FLAG(can_pop_frame)94JVMTI_SUPPORT_FLAG(can_force_early_return)9596JVMTI_SUPPORT_FLAG(early_vmstart_recorded)97JVMTI_SUPPORT_FLAG(can_get_owned_monitor_info) // includes can_get_owned_monitor_stack_depth_info9899friend class JvmtiEventControllerPrivate; // should only modify these flags100JVMTI_SUPPORT_FLAG(should_post_single_step)101JVMTI_SUPPORT_FLAG(should_post_field_access)102JVMTI_SUPPORT_FLAG(should_post_field_modification)103JVMTI_SUPPORT_FLAG(should_post_class_load)104JVMTI_SUPPORT_FLAG(should_post_class_prepare)105JVMTI_SUPPORT_FLAG(should_post_class_unload)106JVMTI_SUPPORT_FLAG(should_post_native_method_bind)107JVMTI_SUPPORT_FLAG(should_post_compiled_method_load)108JVMTI_SUPPORT_FLAG(should_post_compiled_method_unload)109JVMTI_SUPPORT_FLAG(should_post_dynamic_code_generated)110JVMTI_SUPPORT_FLAG(should_post_monitor_contended_enter)111JVMTI_SUPPORT_FLAG(should_post_monitor_contended_entered)112JVMTI_SUPPORT_FLAG(should_post_monitor_wait)113JVMTI_SUPPORT_FLAG(should_post_monitor_waited)114JVMTI_SUPPORT_FLAG(should_post_data_dump)115JVMTI_SUPPORT_FLAG(should_post_garbage_collection_start)116JVMTI_SUPPORT_FLAG(should_post_garbage_collection_finish)117JVMTI_SUPPORT_FLAG(should_post_on_exceptions)118119// ------ the below maybe don't have to be (but are for now)120// fixed conditions here ------------121// any events can be enabled122JVMTI_SUPPORT_FLAG(should_post_thread_life)123JVMTI_SUPPORT_FLAG(should_post_object_free)124JVMTI_SUPPORT_FLAG(should_post_resource_exhausted)125126// we are holding objects on the heap - need to talk to GC - e.g.127// breakpoint info128JVMTI_SUPPORT_FLAG(should_clean_up_heap_objects)129JVMTI_SUPPORT_FLAG(should_post_vm_object_alloc)130JVMTI_SUPPORT_FLAG(should_post_sampled_object_alloc)131132// If flag cannot be implemented, give an error if on=true133static void report_unsupported(bool on);134135// these should only be called by the friend class136friend class JvmtiManageCapabilities;137inline static void set_can_modify_any_class(bool on) {138JVMTI_ONLY(_can_modify_any_class = (on != 0);)139}140inline static void set_can_access_local_variables(bool on) {141JVMTI_ONLY(_can_access_local_variables = (on != 0);)142}143inline static void set_can_hotswap_or_post_breakpoint(bool on) {144JVMTI_ONLY(_can_hotswap_or_post_breakpoint = (on != 0);)145}146inline static void set_can_walk_any_space(bool on) {147JVMTI_ONLY(_can_walk_any_space = (on != 0);)148}149150enum {151JVMTI_VERSION_MASK = 0x70000000,152JVMTI_VERSION_VALUE = 0x30000000,153JVMDI_VERSION_VALUE = 0x20000000154};155156static void post_field_modification(JavaThread *thread, Method* method, address location,157Klass* field_klass, Handle object, jfieldID field,158char sig_type, jvalue *value);159160161// posts a DynamicCodeGenerated event (internal/private implementation).162// The public post_dynamic_code_generated* functions make use of the163// internal implementation. Also called from JvmtiDeferredEvent::post()164static void post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) NOT_JVMTI_RETURN;165166static void post_class_unload_internal(const char *name) NOT_JVMTI_RETURN;167168static void initialize_oop_storage() NOT_JVMTI_RETURN;169static OopStorage* jvmti_oop_storage();170static OopStorage* weak_tag_storage();171private:172173// GenerateEvents support to allow posting of CompiledMethodLoad and174// DynamicCodeGenerated events for a given environment.175friend class JvmtiCodeBlobEvents;176177static void post_dynamic_code_generated(JvmtiEnv* env, const char *name, const void *code_begin,178const void *code_end) NOT_JVMTI_RETURN;179180// This flag indicates whether RedefineClasses() has ever redefined181// one or more classes during the lifetime of the VM. The flag should182// only be set by the friend class and can be queried by other sub183// systems as needed to relax invariant checks.184static uint64_t _redefinition_count;185friend class VM_RedefineClasses;186inline static void increment_redefinition_count() {187JVMTI_ONLY(_redefinition_count++;)188}189// Flag to indicate if the compiler has recorded all dependencies. When the190// can_redefine_classes capability is enabled in the OnLoad phase then the compiler191// records all dependencies from startup. However if the capability is first192// enabled some time later then the dependencies recorded by the compiler193// are incomplete. This flag is used by RedefineClasses to know if the194// dependency information is complete or not.195static bool _all_dependencies_are_recorded;196197static void post_method_exit_inner(JavaThread* thread,198methodHandle& mh,199JvmtiThreadState *state,200bool exception_exit,201frame current_frame,202jvalue& value);203204public:205inline static bool has_redefined_a_class() {206JVMTI_ONLY(return _redefinition_count != 0);207NOT_JVMTI(return false);208}209210// Only set in safepoint, so no memory ordering needed.211inline static uint64_t redefinition_count() {212JVMTI_ONLY(return _redefinition_count);213NOT_JVMTI(return 0);214}215216inline static bool all_dependencies_are_recorded() {217return _all_dependencies_are_recorded;218}219220inline static void set_all_dependencies_are_recorded(bool on) {221_all_dependencies_are_recorded = (on != 0);222}223224// Add read edges to the unnamed modules of the bootstrap and app class loaders225static void add_default_read_edges(Handle h_module, TRAPS) NOT_JVMTI_RETURN;226227// Add a read edge to the module228static jvmtiError add_module_reads(Handle module, Handle to_module, TRAPS);229230// Updates a module to export a package231static jvmtiError add_module_exports(Handle module, Handle pkg_name, Handle to_module, TRAPS);232233// Updates a module to open a package234static jvmtiError add_module_opens(Handle module, Handle pkg_name, Handle to_module, TRAPS);235236// Add a used service to the module237static jvmtiError add_module_uses(Handle module, Handle service, TRAPS);238239// Add a service provider to the module240static jvmtiError add_module_provides(Handle module, Handle service, Handle impl_class, TRAPS);241242// let JVMTI know that the JVM_OnLoad code is running243static void enter_onload_phase() NOT_JVMTI_RETURN;244245// let JVMTI know that the VM isn't up yet (and JVM_OnLoad code isn't running)246static void enter_primordial_phase() NOT_JVMTI_RETURN;247248// let JVMTI know that the VM isn't up yet but JNI is live249static void enter_early_start_phase() NOT_JVMTI_RETURN;250static void enter_start_phase() NOT_JVMTI_RETURN;251252// let JVMTI know that the VM is fully up and running now253static void enter_live_phase() NOT_JVMTI_RETURN;254255// ------ can_* conditions (below) are set at OnLoad and never changed ------------256inline static bool can_modify_any_class() {257JVMTI_ONLY(return _can_modify_any_class);258NOT_JVMTI(return false);259}260inline static bool can_access_local_variables() {261JVMTI_ONLY(return _can_access_local_variables);262NOT_JVMTI(return false);263}264inline static bool can_hotswap_or_post_breakpoint() {265JVMTI_ONLY(return _can_hotswap_or_post_breakpoint);266NOT_JVMTI(return false);267}268inline static bool can_walk_any_space() {269JVMTI_ONLY(return _can_walk_any_space);270NOT_JVMTI(return false);271}272273// field access management274static address get_field_access_count_addr() NOT_JVMTI_RETURN_(0);275276// field modification management277static address get_field_modification_count_addr() NOT_JVMTI_RETURN_(0);278279// -----------------280281static bool is_jvmti_version(jint version) {282JVMTI_ONLY(return (version & JVMTI_VERSION_MASK) == JVMTI_VERSION_VALUE);283NOT_JVMTI(return false);284}285static bool is_jvmdi_version(jint version) {286JVMTI_ONLY(return (version & JVMTI_VERSION_MASK) == JVMDI_VERSION_VALUE);287NOT_JVMTI(return false);288}289static jint get_jvmti_interface(JavaVM *jvm, void **penv, jint version) NOT_JVMTI_RETURN_(0);290static void decode_version_values(jint version, int * major, int * minor,291int * micro) NOT_JVMTI_RETURN;292293// single stepping management methods294static void at_single_stepping_point(JavaThread *thread, Method* method, address location) NOT_JVMTI_RETURN;295static void expose_single_stepping(JavaThread *thread) NOT_JVMTI_RETURN;296static bool hide_single_stepping(JavaThread *thread) NOT_JVMTI_RETURN_(false);297298// Methods that notify the debugger that something interesting has happened in the VM.299static void post_early_vm_start () NOT_JVMTI_RETURN;300static void post_vm_start () NOT_JVMTI_RETURN;301static void post_vm_initialized () NOT_JVMTI_RETURN;302static void post_vm_death () NOT_JVMTI_RETURN;303304static void post_single_step (JavaThread *thread, Method* method, address location) NOT_JVMTI_RETURN;305static void post_raw_breakpoint (JavaThread *thread, Method* method, address location) NOT_JVMTI_RETURN;306307static void post_exception_throw (JavaThread *thread, Method* method, address location, oop exception) NOT_JVMTI_RETURN;308static void notice_unwind_due_to_exception (JavaThread *thread, Method* method, address location, oop exception, bool in_handler_frame) NOT_JVMTI_RETURN;309310static oop jni_GetField_probe (JavaThread *thread, jobject jobj,311oop obj, Klass* klass, jfieldID fieldID, bool is_static)312NOT_JVMTI_RETURN_(NULL);313static void post_field_access_by_jni (JavaThread *thread, oop obj,314Klass* klass, jfieldID fieldID, bool is_static) NOT_JVMTI_RETURN;315static void post_field_access (JavaThread *thread, Method* method,316address location, Klass* field_klass, Handle object, jfieldID field) NOT_JVMTI_RETURN;317static oop jni_SetField_probe (JavaThread *thread, jobject jobj,318oop obj, Klass* klass, jfieldID fieldID, bool is_static, char sig_type,319jvalue *value) NOT_JVMTI_RETURN_(NULL);320static void post_field_modification_by_jni(JavaThread *thread, oop obj,321Klass* klass, jfieldID fieldID, bool is_static, char sig_type,322jvalue *value);323static void post_raw_field_modification(JavaThread *thread, Method* method,324address location, Klass* field_klass, Handle object, jfieldID field,325char sig_type, jvalue *value) NOT_JVMTI_RETURN;326327static void post_method_entry (JavaThread *thread, Method* method, frame current_frame) NOT_JVMTI_RETURN;328static void post_method_exit (JavaThread *thread, Method* method, frame current_frame) NOT_JVMTI_RETURN;329330static void post_class_load (JavaThread *thread, Klass* klass) NOT_JVMTI_RETURN;331static void post_class_unload (Klass* klass) NOT_JVMTI_RETURN;332static void post_class_prepare (JavaThread *thread, Klass* klass) NOT_JVMTI_RETURN;333334static void post_thread_start (JavaThread *thread) NOT_JVMTI_RETURN;335static void post_thread_end (JavaThread *thread) NOT_JVMTI_RETURN;336337// Support for java.lang.instrument agent loading.338static bool _should_post_class_file_load_hook;339inline static void set_should_post_class_file_load_hook(bool on) { _should_post_class_file_load_hook = on; }340inline static bool should_post_class_file_load_hook() {341JVMTI_ONLY(return _should_post_class_file_load_hook);342NOT_JVMTI(return false;)343}344static bool is_early_phase() NOT_JVMTI_RETURN_(false);345static bool has_early_class_hook_env() NOT_JVMTI_RETURN_(false);346// Return true if the class was modified by the hook.347static bool post_class_file_load_hook(Symbol* h_name, Handle class_loader,348Handle h_protection_domain,349unsigned char **data_ptr, unsigned char **end_ptr,350JvmtiCachedClassFileData **cache_ptr) NOT_JVMTI_RETURN_(false);351static void post_native_method_bind(Method* method, address* function_ptr) NOT_JVMTI_RETURN;352static void post_compiled_method_load(JvmtiEnv* env, nmethod *nm) NOT_JVMTI_RETURN;353static void post_compiled_method_load(nmethod *nm) NOT_JVMTI_RETURN;354static void post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end) NOT_JVMTI_RETURN;355356// used to post a CompiledMethodUnload event357static void post_compiled_method_unload(jmethodID mid, const void *code_begin) NOT_JVMTI_RETURN;358359// similiar to post_dynamic_code_generated except that it can be used to360// post a DynamicCodeGenerated event while holding locks in the VM. Any event361// posted using this function is recorded by the enclosing event collector362// -- JvmtiDynamicCodeEventCollector.363static void post_dynamic_code_generated_while_holding_locks(const char* name, address code_begin, address code_end) NOT_JVMTI_RETURN;364365static void post_garbage_collection_finish() NOT_JVMTI_RETURN;366static void post_garbage_collection_start() NOT_JVMTI_RETURN;367static void post_data_dump() NOT_JVMTI_RETURN;368static void post_monitor_contended_enter(JavaThread *thread, ObjectMonitor *obj_mntr) NOT_JVMTI_RETURN;369static void post_monitor_contended_entered(JavaThread *thread, ObjectMonitor *obj_mntr) NOT_JVMTI_RETURN;370static void post_monitor_wait(JavaThread *thread, oop obj, jlong timeout) NOT_JVMTI_RETURN;371static void post_monitor_waited(JavaThread *thread, ObjectMonitor *obj_mntr, jboolean timed_out) NOT_JVMTI_RETURN;372static void post_object_free(JvmtiEnv* env, jlong tag) NOT_JVMTI_RETURN;373static void post_resource_exhausted(jint resource_exhausted_flags, const char* detail) NOT_JVMTI_RETURN;374static void record_vm_internal_object_allocation(oop object) NOT_JVMTI_RETURN;375// Post objects collected by vm_object_alloc_event_collector.376static void post_vm_object_alloc(JavaThread *thread, oop object) NOT_JVMTI_RETURN;377// Collects vm internal objects for later event posting.378inline static void vm_object_alloc_event_collector(oop object) {379if (should_post_vm_object_alloc()) {380record_vm_internal_object_allocation(object);381}382}383384static void record_sampled_internal_object_allocation(oop object) NOT_JVMTI_RETURN;385// Post objects collected by sampled_object_alloc_event_collector.386static void post_sampled_object_alloc(JavaThread *thread, oop object) NOT_JVMTI_RETURN;387388// Collects vm internal objects for later event posting.389inline static void sampled_object_alloc_event_collector(oop object) {390if (should_post_sampled_object_alloc()) {391record_sampled_internal_object_allocation(object);392}393}394395inline static void post_array_size_exhausted() {396if (should_post_resource_exhausted()) {397post_resource_exhausted(JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR,398"Requested array size exceeds VM limit");399}400}401402static void cleanup_thread (JavaThread* thread) NOT_JVMTI_RETURN;403static void clear_detected_exception (JavaThread* thread) NOT_JVMTI_RETURN;404405static void transition_pending_onload_raw_monitors() NOT_JVMTI_RETURN;406407#if INCLUDE_SERVICES408// attach support409static jint load_agent_library(const char *agent, const char *absParam, const char *options, outputStream* out) NOT_JVMTI_RETURN_(JNI_ERR);410#endif411412// SetNativeMethodPrefix support413static char** get_all_native_method_prefixes(int* count_ptr) NOT_JVMTI_RETURN_(NULL);414415// JavaThread lifecycle support:416static jvmtiError cv_external_thread_to_JavaThread(ThreadsList * t_list,417jthread thread,418JavaThread ** jt_pp,419oop * thread_oop_p);420static jvmtiError cv_oop_to_JavaThread(ThreadsList * t_list, oop thread_oop,421JavaThread ** jt_pp);422};423424// Support class used by JvmtiDynamicCodeEventCollector and others. It425// describes a single code blob by name and address range.426class JvmtiCodeBlobDesc : public CHeapObj<mtInternal> {427private:428char _name[64];429address _code_begin;430address _code_end;431432public:433JvmtiCodeBlobDesc(const char *name, address code_begin, address code_end) {434assert(name != NULL, "all code blobs must be named");435strncpy(_name, name, sizeof(_name) - 1);436_name[sizeof(_name)-1] = '\0';437_code_begin = code_begin;438_code_end = code_end;439}440char* name() { return _name; }441address code_begin() { return _code_begin; }442address code_end() { return _code_end; }443};444445// JvmtiEventCollector is a helper class to setup thread for446// event collection.447class JvmtiEventCollector : public StackObj {448private:449JvmtiEventCollector* _prev; // Save previous one to support nested event collector.450bool _unset_jvmti_thread_state;451452public:453JvmtiEventCollector() : _prev(NULL), _unset_jvmti_thread_state(false) {}454455void setup_jvmti_thread_state(); // Set this collector in current thread, returns if success.456void unset_jvmti_thread_state(); // Reset previous collector in current thread.457virtual bool is_dynamic_code_event() { return false; }458virtual bool is_vm_object_alloc_event(){ return false; }459virtual bool is_sampled_object_alloc_event(){ return false; }460JvmtiEventCollector *get_prev() { return _prev; }461};462463// A JvmtiDynamicCodeEventCollector is a helper class for the JvmtiExport464// interface. It collects "dynamic code generated" events that are posted465// while holding locks. When the event collector goes out of scope the466// events will be posted.467//468// Usage :-469//470// {471// JvmtiDynamicCodeEventCollector event_collector;472// :473// { MutexLocker ml(...)474// :475// JvmtiExport::post_dynamic_code_generated_while_holding_locks(...)476// }477// // event collector goes out of scope => post events to profiler.478// }479480class JvmtiDynamicCodeEventCollector : public JvmtiEventCollector {481private:482GrowableArray<JvmtiCodeBlobDesc*>* _code_blobs; // collected code blob events483484friend class JvmtiExport;485void register_stub(const char* name, address start, address end);486487public:488JvmtiDynamicCodeEventCollector() NOT_JVMTI_RETURN;489~JvmtiDynamicCodeEventCollector() NOT_JVMTI_RETURN;490bool is_dynamic_code_event() { return true; }491492};493494// Used as a base class for object allocation collection and then posting495// the allocations to any event notification callbacks.496//497class JvmtiObjectAllocEventCollector : public JvmtiEventCollector {498protected:499GrowableArray<OopHandle>* _allocated; // field to record collected allocated object oop.500bool _enable; // This flag is enabled in constructor if set up in the thread state501// and disabled in destructor before posting event. To avoid502// collection of objects allocated while running java code inside503// agent post_X_object_alloc() event handler.504void (*_post_callback)(JavaThread*, oop); // what callback to use when destroying the collector.505506friend class JvmtiExport;507508// Record allocated object oop.509inline void record_allocation(oop obj);510511public:512JvmtiObjectAllocEventCollector() NOT_JVMTI_RETURN;513514void generate_call_for_allocated();515516bool is_enabled() { return _enable; }517void set_enabled(bool on) { _enable = on; }518};519520// Used to record vm internally allocated object oops and post521// vm object alloc event for objects visible to java world.522// Constructor enables JvmtiThreadState flag and all vm allocated523// objects are recorded in a growable array. When destructor is524// called the vm object alloc event is posted for each object525// visible to java world.526// See jvm.cpp file for its usage.527//528class JvmtiVMObjectAllocEventCollector : public JvmtiObjectAllocEventCollector {529public:530JvmtiVMObjectAllocEventCollector() NOT_JVMTI_RETURN;531~JvmtiVMObjectAllocEventCollector() NOT_JVMTI_RETURN;532virtual bool is_vm_object_alloc_event() { return true; }533};534535// Used to record sampled allocated object oops and post536// sampled object alloc event.537// Constructor enables JvmtiThreadState flag and all sampled allocated538// objects are recorded in a growable array. When destructor is539// called the sampled object alloc event is posted for each sampled object.540// See jvm.cpp file for its usage.541//542class JvmtiSampledObjectAllocEventCollector : public JvmtiObjectAllocEventCollector {543public:544JvmtiSampledObjectAllocEventCollector() NOT_JVMTI_RETURN;545~JvmtiSampledObjectAllocEventCollector() NOT_JVMTI_RETURN;546bool is_sampled_object_alloc_event() { return true; }547static bool object_alloc_is_safe_to_sample() NOT_JVMTI_RETURN_(false);548};549550// Marker class to disable the posting of VMObjectAlloc events551// within its scope.552//553// Usage :-554//555// {556// NoJvmtiVMObjectAllocMark njm;557// :558// // VMObjAlloc event will not be posted559// JvmtiExport::vm_object_alloc_event_collector(obj);560// :561// }562563class NoJvmtiVMObjectAllocMark : public StackObj {564private:565// enclosing collector if enabled, NULL otherwise566JvmtiVMObjectAllocEventCollector *_collector;567568bool was_enabled() { return _collector != NULL; }569570public:571NoJvmtiVMObjectAllocMark() NOT_JVMTI_RETURN;572~NoJvmtiVMObjectAllocMark() NOT_JVMTI_RETURN;573};574575576// Base class for reporting GC events to JVMTI.577class JvmtiGCMarker : public StackObj {578public:579JvmtiGCMarker() NOT_JVMTI_RETURN;580~JvmtiGCMarker() NOT_JVMTI_RETURN;581};582583// JvmtiHideSingleStepping is a helper class for hiding584// internal single step events.585class JvmtiHideSingleStepping : public StackObj {586private:587bool _single_step_hidden;588JavaThread * _thread;589590public:591JvmtiHideSingleStepping(JavaThread * thread) {592assert(thread != NULL, "sanity check");593594_single_step_hidden = false;595_thread = thread;596if (JvmtiExport::should_post_single_step()) {597_single_step_hidden = JvmtiExport::hide_single_stepping(_thread);598}599}600601~JvmtiHideSingleStepping() {602if (_single_step_hidden) {603JvmtiExport::expose_single_stepping(_thread);604}605}606};607608#endif // SHARE_PRIMS_JVMTIEXPORT_HPP609610611