/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_PRIMS_JVMTIEXPORT_HPP
#define SHARE_VM_PRIMS_JVMTIEXPORT_HPP
#include "jvmtifiles/jvmti.h"
#include "memory/allocation.hpp"
#include "memory/iterator.hpp"
#include "oops/oopsHierarchy.hpp"
#include "runtime/handles.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/growableArray.hpp"
// Must be included after jvmti.h.
#include "code/jvmticmlr.h"
// Forward declarations
class JvmtiEventControllerPrivate;
class JvmtiManageCapabilities;
class JvmtiEnv;
class JvmtiThreadState;
class AttachOperation;
private: \
static bool _##key; \
public: \
// This class contains the JVMTI interface for the rest of hotspot.
//
friend class VMStructs;
private:
static int _field_access_count;
static int _field_modification_count;
static bool _can_access_local_variables;
static bool _can_hotswap_or_post_breakpoint;
static bool _can_modify_any_class;
static bool _can_walk_any_space;
friend class JvmtiEventControllerPrivate; // should only modify these flags
// ------ the below maybe don't have to be (but are for now)
// fixed conditions here ------------
// any events can be enabled
// we are holding objects on the heap - need to talk to GC - e.g.
// breakpoint info
// these should only be called by the friend class
friend class JvmtiManageCapabilities;
inline static void set_can_access_local_variables(bool on) { _can_access_local_variables = (on != 0); }
inline static void set_can_hotswap_or_post_breakpoint(bool on) { _can_hotswap_or_post_breakpoint = (on != 0); }
enum {
};
// The public post_dynamic_code_generated* functions make use of the
// internal implementation. Also called from JvmtiDeferredEvent::post()
static void post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end);
private:
// GenerateEvents support to allow posting of CompiledMethodLoad and
// DynamicCodeGenerated events for a given environment.
friend class JvmtiCodeBlobEvents;
const jvmtiAddrLocationMap* map);
const void *code_end);
// The RedefineClasses() API breaks some invariants in the "regular"
// system. For example, there are sanity checks when GC'ing nmethods
// that require the containing class to be unloading. However, when a
// method is redefined, the old method and nmethod can become GC'able
// without the containing class unloading. The state of becoming
// GC'able can be asynchronous to the RedefineClasses() call since
// the old method may still be running and cannot be GC'ed until
// after all old invocations have finished. Additionally, a method
// that has not been redefined may have an nmethod that depends on
// the redefined method. The dependent nmethod will get deopted in
// this case and may also be GC'able without the containing class
// being unloaded.
//
// This flag indicates whether RedefineClasses() has ever redefined
// one or more classes during the lifetime of the VM. The flag should
// only be set by the friend class and can be queried by other sub
// systems as needed to relax invariant checks.
static bool _has_redefined_a_class;
friend class VM_RedefineClasses;
inline static void set_has_redefined_a_class() {
_has_redefined_a_class = true;
}
// Flag to indicate if the compiler has recorded all dependencies. When the
// can_redefine_classes capability is enabled in the OnLoad phase then the compiler
// records all dependencies from startup. However if the capability is first
// enabled some time later then the dependencies recorded by the compiler
// are incomplete. This flag is used by RedefineClasses to know if the
// dependency information is complete or not.
static bool _all_dependencies_are_recorded;
public:
inline static bool has_redefined_a_class() {
return _has_redefined_a_class;
}
inline static bool all_dependencies_are_recorded() {
return _all_dependencies_are_recorded;
}
_all_dependencies_are_recorded = (on != 0);
}
// let JVMTI know that the JVM_OnLoad code is running
static void enter_onload_phase();
// let JVMTI know that the VM isn't up yet (and JVM_OnLoad code isn't running)
static void enter_primordial_phase();
// let JVMTI know that the VM isn't up yet but JNI is live
static void enter_start_phase();
// let JVMTI know that the VM is fully up and running now
static void enter_live_phase();
// ------ can_* conditions (below) are set at OnLoad and never changed ------------
// field access management
static address get_field_access_count_addr();
// field modification management
static address get_field_modification_count_addr();
// -----------------
static bool is_jvmti_version(jint version) { return (version & JVMTI_VERSION_MASK) == JVMTI_VERSION_VALUE; }
static bool is_jvmdi_version(jint version) { return (version & JVMTI_VERSION_MASK) == JVMDI_VERSION_VALUE; }
int * micro);
// single stepping management methods
// Methods that notify the debugger that something interesting has happened in the VM.
static void post_vm_start ();
static void post_vm_initialized ();
static void post_vm_death ();
static void post_exception_throw (JavaThread *thread, methodOop method, address location, oop exception);
static void notice_unwind_due_to_exception (JavaThread *thread, methodOop method, address location, oop exception, bool in_handler_frame);
// Support for java.lang.instrument agent loading.
static bool _should_post_class_file_load_hook;
inline static void set_should_post_class_file_load_hook(bool on) { _should_post_class_file_load_hook = on; }
unsigned char **cached_data_ptr,
static void post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end);
// used to post a CompiledMethodUnload event
// similiar to post_dynamic_code_generated except that it can be used to
// post a DynamicCodeGenerated event while holding locks in the VM. Any event
// posted using this function is recorded by the enclosing event collector
// -- JvmtiDynamicCodeEventCollector.
static void post_dynamic_code_generated_while_holding_locks(const char* name, address code_begin, address code_end);
static void post_garbage_collection_finish();
static void post_garbage_collection_start();
static void post_data_dump();
// Post objects collected by vm_object_alloc_event_collector.
// Collects vm internal objects for later event posting.
if (should_post_vm_object_alloc()) {
}
}
inline static void post_array_size_exhausted() {
if (should_post_resource_exhausted()) {
"Requested array size exceeds VM limit");
}
}
static void oops_do(OopClosure* f);
static void gc_epilogue();
static void transition_pending_onload_raw_monitors();
// attach support
// SetNativeMethodPrefix support
static char** get_all_native_method_prefixes(int* count_ptr);
};
// Support class used by JvmtiDynamicCodeEventCollector and others. It
// describes a single code blob by name and address range.
private:
public:
}
};
// JvmtiEventCollector is a helper class to setup thread for
// event collection.
private:
public:
void setup_jvmti_thread_state(); // Set this collector in current thread.
void unset_jvmti_thread_state(); // Reset previous collector in current thread.
virtual bool is_dynamic_code_event() { return false; }
virtual bool is_vm_object_alloc_event(){ return false; }
};
// A JvmtiDynamicCodeEventCollector is a helper class for the JvmtiExport
// interface. It collects "dynamic code generated" events that are posted
// while holding locks. When the event collector goes out of scope the
// events will be posted.
//
// Usage :-
//
// {
// JvmtiDynamicCodeEventCollector event_collector;
// :
// { MutexLocker ml(...)
// :
// JvmtiExport::post_dynamic_code_generated_while_holding_locks(...)
// }
// // event collector goes out of scope => post events to profiler.
// }
private:
friend class JvmtiExport;
public:
bool is_dynamic_code_event() { return true; }
};
// Used to record vm internally allocated object oops and post
// vm object alloc event for objects visible to java world.
// Constructor enables JvmtiThreadState flag and all vm allocated
// objects are recorded in a growable array. When destructor is
// called the vm object alloc event is posted for each objects
// visible to java world.
// See jvm.cpp file for its usage.
//
private:
// in destructor before posting event. To avoid
// collection of objects allocated while running java code inside
// agent post_vm_object_alloc() event handler.
//GC support
void oops_do(OopClosure* f);
friend class JvmtiExport;
// Record vm allocated object oop.
//GC support
static void oops_do_for_all_threads(OopClosure* f);
public:
bool is_vm_object_alloc_event() { return true; }
};
// Marker class to disable the posting of VMObjectAlloc events
// within its scope.
//
// Usage :-
//
// {
// NoJvmtiVMObjectAllocMark njm;
// :
// // VMObjAlloc event will not be posted
// JvmtiExport::vm_object_alloc_event_collector(obj);
// :
// }
private:
// enclosing collector if enabled, NULL otherwise
public:
};
// Base class for reporting GC events to JVMTI.
public:
~JvmtiGCMarker();
};
// JvmtiHideSingleStepping is a helper class for hiding
// internal single step events.
private:
bool _single_step_hidden;
public:
_single_step_hidden = false;
if (JvmtiExport::should_post_single_step()) {
}
}
if (_single_step_hidden) {
}
}
};
#endif // SHARE_VM_PRIMS_JVMTIEXPORT_HPP