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