Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp
32285 views
/*1* Copyright (c) 2003, 2017, 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_VM_PRIMS_JVMTIENVBASE_HPP25#define SHARE_VM_PRIMS_JVMTIENVBASE_HPP2627#include "classfile/classLoader.hpp"28#include "prims/jvmtiEnvThreadState.hpp"29#include "prims/jvmtiEventController.hpp"30#include "prims/jvmtiThreadState.hpp"31#include "runtime/fieldDescriptor.hpp"32#include "runtime/frame.hpp"33#include "runtime/handles.inline.hpp"34#include "runtime/orderAccess.hpp"35#include "runtime/thread.hpp"36#include "runtime/vm_operations.hpp"37#include "utilities/growableArray.hpp"38#include "utilities/macros.hpp"3940//41// Forward Declarations42//4344class JvmtiEnv;45class JvmtiThreadState;46class JvmtiRawMonitor; // for jvmtiEnv.hpp47class JvmtiEventControllerPrivate;48class JvmtiTagMap;49505152// One JvmtiEnv object is created per jvmti attachment;53// done via JNI GetEnv() call. Multiple attachments are54// allowed in jvmti.5556class JvmtiEnvBase : public CHeapObj<mtInternal> {5758private:5960#if INCLUDE_JVMTI61static JvmtiEnvBase* _head_environment; // head of environment list62#endif // INCLUDE_JVMTI6364static bool _globally_initialized;65static jvmtiPhase _phase;66static volatile int _dying_thread_env_iteration_count;6768public:6970enum {71JDK15_JVMTI_VERSION = JVMTI_VERSION_1_0 + 33, /* version: 1.0.33 */72JDK16_JVMTI_VERSION = JVMTI_VERSION_1_1 + 102, /* version: 1.1.102 */73JDK17_JVMTI_VERSION = JVMTI_VERSION_1_2 + 2 /* version: 1.2.2 */74};7576static jvmtiPhase get_phase() { return _phase; }77static void set_phase(jvmtiPhase phase) { _phase = phase; }78static bool is_vm_live() { return _phase == JVMTI_PHASE_LIVE; }7980static void entering_dying_thread_env_iteration() { ++_dying_thread_env_iteration_count; }81static void leaving_dying_thread_env_iteration() { --_dying_thread_env_iteration_count; }82static bool is_inside_dying_thread_env_iteration(){ return _dying_thread_env_iteration_count > 0; }8384private:8586enum {87JVMTI_MAGIC = 0x71EE,88DISPOSED_MAGIC = 0xDEFC,89BAD_MAGIC = 0xDEAD90};9192jvmtiEnv _jvmti_external;93jint _magic;94jint _version; // version value passed to JNI GetEnv()95JvmtiEnvBase* _next;96bool _is_retransformable;97const void *_env_local_storage; // per env agent allocated data.98jvmtiEventCallbacks _event_callbacks;99jvmtiExtEventCallbacks _ext_event_callbacks;100JvmtiTagMap* volatile _tag_map;101JvmtiEnvEventEnable _env_event_enable;102jvmtiCapabilities _current_capabilities;103jvmtiCapabilities _prohibited_capabilities;104volatile bool _class_file_load_hook_ever_enabled;105static volatile bool _needs_clean_up;106char** _native_method_prefixes;107int _native_method_prefix_count;108109protected:110JvmtiEnvBase(jint version);111~JvmtiEnvBase();112void dispose();113void env_dispose();114115void set_env_local_storage(const void* data) { _env_local_storage = data; }116const void* get_env_local_storage() { return _env_local_storage; }117118void record_class_file_load_hook_enabled();119void record_first_time_class_file_load_hook_enabled();120121char** get_native_method_prefixes() { return _native_method_prefixes; }122int get_native_method_prefix_count() { return _native_method_prefix_count; }123jvmtiError set_native_method_prefixes(jint prefix_count, char** prefixes);124125private:126friend class JvmtiEventControllerPrivate;127void initialize();128void set_event_callbacks(const jvmtiEventCallbacks* callbacks, jint size_of_callbacks);129static void globally_initialize();130static void periodic_clean_up();131132friend class JvmtiEnvIterator;133JvmtiEnv* next_environment() { return (JvmtiEnv*)_next; }134void set_next_environment(JvmtiEnvBase* env) { _next = env; }135static JvmtiEnv* head_environment() {136JVMTI_ONLY(return (JvmtiEnv*)_head_environment);137NOT_JVMTI(return NULL);138}139140public:141142bool is_valid();143144bool use_version_1_0_semantics(); // agent asked for version 1.0145bool use_version_1_1_semantics(); // agent asked for version 1.1146bool use_version_1_2_semantics(); // agent asked for version 1.2147148bool is_retransformable() { return _is_retransformable; }149150static ByteSize jvmti_external_offset() {151return byte_offset_of(JvmtiEnvBase, _jvmti_external);152};153154static JvmtiEnv* JvmtiEnv_from_jvmti_env(jvmtiEnv *env) {155return (JvmtiEnv*)((intptr_t)env - in_bytes(jvmti_external_offset()));156};157158jvmtiCapabilities *get_capabilities() { return &_current_capabilities; }159160jvmtiCapabilities *get_prohibited_capabilities() { return &_prohibited_capabilities; }161162static char** get_all_native_method_prefixes(int* count_ptr);163164// This test will answer true when all environments have been disposed and some have165// not yet been deallocated. As a result, this test should only be used as an166// optimization for the no environment case.167static bool environments_might_exist() {168return head_environment() != NULL;169}170171static void check_for_periodic_clean_up();172173JvmtiEnvEventEnable *env_event_enable() {174return &_env_event_enable;175}176177jvmtiError allocate(jlong size, unsigned char** mem_ptr) {178if (size < 0) {179return JVMTI_ERROR_ILLEGAL_ARGUMENT;180}181if (size == 0) {182*mem_ptr = NULL;183} else {184*mem_ptr = (unsigned char *)os::malloc((size_t)size, mtInternal);185if (*mem_ptr == NULL) {186return JVMTI_ERROR_OUT_OF_MEMORY;187}188}189return JVMTI_ERROR_NONE;190}191192jvmtiError deallocate(unsigned char* mem) {193if (mem != NULL) {194os::free(mem, mtInternal);195}196return JVMTI_ERROR_NONE;197}198199200// Memory functions201unsigned char* jvmtiMalloc(jlong size); // don't use this - call allocate202203// method to create a local handle204jobject jni_reference(Handle hndl) {205return JNIHandles::make_local(hndl());206}207208// method to create a local handle.209// This function allows caller to specify which210// threads local handle table to use.211jobject jni_reference(JavaThread *thread, Handle hndl) {212return JNIHandles::make_local(thread, hndl());213}214215// method to destroy a local handle216void destroy_jni_reference(jobject jobj) {217JNIHandles::destroy_local(jobj);218}219220// method to destroy a local handle.221// This function allows caller to specify which222// threads local handle table to use although currently it is223// not used.224void destroy_jni_reference(JavaThread *thread, jobject jobj) {225destroy_jni_reference(jobj);226}227228jvmtiEnv* jvmti_external() { return &_jvmti_external; };229230// Event Dispatch231232bool has_callback(jvmtiEvent event_type) {233assert(event_type >= JVMTI_MIN_EVENT_TYPE_VAL &&234event_type <= JVMTI_MAX_EVENT_TYPE_VAL, "checking");235return ((void**)&_event_callbacks)[event_type-JVMTI_MIN_EVENT_TYPE_VAL] != NULL;236}237238jvmtiEventCallbacks* callbacks() {239return &_event_callbacks;240}241242jvmtiExtEventCallbacks* ext_callbacks() {243return &_ext_event_callbacks;244}245246void set_tag_map(JvmtiTagMap* tag_map) {247_tag_map = tag_map;248}249250JvmtiTagMap* tag_map() {251return _tag_map;252}253254JvmtiTagMap* tag_map_acquire() {255return (JvmtiTagMap*)OrderAccess::load_ptr_acquire(&_tag_map);256}257258void release_set_tag_map(JvmtiTagMap* tag_map) {259OrderAccess::release_store_ptr(&_tag_map, tag_map);260}261262// return true if event is enabled globally or for any thread263// True only if there is a callback for it.264bool is_enabled(jvmtiEvent event_type) {265return _env_event_enable.is_enabled(event_type);266}267268// Random Utilities269270protected:271// helper methods for creating arrays of global JNI Handles from local Handles272// allocated into environment specific storage273jobject * new_jobjectArray(int length, Handle *handles);274jthread * new_jthreadArray(int length, Handle *handles);275jthreadGroup * new_jthreadGroupArray(int length, Handle *handles);276277// convert from JNIHandle to JavaThread *278JavaThread * get_JavaThread(jthread jni_thread);279280// convert to a jni jclass from a non-null Klass*281jclass get_jni_class_non_null(Klass* k);282283jint count_locked_objects(JavaThread *java_thread, Handle hobj);284jvmtiError get_locked_objects_in_frame(JavaThread *calling_thread,285JavaThread* java_thread,286javaVFrame *jvf,287GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list,288jint depth);289vframe* vframeFor(JavaThread* java_thread, jint depth);290291public:292// get a field descriptor for the specified class and field293static bool get_field_descriptor(Klass* k, jfieldID field, fieldDescriptor* fd);294// test for suspend - most (all?) of these should go away295static bool is_thread_fully_suspended(JavaThread *thread,296bool wait_for_suspend,297uint32_t *bits);298299300// JVMTI API helper functions which are called at safepoint or thread is suspended.301jvmtiError get_frame_count(JvmtiThreadState *state, jint *count_ptr);302jvmtiError get_frame_location(JavaThread* java_thread, jint depth,303jmethodID* method_ptr, jlocation* location_ptr);304jvmtiError get_object_monitor_usage(JavaThread *calling_thread,305jobject object, jvmtiMonitorUsage* info_ptr);306jvmtiError get_stack_trace(JavaThread *java_thread,307jint stack_depth, jint max_count,308jvmtiFrameInfo* frame_buffer, jint* count_ptr);309jvmtiError get_current_contended_monitor(JavaThread *calling_thread,310JavaThread *java_thread,311jobject *monitor_ptr);312jvmtiError get_owned_monitors(JavaThread *calling_thread, JavaThread* java_thread,313GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list);314jvmtiError check_top_frame(JavaThread* current_thread, JavaThread* java_thread,315jvalue value, TosState tos, Handle* ret_ob_h);316jvmtiError force_early_return(JavaThread* java_thread, jvalue value, TosState tos);317};318319// This class is the only safe means of iterating through environments.320// Note that this iteratation includes invalid environments pending321// deallocation -- in fact, some uses depend on this behavior.322323class JvmtiEnvIterator : public StackObj {324private:325bool _entry_was_marked;326public:327JvmtiEnvIterator() {328if (Threads::number_of_threads() == 0) {329_entry_was_marked = false; // we are single-threaded, no need330} else {331Thread::current()->entering_jvmti_env_iteration();332_entry_was_marked = true;333}334}335~JvmtiEnvIterator() {336if (_entry_was_marked) {337Thread::current()->leaving_jvmti_env_iteration();338}339}340JvmtiEnv* first() { return JvmtiEnvBase::head_environment(); }341JvmtiEnv* next(JvmtiEnvBase* env) { return env->next_environment(); }342};343344345// VM operation to get monitor information with stack depth.346class VM_GetOwnedMonitorInfo : public VM_Operation {347private:348JvmtiEnv *_env;349JavaThread* _calling_thread;350JavaThread *_java_thread;351jvmtiError _result;352GrowableArray<jvmtiMonitorStackDepthInfo*> *_owned_monitors_list;353354public:355VM_GetOwnedMonitorInfo(JvmtiEnv* env, JavaThread* calling_thread,356JavaThread* java_thread,357GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitor_list) {358_env = env;359_calling_thread = calling_thread;360_java_thread = java_thread;361_owned_monitors_list = owned_monitor_list;362_result = JVMTI_ERROR_NONE;363}364VMOp_Type type() const { return VMOp_GetOwnedMonitorInfo; }365void doit() {366_result = JVMTI_ERROR_THREAD_NOT_ALIVE;367if (Threads::includes(_java_thread) && !_java_thread->is_exiting()368&& _java_thread->threadObj() != NULL) {369_result = ((JvmtiEnvBase *)_env)->get_owned_monitors(_calling_thread, _java_thread,370_owned_monitors_list);371}372}373jvmtiError result() { return _result; }374};375376377// VM operation to get object monitor usage.378class VM_GetObjectMonitorUsage : public VM_Operation {379private:380JvmtiEnv *_env;381jobject _object;382JavaThread* _calling_thread;383jvmtiMonitorUsage* _info_ptr;384jvmtiError _result;385386public:387VM_GetObjectMonitorUsage(JvmtiEnv *env, JavaThread* calling_thread, jobject object, jvmtiMonitorUsage* info_ptr) {388_env = env;389_object = object;390_calling_thread = calling_thread;391_info_ptr = info_ptr;392}393VMOp_Type type() const { return VMOp_GetObjectMonitorUsage; }394jvmtiError result() { return _result; }395void doit() {396_result = ((JvmtiEnvBase*) _env)->get_object_monitor_usage(_calling_thread, _object, _info_ptr);397}398399};400401// VM operation to get current contended monitor.402class VM_GetCurrentContendedMonitor : public VM_Operation {403private:404JvmtiEnv *_env;405JavaThread *_calling_thread;406JavaThread *_java_thread;407jobject *_owned_monitor_ptr;408jvmtiError _result;409410public:411VM_GetCurrentContendedMonitor(JvmtiEnv *env, JavaThread *calling_thread, JavaThread *java_thread, jobject *mon_ptr) {412_env = env;413_calling_thread = calling_thread;414_java_thread = java_thread;415_owned_monitor_ptr = mon_ptr;416}417VMOp_Type type() const { return VMOp_GetCurrentContendedMonitor; }418jvmtiError result() { return _result; }419void doit() {420_result = JVMTI_ERROR_THREAD_NOT_ALIVE;421if (Threads::includes(_java_thread) && !_java_thread->is_exiting() &&422_java_thread->threadObj() != NULL) {423_result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,_java_thread,_owned_monitor_ptr);424}425}426};427428// VM operation to get stack trace at safepoint.429class VM_GetStackTrace : public VM_Operation {430private:431JvmtiEnv *_env;432JavaThread *_java_thread;433jint _start_depth;434jint _max_count;435jvmtiFrameInfo *_frame_buffer;436jint *_count_ptr;437jvmtiError _result;438439public:440VM_GetStackTrace(JvmtiEnv *env, JavaThread *java_thread,441jint start_depth, jint max_count,442jvmtiFrameInfo* frame_buffer, jint* count_ptr) {443_env = env;444_java_thread = java_thread;445_start_depth = start_depth;446_max_count = max_count;447_frame_buffer = frame_buffer;448_count_ptr = count_ptr;449}450jvmtiError result() { return _result; }451VMOp_Type type() const { return VMOp_GetStackTrace; }452void doit() {453_result = JVMTI_ERROR_THREAD_NOT_ALIVE;454if (Threads::includes(_java_thread) && !_java_thread->is_exiting()455&& _java_thread->threadObj() != NULL) {456_result = ((JvmtiEnvBase *)_env)->get_stack_trace(_java_thread,457_start_depth, _max_count,458_frame_buffer, _count_ptr);459}460}461};462463// forward declaration464struct StackInfoNode;465466// VM operation to get stack trace at safepoint.467class VM_GetMultipleStackTraces : public VM_Operation {468private:469JvmtiEnv *_env;470jint _max_frame_count;471jvmtiStackInfo *_stack_info;472jvmtiError _result;473int _frame_count_total;474struct StackInfoNode *_head;475476JvmtiEnvBase *env() { return (JvmtiEnvBase *)_env; }477jint max_frame_count() { return _max_frame_count; }478struct StackInfoNode *head() { return _head; }479void set_head(StackInfoNode *head) { _head = head; }480481protected:482void set_result(jvmtiError result) { _result = result; }483void fill_frames(jthread jt, JavaThread *thr, oop thread_oop);484void allocate_and_fill_stacks(jint thread_count);485486public:487VM_GetMultipleStackTraces(JvmtiEnv *env, jint max_frame_count) {488_env = env;489_max_frame_count = max_frame_count;490_frame_count_total = 0;491_head = NULL;492_result = JVMTI_ERROR_NONE;493}494VMOp_Type type() const { return VMOp_GetMultipleStackTraces; }495jvmtiStackInfo *stack_info() { return _stack_info; }496jvmtiError result() { return _result; }497};498499500// VM operation to get stack trace at safepoint.501class VM_GetAllStackTraces : public VM_GetMultipleStackTraces {502private:503JavaThread *_calling_thread;504jint _final_thread_count;505506public:507VM_GetAllStackTraces(JvmtiEnv *env, JavaThread *calling_thread,508jint max_frame_count)509: VM_GetMultipleStackTraces(env, max_frame_count) {510_calling_thread = calling_thread;511}512VMOp_Type type() const { return VMOp_GetAllStackTraces; }513void doit();514jint final_thread_count() { return _final_thread_count; }515};516517// VM operation to get stack trace at safepoint.518class VM_GetThreadListStackTraces : public VM_GetMultipleStackTraces {519private:520jint _thread_count;521const jthread* _thread_list;522523public:524VM_GetThreadListStackTraces(JvmtiEnv *env, jint thread_count, const jthread* thread_list, jint max_frame_count)525: VM_GetMultipleStackTraces(env, max_frame_count) {526_thread_count = thread_count;527_thread_list = thread_list;528}529VMOp_Type type() const { return VMOp_GetThreadListStackTraces; }530void doit();531};532533534// VM operation to count stack frames at safepoint.535class VM_GetFrameCount : public VM_Operation {536private:537JvmtiEnv *_env;538JvmtiThreadState *_state;539jint *_count_ptr;540jvmtiError _result;541542public:543VM_GetFrameCount(JvmtiEnv *env, JvmtiThreadState *state, jint *count_ptr) {544_env = env;545_state = state;546_count_ptr = count_ptr;547}548VMOp_Type type() const { return VMOp_GetFrameCount; }549jvmtiError result() { return _result; }550void doit() {551_result = ((JvmtiEnvBase*)_env)->get_frame_count(_state, _count_ptr);552}553};554555// VM operation to frame location at safepoint.556class VM_GetFrameLocation : public VM_Operation {557private:558JvmtiEnv *_env;559JavaThread* _java_thread;560jint _depth;561jmethodID* _method_ptr;562jlocation* _location_ptr;563jvmtiError _result;564565public:566VM_GetFrameLocation(JvmtiEnv *env, JavaThread* java_thread, jint depth,567jmethodID* method_ptr, jlocation* location_ptr) {568_env = env;569_java_thread = java_thread;570_depth = depth;571_method_ptr = method_ptr;572_location_ptr = location_ptr;573}574VMOp_Type type() const { return VMOp_GetFrameLocation; }575jvmtiError result() { return _result; }576void doit() {577_result = ((JvmtiEnvBase*)_env)->get_frame_location(_java_thread, _depth,578_method_ptr, _location_ptr);579}580};581582583// ResourceTracker584//585// ResourceTracker works a little like a ResourceMark. All allocates586// using the resource tracker are recorded. If an allocate using the587// resource tracker fails the destructor will free any resources588// that were allocated using the tracker.589// The motive for this class is to avoid messy error recovery code590// in situations where multiple allocations are done in sequence. If591// the second or subsequent allocation fails it avoids any code to592// release memory allocated in the previous calls.593//594// Usage :-595// ResourceTracker rt(env);596// :597// err = rt.allocate(1024, &ptr);598599class ResourceTracker : public StackObj {600private:601JvmtiEnv* _env;602GrowableArray<unsigned char*> *_allocations;603bool _failed;604public:605ResourceTracker(JvmtiEnv* env);606~ResourceTracker();607jvmtiError allocate(jlong size, unsigned char** mem_ptr);608unsigned char* allocate(jlong size);609char* strdup(const char* str);610};611612613// Jvmti monitor closure to collect off stack monitors.614class JvmtiMonitorClosure: public MonitorClosure {615private:616JavaThread *_java_thread;617JavaThread *_calling_thread;618GrowableArray<jvmtiMonitorStackDepthInfo*> *_owned_monitors_list;619jvmtiError _error;620JvmtiEnvBase *_env;621622public:623JvmtiMonitorClosure(JavaThread* thread, JavaThread *calling_thread,624GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors,625JvmtiEnvBase *env) {626_java_thread = thread;627_calling_thread = calling_thread;628_owned_monitors_list = owned_monitors;629_error = JVMTI_ERROR_NONE;630_env = env;631}632void do_monitor(ObjectMonitor* mon);633jvmtiError error() { return _error;}634};635636#endif // SHARE_VM_PRIMS_JVMTIENVBASE_HPP637638639