Path: blob/master/src/hotspot/share/prims/jvmtiExport.cpp
41145 views
/*1* Copyright (c) 2003, 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#include "precompiled.hpp"25#include "classfile/javaClasses.inline.hpp"26#include "classfile/moduleEntry.hpp"27#include "classfile/vmClasses.hpp"28#include "classfile/vmSymbols.hpp"29#include "code/nmethod.hpp"30#include "code/pcDesc.hpp"31#include "code/scopeDesc.hpp"32#include "gc/shared/oopStorageSet.hpp"33#include "interpreter/interpreter.hpp"34#include "jvmtifiles/jvmtiEnv.hpp"35#include "logging/log.hpp"36#include "logging/logStream.hpp"37#include "memory/allocation.inline.hpp"38#include "memory/resourceArea.hpp"39#include "memory/universe.hpp"40#include "oops/klass.inline.hpp"41#include "oops/objArrayKlass.hpp"42#include "oops/objArrayOop.hpp"43#include "oops/oop.inline.hpp"44#include "oops/oopHandle.inline.hpp"45#include "prims/jvmtiCodeBlobEvents.hpp"46#include "prims/jvmtiEventController.hpp"47#include "prims/jvmtiEventController.inline.hpp"48#include "prims/jvmtiExport.hpp"49#include "prims/jvmtiImpl.hpp"50#include "prims/jvmtiManageCapabilities.hpp"51#include "prims/jvmtiRawMonitor.hpp"52#include "prims/jvmtiRedefineClasses.hpp"53#include "prims/jvmtiTagMap.hpp"54#include "prims/jvmtiThreadState.inline.hpp"55#include "runtime/arguments.hpp"56#include "runtime/fieldDescriptor.inline.hpp"57#include "runtime/handles.inline.hpp"58#include "runtime/interfaceSupport.inline.hpp"59#include "runtime/javaCalls.hpp"60#include "runtime/jniHandles.inline.hpp"61#include "runtime/objectMonitor.hpp"62#include "runtime/objectMonitor.inline.hpp"63#include "runtime/os.hpp"64#include "runtime/osThread.hpp"65#include "runtime/safepointVerifiers.hpp"66#include "runtime/serviceThread.hpp"67#include "runtime/thread.inline.hpp"68#include "runtime/threadSMR.hpp"69#include "runtime/vframe.inline.hpp"70#include "runtime/vm_version.hpp"71#include "utilities/macros.hpp"7273#ifdef JVMTI_TRACE74#define EVT_TRACE(evt,out) if ((JvmtiTrace::event_trace_flags(evt) & JvmtiTrace::SHOW_EVENT_SENT) != 0) { SafeResourceMark rm; log_trace(jvmti) out; }75#define EVT_TRIG_TRACE(evt,out) if ((JvmtiTrace::event_trace_flags(evt) & JvmtiTrace::SHOW_EVENT_TRIGGER) != 0) { SafeResourceMark rm; log_trace(jvmti) out; }76#else77#define EVT_TRIG_TRACE(evt,out)78#define EVT_TRACE(evt,out)79#endif8081///////////////////////////////////////////////////////////////82//83// JvmtiEventTransition84//85// TO DO --86// more handle purging8788// Use this for JavaThreads and state is _thread_in_vm.89class JvmtiJavaThreadEventTransition : StackObj {90private:91ResourceMark _rm;92ThreadToNativeFromVM _transition;93HandleMark _hm;9495public:96JvmtiJavaThreadEventTransition(JavaThread *thread) :97_rm(),98_transition(thread),99_hm(thread) {};100};101102// For JavaThreads which are not in _thread_in_vm state103// and other system threads use this.104class JvmtiThreadEventTransition : StackObj {105private:106ResourceMark _rm;107HandleMark _hm;108JavaThreadState _saved_state;109JavaThread *_jthread;110111public:112JvmtiThreadEventTransition(Thread *thread) : _rm(), _hm(thread) {113if (thread->is_Java_thread()) {114_jthread = thread->as_Java_thread();115_saved_state = _jthread->thread_state();116if (_saved_state == _thread_in_Java) {117ThreadStateTransition::transition_from_java(_jthread, _thread_in_native);118} else {119ThreadStateTransition::transition(_jthread, _saved_state, _thread_in_native);120}121} else {122_jthread = NULL;123}124}125126~JvmtiThreadEventTransition() {127if (_jthread != NULL)128ThreadStateTransition::transition_from_native(_jthread, _saved_state);129}130};131132133///////////////////////////////////////////////////////////////134//135// JvmtiEventMark136//137138class JvmtiEventMark : public StackObj {139private:140JavaThread *_thread;141JNIEnv* _jni_env;142JvmtiThreadState::ExceptionState _saved_exception_state;143#if 0144JNIHandleBlock* _hblock;145#endif146147public:148JvmtiEventMark(JavaThread *thread) : _thread(thread),149_jni_env(thread->jni_environment()),150_saved_exception_state(JvmtiThreadState::ES_CLEARED) {151#if 0152_hblock = thread->active_handles();153_hblock->clear_thoroughly(); // so we can be safe154#else155// we want to use the code above - but that needs the JNIHandle changes - later...156// for now, steal JNI push local frame code157JvmtiThreadState *state = thread->jvmti_thread_state();158// we are before an event.159// Save current jvmti thread exception state.160if (state != NULL) {161_saved_exception_state = state->get_exception_state();162}163164JNIHandleBlock* old_handles = thread->active_handles();165JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread);166assert(new_handles != NULL, "should not be NULL");167new_handles->set_pop_frame_link(old_handles);168thread->set_active_handles(new_handles);169#endif170assert(thread == JavaThread::current(), "thread must be current!");171thread->frame_anchor()->make_walkable(thread);172};173174~JvmtiEventMark() {175#if 0176_hblock->clear(); // for consistency with future correct behavior177#else178// we want to use the code above - but that needs the JNIHandle changes - later...179// for now, steal JNI pop local frame code180JNIHandleBlock* old_handles = _thread->active_handles();181JNIHandleBlock* new_handles = old_handles->pop_frame_link();182assert(new_handles != NULL, "should not be NULL");183_thread->set_active_handles(new_handles);184// Note that we set the pop_frame_link to NULL explicitly, otherwise185// the release_block call will release the blocks.186old_handles->set_pop_frame_link(NULL);187JNIHandleBlock::release_block(old_handles, _thread); // may block188#endif189190JvmtiThreadState* state = _thread->jvmti_thread_state();191// we are continuing after an event.192if (state != NULL) {193// Restore the jvmti thread exception state.194state->restore_exception_state(_saved_exception_state);195}196}197198#if 0199jobject to_jobject(oop obj) { return obj == NULL? NULL : _hblock->allocate_handle_fast(obj); }200#else201// we want to use the code above - but that needs the JNIHandle changes - later...202// for now, use regular make_local203jobject to_jobject(oop obj) { return JNIHandles::make_local(_thread,obj); }204#endif205206jclass to_jclass(Klass* klass) { return (klass == NULL ? NULL : (jclass)to_jobject(klass->java_mirror())); }207208jmethodID to_jmethodID(const methodHandle& method) { return method->jmethod_id(); }209210JNIEnv* jni_env() { return _jni_env; }211};212213class JvmtiThreadEventMark : public JvmtiEventMark {214private:215jthread _jt;216217public:218JvmtiThreadEventMark(JavaThread *thread) :219JvmtiEventMark(thread) {220_jt = (jthread)(to_jobject(thread->threadObj()));221};222jthread jni_thread() { return _jt; }223};224225class JvmtiClassEventMark : public JvmtiThreadEventMark {226private:227jclass _jc;228229public:230JvmtiClassEventMark(JavaThread *thread, Klass* klass) :231JvmtiThreadEventMark(thread) {232_jc = to_jclass(klass);233};234jclass jni_class() { return _jc; }235};236237class JvmtiMethodEventMark : public JvmtiThreadEventMark {238private:239jmethodID _mid;240241public:242JvmtiMethodEventMark(JavaThread *thread, const methodHandle& method) :243JvmtiThreadEventMark(thread),244_mid(to_jmethodID(method)) {};245jmethodID jni_methodID() { return _mid; }246};247248class JvmtiLocationEventMark : public JvmtiMethodEventMark {249private:250jlocation _loc;251252public:253JvmtiLocationEventMark(JavaThread *thread, const methodHandle& method, address location) :254JvmtiMethodEventMark(thread, method),255_loc(location - method->code_base()) {};256jlocation location() { return _loc; }257};258259class JvmtiExceptionEventMark : public JvmtiLocationEventMark {260private:261jobject _exc;262263public:264JvmtiExceptionEventMark(JavaThread *thread, const methodHandle& method, address location, Handle exception) :265JvmtiLocationEventMark(thread, method, location),266_exc(to_jobject(exception())) {};267jobject exception() { return _exc; }268};269270class JvmtiClassFileLoadEventMark : public JvmtiThreadEventMark {271private:272const char *_class_name;273jobject _jloader;274jobject _protection_domain;275jclass _class_being_redefined;276277public:278JvmtiClassFileLoadEventMark(JavaThread *thread, Symbol* name,279Handle class_loader, Handle prot_domain, Klass* class_being_redefined) : JvmtiThreadEventMark(thread) {280_class_name = name != NULL? name->as_utf8() : NULL;281_jloader = (jobject)to_jobject(class_loader());282_protection_domain = (jobject)to_jobject(prot_domain());283if (class_being_redefined == NULL) {284_class_being_redefined = NULL;285} else {286_class_being_redefined = (jclass)to_jclass(class_being_redefined);287}288};289const char *class_name() {290return _class_name;291}292jobject jloader() {293return _jloader;294}295jobject protection_domain() {296return _protection_domain;297}298jclass class_being_redefined() {299return _class_being_redefined;300}301};302303//////////////////////////////////////////////////////////////////////////////304305int JvmtiExport::_field_access_count = 0;306int JvmtiExport::_field_modification_count = 0;307308bool JvmtiExport::_can_access_local_variables = false;309bool JvmtiExport::_can_hotswap_or_post_breakpoint = false;310bool JvmtiExport::_can_modify_any_class = false;311bool JvmtiExport::_can_walk_any_space = false;312313uint64_t JvmtiExport::_redefinition_count = 0;314bool JvmtiExport::_all_dependencies_are_recorded = false;315316//317// field access management318//319320// interpreter generator needs the address of the counter321address JvmtiExport::get_field_access_count_addr() {322// We don't grab a lock because we don't want to323// serialize field access between all threads. This means that a324// thread on another processor can see the wrong count value and325// may either miss making a needed call into post_field_access()326// or will make an unneeded call into post_field_access(). We pay327// this price to avoid slowing down the VM when we aren't watching328// field accesses.329// Other access/mutation safe by virtue of being in VM state.330return (address)(&_field_access_count);331}332333//334// field modification management335//336337// interpreter generator needs the address of the counter338address JvmtiExport::get_field_modification_count_addr() {339// We don't grab a lock because we don't340// want to serialize field modification between all threads. This341// means that a thread on another processor can see the wrong342// count value and may either miss making a needed call into343// post_field_modification() or will make an unneeded call into344// post_field_modification(). We pay this price to avoid slowing345// down the VM when we aren't watching field modifications.346// Other access/mutation safe by virtue of being in VM state.347return (address)(&_field_modification_count);348}349350351///////////////////////////////////////////////////////////////352// Functions needed by java.lang.instrument for starting up javaagent.353///////////////////////////////////////////////////////////////354355jint356JvmtiExport::get_jvmti_interface(JavaVM *jvm, void **penv, jint version) {357// The JVMTI_VERSION_INTERFACE_JVMTI part of the version number358// has already been validated in JNI GetEnv().359int major, minor, micro;360361// micro version doesn't matter here (yet?)362decode_version_values(version, &major, &minor, µ);363switch (major) {364case 1:365switch (minor) {366case 0: // version 1.0.<micro> is recognized367case 1: // version 1.1.<micro> is recognized368case 2: // version 1.2.<micro> is recognized369break;370371default:372return JNI_EVERSION; // unsupported minor version number373}374break;375case 9:376switch (minor) {377case 0: // version 9.0.<micro> is recognized378break;379default:380return JNI_EVERSION; // unsupported minor version number381}382break;383case 11:384switch (minor) {385case 0: // version 11.0.<micro> is recognized386break;387default:388return JNI_EVERSION; // unsupported minor version number389}390break;391default:392// Starting from 13 we do not care about minor version anymore393if (major < 13 || major > Abstract_VM_Version::vm_major_version()) {394return JNI_EVERSION; // unsupported major version number395}396}397398if (JvmtiEnv::get_phase() == JVMTI_PHASE_LIVE) {399JavaThread* current_thread = JavaThread::current();400// transition code: native to VM401ThreadInVMfromNative __tiv(current_thread);402VM_ENTRY_BASE(jvmtiEnv*, JvmtiExport::get_jvmti_interface, current_thread)403debug_only(VMNativeEntryWrapper __vew;)404405JvmtiEnv *jvmti_env = JvmtiEnv::create_a_jvmti(version);406*penv = jvmti_env->jvmti_external(); // actual type is jvmtiEnv* -- not to be confused with JvmtiEnv*407return JNI_OK;408409} else if (JvmtiEnv::get_phase() == JVMTI_PHASE_ONLOAD) {410// not live, no thread to transition411JvmtiEnv *jvmti_env = JvmtiEnv::create_a_jvmti(version);412*penv = jvmti_env->jvmti_external(); // actual type is jvmtiEnv* -- not to be confused with JvmtiEnv*413return JNI_OK;414415} else {416// Called at the wrong time417*penv = NULL;418return JNI_EDETACHED;419}420}421422void423JvmtiExport::add_default_read_edges(Handle h_module, TRAPS) {424if (!Universe::is_module_initialized()) {425return; // extra safety426}427assert(!h_module.is_null(), "module should always be set");428429// Invoke the transformedByAgent method430JavaValue result(T_VOID);431JavaCalls::call_static(&result,432vmClasses::module_Modules_klass(),433vmSymbols::transformedByAgent_name(),434vmSymbols::transformedByAgent_signature(),435h_module,436THREAD);437438if (HAS_PENDING_EXCEPTION) {439LogTarget(Trace, jvmti) log;440LogStream log_stream(log);441java_lang_Throwable::print(PENDING_EXCEPTION, &log_stream);442log_stream.cr();443CLEAR_PENDING_EXCEPTION;444return;445}446}447448jvmtiError449JvmtiExport::add_module_reads(Handle module, Handle to_module, TRAPS) {450if (!Universe::is_module_initialized()) {451return JVMTI_ERROR_NONE; // extra safety452}453assert(!module.is_null(), "module should always be set");454assert(!to_module.is_null(), "to_module should always be set");455456// Invoke the addReads method457JavaValue result(T_VOID);458JavaCalls::call_static(&result,459vmClasses::module_Modules_klass(),460vmSymbols::addReads_name(),461vmSymbols::addReads_signature(),462module,463to_module,464THREAD);465466if (HAS_PENDING_EXCEPTION) {467LogTarget(Trace, jvmti) log;468LogStream log_stream(log);469java_lang_Throwable::print(PENDING_EXCEPTION, &log_stream);470log_stream.cr();471CLEAR_PENDING_EXCEPTION;472return JVMTI_ERROR_INTERNAL;473}474return JVMTI_ERROR_NONE;475}476477jvmtiError478JvmtiExport::add_module_exports(Handle module, Handle pkg_name, Handle to_module, TRAPS) {479if (!Universe::is_module_initialized()) {480return JVMTI_ERROR_NONE; // extra safety481}482assert(!module.is_null(), "module should always be set");483assert(!to_module.is_null(), "to_module should always be set");484assert(!pkg_name.is_null(), "pkg_name should always be set");485486// Invoke the addExports method487JavaValue result(T_VOID);488JavaCalls::call_static(&result,489vmClasses::module_Modules_klass(),490vmSymbols::addExports_name(),491vmSymbols::addExports_signature(),492module,493pkg_name,494to_module,495THREAD);496497if (HAS_PENDING_EXCEPTION) {498Symbol* ex_name = PENDING_EXCEPTION->klass()->name();499LogTarget(Trace, jvmti) log;500LogStream log_stream(log);501java_lang_Throwable::print(PENDING_EXCEPTION, &log_stream);502log_stream.cr();503CLEAR_PENDING_EXCEPTION;504if (ex_name == vmSymbols::java_lang_IllegalArgumentException()) {505return JVMTI_ERROR_ILLEGAL_ARGUMENT;506}507return JVMTI_ERROR_INTERNAL;508}509return JVMTI_ERROR_NONE;510}511512jvmtiError513JvmtiExport::add_module_opens(Handle module, Handle pkg_name, Handle to_module, TRAPS) {514if (!Universe::is_module_initialized()) {515return JVMTI_ERROR_NONE; // extra safety516}517assert(!module.is_null(), "module should always be set");518assert(!to_module.is_null(), "to_module should always be set");519assert(!pkg_name.is_null(), "pkg_name should always be set");520521// Invoke the addOpens method522JavaValue result(T_VOID);523JavaCalls::call_static(&result,524vmClasses::module_Modules_klass(),525vmSymbols::addOpens_name(),526vmSymbols::addExports_signature(),527module,528pkg_name,529to_module,530THREAD);531532if (HAS_PENDING_EXCEPTION) {533Symbol* ex_name = PENDING_EXCEPTION->klass()->name();534LogTarget(Trace, jvmti) log;535LogStream log_stream(log);536java_lang_Throwable::print(PENDING_EXCEPTION, &log_stream);537log_stream.cr();538CLEAR_PENDING_EXCEPTION;539if (ex_name == vmSymbols::java_lang_IllegalArgumentException()) {540return JVMTI_ERROR_ILLEGAL_ARGUMENT;541}542return JVMTI_ERROR_INTERNAL;543}544return JVMTI_ERROR_NONE;545}546547jvmtiError548JvmtiExport::add_module_uses(Handle module, Handle service, TRAPS) {549if (!Universe::is_module_initialized()) {550return JVMTI_ERROR_NONE; // extra safety551}552assert(!module.is_null(), "module should always be set");553assert(!service.is_null(), "service should always be set");554555// Invoke the addUses method556JavaValue result(T_VOID);557JavaCalls::call_static(&result,558vmClasses::module_Modules_klass(),559vmSymbols::addUses_name(),560vmSymbols::addUses_signature(),561module,562service,563THREAD);564565if (HAS_PENDING_EXCEPTION) {566LogTarget(Trace, jvmti) log;567LogStream log_stream(log);568java_lang_Throwable::print(PENDING_EXCEPTION, &log_stream);569log_stream.cr();570CLEAR_PENDING_EXCEPTION;571return JVMTI_ERROR_INTERNAL;572}573return JVMTI_ERROR_NONE;574}575576jvmtiError577JvmtiExport::add_module_provides(Handle module, Handle service, Handle impl_class, TRAPS) {578if (!Universe::is_module_initialized()) {579return JVMTI_ERROR_NONE; // extra safety580}581assert(!module.is_null(), "module should always be set");582assert(!service.is_null(), "service should always be set");583assert(!impl_class.is_null(), "impl_class should always be set");584585// Invoke the addProvides method586JavaValue result(T_VOID);587JavaCalls::call_static(&result,588vmClasses::module_Modules_klass(),589vmSymbols::addProvides_name(),590vmSymbols::addProvides_signature(),591module,592service,593impl_class,594THREAD);595596if (HAS_PENDING_EXCEPTION) {597LogTarget(Trace, jvmti) log;598LogStream log_stream(log);599java_lang_Throwable::print(PENDING_EXCEPTION, &log_stream);600log_stream.cr();601CLEAR_PENDING_EXCEPTION;602return JVMTI_ERROR_INTERNAL;603}604return JVMTI_ERROR_NONE;605}606607void608JvmtiExport::decode_version_values(jint version, int * major, int * minor,609int * micro) {610*major = (version & JVMTI_VERSION_MASK_MAJOR) >> JVMTI_VERSION_SHIFT_MAJOR;611*minor = (version & JVMTI_VERSION_MASK_MINOR) >> JVMTI_VERSION_SHIFT_MINOR;612*micro = (version & JVMTI_VERSION_MASK_MICRO) >> JVMTI_VERSION_SHIFT_MICRO;613}614615void JvmtiExport::enter_primordial_phase() {616JvmtiEnvBase::set_phase(JVMTI_PHASE_PRIMORDIAL);617}618619void JvmtiExport::enter_early_start_phase() {620set_early_vmstart_recorded(true);621}622623void JvmtiExport::enter_start_phase() {624JvmtiEnvBase::set_phase(JVMTI_PHASE_START);625}626627void JvmtiExport::enter_onload_phase() {628JvmtiEnvBase::set_phase(JVMTI_PHASE_ONLOAD);629}630631void JvmtiExport::enter_live_phase() {632JvmtiEnvBase::set_phase(JVMTI_PHASE_LIVE);633}634635//636// JVMTI events that the VM posts to the debugger and also startup agent637// and call the agent's premain() for java.lang.instrument.638//639640void JvmtiExport::post_early_vm_start() {641EVT_TRIG_TRACE(JVMTI_EVENT_VM_START, ("Trg Early VM start event triggered" ));642643// can now enable some events644JvmtiEventController::vm_start();645646JvmtiEnvIterator it;647for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {648// Only early vmstart envs post early VMStart event649if (env->early_vmstart_env() && env->is_enabled(JVMTI_EVENT_VM_START)) {650EVT_TRACE(JVMTI_EVENT_VM_START, ("Evt Early VM start event sent" ));651JavaThread *thread = JavaThread::current();652JvmtiThreadEventMark jem(thread);653JvmtiJavaThreadEventTransition jet(thread);654jvmtiEventVMStart callback = env->callbacks()->VMStart;655if (callback != NULL) {656(*callback)(env->jvmti_external(), jem.jni_env());657}658}659}660}661662void JvmtiExport::post_vm_start() {663EVT_TRIG_TRACE(JVMTI_EVENT_VM_START, ("Trg VM start event triggered" ));664665// can now enable some events666JvmtiEventController::vm_start();667668JvmtiEnvIterator it;669for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {670// Early vmstart envs do not post normal VMStart event671if (!env->early_vmstart_env() && env->is_enabled(JVMTI_EVENT_VM_START)) {672EVT_TRACE(JVMTI_EVENT_VM_START, ("Evt VM start event sent" ));673674JavaThread *thread = JavaThread::current();675JvmtiThreadEventMark jem(thread);676JvmtiJavaThreadEventTransition jet(thread);677jvmtiEventVMStart callback = env->callbacks()->VMStart;678if (callback != NULL) {679(*callback)(env->jvmti_external(), jem.jni_env());680}681}682}683}684685static OopStorage* _jvmti_oop_storage = NULL;686static OopStorage* _weak_tag_storage = NULL;687688OopStorage* JvmtiExport::jvmti_oop_storage() {689assert(_jvmti_oop_storage != NULL, "not yet initialized");690return _jvmti_oop_storage;691}692693OopStorage* JvmtiExport::weak_tag_storage() {694assert(_weak_tag_storage != NULL, "not yet initialized");695return _weak_tag_storage;696}697698void JvmtiExport::initialize_oop_storage() {699// OopStorage needs to be created early in startup and unconditionally700// because of OopStorageSet static array indices.701_jvmti_oop_storage = OopStorageSet::create_strong("JVMTI OopStorage", mtServiceability);702_weak_tag_storage = OopStorageSet::create_weak("JVMTI Tag Weak OopStorage", mtServiceability);703_weak_tag_storage->register_num_dead_callback(&JvmtiTagMap::gc_notification);704}705706void JvmtiExport::post_vm_initialized() {707EVT_TRIG_TRACE(JVMTI_EVENT_VM_INIT, ("Trg VM init event triggered" ));708709// can now enable events710JvmtiEventController::vm_init();711712JvmtiEnvIterator it;713for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {714if (env->is_enabled(JVMTI_EVENT_VM_INIT)) {715EVT_TRACE(JVMTI_EVENT_VM_INIT, ("Evt VM init event sent" ));716717JavaThread *thread = JavaThread::current();718JvmtiThreadEventMark jem(thread);719JvmtiJavaThreadEventTransition jet(thread);720jvmtiEventVMInit callback = env->callbacks()->VMInit;721if (callback != NULL) {722(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread());723}724}725}726}727728729void JvmtiExport::post_vm_death() {730EVT_TRIG_TRACE(JVMTI_EVENT_VM_DEATH, ("Trg VM death event triggered" ));731732JvmtiEnvIterator it;733for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {734if (env->is_enabled(JVMTI_EVENT_VM_DEATH)) {735EVT_TRACE(JVMTI_EVENT_VM_DEATH, ("Evt VM death event sent" ));736737JavaThread *thread = JavaThread::current();738JvmtiEventMark jem(thread);739JvmtiJavaThreadEventTransition jet(thread);740jvmtiEventVMDeath callback = env->callbacks()->VMDeath;741if (callback != NULL) {742(*callback)(env->jvmti_external(), jem.jni_env());743}744}745}746747JvmtiEnvBase::set_phase(JVMTI_PHASE_DEAD);748JvmtiEventController::vm_death();749}750751char**752JvmtiExport::get_all_native_method_prefixes(int* count_ptr) {753// Have to grab JVMTI thread state lock to be sure environment doesn't754// go away while we iterate them. No locks during VM bring-up.755if (Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint()) {756return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr);757} else {758MutexLocker mu(JvmtiThreadState_lock);759return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr);760}761}762763// Convert an external thread reference to a JavaThread found on the764// specified ThreadsList. The ThreadsListHandle in the caller "protects"765// the returned JavaThread *.766//767// If thread_oop_p is not NULL, then the caller wants to use the oop768// after this call so the oop is returned. On success, *jt_pp is set769// to the converted JavaThread * and JVMTI_ERROR_NONE is returned.770// On error, returns various JVMTI_ERROR_* values.771//772jvmtiError773JvmtiExport::cv_external_thread_to_JavaThread(ThreadsList * t_list,774jthread thread,775JavaThread ** jt_pp,776oop * thread_oop_p) {777assert(t_list != NULL, "must have a ThreadsList");778assert(jt_pp != NULL, "must have a return JavaThread pointer");779// thread_oop_p is optional so no assert()780781oop thread_oop = JNIHandles::resolve_external_guard(thread);782if (thread_oop == NULL) {783// NULL jthread, GC'ed jthread or a bad JNI handle.784return JVMTI_ERROR_INVALID_THREAD;785}786// Looks like an oop at this point.787788if (!thread_oop->is_a(vmClasses::Thread_klass())) {789// The oop is not a java.lang.Thread.790return JVMTI_ERROR_INVALID_THREAD;791}792// Looks like a java.lang.Thread oop at this point.793794if (thread_oop_p != NULL) {795// Return the oop to the caller; the caller may still want796// the oop even if this function returns an error.797*thread_oop_p = thread_oop;798}799800JavaThread * java_thread = java_lang_Thread::thread(thread_oop);801if (java_thread == NULL) {802// The java.lang.Thread does not contain a JavaThread * so it has803// not yet run or it has died.804return JVMTI_ERROR_THREAD_NOT_ALIVE;805}806// Looks like a live JavaThread at this point.807808// We do not check the EnableThreadSMRExtraValidityChecks option809// for this includes() call because JVM/TI's spec is tighter.810if (!t_list->includes(java_thread)) {811// Not on the JavaThreads list so it is not alive.812return JVMTI_ERROR_THREAD_NOT_ALIVE;813}814815// Return a live JavaThread that is "protected" by the816// ThreadsListHandle in the caller.817*jt_pp = java_thread;818819return JVMTI_ERROR_NONE;820}821822// Convert an oop to a JavaThread found on the specified ThreadsList.823// The ThreadsListHandle in the caller "protects" the returned824// JavaThread *.825//826// On success, *jt_pp is set to the converted JavaThread * and827// JVMTI_ERROR_NONE is returned. On error, returns various828// JVMTI_ERROR_* values.829//830jvmtiError831JvmtiExport::cv_oop_to_JavaThread(ThreadsList * t_list, oop thread_oop,832JavaThread ** jt_pp) {833assert(t_list != NULL, "must have a ThreadsList");834assert(thread_oop != NULL, "must have an oop");835assert(jt_pp != NULL, "must have a return JavaThread pointer");836837if (!thread_oop->is_a(vmClasses::Thread_klass())) {838// The oop is not a java.lang.Thread.839return JVMTI_ERROR_INVALID_THREAD;840}841// Looks like a java.lang.Thread oop at this point.842843JavaThread * java_thread = java_lang_Thread::thread(thread_oop);844if (java_thread == NULL) {845// The java.lang.Thread does not contain a JavaThread * so it has846// not yet run or it has died.847return JVMTI_ERROR_THREAD_NOT_ALIVE;848}849// Looks like a live JavaThread at this point.850851// We do not check the EnableThreadSMRExtraValidityChecks option852// for this includes() call because JVM/TI's spec is tighter.853if (!t_list->includes(java_thread)) {854// Not on the JavaThreads list so it is not alive.855return JVMTI_ERROR_THREAD_NOT_ALIVE;856}857858// Return a live JavaThread that is "protected" by the859// ThreadsListHandle in the caller.860*jt_pp = java_thread;861862return JVMTI_ERROR_NONE;863}864865class JvmtiClassFileLoadHookPoster : public StackObj {866private:867Symbol* _h_name;868Handle _class_loader;869Handle _h_protection_domain;870unsigned char ** _data_ptr;871unsigned char ** _end_ptr;872JavaThread * _thread;873jint _curr_len;874unsigned char * _curr_data;875JvmtiEnv * _curr_env;876JvmtiCachedClassFileData ** _cached_class_file_ptr;877JvmtiThreadState * _state;878Klass* _class_being_redefined;879JvmtiClassLoadKind _load_kind;880bool _has_been_modified;881882public:883inline JvmtiClassFileLoadHookPoster(Symbol* h_name, Handle class_loader,884Handle h_protection_domain,885unsigned char **data_ptr, unsigned char **end_ptr,886JvmtiCachedClassFileData **cache_ptr) {887_h_name = h_name;888_class_loader = class_loader;889_h_protection_domain = h_protection_domain;890_data_ptr = data_ptr;891_end_ptr = end_ptr;892_thread = JavaThread::current();893_curr_len = *end_ptr - *data_ptr;894_curr_data = *data_ptr;895_curr_env = NULL;896_cached_class_file_ptr = cache_ptr;897_has_been_modified = false;898899_state = _thread->jvmti_thread_state();900if (_state != NULL) {901_class_being_redefined = _state->get_class_being_redefined();902_load_kind = _state->get_class_load_kind();903Klass* klass = (_class_being_redefined == NULL) ? NULL : _class_being_redefined;904if (_load_kind != jvmti_class_load_kind_load && klass != NULL) {905ModuleEntry* module_entry = InstanceKlass::cast(klass)->module();906assert(module_entry != NULL, "module_entry should always be set");907if (module_entry->is_named() &&908module_entry->module() != NULL &&909!module_entry->has_default_read_edges()) {910if (!module_entry->set_has_default_read_edges()) {911// We won a potential race.912// Add read edges to the unnamed modules of the bootstrap and app class loaders913Handle class_module(_thread, module_entry->module()); // Obtain j.l.r.Module914JvmtiExport::add_default_read_edges(class_module, _thread);915}916}917}918// Clear class_being_redefined flag here. The action919// from agent handler could generate a new class file load920// hook event and if it is not cleared the new event generated921// from regular class file load could have this stale redefined922// class handle info.923_state->clear_class_being_redefined();924} else {925// redefine and retransform will always set the thread state926_class_being_redefined = NULL;927_load_kind = jvmti_class_load_kind_load;928}929}930931void post() {932post_all_envs();933copy_modified_data();934}935936bool has_been_modified() { return _has_been_modified; }937938private:939void post_all_envs() {940if (_load_kind != jvmti_class_load_kind_retransform) {941// for class load and redefine,942// call the non-retransformable agents943JvmtiEnvIterator it;944for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {945if (!env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) {946// non-retransformable agents cannot retransform back,947// so no need to cache the original class file bytes948post_to_env(env, false);949}950}951}952JvmtiEnvIterator it;953for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {954// retransformable agents get all events955if (env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) {956// retransformable agents need to cache the original class file957// bytes if changes are made via the ClassFileLoadHook958post_to_env(env, true);959}960}961}962963void post_to_env(JvmtiEnv* env, bool caching_needed) {964if (env->phase() == JVMTI_PHASE_PRIMORDIAL && !env->early_class_hook_env()) {965return;966}967unsigned char *new_data = NULL;968jint new_len = 0;969JvmtiClassFileLoadEventMark jem(_thread, _h_name, _class_loader,970_h_protection_domain,971_class_being_redefined);972JvmtiJavaThreadEventTransition jet(_thread);973jvmtiEventClassFileLoadHook callback = env->callbacks()->ClassFileLoadHook;974if (callback != NULL) {975(*callback)(env->jvmti_external(), jem.jni_env(),976jem.class_being_redefined(),977jem.jloader(), jem.class_name(),978jem.protection_domain(),979_curr_len, _curr_data,980&new_len, &new_data);981}982if (new_data != NULL) {983// this agent has modified class data.984_has_been_modified = true;985if (caching_needed && *_cached_class_file_ptr == NULL) {986// data has been changed by the new retransformable agent987// and it hasn't already been cached, cache it988JvmtiCachedClassFileData *p;989p = (JvmtiCachedClassFileData *)os::malloc(990offset_of(JvmtiCachedClassFileData, data) + _curr_len, mtInternal);991if (p == NULL) {992vm_exit_out_of_memory(offset_of(JvmtiCachedClassFileData, data) + _curr_len,993OOM_MALLOC_ERROR,994"unable to allocate cached copy of original class bytes");995}996p->length = _curr_len;997memcpy(p->data, _curr_data, _curr_len);998*_cached_class_file_ptr = p;999}10001001if (_curr_data != *_data_ptr) {1002// curr_data is previous agent modified class data.1003// And this has been changed by the new agent so1004// we can delete it now.1005_curr_env->Deallocate(_curr_data);1006}10071008// Class file data has changed by the current agent.1009_curr_data = new_data;1010_curr_len = new_len;1011// Save the current agent env we need this to deallocate the1012// memory allocated by this agent.1013_curr_env = env;1014}1015}10161017void copy_modified_data() {1018// if one of the agent has modified class file data.1019// Copy modified class data to new resources array.1020if (_curr_data != *_data_ptr) {1021*_data_ptr = NEW_RESOURCE_ARRAY(u1, _curr_len);1022memcpy(*_data_ptr, _curr_data, _curr_len);1023*_end_ptr = *_data_ptr + _curr_len;1024_curr_env->Deallocate(_curr_data);1025}1026}1027};10281029bool JvmtiExport::is_early_phase() {1030return JvmtiEnvBase::get_phase() <= JVMTI_PHASE_PRIMORDIAL;1031}10321033bool JvmtiExport::has_early_class_hook_env() {1034JvmtiEnvIterator it;1035for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {1036if (env->early_class_hook_env()) {1037return true;1038}1039}1040return false;1041}10421043bool JvmtiExport::_should_post_class_file_load_hook = false;10441045// this entry is for class file load hook on class load, redefine and retransform1046bool JvmtiExport::post_class_file_load_hook(Symbol* h_name,1047Handle class_loader,1048Handle h_protection_domain,1049unsigned char **data_ptr,1050unsigned char **end_ptr,1051JvmtiCachedClassFileData **cache_ptr) {1052if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {1053return false;1054}10551056JvmtiClassFileLoadHookPoster poster(h_name, class_loader,1057h_protection_domain,1058data_ptr, end_ptr,1059cache_ptr);1060poster.post();1061return poster.has_been_modified();1062}10631064void JvmtiExport::report_unsupported(bool on) {1065// If any JVMTI service is turned on, we need to exit before native code1066// tries to access nonexistant services.1067if (on) {1068vm_exit_during_initialization("Java Kernel does not support JVMTI.");1069}1070}107110721073static inline Klass* oop_to_klass(oop obj) {1074Klass* k = obj->klass();10751076// if the object is a java.lang.Class then return the java mirror1077if (k == vmClasses::Class_klass()) {1078if (!java_lang_Class::is_primitive(obj)) {1079k = java_lang_Class::as_Klass(obj);1080assert(k != NULL, "class for non-primitive mirror must exist");1081}1082}1083return k;1084}10851086class JvmtiObjectAllocEventMark : public JvmtiClassEventMark {1087private:1088jobject _jobj;1089jlong _size;1090public:1091JvmtiObjectAllocEventMark(JavaThread *thread, oop obj) : JvmtiClassEventMark(thread, oop_to_klass(obj)) {1092_jobj = (jobject)to_jobject(obj);1093_size = obj->size() * wordSize;1094};1095jobject jni_jobject() { return _jobj; }1096jlong size() { return _size; }1097};10981099class JvmtiCompiledMethodLoadEventMark : public JvmtiMethodEventMark {1100private:1101jint _code_size;1102const void *_code_data;1103jint _map_length;1104jvmtiAddrLocationMap *_map;1105const void *_compile_info;1106public:1107JvmtiCompiledMethodLoadEventMark(JavaThread *thread, nmethod *nm, void* compile_info_ptr = NULL)1108: JvmtiMethodEventMark(thread,methodHandle(thread, nm->method())) {1109_code_data = nm->code_begin();1110_code_size = nm->code_size();1111_compile_info = compile_info_ptr; // Set void pointer of compiledMethodLoad Event. Default value is NULL.1112JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &_map, &_map_length);1113}1114~JvmtiCompiledMethodLoadEventMark() {1115FREE_C_HEAP_ARRAY(jvmtiAddrLocationMap, _map);1116}11171118jint code_size() { return _code_size; }1119const void *code_data() { return _code_data; }1120jint map_length() { return _map_length; }1121const jvmtiAddrLocationMap* map() { return _map; }1122const void *compile_info() { return _compile_info; }1123};1124112511261127class JvmtiMonitorEventMark : public JvmtiThreadEventMark {1128private:1129jobject _jobj;1130public:1131JvmtiMonitorEventMark(JavaThread *thread, oop object)1132: JvmtiThreadEventMark(thread){1133_jobj = to_jobject(object);1134}1135jobject jni_object() { return _jobj; }1136};11371138///////////////////////////////////////////////////////////////1139//1140// pending CompiledMethodUnload support1141//11421143void JvmtiExport::post_compiled_method_unload(1144jmethodID method, const void *code_begin) {1145if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {1146return;1147}1148JavaThread* thread = JavaThread::current();1149EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,1150("[%s] method compile unload event triggered",1151JvmtiTrace::safe_get_thread_name(thread)));11521153// post the event for each environment that has this event enabled.1154JvmtiEnvIterator it;1155for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {1156if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_UNLOAD)) {1157if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {1158continue;1159}1160EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,1161("[%s] class compile method unload event sent jmethodID " PTR_FORMAT,1162JvmtiTrace::safe_get_thread_name(thread), p2i(method)));11631164ResourceMark rm(thread);11651166JvmtiEventMark jem(thread);1167JvmtiJavaThreadEventTransition jet(thread);1168jvmtiEventCompiledMethodUnload callback = env->callbacks()->CompiledMethodUnload;1169if (callback != NULL) {1170(*callback)(env->jvmti_external(), method, code_begin);1171}1172}1173}1174}11751176///////////////////////////////////////////////////////////////1177//1178// JvmtiExport1179//11801181void JvmtiExport::post_raw_breakpoint(JavaThread *thread, Method* method, address location) {1182HandleMark hm(thread);1183methodHandle mh(thread, method);11841185JvmtiThreadState *state = thread->jvmti_thread_state();1186if (state == NULL) {1187return;1188}1189EVT_TRIG_TRACE(JVMTI_EVENT_BREAKPOINT, ("[%s] Trg Breakpoint triggered",1190JvmtiTrace::safe_get_thread_name(thread)));1191JvmtiEnvThreadStateIterator it(state);1192for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {1193ets->compare_and_set_current_location(mh(), location, JVMTI_EVENT_BREAKPOINT);1194if (!ets->breakpoint_posted() && ets->is_enabled(JVMTI_EVENT_BREAKPOINT)) {1195ThreadState old_os_state = thread->osthread()->get_state();1196thread->osthread()->set_state(BREAKPOINTED);1197EVT_TRACE(JVMTI_EVENT_BREAKPOINT, ("[%s] Evt Breakpoint sent %s.%s @ " INTX_FORMAT,1198JvmtiTrace::safe_get_thread_name(thread),1199(mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),1200(mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),1201location - mh()->code_base() ));12021203JvmtiEnv *env = ets->get_env();1204JvmtiLocationEventMark jem(thread, mh, location);1205JvmtiJavaThreadEventTransition jet(thread);1206jvmtiEventBreakpoint callback = env->callbacks()->Breakpoint;1207if (callback != NULL) {1208(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),1209jem.jni_methodID(), jem.location());1210}12111212ets->set_breakpoint_posted();1213thread->osthread()->set_state(old_os_state);1214}1215}1216}12171218//////////////////////////////////////////////////////////////////////////////12191220bool JvmtiExport::_can_get_source_debug_extension = false;1221bool JvmtiExport::_can_maintain_original_method_order = false;1222bool JvmtiExport::_can_post_interpreter_events = false;1223bool JvmtiExport::_can_post_on_exceptions = false;1224bool JvmtiExport::_can_post_breakpoint = false;1225bool JvmtiExport::_can_post_field_access = false;1226bool JvmtiExport::_can_post_field_modification = false;1227bool JvmtiExport::_can_post_method_entry = false;1228bool JvmtiExport::_can_post_method_exit = false;1229bool JvmtiExport::_can_pop_frame = false;1230bool JvmtiExport::_can_force_early_return = false;1231bool JvmtiExport::_can_get_owned_monitor_info = false;12321233bool JvmtiExport::_early_vmstart_recorded = false;12341235bool JvmtiExport::_should_post_single_step = false;1236bool JvmtiExport::_should_post_field_access = false;1237bool JvmtiExport::_should_post_field_modification = false;1238bool JvmtiExport::_should_post_class_load = false;1239bool JvmtiExport::_should_post_class_prepare = false;1240bool JvmtiExport::_should_post_class_unload = false;1241bool JvmtiExport::_should_post_thread_life = false;1242bool JvmtiExport::_should_clean_up_heap_objects = false;1243bool JvmtiExport::_should_post_native_method_bind = false;1244bool JvmtiExport::_should_post_dynamic_code_generated = false;1245bool JvmtiExport::_should_post_data_dump = false;1246bool JvmtiExport::_should_post_compiled_method_load = false;1247bool JvmtiExport::_should_post_compiled_method_unload = false;1248bool JvmtiExport::_should_post_monitor_contended_enter = false;1249bool JvmtiExport::_should_post_monitor_contended_entered = false;1250bool JvmtiExport::_should_post_monitor_wait = false;1251bool JvmtiExport::_should_post_monitor_waited = false;1252bool JvmtiExport::_should_post_garbage_collection_start = false;1253bool JvmtiExport::_should_post_garbage_collection_finish = false;1254bool JvmtiExport::_should_post_object_free = false;1255bool JvmtiExport::_should_post_resource_exhausted = false;1256bool JvmtiExport::_should_post_vm_object_alloc = false;1257bool JvmtiExport::_should_post_sampled_object_alloc = false;1258bool JvmtiExport::_should_post_on_exceptions = false;12591260////////////////////////////////////////////////////////////////////////////////////////////////126112621263//1264// JVMTI single step management1265//1266void JvmtiExport::at_single_stepping_point(JavaThread *thread, Method* method, address location) {1267assert(JvmtiExport::should_post_single_step(), "must be single stepping");12681269HandleMark hm(thread);1270methodHandle mh(thread, method);12711272// update information about current location and post a step event1273JvmtiThreadState *state = thread->jvmti_thread_state();1274if (state == NULL) {1275return;1276}1277EVT_TRIG_TRACE(JVMTI_EVENT_SINGLE_STEP, ("[%s] Trg Single Step triggered",1278JvmtiTrace::safe_get_thread_name(thread)));1279if (!state->hide_single_stepping()) {1280if (state->is_pending_step_for_popframe()) {1281state->process_pending_step_for_popframe();1282}1283if (state->is_pending_step_for_earlyret()) {1284state->process_pending_step_for_earlyret();1285}1286JvmtiExport::post_single_step(thread, mh(), location);1287}1288}128912901291void JvmtiExport::expose_single_stepping(JavaThread *thread) {1292JvmtiThreadState *state = thread->jvmti_thread_state();1293if (state != NULL) {1294state->clear_hide_single_stepping();1295}1296}129712981299bool JvmtiExport::hide_single_stepping(JavaThread *thread) {1300JvmtiThreadState *state = thread->jvmti_thread_state();1301if (state != NULL && state->is_enabled(JVMTI_EVENT_SINGLE_STEP)) {1302state->set_hide_single_stepping();1303return true;1304} else {1305return false;1306}1307}13081309void JvmtiExport::post_class_load(JavaThread *thread, Klass* klass) {1310if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {1311return;1312}1313HandleMark hm(thread);13141315EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_LOAD, ("[%s] Trg Class Load triggered",1316JvmtiTrace::safe_get_thread_name(thread)));1317JvmtiThreadState* state = thread->jvmti_thread_state();1318if (state == NULL) {1319return;1320}1321JvmtiEnvThreadStateIterator it(state);1322for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {1323if (ets->is_enabled(JVMTI_EVENT_CLASS_LOAD)) {1324JvmtiEnv *env = ets->get_env();1325if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {1326continue;1327}1328EVT_TRACE(JVMTI_EVENT_CLASS_LOAD, ("[%s] Evt Class Load sent %s",1329JvmtiTrace::safe_get_thread_name(thread),1330klass==NULL? "NULL" : klass->external_name() ));1331JvmtiClassEventMark jem(thread, klass);1332JvmtiJavaThreadEventTransition jet(thread);1333jvmtiEventClassLoad callback = env->callbacks()->ClassLoad;1334if (callback != NULL) {1335(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_class());1336}1337}1338}1339}134013411342void JvmtiExport::post_class_prepare(JavaThread *thread, Klass* klass) {1343if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {1344return;1345}1346HandleMark hm(thread);13471348EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_PREPARE, ("[%s] Trg Class Prepare triggered",1349JvmtiTrace::safe_get_thread_name(thread)));1350JvmtiThreadState* state = thread->jvmti_thread_state();1351if (state == NULL) {1352return;1353}1354JvmtiEnvThreadStateIterator it(state);1355for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {1356if (ets->is_enabled(JVMTI_EVENT_CLASS_PREPARE)) {1357JvmtiEnv *env = ets->get_env();1358if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {1359continue;1360}1361EVT_TRACE(JVMTI_EVENT_CLASS_PREPARE, ("[%s] Evt Class Prepare sent %s",1362JvmtiTrace::safe_get_thread_name(thread),1363klass==NULL? "NULL" : klass->external_name() ));1364JvmtiClassEventMark jem(thread, klass);1365JvmtiJavaThreadEventTransition jet(thread);1366jvmtiEventClassPrepare callback = env->callbacks()->ClassPrepare;1367if (callback != NULL) {1368(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_class());1369}1370}1371}1372}13731374void JvmtiExport::post_class_unload(Klass* klass) {1375if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {1376return;1377}13781379// postings to the service thread so that it can perform them in a safe1380// context and in-order.1381ResourceMark rm;1382// JvmtiDeferredEvent copies the string.1383JvmtiDeferredEvent event = JvmtiDeferredEvent::class_unload_event(klass->name()->as_C_string());1384ServiceThread::enqueue_deferred_event(&event);1385}138613871388void JvmtiExport::post_class_unload_internal(const char* name) {1389if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {1390return;1391}1392assert(Thread::current()->is_service_thread(), "must be called from ServiceThread");1393JavaThread *thread = JavaThread::current();1394HandleMark hm(thread);13951396EVT_TRIG_TRACE(EXT_EVENT_CLASS_UNLOAD, ("[?] Trg Class Unload triggered" ));1397if (JvmtiEventController::is_enabled((jvmtiEvent)EXT_EVENT_CLASS_UNLOAD)) {13981399JvmtiEnvIterator it;1400for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {1401if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {1402continue;1403}1404if (env->is_enabled((jvmtiEvent)EXT_EVENT_CLASS_UNLOAD)) {1405EVT_TRACE(EXT_EVENT_CLASS_UNLOAD, ("[?] Evt Class Unload sent %s", name));14061407JvmtiEventMark jem(thread);1408JvmtiJavaThreadEventTransition jet(thread);1409jvmtiExtensionEvent callback = env->ext_callbacks()->ClassUnload;1410if (callback != NULL) {1411(*callback)(env->jvmti_external(), jem.jni_env(), name);1412}1413}1414}1415}1416}141714181419void JvmtiExport::post_thread_start(JavaThread *thread) {1420if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {1421return;1422}1423assert(thread->thread_state() == _thread_in_vm, "must be in vm state");14241425EVT_TRIG_TRACE(JVMTI_EVENT_THREAD_START, ("[%s] Trg Thread Start event triggered",1426JvmtiTrace::safe_get_thread_name(thread)));14271428// do JVMTI thread initialization (if needed)1429JvmtiEventController::thread_started(thread);14301431// Do not post thread start event for hidden java thread.1432if (JvmtiEventController::is_enabled(JVMTI_EVENT_THREAD_START) &&1433!thread->is_hidden_from_external_view()) {1434JvmtiEnvIterator it;1435for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {1436if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {1437continue;1438}1439if (env->is_enabled(JVMTI_EVENT_THREAD_START)) {1440EVT_TRACE(JVMTI_EVENT_THREAD_START, ("[%s] Evt Thread Start event sent",1441JvmtiTrace::safe_get_thread_name(thread) ));14421443JvmtiThreadEventMark jem(thread);1444JvmtiJavaThreadEventTransition jet(thread);1445jvmtiEventThreadStart callback = env->callbacks()->ThreadStart;1446if (callback != NULL) {1447(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread());1448}1449}1450}1451}1452}145314541455void JvmtiExport::post_thread_end(JavaThread *thread) {1456if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {1457return;1458}1459EVT_TRIG_TRACE(JVMTI_EVENT_THREAD_END, ("[%s] Trg Thread End event triggered",1460JvmtiTrace::safe_get_thread_name(thread)));14611462JvmtiThreadState *state = thread->jvmti_thread_state();1463if (state == NULL) {1464return;1465}14661467// Do not post thread end event for hidden java thread.1468if (state->is_enabled(JVMTI_EVENT_THREAD_END) &&1469!thread->is_hidden_from_external_view()) {14701471JvmtiEnvThreadStateIterator it(state);1472for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {1473if (ets->is_enabled(JVMTI_EVENT_THREAD_END)) {1474JvmtiEnv *env = ets->get_env();1475if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {1476continue;1477}1478EVT_TRACE(JVMTI_EVENT_THREAD_END, ("[%s] Evt Thread End event sent",1479JvmtiTrace::safe_get_thread_name(thread) ));14801481JvmtiThreadEventMark jem(thread);1482JvmtiJavaThreadEventTransition jet(thread);1483jvmtiEventThreadEnd callback = env->callbacks()->ThreadEnd;1484if (callback != NULL) {1485(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread());1486}1487}1488}1489}1490}14911492void JvmtiExport::post_object_free(JvmtiEnv* env, jlong tag) {1493assert(env->is_enabled(JVMTI_EVENT_OBJECT_FREE), "checking");14941495EVT_TRIG_TRACE(JVMTI_EVENT_OBJECT_FREE, ("[?] Trg Object Free triggered" ));1496EVT_TRACE(JVMTI_EVENT_OBJECT_FREE, ("[?] Evt Object Free sent"));14971498jvmtiEventObjectFree callback = env->callbacks()->ObjectFree;1499if (callback != NULL) {1500(*callback)(env->jvmti_external(), tag);1501}1502}15031504void JvmtiExport::post_resource_exhausted(jint resource_exhausted_flags, const char* description) {15051506JavaThread *thread = JavaThread::current();15071508log_error(jvmti)("Posting Resource Exhausted event: %s",1509description != nullptr ? description : "unknown");15101511// JDK-8213834: handlers of ResourceExhausted may attempt some analysis1512// which often requires running java.1513// This will cause problems on threads not able to run java, e.g. compiler1514// threads. To forestall these problems, we therefore suppress sending this1515// event from threads which are not able to run java.1516if (!thread->can_call_java()) {1517return;1518}15191520EVT_TRIG_TRACE(JVMTI_EVENT_RESOURCE_EXHAUSTED, ("Trg resource exhausted event triggered" ));15211522JvmtiEnvIterator it;1523for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {1524if (env->is_enabled(JVMTI_EVENT_RESOURCE_EXHAUSTED)) {1525EVT_TRACE(JVMTI_EVENT_RESOURCE_EXHAUSTED, ("Evt resource exhausted event sent" ));15261527JvmtiThreadEventMark jem(thread);1528JvmtiJavaThreadEventTransition jet(thread);1529jvmtiEventResourceExhausted callback = env->callbacks()->ResourceExhausted;1530if (callback != NULL) {1531(*callback)(env->jvmti_external(), jem.jni_env(),1532resource_exhausted_flags, NULL, description);1533}1534}1535}1536}15371538void JvmtiExport::post_method_entry(JavaThread *thread, Method* method, frame current_frame) {1539HandleMark hm(thread);1540methodHandle mh(thread, method);15411542EVT_TRIG_TRACE(JVMTI_EVENT_METHOD_ENTRY, ("[%s] Trg Method Entry triggered %s.%s",1543JvmtiTrace::safe_get_thread_name(thread),1544(mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),1545(mh() == NULL) ? "NULL" : mh()->name()->as_C_string() ));15461547JvmtiThreadState* state = thread->jvmti_thread_state();1548if (state == NULL || !state->is_interp_only_mode()) {1549// for any thread that actually wants method entry, interp_only_mode is set1550return;1551}15521553state->incr_cur_stack_depth();15541555if (state->is_enabled(JVMTI_EVENT_METHOD_ENTRY)) {1556JvmtiEnvThreadStateIterator it(state);1557for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {1558if (ets->is_enabled(JVMTI_EVENT_METHOD_ENTRY)) {1559EVT_TRACE(JVMTI_EVENT_METHOD_ENTRY, ("[%s] Evt Method Entry sent %s.%s",1560JvmtiTrace::safe_get_thread_name(thread),1561(mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),1562(mh() == NULL) ? "NULL" : mh()->name()->as_C_string() ));15631564JvmtiEnv *env = ets->get_env();1565JvmtiMethodEventMark jem(thread, mh);1566JvmtiJavaThreadEventTransition jet(thread);1567jvmtiEventMethodEntry callback = env->callbacks()->MethodEntry;1568if (callback != NULL) {1569(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_methodID());1570}1571}1572}1573}1574}15751576void JvmtiExport::post_method_exit(JavaThread* thread, Method* method, frame current_frame) {1577HandleMark hm(thread);1578methodHandle mh(thread, method);15791580JvmtiThreadState *state = thread->jvmti_thread_state();15811582if (state == NULL || !state->is_interp_only_mode()) {1583// for any thread that actually wants method exit, interp_only_mode is set1584return;1585}15861587// return a flag when a method terminates by throwing an exception1588// i.e. if an exception is thrown and it's not caught by the current method1589bool exception_exit = state->is_exception_detected() && !state->is_exception_caught();1590Handle result;1591jvalue value;1592value.j = 0L;15931594if (state->is_enabled(JVMTI_EVENT_METHOD_EXIT)) {1595// if the method hasn't been popped because of an exception then we populate1596// the return_value parameter for the callback. At this point we only have1597// the address of a "raw result" and we just call into the interpreter to1598// convert this into a jvalue.1599if (!exception_exit) {1600oop oop_result;1601BasicType type = current_frame.interpreter_frame_result(&oop_result, &value);1602if (is_reference_type(type)) {1603result = Handle(thread, oop_result);1604value.l = JNIHandles::make_local(thread, result());1605}1606}1607}16081609// Deferred transition to VM, so we can stash away the return oop before GC1610// Note that this transition is not needed when throwing an exception, because1611// there is no oop to retain.1612JavaThread* current = thread; // for JRT_BLOCK1613JRT_BLOCK1614post_method_exit_inner(thread, mh, state, exception_exit, current_frame, value);1615JRT_BLOCK_END16161617if (result.not_null() && !mh->is_native()) {1618// We have to restore the oop on the stack for interpreter frames1619*(oop*)current_frame.interpreter_frame_tos_address() = result();1620}1621}16221623void JvmtiExport::post_method_exit_inner(JavaThread* thread,1624methodHandle& mh,1625JvmtiThreadState *state,1626bool exception_exit,1627frame current_frame,1628jvalue& value) {1629EVT_TRIG_TRACE(JVMTI_EVENT_METHOD_EXIT, ("[%s] Trg Method Exit triggered %s.%s",1630JvmtiTrace::safe_get_thread_name(thread),1631(mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),1632(mh() == NULL) ? "NULL" : mh()->name()->as_C_string() ));16331634if (state->is_enabled(JVMTI_EVENT_METHOD_EXIT)) {1635JvmtiEnvThreadStateIterator it(state);1636for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {1637if (ets->is_enabled(JVMTI_EVENT_METHOD_EXIT)) {1638EVT_TRACE(JVMTI_EVENT_METHOD_EXIT, ("[%s] Evt Method Exit sent %s.%s",1639JvmtiTrace::safe_get_thread_name(thread),1640(mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),1641(mh() == NULL) ? "NULL" : mh()->name()->as_C_string() ));16421643JvmtiEnv *env = ets->get_env();1644JvmtiMethodEventMark jem(thread, mh);1645JvmtiJavaThreadEventTransition jet(thread);1646jvmtiEventMethodExit callback = env->callbacks()->MethodExit;1647if (callback != NULL) {1648(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),1649jem.jni_methodID(), exception_exit, value);1650}1651}1652}1653}16541655JvmtiEnvThreadStateIterator it(state);1656for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {1657if (ets->has_frame_pops()) {1658int cur_frame_number = state->cur_stack_depth();16591660if (ets->is_frame_pop(cur_frame_number)) {1661// we have a NotifyFramePop entry for this frame.1662// now check that this env/thread wants this event1663if (ets->is_enabled(JVMTI_EVENT_FRAME_POP)) {1664EVT_TRACE(JVMTI_EVENT_FRAME_POP, ("[%s] Evt Frame Pop sent %s.%s",1665JvmtiTrace::safe_get_thread_name(thread),1666(mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),1667(mh() == NULL) ? "NULL" : mh()->name()->as_C_string() ));16681669// we also need to issue a frame pop event for this frame1670JvmtiEnv *env = ets->get_env();1671JvmtiMethodEventMark jem(thread, mh);1672JvmtiJavaThreadEventTransition jet(thread);1673jvmtiEventFramePop callback = env->callbacks()->FramePop;1674if (callback != NULL) {1675(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),1676jem.jni_methodID(), exception_exit);1677}1678}1679// remove the frame's entry1680{1681MutexLocker mu(JvmtiThreadState_lock);1682ets->clear_frame_pop(cur_frame_number);1683}1684}1685}1686}16871688state->decr_cur_stack_depth();1689}169016911692// Todo: inline this for optimization1693void JvmtiExport::post_single_step(JavaThread *thread, Method* method, address location) {1694HandleMark hm(thread);1695methodHandle mh(thread, method);16961697JvmtiThreadState *state = thread->jvmti_thread_state();1698if (state == NULL) {1699return;1700}1701JvmtiEnvThreadStateIterator it(state);1702for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {1703ets->compare_and_set_current_location(mh(), location, JVMTI_EVENT_SINGLE_STEP);1704if (!ets->single_stepping_posted() && ets->is_enabled(JVMTI_EVENT_SINGLE_STEP)) {1705EVT_TRACE(JVMTI_EVENT_SINGLE_STEP, ("[%s] Evt Single Step sent %s.%s @ " INTX_FORMAT,1706JvmtiTrace::safe_get_thread_name(thread),1707(mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),1708(mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),1709location - mh()->code_base() ));17101711JvmtiEnv *env = ets->get_env();1712JvmtiLocationEventMark jem(thread, mh, location);1713JvmtiJavaThreadEventTransition jet(thread);1714jvmtiEventSingleStep callback = env->callbacks()->SingleStep;1715if (callback != NULL) {1716(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),1717jem.jni_methodID(), jem.location());1718}17191720ets->set_single_stepping_posted();1721}1722}1723}17241725void JvmtiExport::post_exception_throw(JavaThread *thread, Method* method, address location, oop exception) {1726HandleMark hm(thread);1727methodHandle mh(thread, method);1728Handle exception_handle(thread, exception);17291730JvmtiThreadState *state = thread->jvmti_thread_state();1731if (state == NULL) {1732return;1733}17341735EVT_TRIG_TRACE(JVMTI_EVENT_EXCEPTION, ("[%s] Trg Exception thrown triggered",1736JvmtiTrace::safe_get_thread_name(thread)));1737if (!state->is_exception_detected()) {1738state->set_exception_detected();1739JvmtiEnvThreadStateIterator it(state);1740for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {1741if (ets->is_enabled(JVMTI_EVENT_EXCEPTION) && (exception != NULL)) {17421743EVT_TRACE(JVMTI_EVENT_EXCEPTION,1744("[%s] Evt Exception thrown sent %s.%s @ " INTX_FORMAT,1745JvmtiTrace::safe_get_thread_name(thread),1746(mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),1747(mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),1748location - mh()->code_base() ));17491750JvmtiEnv *env = ets->get_env();1751JvmtiExceptionEventMark jem(thread, mh, location, exception_handle);17521753// It's okay to clear these exceptions here because we duplicate1754// this lookup in InterpreterRuntime::exception_handler_for_exception.1755EXCEPTION_MARK;17561757bool should_repeat;1758vframeStream st(thread);1759assert(!st.at_end(), "cannot be at end");1760Method* current_method = NULL;1761// A GC may occur during the Method::fast_exception_handler_bci_for()1762// call below if it needs to load the constraint class. Using a1763// methodHandle to keep the 'current_method' from being deallocated1764// if GC happens.1765methodHandle current_mh = methodHandle(thread, current_method);1766int current_bci = -1;1767do {1768current_method = st.method();1769current_mh = methodHandle(thread, current_method);1770current_bci = st.bci();1771do {1772should_repeat = false;1773Klass* eh_klass = exception_handle()->klass();1774current_bci = Method::fast_exception_handler_bci_for(1775current_mh, eh_klass, current_bci, THREAD);1776if (HAS_PENDING_EXCEPTION) {1777exception_handle = Handle(thread, PENDING_EXCEPTION);1778CLEAR_PENDING_EXCEPTION;1779should_repeat = true;1780}1781} while (should_repeat && (current_bci != -1));1782st.next();1783} while ((current_bci < 0) && (!st.at_end()));17841785jmethodID catch_jmethodID;1786if (current_bci < 0) {1787catch_jmethodID = 0;1788current_bci = 0;1789} else {1790catch_jmethodID = jem.to_jmethodID(current_mh);1791}17921793JvmtiJavaThreadEventTransition jet(thread);1794jvmtiEventException callback = env->callbacks()->Exception;1795if (callback != NULL) {1796(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),1797jem.jni_methodID(), jem.location(),1798jem.exception(),1799catch_jmethodID, current_bci);1800}1801}1802}1803}18041805// frames may get popped because of this throw, be safe - invalidate cached depth1806state->invalidate_cur_stack_depth();1807}180818091810void JvmtiExport::notice_unwind_due_to_exception(JavaThread *thread, Method* method, address location, oop exception, bool in_handler_frame) {1811HandleMark hm(thread);1812methodHandle mh(thread, method);1813Handle exception_handle(thread, exception);18141815JvmtiThreadState *state = thread->jvmti_thread_state();1816if (state == NULL) {1817return;1818}1819EVT_TRIG_TRACE(JVMTI_EVENT_EXCEPTION_CATCH,1820("[%s] Trg unwind_due_to_exception triggered %s.%s @ %s" INTX_FORMAT " - %s",1821JvmtiTrace::safe_get_thread_name(thread),1822(mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),1823(mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),1824location==0? "no location:" : "",1825location==0? 0 : location - mh()->code_base(),1826in_handler_frame? "in handler frame" : "not handler frame" ));18271828if (state->is_exception_detected()) {18291830state->invalidate_cur_stack_depth();1831if (!in_handler_frame) {1832// Not in exception handler.1833if(state->is_interp_only_mode()) {1834// method exit and frame pop events are posted only in interp mode.1835// When these events are enabled code should be in running in interp mode.1836jvalue no_value;1837no_value.j = 0L;1838JvmtiExport::post_method_exit_inner(thread, mh, state, true, thread->last_frame(), no_value);1839// The cached cur_stack_depth might have changed from the1840// operations of frame pop or method exit. We are not 100% sure1841// the cached cur_stack_depth is still valid depth so invalidate1842// it.1843state->invalidate_cur_stack_depth();1844}1845} else {1846// In exception handler frame. Report exception catch.1847assert(location != NULL, "must be a known location");1848// Update cur_stack_depth - the frames above the current frame1849// have been unwound due to this exception:1850assert(!state->is_exception_caught(), "exception must not be caught yet.");1851state->set_exception_caught();18521853JvmtiEnvThreadStateIterator it(state);1854for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {1855if (ets->is_enabled(JVMTI_EVENT_EXCEPTION_CATCH) && (exception_handle() != NULL)) {1856EVT_TRACE(JVMTI_EVENT_EXCEPTION_CATCH,1857("[%s] Evt ExceptionCatch sent %s.%s @ " INTX_FORMAT,1858JvmtiTrace::safe_get_thread_name(thread),1859(mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),1860(mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),1861location - mh()->code_base() ));18621863JvmtiEnv *env = ets->get_env();1864JvmtiExceptionEventMark jem(thread, mh, location, exception_handle);1865JvmtiJavaThreadEventTransition jet(thread);1866jvmtiEventExceptionCatch callback = env->callbacks()->ExceptionCatch;1867if (callback != NULL) {1868(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),1869jem.jni_methodID(), jem.location(),1870jem.exception());1871}1872}1873}1874}1875}1876}18771878oop JvmtiExport::jni_GetField_probe(JavaThread *thread, jobject jobj, oop obj,1879Klass* klass, jfieldID fieldID, bool is_static) {1880if (*((int *)get_field_access_count_addr()) > 0 && thread->has_last_Java_frame()) {1881// At least one field access watch is set so we have more work to do.1882post_field_access_by_jni(thread, obj, klass, fieldID, is_static);1883// event posting can block so refetch oop if we were passed a jobj1884if (jobj != NULL) return JNIHandles::resolve_non_null(jobj);1885}1886return obj;1887}18881889void JvmtiExport::post_field_access_by_jni(JavaThread *thread, oop obj,1890Klass* klass, jfieldID fieldID, bool is_static) {1891// We must be called with a Java context in order to provide reasonable1892// values for the klazz, method, and location fields. The callers of this1893// function don't make the call unless there is a Java context.1894assert(thread->has_last_Java_frame(), "must be called with a Java context");18951896ResourceMark rm;1897fieldDescriptor fd;1898// if get_field_descriptor finds fieldID to be invalid, then we just bail1899bool valid_fieldID = JvmtiEnv::get_field_descriptor(klass, fieldID, &fd);1900assert(valid_fieldID == true,"post_field_access_by_jni called with invalid fieldID");1901if (!valid_fieldID) return;1902// field accesses are not watched so bail1903if (!fd.is_field_access_watched()) return;19041905HandleMark hm(thread);1906Handle h_obj;1907if (!is_static) {1908// non-static field accessors have an object, but we need a handle1909assert(obj != NULL, "non-static needs an object");1910h_obj = Handle(thread, obj);1911}1912post_field_access(thread,1913thread->last_frame().interpreter_frame_method(),1914thread->last_frame().interpreter_frame_bcp(),1915klass, h_obj, fieldID);1916}19171918void JvmtiExport::post_field_access(JavaThread *thread, Method* method,1919address location, Klass* field_klass, Handle object, jfieldID field) {19201921HandleMark hm(thread);1922methodHandle mh(thread, method);19231924JvmtiThreadState *state = thread->jvmti_thread_state();1925if (state == NULL) {1926return;1927}1928EVT_TRIG_TRACE(JVMTI_EVENT_FIELD_ACCESS, ("[%s] Trg Field Access event triggered",1929JvmtiTrace::safe_get_thread_name(thread)));1930JvmtiEnvThreadStateIterator it(state);1931for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {1932if (ets->is_enabled(JVMTI_EVENT_FIELD_ACCESS)) {1933EVT_TRACE(JVMTI_EVENT_FIELD_ACCESS, ("[%s] Evt Field Access event sent %s.%s @ " INTX_FORMAT,1934JvmtiTrace::safe_get_thread_name(thread),1935(mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),1936(mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),1937location - mh()->code_base() ));19381939JvmtiEnv *env = ets->get_env();1940JvmtiLocationEventMark jem(thread, mh, location);1941jclass field_jclass = jem.to_jclass(field_klass);1942jobject field_jobject = jem.to_jobject(object());1943JvmtiJavaThreadEventTransition jet(thread);1944jvmtiEventFieldAccess callback = env->callbacks()->FieldAccess;1945if (callback != NULL) {1946(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),1947jem.jni_methodID(), jem.location(),1948field_jclass, field_jobject, field);1949}1950}1951}1952}19531954oop JvmtiExport::jni_SetField_probe(JavaThread *thread, jobject jobj, oop obj,1955Klass* klass, jfieldID fieldID, bool is_static,1956char sig_type, jvalue *value) {1957if (*((int *)get_field_modification_count_addr()) > 0 && thread->has_last_Java_frame()) {1958// At least one field modification watch is set so we have more work to do.1959post_field_modification_by_jni(thread, obj, klass, fieldID, is_static, sig_type, value);1960// event posting can block so refetch oop if we were passed a jobj1961if (jobj != NULL) return JNIHandles::resolve_non_null(jobj);1962}1963return obj;1964}19651966void JvmtiExport::post_field_modification_by_jni(JavaThread *thread, oop obj,1967Klass* klass, jfieldID fieldID, bool is_static,1968char sig_type, jvalue *value) {1969// We must be called with a Java context in order to provide reasonable1970// values for the klazz, method, and location fields. The callers of this1971// function don't make the call unless there is a Java context.1972assert(thread->has_last_Java_frame(), "must be called with Java context");19731974ResourceMark rm;1975fieldDescriptor fd;1976// if get_field_descriptor finds fieldID to be invalid, then we just bail1977bool valid_fieldID = JvmtiEnv::get_field_descriptor(klass, fieldID, &fd);1978assert(valid_fieldID == true,"post_field_modification_by_jni called with invalid fieldID");1979if (!valid_fieldID) return;1980// field modifications are not watched so bail1981if (!fd.is_field_modification_watched()) return;19821983HandleMark hm(thread);19841985Handle h_obj;1986if (!is_static) {1987// non-static field accessors have an object, but we need a handle1988assert(obj != NULL, "non-static needs an object");1989h_obj = Handle(thread, obj);1990}1991post_field_modification(thread,1992thread->last_frame().interpreter_frame_method(),1993thread->last_frame().interpreter_frame_bcp(),1994klass, h_obj, fieldID, sig_type, value);1995}19961997void JvmtiExport::post_raw_field_modification(JavaThread *thread, Method* method,1998address location, Klass* field_klass, Handle object, jfieldID field,1999char sig_type, jvalue *value) {20002001if (sig_type == JVM_SIGNATURE_INT || sig_type == JVM_SIGNATURE_BOOLEAN ||2002sig_type == JVM_SIGNATURE_BYTE || sig_type == JVM_SIGNATURE_CHAR ||2003sig_type == JVM_SIGNATURE_SHORT) {2004// 'I' instructions are used for byte, char, short and int.2005// determine which it really is, and convert2006fieldDescriptor fd;2007bool found = JvmtiEnv::get_field_descriptor(field_klass, field, &fd);2008// should be found (if not, leave as is)2009if (found) {2010jint ival = value->i;2011// convert value from int to appropriate type2012switch (fd.field_type()) {2013case T_BOOLEAN:2014sig_type = JVM_SIGNATURE_BOOLEAN;2015value->i = 0; // clear it2016value->z = (jboolean)ival;2017break;2018case T_BYTE:2019sig_type = JVM_SIGNATURE_BYTE;2020value->i = 0; // clear it2021value->b = (jbyte)ival;2022break;2023case T_CHAR:2024sig_type = JVM_SIGNATURE_CHAR;2025value->i = 0; // clear it2026value->c = (jchar)ival;2027break;2028case T_SHORT:2029sig_type = JVM_SIGNATURE_SHORT;2030value->i = 0; // clear it2031value->s = (jshort)ival;2032break;2033case T_INT:2034// nothing to do2035break;2036default:2037// this is an integer instruction, should be one of above2038ShouldNotReachHere();2039break;2040}2041}2042}20432044assert(sig_type != JVM_SIGNATURE_ARRAY, "array should have sig_type == 'L'");2045bool handle_created = false;20462047// convert oop to JNI handle.2048if (sig_type == JVM_SIGNATURE_CLASS) {2049handle_created = true;2050value->l = (jobject)JNIHandles::make_local(thread, cast_to_oop(value->l));2051}20522053post_field_modification(thread, method, location, field_klass, object, field, sig_type, value);20542055// Destroy the JNI handle allocated above.2056if (handle_created) {2057JNIHandles::destroy_local(value->l);2058}2059}20602061void JvmtiExport::post_field_modification(JavaThread *thread, Method* method,2062address location, Klass* field_klass, Handle object, jfieldID field,2063char sig_type, jvalue *value_ptr) {20642065HandleMark hm(thread);2066methodHandle mh(thread, method);20672068JvmtiThreadState *state = thread->jvmti_thread_state();2069if (state == NULL) {2070return;2071}2072EVT_TRIG_TRACE(JVMTI_EVENT_FIELD_MODIFICATION,2073("[%s] Trg Field Modification event triggered",2074JvmtiTrace::safe_get_thread_name(thread)));20752076JvmtiEnvThreadStateIterator it(state);2077for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {2078if (ets->is_enabled(JVMTI_EVENT_FIELD_MODIFICATION)) {2079EVT_TRACE(JVMTI_EVENT_FIELD_MODIFICATION,2080("[%s] Evt Field Modification event sent %s.%s @ " INTX_FORMAT,2081JvmtiTrace::safe_get_thread_name(thread),2082(mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),2083(mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),2084location - mh()->code_base() ));20852086JvmtiEnv *env = ets->get_env();2087JvmtiLocationEventMark jem(thread, mh, location);2088jclass field_jclass = jem.to_jclass(field_klass);2089jobject field_jobject = jem.to_jobject(object());2090JvmtiJavaThreadEventTransition jet(thread);2091jvmtiEventFieldModification callback = env->callbacks()->FieldModification;2092if (callback != NULL) {2093(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),2094jem.jni_methodID(), jem.location(),2095field_jclass, field_jobject, field, sig_type, *value_ptr);2096}2097}2098}2099}21002101void JvmtiExport::post_native_method_bind(Method* method, address* function_ptr) {2102JavaThread* thread = JavaThread::current();2103assert(thread->thread_state() == _thread_in_vm, "must be in vm state");21042105HandleMark hm(thread);2106methodHandle mh(thread, method);21072108EVT_TRIG_TRACE(JVMTI_EVENT_NATIVE_METHOD_BIND, ("[%s] Trg Native Method Bind event triggered",2109JvmtiTrace::safe_get_thread_name(thread)));21102111if (JvmtiEventController::is_enabled(JVMTI_EVENT_NATIVE_METHOD_BIND)) {2112JvmtiEnvIterator it;2113for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {2114if (env->is_enabled(JVMTI_EVENT_NATIVE_METHOD_BIND)) {2115EVT_TRACE(JVMTI_EVENT_NATIVE_METHOD_BIND, ("[%s] Evt Native Method Bind event sent",2116JvmtiTrace::safe_get_thread_name(thread) ));21172118JvmtiMethodEventMark jem(thread, mh);2119JvmtiJavaThreadEventTransition jet(thread);2120JNIEnv* jni_env = (env->phase() == JVMTI_PHASE_PRIMORDIAL) ? NULL : jem.jni_env();2121jvmtiEventNativeMethodBind callback = env->callbacks()->NativeMethodBind;2122if (callback != NULL) {2123(*callback)(env->jvmti_external(), jni_env, jem.jni_thread(),2124jem.jni_methodID(), (void*)(*function_ptr), (void**)function_ptr);2125}2126}2127}2128}2129}21302131// Returns a record containing inlining information for the given nmethod2132jvmtiCompiledMethodLoadInlineRecord* create_inline_record(nmethod* nm) {2133jint numstackframes = 0;2134jvmtiCompiledMethodLoadInlineRecord* record = (jvmtiCompiledMethodLoadInlineRecord*)NEW_RESOURCE_OBJ(jvmtiCompiledMethodLoadInlineRecord);2135record->header.kind = JVMTI_CMLR_INLINE_INFO;2136record->header.next = NULL;2137record->header.majorinfoversion = JVMTI_CMLR_MAJOR_VERSION_1;2138record->header.minorinfoversion = JVMTI_CMLR_MINOR_VERSION_0;2139record->numpcs = 0;2140for(PcDesc* p = nm->scopes_pcs_begin(); p < nm->scopes_pcs_end(); p++) {2141if(p->scope_decode_offset() == DebugInformationRecorder::serialized_null) continue;2142record->numpcs++;2143}2144record->pcinfo = (PCStackInfo*)(NEW_RESOURCE_ARRAY(PCStackInfo, record->numpcs));2145int scope = 0;2146for(PcDesc* p = nm->scopes_pcs_begin(); p < nm->scopes_pcs_end(); p++) {2147if(p->scope_decode_offset() == DebugInformationRecorder::serialized_null) continue;2148void* pc_address = (void*)p->real_pc(nm);2149assert(pc_address != NULL, "pc_address must be non-null");2150record->pcinfo[scope].pc = pc_address;2151numstackframes=0;2152for(ScopeDesc* sd = nm->scope_desc_at(p->real_pc(nm));sd != NULL;sd = sd->sender()) {2153numstackframes++;2154}2155assert(numstackframes != 0, "numstackframes must be nonzero.");2156record->pcinfo[scope].methods = (jmethodID *)NEW_RESOURCE_ARRAY(jmethodID, numstackframes);2157record->pcinfo[scope].bcis = (jint *)NEW_RESOURCE_ARRAY(jint, numstackframes);2158record->pcinfo[scope].numstackframes = numstackframes;2159int stackframe = 0;2160for(ScopeDesc* sd = nm->scope_desc_at(p->real_pc(nm));sd != NULL;sd = sd->sender()) {2161// sd->method() can be NULL for stubs but not for nmethods. To be completely robust, include an assert that we should never see a null sd->method()2162guarantee(sd->method() != NULL, "sd->method() cannot be null.");2163record->pcinfo[scope].methods[stackframe] = sd->method()->jmethod_id();2164record->pcinfo[scope].bcis[stackframe] = sd->bci();2165stackframe++;2166}2167scope++;2168}2169return record;2170}21712172void JvmtiExport::post_compiled_method_load(nmethod *nm) {2173guarantee(!nm->is_unloading(), "nmethod isn't unloaded or unloading");2174if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {2175return;2176}2177JavaThread* thread = JavaThread::current();21782179EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,2180("[%s] method compile load event triggered",2181JvmtiTrace::safe_get_thread_name(thread)));21822183JvmtiEnvIterator it;2184for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {2185post_compiled_method_load(env, nm);2186}2187}21882189// post a COMPILED_METHOD_LOAD event for a given environment2190void JvmtiExport::post_compiled_method_load(JvmtiEnv* env, nmethod *nm) {2191if (env->phase() == JVMTI_PHASE_PRIMORDIAL || !env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_LOAD)) {2192return;2193}2194jvmtiEventCompiledMethodLoad callback = env->callbacks()->CompiledMethodLoad;2195if (callback == NULL) {2196return;2197}2198JavaThread* thread = JavaThread::current();21992200EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,2201("[%s] method compile load event sent %s.%s ",2202JvmtiTrace::safe_get_thread_name(thread),2203(nm->method() == NULL) ? "NULL" : nm->method()->klass_name()->as_C_string(),2204(nm->method() == NULL) ? "NULL" : nm->method()->name()->as_C_string()));2205ResourceMark rm(thread);2206HandleMark hm(thread);22072208// Add inlining information2209jvmtiCompiledMethodLoadInlineRecord* inlinerecord = create_inline_record(nm);2210// Pass inlining information through the void pointer2211JvmtiCompiledMethodLoadEventMark jem(thread, nm, inlinerecord);2212JvmtiJavaThreadEventTransition jet(thread);2213(*callback)(env->jvmti_external(), jem.jni_methodID(),2214jem.code_size(), jem.code_data(), jem.map_length(),2215jem.map(), jem.compile_info());2216}22172218void JvmtiExport::post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) {2219assert(name != NULL && name[0] != '\0', "sanity check");22202221JavaThread* thread = JavaThread::current();2222// In theory everyone coming thru here is in_vm but we need to be certain2223// because a callee will do a vm->native transition2224ThreadInVMfromUnknown __tiv;22252226EVT_TRIG_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED,2227("[%s] method dynamic code generated event triggered",2228JvmtiTrace::safe_get_thread_name(thread)));2229JvmtiEnvIterator it;2230for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {2231if (env->is_enabled(JVMTI_EVENT_DYNAMIC_CODE_GENERATED)) {2232EVT_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED,2233("[%s] dynamic code generated event sent for %s",2234JvmtiTrace::safe_get_thread_name(thread), name));2235JvmtiEventMark jem(thread);2236JvmtiJavaThreadEventTransition jet(thread);2237jint length = (jint)pointer_delta(code_end, code_begin, sizeof(char));2238jvmtiEventDynamicCodeGenerated callback = env->callbacks()->DynamicCodeGenerated;2239if (callback != NULL) {2240(*callback)(env->jvmti_external(), name, (void*)code_begin, length);2241}2242}2243}2244}22452246void JvmtiExport::post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end) {2247jvmtiPhase phase = JvmtiEnv::get_phase();2248if (phase == JVMTI_PHASE_PRIMORDIAL || phase == JVMTI_PHASE_START) {2249post_dynamic_code_generated_internal(name, code_begin, code_end);2250} else {2251// It may not be safe to post the event from this thread. Defer all2252// postings to the service thread so that it can perform them in a safe2253// context and in-order.2254JvmtiDeferredEvent event = JvmtiDeferredEvent::dynamic_code_generated_event(2255name, code_begin, code_end);2256ServiceThread::enqueue_deferred_event(&event);2257}2258}225922602261// post a DYNAMIC_CODE_GENERATED event for a given environment2262// used by GenerateEvents2263void JvmtiExport::post_dynamic_code_generated(JvmtiEnv* env, const char *name,2264const void *code_begin, const void *code_end)2265{2266JavaThread* thread = JavaThread::current();2267EVT_TRIG_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED,2268("[%s] dynamic code generated event triggered (by GenerateEvents)",2269JvmtiTrace::safe_get_thread_name(thread)));2270if (env->is_enabled(JVMTI_EVENT_DYNAMIC_CODE_GENERATED)) {2271EVT_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED,2272("[%s] dynamic code generated event sent for %s",2273JvmtiTrace::safe_get_thread_name(thread), name));2274JvmtiEventMark jem(thread);2275JvmtiJavaThreadEventTransition jet(thread);2276jint length = (jint)pointer_delta(code_end, code_begin, sizeof(char));2277jvmtiEventDynamicCodeGenerated callback = env->callbacks()->DynamicCodeGenerated;2278if (callback != NULL) {2279(*callback)(env->jvmti_external(), name, (void*)code_begin, length);2280}2281}2282}22832284// post a DynamicCodeGenerated event while holding locks in the VM.2285void JvmtiExport::post_dynamic_code_generated_while_holding_locks(const char* name,2286address code_begin, address code_end)2287{2288// register the stub with the current dynamic code event collector2289// Cannot take safepoint here so do not use state_for to get2290// jvmti thread state.2291// The collector and/or state might be NULL if JvmtiDynamicCodeEventCollector2292// has been initialized while JVMTI_EVENT_DYNAMIC_CODE_GENERATED was disabled.2293JvmtiThreadState* state = JavaThread::current()->jvmti_thread_state();2294if (state != NULL) {2295JvmtiDynamicCodeEventCollector *collector = state->get_dynamic_code_event_collector();2296if (collector != NULL) {2297collector->register_stub(name, code_begin, code_end);2298}2299}2300}23012302// Collect all the vm internally allocated objects which are visible to java world2303void JvmtiExport::record_vm_internal_object_allocation(oop obj) {2304Thread* thread = Thread::current_or_null();2305if (thread != NULL && thread->is_Java_thread()) {2306// Can not take safepoint here.2307NoSafepointVerifier no_sfpt;2308// Cannot take safepoint here so do not use state_for to get2309// jvmti thread state.2310JvmtiThreadState *state = thread->as_Java_thread()->jvmti_thread_state();2311if (state != NULL) {2312// state is non NULL when VMObjectAllocEventCollector is enabled.2313JvmtiVMObjectAllocEventCollector *collector;2314collector = state->get_vm_object_alloc_event_collector();2315if (collector != NULL && collector->is_enabled()) {2316// Don't record classes as these will be notified via the ClassLoad2317// event.2318if (obj->klass() != vmClasses::Class_klass()) {2319collector->record_allocation(obj);2320}2321}2322}2323}2324}23252326// Collect all the sampled allocated objects.2327void JvmtiExport::record_sampled_internal_object_allocation(oop obj) {2328Thread* thread = Thread::current_or_null();2329if (thread != NULL && thread->is_Java_thread()) {2330// Can not take safepoint here.2331NoSafepointVerifier no_sfpt;2332// Cannot take safepoint here so do not use state_for to get2333// jvmti thread state.2334JvmtiThreadState *state = thread->as_Java_thread()->jvmti_thread_state();2335if (state != NULL) {2336// state is non NULL when SampledObjectAllocEventCollector is enabled.2337JvmtiSampledObjectAllocEventCollector *collector;2338collector = state->get_sampled_object_alloc_event_collector();23392340if (collector != NULL && collector->is_enabled()) {2341collector->record_allocation(obj);2342}2343}2344}2345}23462347void JvmtiExport::post_garbage_collection_finish() {2348Thread *thread = Thread::current(); // this event is posted from VM-Thread.2349EVT_TRIG_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH,2350("[%s] garbage collection finish event triggered",2351JvmtiTrace::safe_get_thread_name(thread)));2352JvmtiEnvIterator it;2353for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {2354if (env->is_enabled(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH)) {2355EVT_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH,2356("[%s] garbage collection finish event sent",2357JvmtiTrace::safe_get_thread_name(thread)));2358JvmtiThreadEventTransition jet(thread);2359// JNIEnv is NULL here because this event is posted from VM Thread2360jvmtiEventGarbageCollectionFinish callback = env->callbacks()->GarbageCollectionFinish;2361if (callback != NULL) {2362(*callback)(env->jvmti_external());2363}2364}2365}2366}23672368void JvmtiExport::post_garbage_collection_start() {2369Thread* thread = Thread::current(); // this event is posted from vm-thread.2370EVT_TRIG_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_START,2371("[%s] garbage collection start event triggered",2372JvmtiTrace::safe_get_thread_name(thread)));2373JvmtiEnvIterator it;2374for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {2375if (env->is_enabled(JVMTI_EVENT_GARBAGE_COLLECTION_START)) {2376EVT_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_START,2377("[%s] garbage collection start event sent",2378JvmtiTrace::safe_get_thread_name(thread)));2379JvmtiThreadEventTransition jet(thread);2380// JNIEnv is NULL here because this event is posted from VM Thread2381jvmtiEventGarbageCollectionStart callback = env->callbacks()->GarbageCollectionStart;2382if (callback != NULL) {2383(*callback)(env->jvmti_external());2384}2385}2386}2387}23882389void JvmtiExport::post_data_dump() {2390Thread *thread = Thread::current();2391EVT_TRIG_TRACE(JVMTI_EVENT_DATA_DUMP_REQUEST,2392("[%s] data dump request event triggered",2393JvmtiTrace::safe_get_thread_name(thread)));2394JvmtiEnvIterator it;2395for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {2396if (env->is_enabled(JVMTI_EVENT_DATA_DUMP_REQUEST)) {2397EVT_TRACE(JVMTI_EVENT_DATA_DUMP_REQUEST,2398("[%s] data dump request event sent",2399JvmtiTrace::safe_get_thread_name(thread)));2400JvmtiThreadEventTransition jet(thread);2401// JNIEnv is NULL here because this event is posted from VM Thread2402jvmtiEventDataDumpRequest callback = env->callbacks()->DataDumpRequest;2403if (callback != NULL) {2404(*callback)(env->jvmti_external());2405}2406}2407}2408}24092410void JvmtiExport::post_monitor_contended_enter(JavaThread *thread, ObjectMonitor *obj_mntr) {2411oop object = obj_mntr->object();2412JvmtiThreadState *state = thread->jvmti_thread_state();2413if (state == NULL) {2414return;2415}24162417HandleMark hm(thread);2418Handle h(thread, object);24192420EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTER,2421("[%s] monitor contended enter event triggered",2422JvmtiTrace::safe_get_thread_name(thread)));24232424JvmtiEnvThreadStateIterator it(state);2425for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {2426if (ets->is_enabled(JVMTI_EVENT_MONITOR_CONTENDED_ENTER)) {2427EVT_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTER,2428("[%s] monitor contended enter event sent",2429JvmtiTrace::safe_get_thread_name(thread)));2430JvmtiMonitorEventMark jem(thread, h());2431JvmtiEnv *env = ets->get_env();2432JvmtiThreadEventTransition jet(thread);2433jvmtiEventMonitorContendedEnter callback = env->callbacks()->MonitorContendedEnter;2434if (callback != NULL) {2435(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_object());2436}2437}2438}2439}24402441void JvmtiExport::post_monitor_contended_entered(JavaThread *thread, ObjectMonitor *obj_mntr) {2442oop object = obj_mntr->object();2443JvmtiThreadState *state = thread->jvmti_thread_state();2444if (state == NULL) {2445return;2446}24472448HandleMark hm(thread);2449Handle h(thread, object);24502451EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED,2452("[%s] monitor contended entered event triggered",2453JvmtiTrace::safe_get_thread_name(thread)));24542455JvmtiEnvThreadStateIterator it(state);2456for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {2457if (ets->is_enabled(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED)) {2458EVT_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED,2459("[%s] monitor contended enter event sent",2460JvmtiTrace::safe_get_thread_name(thread)));2461JvmtiMonitorEventMark jem(thread, h());2462JvmtiEnv *env = ets->get_env();2463JvmtiThreadEventTransition jet(thread);2464jvmtiEventMonitorContendedEntered callback = env->callbacks()->MonitorContendedEntered;2465if (callback != NULL) {2466(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_object());2467}2468}2469}2470}24712472void JvmtiExport::post_monitor_wait(JavaThread *thread, oop object,2473jlong timeout) {2474JvmtiThreadState *state = thread->jvmti_thread_state();2475if (state == NULL) {2476return;2477}24782479HandleMark hm(thread);2480Handle h(thread, object);24812482EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_WAIT,2483("[%s] monitor wait event triggered",2484JvmtiTrace::safe_get_thread_name(thread)));24852486JvmtiEnvThreadStateIterator it(state);2487for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {2488if (ets->is_enabled(JVMTI_EVENT_MONITOR_WAIT)) {2489EVT_TRACE(JVMTI_EVENT_MONITOR_WAIT,2490("[%s] monitor wait event sent",2491JvmtiTrace::safe_get_thread_name(thread)));2492JvmtiMonitorEventMark jem(thread, h());2493JvmtiEnv *env = ets->get_env();2494JvmtiThreadEventTransition jet(thread);2495jvmtiEventMonitorWait callback = env->callbacks()->MonitorWait;2496if (callback != NULL) {2497(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),2498jem.jni_object(), timeout);2499}2500}2501}2502}25032504void JvmtiExport::post_monitor_waited(JavaThread *thread, ObjectMonitor *obj_mntr, jboolean timed_out) {2505oop object = obj_mntr->object();2506JvmtiThreadState *state = thread->jvmti_thread_state();2507if (state == NULL) {2508return;2509}25102511HandleMark hm(thread);2512Handle h(thread, object);25132514EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_WAITED,2515("[%s] monitor waited event triggered",2516JvmtiTrace::safe_get_thread_name(thread)));25172518JvmtiEnvThreadStateIterator it(state);2519for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {2520if (ets->is_enabled(JVMTI_EVENT_MONITOR_WAITED)) {2521EVT_TRACE(JVMTI_EVENT_MONITOR_WAITED,2522("[%s] monitor waited event sent",2523JvmtiTrace::safe_get_thread_name(thread)));2524JvmtiMonitorEventMark jem(thread, h());2525JvmtiEnv *env = ets->get_env();2526JvmtiThreadEventTransition jet(thread);2527jvmtiEventMonitorWaited callback = env->callbacks()->MonitorWaited;2528if (callback != NULL) {2529(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),2530jem.jni_object(), timed_out);2531}2532}2533}2534}25352536void JvmtiExport::post_vm_object_alloc(JavaThread *thread, oop object) {2537EVT_TRIG_TRACE(JVMTI_EVENT_VM_OBJECT_ALLOC, ("[%s] Trg vm object alloc triggered",2538JvmtiTrace::safe_get_thread_name(thread)));2539if (object == NULL) {2540return;2541}2542HandleMark hm(thread);2543Handle h(thread, object);2544JvmtiEnvIterator it;2545for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {2546if (env->is_enabled(JVMTI_EVENT_VM_OBJECT_ALLOC)) {2547EVT_TRACE(JVMTI_EVENT_VM_OBJECT_ALLOC, ("[%s] Evt vmobject alloc sent %s",2548JvmtiTrace::safe_get_thread_name(thread),2549object==NULL? "NULL" : object->klass()->external_name()));25502551JvmtiObjectAllocEventMark jem(thread, h());2552JvmtiJavaThreadEventTransition jet(thread);2553jvmtiEventVMObjectAlloc callback = env->callbacks()->VMObjectAlloc;2554if (callback != NULL) {2555(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),2556jem.jni_jobject(), jem.jni_class(), jem.size());2557}2558}2559}2560}25612562void JvmtiExport::post_sampled_object_alloc(JavaThread *thread, oop object) {2563JvmtiThreadState *state = thread->jvmti_thread_state();2564if (state == NULL) {2565return;2566}25672568EVT_TRIG_TRACE(JVMTI_EVENT_SAMPLED_OBJECT_ALLOC,2569("[%s] Trg sampled object alloc triggered",2570JvmtiTrace::safe_get_thread_name(thread)));2571if (object == NULL) {2572return;2573}2574HandleMark hm(thread);2575Handle h(thread, object);25762577JvmtiEnvThreadStateIterator it(state);2578for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {2579if (ets->is_enabled(JVMTI_EVENT_SAMPLED_OBJECT_ALLOC)) {2580EVT_TRACE(JVMTI_EVENT_SAMPLED_OBJECT_ALLOC,2581("[%s] Evt sampled object alloc sent %s",2582JvmtiTrace::safe_get_thread_name(thread),2583object == NULL ? "NULL" : object->klass()->external_name()));25842585JvmtiEnv *env = ets->get_env();2586JvmtiObjectAllocEventMark jem(thread, h());2587JvmtiJavaThreadEventTransition jet(thread);2588jvmtiEventSampledObjectAlloc callback = env->callbacks()->SampledObjectAlloc;2589if (callback != NULL) {2590(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),2591jem.jni_jobject(), jem.jni_class(), jem.size());2592}2593}2594}2595}25962597////////////////////////////////////////////////////////////////////////////////////////////////25982599void JvmtiExport::cleanup_thread(JavaThread* thread) {2600assert(JavaThread::current() == thread, "thread is not current");2601MutexLocker mu(thread, JvmtiThreadState_lock);26022603if (thread->jvmti_thread_state() != NULL) {2604// This has to happen after the thread state is removed, which is2605// why it is not in post_thread_end_event like its complement2606// Maybe both these functions should be rolled into the posts?2607JvmtiEventController::thread_ended(thread);2608}2609}26102611void JvmtiExport::clear_detected_exception(JavaThread* thread) {2612assert(JavaThread::current() == thread, "thread is not current");26132614JvmtiThreadState* state = thread->jvmti_thread_state();2615if (state != NULL) {2616state->clear_exception_state();2617}2618}26192620// Onload raw monitor transition.2621void JvmtiExport::transition_pending_onload_raw_monitors() {2622JvmtiPendingMonitors::transition_raw_monitors();2623}26242625////////////////////////////////////////////////////////////////////////////////////////////////2626#if INCLUDE_SERVICES2627// Attach is disabled if SERVICES is not included26282629// type for the Agent_OnAttach entry point2630extern "C" {2631typedef jint (JNICALL *OnAttachEntry_t)(JavaVM*, char *, void *);2632}26332634jint JvmtiExport::load_agent_library(const char *agent, const char *absParam,2635const char *options, outputStream* st) {2636char ebuf[1024] = {0};2637char buffer[JVM_MAXPATHLEN];2638void* library = NULL;2639jint result = JNI_ERR;2640const char *on_attach_symbols[] = AGENT_ONATTACH_SYMBOLS;2641size_t num_symbol_entries = ARRAY_SIZE(on_attach_symbols);26422643// The abs paramter should be "true" or "false"2644bool is_absolute_path = (absParam != NULL) && (strcmp(absParam,"true")==0);26452646// Initially marked as invalid. It will be set to valid if we can find the agent2647AgentLibrary *agent_lib = new AgentLibrary(agent, options, is_absolute_path, NULL);26482649// Check for statically linked in agent. If not found then if the path is2650// absolute we attempt to load the library. Otherwise we try to load it2651// from the standard dll directory.26522653if (!os::find_builtin_agent(agent_lib, on_attach_symbols, num_symbol_entries)) {2654if (is_absolute_path) {2655library = os::dll_load(agent, ebuf, sizeof ebuf);2656} else {2657// Try to load the agent from the standard dll directory2658if (os::dll_locate_lib(buffer, sizeof(buffer), Arguments::get_dll_dir(),2659agent)) {2660library = os::dll_load(buffer, ebuf, sizeof ebuf);2661}2662if (library == NULL) {2663// not found - try OS default library path2664if (os::dll_build_name(buffer, sizeof(buffer), agent)) {2665library = os::dll_load(buffer, ebuf, sizeof ebuf);2666}2667}2668}2669if (library != NULL) {2670agent_lib->set_os_lib(library);2671agent_lib->set_valid();2672}2673}2674// If the library was loaded then we attempt to invoke the Agent_OnAttach2675// function2676if (agent_lib->valid()) {2677// Lookup the Agent_OnAttach function2678OnAttachEntry_t on_attach_entry = NULL;2679on_attach_entry = CAST_TO_FN_PTR(OnAttachEntry_t,2680os::find_agent_function(agent_lib, false, on_attach_symbols, num_symbol_entries));2681if (on_attach_entry == NULL) {2682// Agent_OnAttach missing - unload library2683if (!agent_lib->is_static_lib()) {2684os::dll_unload(library);2685}2686st->print_cr("%s is not available in %s",2687on_attach_symbols[0], agent_lib->name());2688delete agent_lib;2689} else {2690// Invoke the Agent_OnAttach function2691JavaThread* THREAD = JavaThread::current(); // For exception macros.2692{2693extern struct JavaVM_ main_vm;2694JvmtiThreadEventMark jem(THREAD);2695JvmtiJavaThreadEventTransition jet(THREAD);26962697result = (*on_attach_entry)(&main_vm, (char*)options, NULL);2698}26992700// Agent_OnAttach may have used JNI2701if (HAS_PENDING_EXCEPTION) {2702CLEAR_PENDING_EXCEPTION;2703}27042705// If OnAttach returns JNI_OK then we add it to the list of2706// agent libraries so that we can call Agent_OnUnload later.2707if (result == JNI_OK) {2708Arguments::add_loaded_agent(agent_lib);2709} else {2710if (!agent_lib->is_static_lib()) {2711os::dll_unload(library);2712}2713delete agent_lib;2714}27152716// Agent_OnAttach executed so completion status is JNI_OK2717st->print_cr("return code: %d", result);2718result = JNI_OK;2719}2720} else {2721st->print_cr("%s was not loaded.", agent);2722if (*ebuf != '\0') {2723st->print_cr("%s", ebuf);2724}2725}2726return result;2727}27282729#endif // INCLUDE_SERVICES2730////////////////////////////////////////////////////////////////////////////////////////////////27312732// Setup current current thread for event collection.2733void JvmtiEventCollector::setup_jvmti_thread_state() {2734// set this event collector to be the current one.2735JvmtiThreadState* state = JvmtiThreadState::state_for(JavaThread::current());2736// state can only be NULL if the current thread is exiting which2737// should not happen since we're trying to configure for event collection2738guarantee(state != NULL, "exiting thread called setup_jvmti_thread_state");2739if (is_vm_object_alloc_event()) {2740JvmtiVMObjectAllocEventCollector *prev = state->get_vm_object_alloc_event_collector();27412742// If we have a previous collector and it is disabled, it means this allocation came from a2743// callback induced VM Object allocation, do not register this collector then.2744if (prev && !prev->is_enabled()) {2745return;2746}2747_prev = prev;2748state->set_vm_object_alloc_event_collector((JvmtiVMObjectAllocEventCollector *)this);2749} else if (is_dynamic_code_event()) {2750_prev = state->get_dynamic_code_event_collector();2751state->set_dynamic_code_event_collector((JvmtiDynamicCodeEventCollector *)this);2752} else if (is_sampled_object_alloc_event()) {2753JvmtiSampledObjectAllocEventCollector *prev = state->get_sampled_object_alloc_event_collector();27542755if (prev) {2756// JvmtiSampledObjectAllocEventCollector wants only one active collector2757// enabled. This allows to have a collector detect a user code requiring2758// a sample in the callback.2759return;2760}2761state->set_sampled_object_alloc_event_collector((JvmtiSampledObjectAllocEventCollector*) this);2762}27632764_unset_jvmti_thread_state = true;2765}27662767// Unset current event collection in this thread and reset it with previous2768// collector.2769void JvmtiEventCollector::unset_jvmti_thread_state() {2770if (!_unset_jvmti_thread_state) {2771return;2772}27732774JvmtiThreadState* state = JavaThread::current()->jvmti_thread_state();2775if (state != NULL) {2776// restore the previous event collector (if any)2777if (is_vm_object_alloc_event()) {2778if (state->get_vm_object_alloc_event_collector() == this) {2779state->set_vm_object_alloc_event_collector((JvmtiVMObjectAllocEventCollector *)_prev);2780} else {2781// this thread's jvmti state was created during the scope of2782// the event collector.2783}2784} else if (is_dynamic_code_event()) {2785if (state->get_dynamic_code_event_collector() == this) {2786state->set_dynamic_code_event_collector((JvmtiDynamicCodeEventCollector *)_prev);2787} else {2788// this thread's jvmti state was created during the scope of2789// the event collector.2790}2791} else if (is_sampled_object_alloc_event()) {2792if (state->get_sampled_object_alloc_event_collector() == this) {2793state->set_sampled_object_alloc_event_collector((JvmtiSampledObjectAllocEventCollector*)_prev);2794} else {2795// this thread's jvmti state was created during the scope of2796// the event collector.2797}2798}2799}2800}28012802// create the dynamic code event collector2803JvmtiDynamicCodeEventCollector::JvmtiDynamicCodeEventCollector() : _code_blobs(NULL) {2804if (JvmtiExport::should_post_dynamic_code_generated()) {2805setup_jvmti_thread_state();2806}2807}28082809// iterate over any code blob descriptors collected and post a2810// DYNAMIC_CODE_GENERATED event to the profiler.2811JvmtiDynamicCodeEventCollector::~JvmtiDynamicCodeEventCollector() {2812assert(!JavaThread::current()->owns_locks(), "all locks must be released to post deferred events");2813// iterate over any code blob descriptors that we collected2814if (_code_blobs != NULL) {2815for (int i=0; i<_code_blobs->length(); i++) {2816JvmtiCodeBlobDesc* blob = _code_blobs->at(i);2817JvmtiExport::post_dynamic_code_generated(blob->name(), blob->code_begin(), blob->code_end());2818FreeHeap(blob);2819}2820delete _code_blobs;2821}2822unset_jvmti_thread_state();2823}28242825// register a stub2826void JvmtiDynamicCodeEventCollector::register_stub(const char* name, address start, address end) {2827if (_code_blobs == NULL) {2828_code_blobs = new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<JvmtiCodeBlobDesc*>(1, mtServiceability);2829}2830_code_blobs->append(new JvmtiCodeBlobDesc(name, start, end));2831}28322833// Setup current thread to record vm allocated objects.2834JvmtiObjectAllocEventCollector::JvmtiObjectAllocEventCollector() :2835_allocated(NULL), _enable(false), _post_callback(NULL) {2836}28372838// Post vm_object_alloc event for vm allocated objects visible to java2839// world.2840void JvmtiObjectAllocEventCollector::generate_call_for_allocated() {2841if (_allocated) {2842set_enabled(false);2843for (int i = 0; i < _allocated->length(); i++) {2844oop obj = _allocated->at(i).resolve();2845_post_callback(JavaThread::current(), obj);2846// Release OopHandle2847_allocated->at(i).release(JvmtiExport::jvmti_oop_storage());28482849}2850delete _allocated, _allocated = NULL;2851}2852}28532854void JvmtiObjectAllocEventCollector::record_allocation(oop obj) {2855assert(is_enabled(), "Object alloc event collector is not enabled");2856if (_allocated == NULL) {2857_allocated = new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<OopHandle>(1, mtServiceability);2858}2859_allocated->push(OopHandle(JvmtiExport::jvmti_oop_storage(), obj));2860}28612862// Disable collection of VMObjectAlloc events2863NoJvmtiVMObjectAllocMark::NoJvmtiVMObjectAllocMark() : _collector(NULL) {2864// a no-op if VMObjectAlloc event is not enabled2865if (!JvmtiExport::should_post_vm_object_alloc()) {2866return;2867}2868Thread* thread = Thread::current_or_null();2869if (thread != NULL && thread->is_Java_thread()) {2870JavaThread* current_thread = thread->as_Java_thread();2871JvmtiThreadState *state = current_thread->jvmti_thread_state();2872if (state != NULL) {2873JvmtiVMObjectAllocEventCollector *collector;2874collector = state->get_vm_object_alloc_event_collector();2875if (collector != NULL && collector->is_enabled()) {2876_collector = collector;2877_collector->set_enabled(false);2878}2879}2880}2881}28822883// Re-Enable collection of VMObjectAlloc events (if previously enabled)2884NoJvmtiVMObjectAllocMark::~NoJvmtiVMObjectAllocMark() {2885if (was_enabled()) {2886_collector->set_enabled(true);2887}2888};28892890// Setup current thread to record vm allocated objects.2891JvmtiVMObjectAllocEventCollector::JvmtiVMObjectAllocEventCollector() {2892if (JvmtiExport::should_post_vm_object_alloc()) {2893_enable = true;2894setup_jvmti_thread_state();2895_post_callback = JvmtiExport::post_vm_object_alloc;2896}2897}28982899JvmtiVMObjectAllocEventCollector::~JvmtiVMObjectAllocEventCollector() {2900if (_enable) {2901generate_call_for_allocated();2902}2903unset_jvmti_thread_state();2904}29052906bool JvmtiSampledObjectAllocEventCollector::object_alloc_is_safe_to_sample() {2907Thread* thread = Thread::current();2908// Really only sample allocations if this is a JavaThread and not the compiler2909// thread.2910if (!thread->is_Java_thread() || thread->is_Compiler_thread()) {2911return false;2912}29132914if (MultiArray_lock->owner() == thread) {2915return false;2916}2917return true;2918}29192920// Setup current thread to record sampled allocated objects.2921JvmtiSampledObjectAllocEventCollector::JvmtiSampledObjectAllocEventCollector() {2922if (JvmtiExport::should_post_sampled_object_alloc()) {2923if (!object_alloc_is_safe_to_sample()) {2924return;2925}29262927_enable = true;2928setup_jvmti_thread_state();2929_post_callback = JvmtiExport::post_sampled_object_alloc;2930}2931}29322933JvmtiSampledObjectAllocEventCollector::~JvmtiSampledObjectAllocEventCollector() {2934if (!_enable) {2935return;2936}29372938generate_call_for_allocated();2939unset_jvmti_thread_state();29402941// Unset the sampling collector as present in assertion mode only.2942assert(Thread::current()->is_Java_thread(),2943"Should always be in a Java thread");2944}29452946JvmtiGCMarker::JvmtiGCMarker() {2947// if there aren't any JVMTI environments then nothing to do2948if (!JvmtiEnv::environments_might_exist()) {2949return;2950}29512952if (JvmtiExport::should_post_garbage_collection_start()) {2953JvmtiExport::post_garbage_collection_start();2954}29552956if (SafepointSynchronize::is_at_safepoint()) {2957// Do clean up tasks that need to be done at a safepoint2958JvmtiEnvBase::check_for_periodic_clean_up();2959}2960}29612962JvmtiGCMarker::~JvmtiGCMarker() {2963// if there aren't any JVMTI environments then nothing to do2964if (!JvmtiEnv::environments_might_exist()) {2965return;2966}29672968// JVMTI notify gc finish2969if (JvmtiExport::should_post_garbage_collection_finish()) {2970JvmtiExport::post_garbage_collection_finish();2971}2972}297329742975