1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/prims/jvmtiExport.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,2476 @@ 1.4 +/* 1.5 + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "classfile/systemDictionary.hpp" 1.30 +#include "code/nmethod.hpp" 1.31 +#include "code/pcDesc.hpp" 1.32 +#include "code/scopeDesc.hpp" 1.33 +#include "interpreter/interpreter.hpp" 1.34 +#include "jvmtifiles/jvmtiEnv.hpp" 1.35 +#include "memory/resourceArea.hpp" 1.36 +#include "oops/objArrayKlass.hpp" 1.37 +#include "oops/objArrayOop.hpp" 1.38 +#include "prims/jvmtiCodeBlobEvents.hpp" 1.39 +#include "prims/jvmtiEventController.hpp" 1.40 +#include "prims/jvmtiEventController.inline.hpp" 1.41 +#include "prims/jvmtiExport.hpp" 1.42 +#include "prims/jvmtiImpl.hpp" 1.43 +#include "prims/jvmtiManageCapabilities.hpp" 1.44 +#include "prims/jvmtiRawMonitor.hpp" 1.45 +#include "prims/jvmtiTagMap.hpp" 1.46 +#include "prims/jvmtiThreadState.inline.hpp" 1.47 +#include "prims/jvmtiRedefineClasses.hpp" 1.48 +#include "runtime/arguments.hpp" 1.49 +#include "runtime/handles.hpp" 1.50 +#include "runtime/interfaceSupport.hpp" 1.51 +#include "runtime/objectMonitor.hpp" 1.52 +#include "runtime/objectMonitor.inline.hpp" 1.53 +#include "runtime/thread.hpp" 1.54 +#include "runtime/vframe.hpp" 1.55 +#include "services/attachListener.hpp" 1.56 +#include "services/serviceUtil.hpp" 1.57 +#include "utilities/macros.hpp" 1.58 +#if INCLUDE_ALL_GCS 1.59 +#include "gc_implementation/parallelScavenge/psMarkSweep.hpp" 1.60 +#endif // INCLUDE_ALL_GCS 1.61 + 1.62 +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC 1.63 + 1.64 +#ifdef JVMTI_TRACE 1.65 +#define EVT_TRACE(evt,out) if ((JvmtiTrace::event_trace_flags(evt) & JvmtiTrace::SHOW_EVENT_SENT) != 0) { SafeResourceMark rm; tty->print_cr out; } 1.66 +#define EVT_TRIG_TRACE(evt,out) if ((JvmtiTrace::event_trace_flags(evt) & JvmtiTrace::SHOW_EVENT_TRIGGER) != 0) { SafeResourceMark rm; tty->print_cr out; } 1.67 +#else 1.68 +#define EVT_TRIG_TRACE(evt,out) 1.69 +#define EVT_TRACE(evt,out) 1.70 +#endif 1.71 + 1.72 +/////////////////////////////////////////////////////////////// 1.73 +// 1.74 +// JvmtiEventTransition 1.75 +// 1.76 +// TO DO -- 1.77 +// more handle purging 1.78 + 1.79 +// Use this for JavaThreads and state is _thread_in_vm. 1.80 +class JvmtiJavaThreadEventTransition : StackObj { 1.81 +private: 1.82 + ResourceMark _rm; 1.83 + ThreadToNativeFromVM _transition; 1.84 + HandleMark _hm; 1.85 + 1.86 +public: 1.87 + JvmtiJavaThreadEventTransition(JavaThread *thread) : 1.88 + _rm(), 1.89 + _transition(thread), 1.90 + _hm(thread) {}; 1.91 +}; 1.92 + 1.93 +// For JavaThreads which are not in _thread_in_vm state 1.94 +// and other system threads use this. 1.95 +class JvmtiThreadEventTransition : StackObj { 1.96 +private: 1.97 + ResourceMark _rm; 1.98 + HandleMark _hm; 1.99 + JavaThreadState _saved_state; 1.100 + JavaThread *_jthread; 1.101 + 1.102 +public: 1.103 + JvmtiThreadEventTransition(Thread *thread) : _rm(), _hm() { 1.104 + if (thread->is_Java_thread()) { 1.105 + _jthread = (JavaThread *)thread; 1.106 + _saved_state = _jthread->thread_state(); 1.107 + if (_saved_state == _thread_in_Java) { 1.108 + ThreadStateTransition::transition_from_java(_jthread, _thread_in_native); 1.109 + } else { 1.110 + ThreadStateTransition::transition(_jthread, _saved_state, _thread_in_native); 1.111 + } 1.112 + } else { 1.113 + _jthread = NULL; 1.114 + } 1.115 + } 1.116 + 1.117 + ~JvmtiThreadEventTransition() { 1.118 + if (_jthread != NULL) 1.119 + ThreadStateTransition::transition_from_native(_jthread, _saved_state); 1.120 + } 1.121 +}; 1.122 + 1.123 + 1.124 +/////////////////////////////////////////////////////////////// 1.125 +// 1.126 +// JvmtiEventMark 1.127 +// 1.128 + 1.129 +class JvmtiEventMark : public StackObj { 1.130 +private: 1.131 + JavaThread *_thread; 1.132 + JNIEnv* _jni_env; 1.133 + bool _exception_detected; 1.134 + bool _exception_caught; 1.135 +#if 0 1.136 + JNIHandleBlock* _hblock; 1.137 +#endif 1.138 + 1.139 +public: 1.140 + JvmtiEventMark(JavaThread *thread) : _thread(thread), 1.141 + _jni_env(thread->jni_environment()) { 1.142 +#if 0 1.143 + _hblock = thread->active_handles(); 1.144 + _hblock->clear_thoroughly(); // so we can be safe 1.145 +#else 1.146 + // we want to use the code above - but that needs the JNIHandle changes - later... 1.147 + // for now, steal JNI push local frame code 1.148 + JvmtiThreadState *state = thread->jvmti_thread_state(); 1.149 + // we are before an event. 1.150 + // Save current jvmti thread exception state. 1.151 + if (state != NULL) { 1.152 + _exception_detected = state->is_exception_detected(); 1.153 + _exception_caught = state->is_exception_caught(); 1.154 + } else { 1.155 + _exception_detected = false; 1.156 + _exception_caught = false; 1.157 + } 1.158 + 1.159 + JNIHandleBlock* old_handles = thread->active_handles(); 1.160 + JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread); 1.161 + assert(new_handles != NULL, "should not be NULL"); 1.162 + new_handles->set_pop_frame_link(old_handles); 1.163 + thread->set_active_handles(new_handles); 1.164 +#endif 1.165 + assert(thread == JavaThread::current(), "thread must be current!"); 1.166 + thread->frame_anchor()->make_walkable(thread); 1.167 + }; 1.168 + 1.169 + ~JvmtiEventMark() { 1.170 +#if 0 1.171 + _hblock->clear(); // for consistency with future correct behavior 1.172 +#else 1.173 + // we want to use the code above - but that needs the JNIHandle changes - later... 1.174 + // for now, steal JNI pop local frame code 1.175 + JNIHandleBlock* old_handles = _thread->active_handles(); 1.176 + JNIHandleBlock* new_handles = old_handles->pop_frame_link(); 1.177 + assert(new_handles != NULL, "should not be NULL"); 1.178 + _thread->set_active_handles(new_handles); 1.179 + // Note that we set the pop_frame_link to NULL explicitly, otherwise 1.180 + // the release_block call will release the blocks. 1.181 + old_handles->set_pop_frame_link(NULL); 1.182 + JNIHandleBlock::release_block(old_handles, _thread); // may block 1.183 +#endif 1.184 + 1.185 + JvmtiThreadState* state = _thread->jvmti_thread_state(); 1.186 + // we are continuing after an event. 1.187 + if (state != NULL) { 1.188 + // Restore the jvmti thread exception state. 1.189 + if (_exception_detected) { 1.190 + state->set_exception_detected(); 1.191 + } 1.192 + if (_exception_caught) { 1.193 + state->set_exception_caught(); 1.194 + } 1.195 + } 1.196 + } 1.197 + 1.198 +#if 0 1.199 + jobject to_jobject(oop obj) { return obj == NULL? NULL : _hblock->allocate_handle_fast(obj); } 1.200 +#else 1.201 + // we want to use the code above - but that needs the JNIHandle changes - later... 1.202 + // for now, use regular make_local 1.203 + jobject to_jobject(oop obj) { return JNIHandles::make_local(_thread,obj); } 1.204 +#endif 1.205 + 1.206 + jclass to_jclass(Klass* klass) { return (klass == NULL ? NULL : (jclass)to_jobject(klass->java_mirror())); } 1.207 + 1.208 + jmethodID to_jmethodID(methodHandle method) { return method->jmethod_id(); } 1.209 + 1.210 + JNIEnv* jni_env() { return _jni_env; } 1.211 +}; 1.212 + 1.213 +class JvmtiThreadEventMark : public JvmtiEventMark { 1.214 +private: 1.215 + jthread _jt; 1.216 + 1.217 +public: 1.218 + JvmtiThreadEventMark(JavaThread *thread) : 1.219 + JvmtiEventMark(thread) { 1.220 + _jt = (jthread)(to_jobject(thread->threadObj())); 1.221 + }; 1.222 + jthread jni_thread() { return _jt; } 1.223 +}; 1.224 + 1.225 +class JvmtiClassEventMark : public JvmtiThreadEventMark { 1.226 +private: 1.227 + jclass _jc; 1.228 + 1.229 +public: 1.230 + JvmtiClassEventMark(JavaThread *thread, Klass* klass) : 1.231 + JvmtiThreadEventMark(thread) { 1.232 + _jc = to_jclass(klass); 1.233 + }; 1.234 + jclass jni_class() { return _jc; } 1.235 +}; 1.236 + 1.237 +class JvmtiMethodEventMark : public JvmtiThreadEventMark { 1.238 +private: 1.239 + jmethodID _mid; 1.240 + 1.241 +public: 1.242 + JvmtiMethodEventMark(JavaThread *thread, methodHandle method) : 1.243 + JvmtiThreadEventMark(thread), 1.244 + _mid(to_jmethodID(method)) {}; 1.245 + jmethodID jni_methodID() { return _mid; } 1.246 +}; 1.247 + 1.248 +class JvmtiLocationEventMark : public JvmtiMethodEventMark { 1.249 +private: 1.250 + jlocation _loc; 1.251 + 1.252 +public: 1.253 + JvmtiLocationEventMark(JavaThread *thread, methodHandle method, address location) : 1.254 + JvmtiMethodEventMark(thread, method), 1.255 + _loc(location - method->code_base()) {}; 1.256 + jlocation location() { return _loc; } 1.257 +}; 1.258 + 1.259 +class JvmtiExceptionEventMark : public JvmtiLocationEventMark { 1.260 +private: 1.261 + jobject _exc; 1.262 + 1.263 +public: 1.264 + JvmtiExceptionEventMark(JavaThread *thread, methodHandle method, address location, Handle exception) : 1.265 + JvmtiLocationEventMark(thread, method, location), 1.266 + _exc(to_jobject(exception())) {}; 1.267 + jobject exception() { return _exc; } 1.268 +}; 1.269 + 1.270 +class JvmtiClassFileLoadEventMark : public JvmtiThreadEventMark { 1.271 +private: 1.272 + const char *_class_name; 1.273 + jobject _jloader; 1.274 + jobject _protection_domain; 1.275 + jclass _class_being_redefined; 1.276 + 1.277 +public: 1.278 + JvmtiClassFileLoadEventMark(JavaThread *thread, Symbol* name, 1.279 + Handle class_loader, Handle prot_domain, KlassHandle *class_being_redefined) : JvmtiThreadEventMark(thread) { 1.280 + _class_name = name != NULL? name->as_utf8() : NULL; 1.281 + _jloader = (jobject)to_jobject(class_loader()); 1.282 + _protection_domain = (jobject)to_jobject(prot_domain()); 1.283 + if (class_being_redefined == NULL) { 1.284 + _class_being_redefined = NULL; 1.285 + } else { 1.286 + _class_being_redefined = (jclass)to_jclass((*class_being_redefined)()); 1.287 + } 1.288 + }; 1.289 + const char *class_name() { 1.290 + return _class_name; 1.291 + } 1.292 + jobject jloader() { 1.293 + return _jloader; 1.294 + } 1.295 + jobject protection_domain() { 1.296 + return _protection_domain; 1.297 + } 1.298 + jclass class_being_redefined() { 1.299 + return _class_being_redefined; 1.300 + } 1.301 +}; 1.302 + 1.303 +////////////////////////////////////////////////////////////////////////////// 1.304 + 1.305 +int JvmtiExport::_field_access_count = 0; 1.306 +int JvmtiExport::_field_modification_count = 0; 1.307 + 1.308 +bool JvmtiExport::_can_access_local_variables = false; 1.309 +bool JvmtiExport::_can_hotswap_or_post_breakpoint = false; 1.310 +bool JvmtiExport::_can_modify_any_class = false; 1.311 +bool JvmtiExport::_can_walk_any_space = false; 1.312 + 1.313 +bool JvmtiExport::_has_redefined_a_class = false; 1.314 +bool JvmtiExport::_all_dependencies_are_recorded = false; 1.315 + 1.316 +// 1.317 +// field access management 1.318 +// 1.319 + 1.320 +// interpreter generator needs the address of the counter 1.321 +address JvmtiExport::get_field_access_count_addr() { 1.322 + // We don't grab a lock because we don't want to 1.323 + // serialize field access between all threads. This means that a 1.324 + // thread on another processor can see the wrong count value and 1.325 + // may either miss making a needed call into post_field_access() 1.326 + // or will make an unneeded call into post_field_access(). We pay 1.327 + // this price to avoid slowing down the VM when we aren't watching 1.328 + // field accesses. 1.329 + // Other access/mutation safe by virtue of being in VM state. 1.330 + return (address)(&_field_access_count); 1.331 +} 1.332 + 1.333 +// 1.334 +// field modification management 1.335 +// 1.336 + 1.337 +// interpreter generator needs the address of the counter 1.338 +address JvmtiExport::get_field_modification_count_addr() { 1.339 + // We don't grab a lock because we don't 1.340 + // want to serialize field modification between all threads. This 1.341 + // means that a thread on another processor can see the wrong 1.342 + // count value and may either miss making a needed call into 1.343 + // post_field_modification() or will make an unneeded call into 1.344 + // post_field_modification(). We pay this price to avoid slowing 1.345 + // down the VM when we aren't watching field modifications. 1.346 + // Other access/mutation safe by virtue of being in VM state. 1.347 + return (address)(&_field_modification_count); 1.348 +} 1.349 + 1.350 + 1.351 +/////////////////////////////////////////////////////////////// 1.352 +// Functions needed by java.lang.instrument for starting up javaagent. 1.353 +/////////////////////////////////////////////////////////////// 1.354 + 1.355 +jint 1.356 +JvmtiExport::get_jvmti_interface(JavaVM *jvm, void **penv, jint version) { 1.357 + // The JVMTI_VERSION_INTERFACE_JVMTI part of the version number 1.358 + // has already been validated in JNI GetEnv(). 1.359 + int major, minor, micro; 1.360 + 1.361 + // micro version doesn't matter here (yet?) 1.362 + decode_version_values(version, &major, &minor, µ); 1.363 + switch (major) { 1.364 + case 1: 1.365 + switch (minor) { 1.366 + case 0: // version 1.0.<micro> is recognized 1.367 + case 1: // version 1.1.<micro> is recognized 1.368 + case 2: // version 1.2.<micro> is recognized 1.369 + break; 1.370 + 1.371 + default: 1.372 + return JNI_EVERSION; // unsupported minor version number 1.373 + } 1.374 + break; 1.375 + default: 1.376 + return JNI_EVERSION; // unsupported major version number 1.377 + } 1.378 + 1.379 + if (JvmtiEnv::get_phase() == JVMTI_PHASE_LIVE) { 1.380 + JavaThread* current_thread = (JavaThread*) ThreadLocalStorage::thread(); 1.381 + // transition code: native to VM 1.382 + ThreadInVMfromNative __tiv(current_thread); 1.383 + VM_ENTRY_BASE(jvmtiEnv*, JvmtiExport::get_jvmti_interface, current_thread) 1.384 + debug_only(VMNativeEntryWrapper __vew;) 1.385 + 1.386 + JvmtiEnv *jvmti_env = JvmtiEnv::create_a_jvmti(version); 1.387 + *penv = jvmti_env->jvmti_external(); // actual type is jvmtiEnv* -- not to be confused with JvmtiEnv* 1.388 + return JNI_OK; 1.389 + 1.390 + } else if (JvmtiEnv::get_phase() == JVMTI_PHASE_ONLOAD) { 1.391 + // not live, no thread to transition 1.392 + JvmtiEnv *jvmti_env = JvmtiEnv::create_a_jvmti(version); 1.393 + *penv = jvmti_env->jvmti_external(); // actual type is jvmtiEnv* -- not to be confused with JvmtiEnv* 1.394 + return JNI_OK; 1.395 + 1.396 + } else { 1.397 + // Called at the wrong time 1.398 + *penv = NULL; 1.399 + return JNI_EDETACHED; 1.400 + } 1.401 +} 1.402 + 1.403 + 1.404 +void 1.405 +JvmtiExport::decode_version_values(jint version, int * major, int * minor, 1.406 + int * micro) { 1.407 + *major = (version & JVMTI_VERSION_MASK_MAJOR) >> JVMTI_VERSION_SHIFT_MAJOR; 1.408 + *minor = (version & JVMTI_VERSION_MASK_MINOR) >> JVMTI_VERSION_SHIFT_MINOR; 1.409 + *micro = (version & JVMTI_VERSION_MASK_MICRO) >> JVMTI_VERSION_SHIFT_MICRO; 1.410 +} 1.411 + 1.412 +void JvmtiExport::enter_primordial_phase() { 1.413 + JvmtiEnvBase::set_phase(JVMTI_PHASE_PRIMORDIAL); 1.414 +} 1.415 + 1.416 +void JvmtiExport::enter_start_phase() { 1.417 + JvmtiManageCapabilities::recompute_always_capabilities(); 1.418 + JvmtiEnvBase::set_phase(JVMTI_PHASE_START); 1.419 +} 1.420 + 1.421 +void JvmtiExport::enter_onload_phase() { 1.422 + JvmtiEnvBase::set_phase(JVMTI_PHASE_ONLOAD); 1.423 +} 1.424 + 1.425 +void JvmtiExport::enter_live_phase() { 1.426 + JvmtiEnvBase::set_phase(JVMTI_PHASE_LIVE); 1.427 +} 1.428 + 1.429 +// 1.430 +// JVMTI events that the VM posts to the debugger and also startup agent 1.431 +// and call the agent's premain() for java.lang.instrument. 1.432 +// 1.433 + 1.434 +void JvmtiExport::post_vm_start() { 1.435 + EVT_TRIG_TRACE(JVMTI_EVENT_VM_START, ("JVMTI Trg VM start event triggered" )); 1.436 + 1.437 + // can now enable some events 1.438 + JvmtiEventController::vm_start(); 1.439 + 1.440 + JvmtiEnvIterator it; 1.441 + for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { 1.442 + if (env->is_enabled(JVMTI_EVENT_VM_START)) { 1.443 + EVT_TRACE(JVMTI_EVENT_VM_START, ("JVMTI Evt VM start event sent" )); 1.444 + 1.445 + JavaThread *thread = JavaThread::current(); 1.446 + JvmtiThreadEventMark jem(thread); 1.447 + JvmtiJavaThreadEventTransition jet(thread); 1.448 + jvmtiEventVMStart callback = env->callbacks()->VMStart; 1.449 + if (callback != NULL) { 1.450 + (*callback)(env->jvmti_external(), jem.jni_env()); 1.451 + } 1.452 + } 1.453 + } 1.454 +} 1.455 + 1.456 + 1.457 +void JvmtiExport::post_vm_initialized() { 1.458 + EVT_TRIG_TRACE(JVMTI_EVENT_VM_INIT, ("JVMTI Trg VM init event triggered" )); 1.459 + 1.460 + // can now enable events 1.461 + JvmtiEventController::vm_init(); 1.462 + 1.463 + JvmtiEnvIterator it; 1.464 + for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { 1.465 + if (env->is_enabled(JVMTI_EVENT_VM_INIT)) { 1.466 + EVT_TRACE(JVMTI_EVENT_VM_INIT, ("JVMTI Evt VM init event sent" )); 1.467 + 1.468 + JavaThread *thread = JavaThread::current(); 1.469 + JvmtiThreadEventMark jem(thread); 1.470 + JvmtiJavaThreadEventTransition jet(thread); 1.471 + jvmtiEventVMInit callback = env->callbacks()->VMInit; 1.472 + if (callback != NULL) { 1.473 + (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread()); 1.474 + } 1.475 + } 1.476 + } 1.477 +} 1.478 + 1.479 + 1.480 +void JvmtiExport::post_vm_death() { 1.481 + EVT_TRIG_TRACE(JVMTI_EVENT_VM_DEATH, ("JVMTI Trg VM death event triggered" )); 1.482 + 1.483 + JvmtiEnvIterator it; 1.484 + for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { 1.485 + if (env->is_enabled(JVMTI_EVENT_VM_DEATH)) { 1.486 + EVT_TRACE(JVMTI_EVENT_VM_DEATH, ("JVMTI Evt VM death event sent" )); 1.487 + 1.488 + JavaThread *thread = JavaThread::current(); 1.489 + JvmtiEventMark jem(thread); 1.490 + JvmtiJavaThreadEventTransition jet(thread); 1.491 + jvmtiEventVMDeath callback = env->callbacks()->VMDeath; 1.492 + if (callback != NULL) { 1.493 + (*callback)(env->jvmti_external(), jem.jni_env()); 1.494 + } 1.495 + } 1.496 + } 1.497 + 1.498 + JvmtiEnvBase::set_phase(JVMTI_PHASE_DEAD); 1.499 + JvmtiEventController::vm_death(); 1.500 +} 1.501 + 1.502 +char** 1.503 +JvmtiExport::get_all_native_method_prefixes(int* count_ptr) { 1.504 + // Have to grab JVMTI thread state lock to be sure environment doesn't 1.505 + // go away while we iterate them. No locks during VM bring-up. 1.506 + if (Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint()) { 1.507 + return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr); 1.508 + } else { 1.509 + MutexLocker mu(JvmtiThreadState_lock); 1.510 + return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr); 1.511 + } 1.512 +} 1.513 + 1.514 +class JvmtiClassFileLoadHookPoster : public StackObj { 1.515 + private: 1.516 + Symbol* _h_name; 1.517 + Handle _class_loader; 1.518 + Handle _h_protection_domain; 1.519 + unsigned char ** _data_ptr; 1.520 + unsigned char ** _end_ptr; 1.521 + JavaThread * _thread; 1.522 + jint _curr_len; 1.523 + unsigned char * _curr_data; 1.524 + JvmtiEnv * _curr_env; 1.525 + JvmtiCachedClassFileData ** _cached_class_file_ptr; 1.526 + JvmtiThreadState * _state; 1.527 + KlassHandle * _h_class_being_redefined; 1.528 + JvmtiClassLoadKind _load_kind; 1.529 + 1.530 + public: 1.531 + inline JvmtiClassFileLoadHookPoster(Symbol* h_name, Handle class_loader, 1.532 + Handle h_protection_domain, 1.533 + unsigned char **data_ptr, unsigned char **end_ptr, 1.534 + JvmtiCachedClassFileData **cache_ptr) { 1.535 + _h_name = h_name; 1.536 + _class_loader = class_loader; 1.537 + _h_protection_domain = h_protection_domain; 1.538 + _data_ptr = data_ptr; 1.539 + _end_ptr = end_ptr; 1.540 + _thread = JavaThread::current(); 1.541 + _curr_len = *end_ptr - *data_ptr; 1.542 + _curr_data = *data_ptr; 1.543 + _curr_env = NULL; 1.544 + _cached_class_file_ptr = cache_ptr; 1.545 + 1.546 + _state = _thread->jvmti_thread_state(); 1.547 + if (_state != NULL) { 1.548 + _h_class_being_redefined = _state->get_class_being_redefined(); 1.549 + _load_kind = _state->get_class_load_kind(); 1.550 + // Clear class_being_redefined flag here. The action 1.551 + // from agent handler could generate a new class file load 1.552 + // hook event and if it is not cleared the new event generated 1.553 + // from regular class file load could have this stale redefined 1.554 + // class handle info. 1.555 + _state->clear_class_being_redefined(); 1.556 + } else { 1.557 + // redefine and retransform will always set the thread state 1.558 + _h_class_being_redefined = (KlassHandle *) NULL; 1.559 + _load_kind = jvmti_class_load_kind_load; 1.560 + } 1.561 + } 1.562 + 1.563 + void post() { 1.564 +// EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, 1.565 +// ("JVMTI [%s] class file load hook event triggered", 1.566 +// JvmtiTrace::safe_get_thread_name(_thread))); 1.567 + post_all_envs(); 1.568 + copy_modified_data(); 1.569 + } 1.570 + 1.571 + private: 1.572 + void post_all_envs() { 1.573 + if (_load_kind != jvmti_class_load_kind_retransform) { 1.574 + // for class load and redefine, 1.575 + // call the non-retransformable agents 1.576 + JvmtiEnvIterator it; 1.577 + for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { 1.578 + if (!env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) { 1.579 + // non-retransformable agents cannot retransform back, 1.580 + // so no need to cache the original class file bytes 1.581 + post_to_env(env, false); 1.582 + } 1.583 + } 1.584 + } 1.585 + JvmtiEnvIterator it; 1.586 + for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { 1.587 + // retransformable agents get all events 1.588 + if (env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) { 1.589 + // retransformable agents need to cache the original class file 1.590 + // bytes if changes are made via the ClassFileLoadHook 1.591 + post_to_env(env, true); 1.592 + } 1.593 + } 1.594 + } 1.595 + 1.596 + void post_to_env(JvmtiEnv* env, bool caching_needed) { 1.597 + unsigned char *new_data = NULL; 1.598 + jint new_len = 0; 1.599 +// EVT_TRACE(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, 1.600 +// ("JVMTI [%s] class file load hook event sent %s data_ptr = %d, data_len = %d", 1.601 +// JvmtiTrace::safe_get_thread_name(_thread), 1.602 +// _h_name == NULL ? "NULL" : _h_name->as_utf8(), 1.603 +// _curr_data, _curr_len )); 1.604 + JvmtiClassFileLoadEventMark jem(_thread, _h_name, _class_loader, 1.605 + _h_protection_domain, 1.606 + _h_class_being_redefined); 1.607 + JvmtiJavaThreadEventTransition jet(_thread); 1.608 + JNIEnv* jni_env = (JvmtiEnv::get_phase() == JVMTI_PHASE_PRIMORDIAL)? 1.609 + NULL : jem.jni_env(); 1.610 + jvmtiEventClassFileLoadHook callback = env->callbacks()->ClassFileLoadHook; 1.611 + if (callback != NULL) { 1.612 + (*callback)(env->jvmti_external(), jni_env, 1.613 + jem.class_being_redefined(), 1.614 + jem.jloader(), jem.class_name(), 1.615 + jem.protection_domain(), 1.616 + _curr_len, _curr_data, 1.617 + &new_len, &new_data); 1.618 + } 1.619 + if (new_data != NULL) { 1.620 + // this agent has modified class data. 1.621 + if (caching_needed && *_cached_class_file_ptr == NULL) { 1.622 + // data has been changed by the new retransformable agent 1.623 + // and it hasn't already been cached, cache it 1.624 + JvmtiCachedClassFileData *p; 1.625 + p = (JvmtiCachedClassFileData *)os::malloc( 1.626 + offset_of(JvmtiCachedClassFileData, data) + _curr_len, mtInternal); 1.627 + if (p == NULL) { 1.628 + vm_exit_out_of_memory(offset_of(JvmtiCachedClassFileData, data) + _curr_len, 1.629 + OOM_MALLOC_ERROR, 1.630 + "unable to allocate cached copy of original class bytes"); 1.631 + } 1.632 + p->length = _curr_len; 1.633 + memcpy(p->data, _curr_data, _curr_len); 1.634 + *_cached_class_file_ptr = p; 1.635 + } 1.636 + 1.637 + if (_curr_data != *_data_ptr) { 1.638 + // curr_data is previous agent modified class data. 1.639 + // And this has been changed by the new agent so 1.640 + // we can delete it now. 1.641 + _curr_env->Deallocate(_curr_data); 1.642 + } 1.643 + 1.644 + // Class file data has changed by the current agent. 1.645 + _curr_data = new_data; 1.646 + _curr_len = new_len; 1.647 + // Save the current agent env we need this to deallocate the 1.648 + // memory allocated by this agent. 1.649 + _curr_env = env; 1.650 + } 1.651 + } 1.652 + 1.653 + void copy_modified_data() { 1.654 + // if one of the agent has modified class file data. 1.655 + // Copy modified class data to new resources array. 1.656 + if (_curr_data != *_data_ptr) { 1.657 + *_data_ptr = NEW_RESOURCE_ARRAY(u1, _curr_len); 1.658 + memcpy(*_data_ptr, _curr_data, _curr_len); 1.659 + *_end_ptr = *_data_ptr + _curr_len; 1.660 + _curr_env->Deallocate(_curr_data); 1.661 + } 1.662 + } 1.663 +}; 1.664 + 1.665 +bool JvmtiExport::_should_post_class_file_load_hook = false; 1.666 + 1.667 +// this entry is for class file load hook on class load, redefine and retransform 1.668 +void JvmtiExport::post_class_file_load_hook(Symbol* h_name, 1.669 + Handle class_loader, 1.670 + Handle h_protection_domain, 1.671 + unsigned char **data_ptr, 1.672 + unsigned char **end_ptr, 1.673 + JvmtiCachedClassFileData **cache_ptr) { 1.674 + JvmtiClassFileLoadHookPoster poster(h_name, class_loader, 1.675 + h_protection_domain, 1.676 + data_ptr, end_ptr, 1.677 + cache_ptr); 1.678 + poster.post(); 1.679 +} 1.680 + 1.681 +void JvmtiExport::report_unsupported(bool on) { 1.682 + // If any JVMTI service is turned on, we need to exit before native code 1.683 + // tries to access nonexistant services. 1.684 + if (on) { 1.685 + vm_exit_during_initialization("Java Kernel does not support JVMTI."); 1.686 + } 1.687 +} 1.688 + 1.689 + 1.690 +static inline Klass* oop_to_klass(oop obj) { 1.691 + Klass* k = obj->klass(); 1.692 + 1.693 + // if the object is a java.lang.Class then return the java mirror 1.694 + if (k == SystemDictionary::Class_klass()) { 1.695 + if (!java_lang_Class::is_primitive(obj)) { 1.696 + k = java_lang_Class::as_Klass(obj); 1.697 + assert(k != NULL, "class for non-primitive mirror must exist"); 1.698 + } 1.699 + } 1.700 + return k; 1.701 +} 1.702 + 1.703 +class JvmtiVMObjectAllocEventMark : public JvmtiClassEventMark { 1.704 + private: 1.705 + jobject _jobj; 1.706 + jlong _size; 1.707 + public: 1.708 + JvmtiVMObjectAllocEventMark(JavaThread *thread, oop obj) : JvmtiClassEventMark(thread, oop_to_klass(obj)) { 1.709 + _jobj = (jobject)to_jobject(obj); 1.710 + _size = obj->size() * wordSize; 1.711 + }; 1.712 + jobject jni_jobject() { return _jobj; } 1.713 + jlong size() { return _size; } 1.714 +}; 1.715 + 1.716 +class JvmtiCompiledMethodLoadEventMark : public JvmtiMethodEventMark { 1.717 + private: 1.718 + jint _code_size; 1.719 + const void *_code_data; 1.720 + jint _map_length; 1.721 + jvmtiAddrLocationMap *_map; 1.722 + const void *_compile_info; 1.723 + public: 1.724 + JvmtiCompiledMethodLoadEventMark(JavaThread *thread, nmethod *nm, void* compile_info_ptr = NULL) 1.725 + : JvmtiMethodEventMark(thread,methodHandle(thread, nm->method())) { 1.726 + _code_data = nm->insts_begin(); 1.727 + _code_size = nm->insts_size(); 1.728 + _compile_info = compile_info_ptr; // Set void pointer of compiledMethodLoad Event. Default value is NULL. 1.729 + JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &_map, &_map_length); 1.730 + } 1.731 + ~JvmtiCompiledMethodLoadEventMark() { 1.732 + FREE_C_HEAP_ARRAY(jvmtiAddrLocationMap, _map, mtInternal); 1.733 + } 1.734 + 1.735 + jint code_size() { return _code_size; } 1.736 + const void *code_data() { return _code_data; } 1.737 + jint map_length() { return _map_length; } 1.738 + const jvmtiAddrLocationMap* map() { return _map; } 1.739 + const void *compile_info() { return _compile_info; } 1.740 +}; 1.741 + 1.742 + 1.743 + 1.744 +class JvmtiMonitorEventMark : public JvmtiThreadEventMark { 1.745 +private: 1.746 + jobject _jobj; 1.747 +public: 1.748 + JvmtiMonitorEventMark(JavaThread *thread, oop object) 1.749 + : JvmtiThreadEventMark(thread){ 1.750 + _jobj = to_jobject(object); 1.751 + } 1.752 + jobject jni_object() { return _jobj; } 1.753 +}; 1.754 + 1.755 +/////////////////////////////////////////////////////////////// 1.756 +// 1.757 +// pending CompiledMethodUnload support 1.758 +// 1.759 + 1.760 +void JvmtiExport::post_compiled_method_unload( 1.761 + jmethodID method, const void *code_begin) { 1.762 + JavaThread* thread = JavaThread::current(); 1.763 + EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD, 1.764 + ("JVMTI [%s] method compile unload event triggered", 1.765 + JvmtiTrace::safe_get_thread_name(thread))); 1.766 + 1.767 + // post the event for each environment that has this event enabled. 1.768 + JvmtiEnvIterator it; 1.769 + for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { 1.770 + if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_UNLOAD)) { 1.771 + 1.772 + EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD, 1.773 + ("JVMTI [%s] class compile method unload event sent jmethodID " PTR_FORMAT, 1.774 + JvmtiTrace::safe_get_thread_name(thread), method)); 1.775 + 1.776 + ResourceMark rm(thread); 1.777 + 1.778 + JvmtiEventMark jem(thread); 1.779 + JvmtiJavaThreadEventTransition jet(thread); 1.780 + jvmtiEventCompiledMethodUnload callback = env->callbacks()->CompiledMethodUnload; 1.781 + if (callback != NULL) { 1.782 + (*callback)(env->jvmti_external(), method, code_begin); 1.783 + } 1.784 + } 1.785 + } 1.786 +} 1.787 + 1.788 +/////////////////////////////////////////////////////////////// 1.789 +// 1.790 +// JvmtiExport 1.791 +// 1.792 + 1.793 +void JvmtiExport::post_raw_breakpoint(JavaThread *thread, Method* method, address location) { 1.794 + HandleMark hm(thread); 1.795 + methodHandle mh(thread, method); 1.796 + 1.797 + JvmtiThreadState *state = thread->jvmti_thread_state(); 1.798 + if (state == NULL) { 1.799 + return; 1.800 + } 1.801 + EVT_TRIG_TRACE(JVMTI_EVENT_BREAKPOINT, ("JVMTI [%s] Trg Breakpoint triggered", 1.802 + JvmtiTrace::safe_get_thread_name(thread))); 1.803 + JvmtiEnvThreadStateIterator it(state); 1.804 + for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { 1.805 + ets->compare_and_set_current_location(mh(), location, JVMTI_EVENT_BREAKPOINT); 1.806 + if (!ets->breakpoint_posted() && ets->is_enabled(JVMTI_EVENT_BREAKPOINT)) { 1.807 + ThreadState old_os_state = thread->osthread()->get_state(); 1.808 + thread->osthread()->set_state(BREAKPOINTED); 1.809 + EVT_TRACE(JVMTI_EVENT_BREAKPOINT, ("JVMTI [%s] Evt Breakpoint sent %s.%s @ %d", 1.810 + JvmtiTrace::safe_get_thread_name(thread), 1.811 + (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), 1.812 + (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(), 1.813 + location - mh()->code_base() )); 1.814 + 1.815 + JvmtiEnv *env = ets->get_env(); 1.816 + JvmtiLocationEventMark jem(thread, mh, location); 1.817 + JvmtiJavaThreadEventTransition jet(thread); 1.818 + jvmtiEventBreakpoint callback = env->callbacks()->Breakpoint; 1.819 + if (callback != NULL) { 1.820 + (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), 1.821 + jem.jni_methodID(), jem.location()); 1.822 + } 1.823 + 1.824 + ets->set_breakpoint_posted(); 1.825 + thread->osthread()->set_state(old_os_state); 1.826 + } 1.827 + } 1.828 +} 1.829 + 1.830 +////////////////////////////////////////////////////////////////////////////// 1.831 + 1.832 +bool JvmtiExport::_can_get_source_debug_extension = false; 1.833 +bool JvmtiExport::_can_maintain_original_method_order = false; 1.834 +bool JvmtiExport::_can_post_interpreter_events = false; 1.835 +bool JvmtiExport::_can_post_on_exceptions = false; 1.836 +bool JvmtiExport::_can_post_breakpoint = false; 1.837 +bool JvmtiExport::_can_post_field_access = false; 1.838 +bool JvmtiExport::_can_post_field_modification = false; 1.839 +bool JvmtiExport::_can_post_method_entry = false; 1.840 +bool JvmtiExport::_can_post_method_exit = false; 1.841 +bool JvmtiExport::_can_pop_frame = false; 1.842 +bool JvmtiExport::_can_force_early_return = false; 1.843 + 1.844 +bool JvmtiExport::_should_post_single_step = false; 1.845 +bool JvmtiExport::_should_post_field_access = false; 1.846 +bool JvmtiExport::_should_post_field_modification = false; 1.847 +bool JvmtiExport::_should_post_class_load = false; 1.848 +bool JvmtiExport::_should_post_class_prepare = false; 1.849 +bool JvmtiExport::_should_post_class_unload = false; 1.850 +bool JvmtiExport::_should_post_thread_life = false; 1.851 +bool JvmtiExport::_should_clean_up_heap_objects = false; 1.852 +bool JvmtiExport::_should_post_native_method_bind = false; 1.853 +bool JvmtiExport::_should_post_dynamic_code_generated = false; 1.854 +bool JvmtiExport::_should_post_data_dump = false; 1.855 +bool JvmtiExport::_should_post_compiled_method_load = false; 1.856 +bool JvmtiExport::_should_post_compiled_method_unload = false; 1.857 +bool JvmtiExport::_should_post_monitor_contended_enter = false; 1.858 +bool JvmtiExport::_should_post_monitor_contended_entered = false; 1.859 +bool JvmtiExport::_should_post_monitor_wait = false; 1.860 +bool JvmtiExport::_should_post_monitor_waited = false; 1.861 +bool JvmtiExport::_should_post_garbage_collection_start = false; 1.862 +bool JvmtiExport::_should_post_garbage_collection_finish = false; 1.863 +bool JvmtiExport::_should_post_object_free = false; 1.864 +bool JvmtiExport::_should_post_resource_exhausted = false; 1.865 +bool JvmtiExport::_should_post_vm_object_alloc = false; 1.866 +bool JvmtiExport::_should_post_on_exceptions = false; 1.867 + 1.868 +//////////////////////////////////////////////////////////////////////////////////////////////// 1.869 + 1.870 + 1.871 +// 1.872 +// JVMTI single step management 1.873 +// 1.874 +void JvmtiExport::at_single_stepping_point(JavaThread *thread, Method* method, address location) { 1.875 + assert(JvmtiExport::should_post_single_step(), "must be single stepping"); 1.876 + 1.877 + HandleMark hm(thread); 1.878 + methodHandle mh(thread, method); 1.879 + 1.880 + // update information about current location and post a step event 1.881 + JvmtiThreadState *state = thread->jvmti_thread_state(); 1.882 + if (state == NULL) { 1.883 + return; 1.884 + } 1.885 + EVT_TRIG_TRACE(JVMTI_EVENT_SINGLE_STEP, ("JVMTI [%s] Trg Single Step triggered", 1.886 + JvmtiTrace::safe_get_thread_name(thread))); 1.887 + if (!state->hide_single_stepping()) { 1.888 + if (state->is_pending_step_for_popframe()) { 1.889 + state->process_pending_step_for_popframe(); 1.890 + } 1.891 + if (state->is_pending_step_for_earlyret()) { 1.892 + state->process_pending_step_for_earlyret(); 1.893 + } 1.894 + JvmtiExport::post_single_step(thread, mh(), location); 1.895 + } 1.896 +} 1.897 + 1.898 + 1.899 +void JvmtiExport::expose_single_stepping(JavaThread *thread) { 1.900 + JvmtiThreadState *state = thread->jvmti_thread_state(); 1.901 + if (state != NULL) { 1.902 + state->clear_hide_single_stepping(); 1.903 + } 1.904 +} 1.905 + 1.906 + 1.907 +bool JvmtiExport::hide_single_stepping(JavaThread *thread) { 1.908 + JvmtiThreadState *state = thread->jvmti_thread_state(); 1.909 + if (state != NULL && state->is_enabled(JVMTI_EVENT_SINGLE_STEP)) { 1.910 + state->set_hide_single_stepping(); 1.911 + return true; 1.912 + } else { 1.913 + return false; 1.914 + } 1.915 +} 1.916 + 1.917 +void JvmtiExport::post_class_load(JavaThread *thread, Klass* klass) { 1.918 + HandleMark hm(thread); 1.919 + KlassHandle kh(thread, klass); 1.920 + 1.921 + EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_LOAD, ("JVMTI [%s] Trg Class Load triggered", 1.922 + JvmtiTrace::safe_get_thread_name(thread))); 1.923 + JvmtiThreadState* state = thread->jvmti_thread_state(); 1.924 + if (state == NULL) { 1.925 + return; 1.926 + } 1.927 + JvmtiEnvThreadStateIterator it(state); 1.928 + for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { 1.929 + if (ets->is_enabled(JVMTI_EVENT_CLASS_LOAD)) { 1.930 + EVT_TRACE(JVMTI_EVENT_CLASS_LOAD, ("JVMTI [%s] Evt Class Load sent %s", 1.931 + JvmtiTrace::safe_get_thread_name(thread), 1.932 + kh()==NULL? "NULL" : kh()->external_name() )); 1.933 + 1.934 + JvmtiEnv *env = ets->get_env(); 1.935 + JvmtiClassEventMark jem(thread, kh()); 1.936 + JvmtiJavaThreadEventTransition jet(thread); 1.937 + jvmtiEventClassLoad callback = env->callbacks()->ClassLoad; 1.938 + if (callback != NULL) { 1.939 + (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_class()); 1.940 + } 1.941 + } 1.942 + } 1.943 +} 1.944 + 1.945 + 1.946 +void JvmtiExport::post_class_prepare(JavaThread *thread, Klass* klass) { 1.947 + HandleMark hm(thread); 1.948 + KlassHandle kh(thread, klass); 1.949 + 1.950 + EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_PREPARE, ("JVMTI [%s] Trg Class Prepare triggered", 1.951 + JvmtiTrace::safe_get_thread_name(thread))); 1.952 + JvmtiThreadState* state = thread->jvmti_thread_state(); 1.953 + if (state == NULL) { 1.954 + return; 1.955 + } 1.956 + JvmtiEnvThreadStateIterator it(state); 1.957 + for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { 1.958 + if (ets->is_enabled(JVMTI_EVENT_CLASS_PREPARE)) { 1.959 + EVT_TRACE(JVMTI_EVENT_CLASS_PREPARE, ("JVMTI [%s] Evt Class Prepare sent %s", 1.960 + JvmtiTrace::safe_get_thread_name(thread), 1.961 + kh()==NULL? "NULL" : kh()->external_name() )); 1.962 + 1.963 + JvmtiEnv *env = ets->get_env(); 1.964 + JvmtiClassEventMark jem(thread, kh()); 1.965 + JvmtiJavaThreadEventTransition jet(thread); 1.966 + jvmtiEventClassPrepare callback = env->callbacks()->ClassPrepare; 1.967 + if (callback != NULL) { 1.968 + (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_class()); 1.969 + } 1.970 + } 1.971 + } 1.972 +} 1.973 + 1.974 +void JvmtiExport::post_class_unload(Klass* klass) { 1.975 + Thread *thread = Thread::current(); 1.976 + HandleMark hm(thread); 1.977 + KlassHandle kh(thread, klass); 1.978 + 1.979 + EVT_TRIG_TRACE(EXT_EVENT_CLASS_UNLOAD, ("JVMTI [?] Trg Class Unload triggered" )); 1.980 + if (JvmtiEventController::is_enabled((jvmtiEvent)EXT_EVENT_CLASS_UNLOAD)) { 1.981 + assert(thread->is_VM_thread(), "wrong thread"); 1.982 + 1.983 + // get JavaThread for whom we are proxy 1.984 + JavaThread *real_thread = 1.985 + (JavaThread *)((VMThread *)thread)->vm_operation()->calling_thread(); 1.986 + 1.987 + JvmtiEnvIterator it; 1.988 + for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { 1.989 + if (env->is_enabled((jvmtiEvent)EXT_EVENT_CLASS_UNLOAD)) { 1.990 + EVT_TRACE(EXT_EVENT_CLASS_UNLOAD, ("JVMTI [?] Evt Class Unload sent %s", 1.991 + kh()==NULL? "NULL" : kh()->external_name() )); 1.992 + 1.993 + // do everything manually, since this is a proxy - needs special care 1.994 + JNIEnv* jni_env = real_thread->jni_environment(); 1.995 + jthread jt = (jthread)JNIHandles::make_local(real_thread, real_thread->threadObj()); 1.996 + jclass jk = (jclass)JNIHandles::make_local(real_thread, kh()->java_mirror()); 1.997 + 1.998 + // Before we call the JVMTI agent, we have to set the state in the 1.999 + // thread for which we are proxying. 1.1000 + JavaThreadState prev_state = real_thread->thread_state(); 1.1001 + assert(prev_state == _thread_blocked, "JavaThread should be at safepoint"); 1.1002 + real_thread->set_thread_state(_thread_in_native); 1.1003 + 1.1004 + jvmtiExtensionEvent callback = env->ext_callbacks()->ClassUnload; 1.1005 + if (callback != NULL) { 1.1006 + (*callback)(env->jvmti_external(), jni_env, jt, jk); 1.1007 + } 1.1008 + 1.1009 + assert(real_thread->thread_state() == _thread_in_native, 1.1010 + "JavaThread should be in native"); 1.1011 + real_thread->set_thread_state(prev_state); 1.1012 + 1.1013 + JNIHandles::destroy_local(jk); 1.1014 + JNIHandles::destroy_local(jt); 1.1015 + } 1.1016 + } 1.1017 + } 1.1018 +} 1.1019 + 1.1020 + 1.1021 +void JvmtiExport::post_thread_start(JavaThread *thread) { 1.1022 + assert(thread->thread_state() == _thread_in_vm, "must be in vm state"); 1.1023 + 1.1024 + EVT_TRIG_TRACE(JVMTI_EVENT_THREAD_START, ("JVMTI [%s] Trg Thread Start event triggered", 1.1025 + JvmtiTrace::safe_get_thread_name(thread))); 1.1026 + 1.1027 + // do JVMTI thread initialization (if needed) 1.1028 + JvmtiEventController::thread_started(thread); 1.1029 + 1.1030 + // Do not post thread start event for hidden java thread. 1.1031 + if (JvmtiEventController::is_enabled(JVMTI_EVENT_THREAD_START) && 1.1032 + !thread->is_hidden_from_external_view()) { 1.1033 + JvmtiEnvIterator it; 1.1034 + for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { 1.1035 + if (env->is_enabled(JVMTI_EVENT_THREAD_START)) { 1.1036 + EVT_TRACE(JVMTI_EVENT_THREAD_START, ("JVMTI [%s] Evt Thread Start event sent", 1.1037 + JvmtiTrace::safe_get_thread_name(thread) )); 1.1038 + 1.1039 + JvmtiThreadEventMark jem(thread); 1.1040 + JvmtiJavaThreadEventTransition jet(thread); 1.1041 + jvmtiEventThreadStart callback = env->callbacks()->ThreadStart; 1.1042 + if (callback != NULL) { 1.1043 + (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread()); 1.1044 + } 1.1045 + } 1.1046 + } 1.1047 + } 1.1048 +} 1.1049 + 1.1050 + 1.1051 +void JvmtiExport::post_thread_end(JavaThread *thread) { 1.1052 + EVT_TRIG_TRACE(JVMTI_EVENT_THREAD_END, ("JVMTI [%s] Trg Thread End event triggered", 1.1053 + JvmtiTrace::safe_get_thread_name(thread))); 1.1054 + 1.1055 + JvmtiThreadState *state = thread->jvmti_thread_state(); 1.1056 + if (state == NULL) { 1.1057 + return; 1.1058 + } 1.1059 + 1.1060 + // Do not post thread end event for hidden java thread. 1.1061 + if (state->is_enabled(JVMTI_EVENT_THREAD_END) && 1.1062 + !thread->is_hidden_from_external_view()) { 1.1063 + 1.1064 + JvmtiEnvThreadStateIterator it(state); 1.1065 + for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { 1.1066 + if (ets->is_enabled(JVMTI_EVENT_THREAD_END)) { 1.1067 + EVT_TRACE(JVMTI_EVENT_THREAD_END, ("JVMTI [%s] Evt Thread End event sent", 1.1068 + JvmtiTrace::safe_get_thread_name(thread) )); 1.1069 + 1.1070 + JvmtiEnv *env = ets->get_env(); 1.1071 + JvmtiThreadEventMark jem(thread); 1.1072 + JvmtiJavaThreadEventTransition jet(thread); 1.1073 + jvmtiEventThreadEnd callback = env->callbacks()->ThreadEnd; 1.1074 + if (callback != NULL) { 1.1075 + (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread()); 1.1076 + } 1.1077 + } 1.1078 + } 1.1079 + } 1.1080 +} 1.1081 + 1.1082 +void JvmtiExport::post_object_free(JvmtiEnv* env, jlong tag) { 1.1083 + assert(SafepointSynchronize::is_at_safepoint(), "must be executed at safepoint"); 1.1084 + assert(env->is_enabled(JVMTI_EVENT_OBJECT_FREE), "checking"); 1.1085 + 1.1086 + EVT_TRIG_TRACE(JVMTI_EVENT_OBJECT_FREE, ("JVMTI [?] Trg Object Free triggered" )); 1.1087 + EVT_TRACE(JVMTI_EVENT_OBJECT_FREE, ("JVMTI [?] Evt Object Free sent")); 1.1088 + 1.1089 + jvmtiEventObjectFree callback = env->callbacks()->ObjectFree; 1.1090 + if (callback != NULL) { 1.1091 + (*callback)(env->jvmti_external(), tag); 1.1092 + } 1.1093 +} 1.1094 + 1.1095 +void JvmtiExport::post_resource_exhausted(jint resource_exhausted_flags, const char* description) { 1.1096 + EVT_TRIG_TRACE(JVMTI_EVENT_RESOURCE_EXHAUSTED, ("JVMTI Trg resource exhausted event triggered" )); 1.1097 + 1.1098 + JvmtiEnvIterator it; 1.1099 + for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { 1.1100 + if (env->is_enabled(JVMTI_EVENT_RESOURCE_EXHAUSTED)) { 1.1101 + EVT_TRACE(JVMTI_EVENT_RESOURCE_EXHAUSTED, ("JVMTI Evt resource exhausted event sent" )); 1.1102 + 1.1103 + JavaThread *thread = JavaThread::current(); 1.1104 + JvmtiThreadEventMark jem(thread); 1.1105 + JvmtiJavaThreadEventTransition jet(thread); 1.1106 + jvmtiEventResourceExhausted callback = env->callbacks()->ResourceExhausted; 1.1107 + if (callback != NULL) { 1.1108 + (*callback)(env->jvmti_external(), jem.jni_env(), 1.1109 + resource_exhausted_flags, NULL, description); 1.1110 + } 1.1111 + } 1.1112 + } 1.1113 +} 1.1114 + 1.1115 +void JvmtiExport::post_method_entry(JavaThread *thread, Method* method, frame current_frame) { 1.1116 + HandleMark hm(thread); 1.1117 + methodHandle mh(thread, method); 1.1118 + 1.1119 + EVT_TRIG_TRACE(JVMTI_EVENT_METHOD_ENTRY, ("JVMTI [%s] Trg Method Entry triggered %s.%s", 1.1120 + JvmtiTrace::safe_get_thread_name(thread), 1.1121 + (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), 1.1122 + (mh() == NULL) ? "NULL" : mh()->name()->as_C_string() )); 1.1123 + 1.1124 + JvmtiThreadState* state = thread->jvmti_thread_state(); 1.1125 + if (state == NULL || !state->is_interp_only_mode()) { 1.1126 + // for any thread that actually wants method entry, interp_only_mode is set 1.1127 + return; 1.1128 + } 1.1129 + 1.1130 + state->incr_cur_stack_depth(); 1.1131 + 1.1132 + if (state->is_enabled(JVMTI_EVENT_METHOD_ENTRY)) { 1.1133 + JvmtiEnvThreadStateIterator it(state); 1.1134 + for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { 1.1135 + if (ets->is_enabled(JVMTI_EVENT_METHOD_ENTRY)) { 1.1136 + EVT_TRACE(JVMTI_EVENT_METHOD_ENTRY, ("JVMTI [%s] Evt Method Entry sent %s.%s", 1.1137 + JvmtiTrace::safe_get_thread_name(thread), 1.1138 + (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), 1.1139 + (mh() == NULL) ? "NULL" : mh()->name()->as_C_string() )); 1.1140 + 1.1141 + JvmtiEnv *env = ets->get_env(); 1.1142 + JvmtiMethodEventMark jem(thread, mh); 1.1143 + JvmtiJavaThreadEventTransition jet(thread); 1.1144 + jvmtiEventMethodEntry callback = env->callbacks()->MethodEntry; 1.1145 + if (callback != NULL) { 1.1146 + (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_methodID()); 1.1147 + } 1.1148 + } 1.1149 + } 1.1150 + } 1.1151 +} 1.1152 + 1.1153 +void JvmtiExport::post_method_exit(JavaThread *thread, Method* method, frame current_frame) { 1.1154 + HandleMark hm(thread); 1.1155 + methodHandle mh(thread, method); 1.1156 + 1.1157 + EVT_TRIG_TRACE(JVMTI_EVENT_METHOD_EXIT, ("JVMTI [%s] Trg Method Exit triggered %s.%s", 1.1158 + JvmtiTrace::safe_get_thread_name(thread), 1.1159 + (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), 1.1160 + (mh() == NULL) ? "NULL" : mh()->name()->as_C_string() )); 1.1161 + 1.1162 + JvmtiThreadState *state = thread->jvmti_thread_state(); 1.1163 + if (state == NULL || !state->is_interp_only_mode()) { 1.1164 + // for any thread that actually wants method exit, interp_only_mode is set 1.1165 + return; 1.1166 + } 1.1167 + 1.1168 + // return a flag when a method terminates by throwing an exception 1.1169 + // i.e. if an exception is thrown and it's not caught by the current method 1.1170 + bool exception_exit = state->is_exception_detected() && !state->is_exception_caught(); 1.1171 + 1.1172 + 1.1173 + if (state->is_enabled(JVMTI_EVENT_METHOD_EXIT)) { 1.1174 + Handle result; 1.1175 + jvalue value; 1.1176 + value.j = 0L; 1.1177 + 1.1178 + // if the method hasn't been popped because of an exception then we populate 1.1179 + // the return_value parameter for the callback. At this point we only have 1.1180 + // the address of a "raw result" and we just call into the interpreter to 1.1181 + // convert this into a jvalue. 1.1182 + if (!exception_exit) { 1.1183 + oop oop_result; 1.1184 + BasicType type = current_frame.interpreter_frame_result(&oop_result, &value); 1.1185 + if (type == T_OBJECT || type == T_ARRAY) { 1.1186 + result = Handle(thread, oop_result); 1.1187 + } 1.1188 + } 1.1189 + 1.1190 + JvmtiEnvThreadStateIterator it(state); 1.1191 + for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { 1.1192 + if (ets->is_enabled(JVMTI_EVENT_METHOD_EXIT)) { 1.1193 + EVT_TRACE(JVMTI_EVENT_METHOD_EXIT, ("JVMTI [%s] Evt Method Exit sent %s.%s", 1.1194 + JvmtiTrace::safe_get_thread_name(thread), 1.1195 + (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), 1.1196 + (mh() == NULL) ? "NULL" : mh()->name()->as_C_string() )); 1.1197 + 1.1198 + JvmtiEnv *env = ets->get_env(); 1.1199 + JvmtiMethodEventMark jem(thread, mh); 1.1200 + if (result.not_null()) { 1.1201 + value.l = JNIHandles::make_local(thread, result()); 1.1202 + } 1.1203 + JvmtiJavaThreadEventTransition jet(thread); 1.1204 + jvmtiEventMethodExit callback = env->callbacks()->MethodExit; 1.1205 + if (callback != NULL) { 1.1206 + (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), 1.1207 + jem.jni_methodID(), exception_exit, value); 1.1208 + } 1.1209 + } 1.1210 + } 1.1211 + } 1.1212 + 1.1213 + if (state->is_enabled(JVMTI_EVENT_FRAME_POP)) { 1.1214 + JvmtiEnvThreadStateIterator it(state); 1.1215 + for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { 1.1216 + int cur_frame_number = state->cur_stack_depth(); 1.1217 + 1.1218 + if (ets->is_frame_pop(cur_frame_number)) { 1.1219 + // we have a NotifyFramePop entry for this frame. 1.1220 + // now check that this env/thread wants this event 1.1221 + if (ets->is_enabled(JVMTI_EVENT_FRAME_POP)) { 1.1222 + EVT_TRACE(JVMTI_EVENT_FRAME_POP, ("JVMTI [%s] Evt Frame Pop sent %s.%s", 1.1223 + JvmtiTrace::safe_get_thread_name(thread), 1.1224 + (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), 1.1225 + (mh() == NULL) ? "NULL" : mh()->name()->as_C_string() )); 1.1226 + 1.1227 + // we also need to issue a frame pop event for this frame 1.1228 + JvmtiEnv *env = ets->get_env(); 1.1229 + JvmtiMethodEventMark jem(thread, mh); 1.1230 + JvmtiJavaThreadEventTransition jet(thread); 1.1231 + jvmtiEventFramePop callback = env->callbacks()->FramePop; 1.1232 + if (callback != NULL) { 1.1233 + (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), 1.1234 + jem.jni_methodID(), exception_exit); 1.1235 + } 1.1236 + } 1.1237 + // remove the frame's entry 1.1238 + ets->clear_frame_pop(cur_frame_number); 1.1239 + } 1.1240 + } 1.1241 + } 1.1242 + 1.1243 + state->decr_cur_stack_depth(); 1.1244 +} 1.1245 + 1.1246 + 1.1247 +// Todo: inline this for optimization 1.1248 +void JvmtiExport::post_single_step(JavaThread *thread, Method* method, address location) { 1.1249 + HandleMark hm(thread); 1.1250 + methodHandle mh(thread, method); 1.1251 + 1.1252 + JvmtiThreadState *state = thread->jvmti_thread_state(); 1.1253 + if (state == NULL) { 1.1254 + return; 1.1255 + } 1.1256 + JvmtiEnvThreadStateIterator it(state); 1.1257 + for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { 1.1258 + ets->compare_and_set_current_location(mh(), location, JVMTI_EVENT_SINGLE_STEP); 1.1259 + if (!ets->single_stepping_posted() && ets->is_enabled(JVMTI_EVENT_SINGLE_STEP)) { 1.1260 + EVT_TRACE(JVMTI_EVENT_SINGLE_STEP, ("JVMTI [%s] Evt Single Step sent %s.%s @ %d", 1.1261 + JvmtiTrace::safe_get_thread_name(thread), 1.1262 + (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), 1.1263 + (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(), 1.1264 + location - mh()->code_base() )); 1.1265 + 1.1266 + JvmtiEnv *env = ets->get_env(); 1.1267 + JvmtiLocationEventMark jem(thread, mh, location); 1.1268 + JvmtiJavaThreadEventTransition jet(thread); 1.1269 + jvmtiEventSingleStep callback = env->callbacks()->SingleStep; 1.1270 + if (callback != NULL) { 1.1271 + (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), 1.1272 + jem.jni_methodID(), jem.location()); 1.1273 + } 1.1274 + 1.1275 + ets->set_single_stepping_posted(); 1.1276 + } 1.1277 + } 1.1278 +} 1.1279 + 1.1280 + 1.1281 +void JvmtiExport::post_exception_throw(JavaThread *thread, Method* method, address location, oop exception) { 1.1282 + HandleMark hm(thread); 1.1283 + methodHandle mh(thread, method); 1.1284 + Handle exception_handle(thread, exception); 1.1285 + 1.1286 + JvmtiThreadState *state = thread->jvmti_thread_state(); 1.1287 + if (state == NULL) { 1.1288 + return; 1.1289 + } 1.1290 + 1.1291 + EVT_TRIG_TRACE(JVMTI_EVENT_EXCEPTION, ("JVMTI [%s] Trg Exception thrown triggered", 1.1292 + JvmtiTrace::safe_get_thread_name(thread))); 1.1293 + if (!state->is_exception_detected()) { 1.1294 + state->set_exception_detected(); 1.1295 + JvmtiEnvThreadStateIterator it(state); 1.1296 + for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { 1.1297 + if (ets->is_enabled(JVMTI_EVENT_EXCEPTION) && (exception != NULL)) { 1.1298 + 1.1299 + EVT_TRACE(JVMTI_EVENT_EXCEPTION, 1.1300 + ("JVMTI [%s] Evt Exception thrown sent %s.%s @ %d", 1.1301 + JvmtiTrace::safe_get_thread_name(thread), 1.1302 + (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), 1.1303 + (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(), 1.1304 + location - mh()->code_base() )); 1.1305 + 1.1306 + JvmtiEnv *env = ets->get_env(); 1.1307 + JvmtiExceptionEventMark jem(thread, mh, location, exception_handle); 1.1308 + 1.1309 + // It's okay to clear these exceptions here because we duplicate 1.1310 + // this lookup in InterpreterRuntime::exception_handler_for_exception. 1.1311 + EXCEPTION_MARK; 1.1312 + 1.1313 + bool should_repeat; 1.1314 + vframeStream st(thread); 1.1315 + assert(!st.at_end(), "cannot be at end"); 1.1316 + Method* current_method = NULL; 1.1317 + // A GC may occur during the Method::fast_exception_handler_bci_for() 1.1318 + // call below if it needs to load the constraint class. Using a 1.1319 + // methodHandle to keep the 'current_method' from being deallocated 1.1320 + // if GC happens. 1.1321 + methodHandle current_mh = methodHandle(thread, current_method); 1.1322 + int current_bci = -1; 1.1323 + do { 1.1324 + current_method = st.method(); 1.1325 + current_mh = methodHandle(thread, current_method); 1.1326 + current_bci = st.bci(); 1.1327 + do { 1.1328 + should_repeat = false; 1.1329 + KlassHandle eh_klass(thread, exception_handle()->klass()); 1.1330 + current_bci = Method::fast_exception_handler_bci_for( 1.1331 + current_mh, eh_klass, current_bci, THREAD); 1.1332 + if (HAS_PENDING_EXCEPTION) { 1.1333 + exception_handle = Handle(thread, PENDING_EXCEPTION); 1.1334 + CLEAR_PENDING_EXCEPTION; 1.1335 + should_repeat = true; 1.1336 + } 1.1337 + } while (should_repeat && (current_bci != -1)); 1.1338 + st.next(); 1.1339 + } while ((current_bci < 0) && (!st.at_end())); 1.1340 + 1.1341 + jmethodID catch_jmethodID; 1.1342 + if (current_bci < 0) { 1.1343 + catch_jmethodID = 0; 1.1344 + current_bci = 0; 1.1345 + } else { 1.1346 + catch_jmethodID = jem.to_jmethodID(current_mh); 1.1347 + } 1.1348 + 1.1349 + JvmtiJavaThreadEventTransition jet(thread); 1.1350 + jvmtiEventException callback = env->callbacks()->Exception; 1.1351 + if (callback != NULL) { 1.1352 + (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), 1.1353 + jem.jni_methodID(), jem.location(), 1.1354 + jem.exception(), 1.1355 + catch_jmethodID, current_bci); 1.1356 + } 1.1357 + } 1.1358 + } 1.1359 + } 1.1360 + 1.1361 + // frames may get popped because of this throw, be safe - invalidate cached depth 1.1362 + state->invalidate_cur_stack_depth(); 1.1363 +} 1.1364 + 1.1365 + 1.1366 +void JvmtiExport::notice_unwind_due_to_exception(JavaThread *thread, Method* method, address location, oop exception, bool in_handler_frame) { 1.1367 + HandleMark hm(thread); 1.1368 + methodHandle mh(thread, method); 1.1369 + Handle exception_handle(thread, exception); 1.1370 + 1.1371 + JvmtiThreadState *state = thread->jvmti_thread_state(); 1.1372 + if (state == NULL) { 1.1373 + return; 1.1374 + } 1.1375 + EVT_TRIG_TRACE(JVMTI_EVENT_EXCEPTION_CATCH, 1.1376 + ("JVMTI [%s] Trg unwind_due_to_exception triggered %s.%s @ %s%d - %s", 1.1377 + JvmtiTrace::safe_get_thread_name(thread), 1.1378 + (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), 1.1379 + (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(), 1.1380 + location==0? "no location:" : "", 1.1381 + location==0? 0 : location - mh()->code_base(), 1.1382 + in_handler_frame? "in handler frame" : "not handler frame" )); 1.1383 + 1.1384 + if (state->is_exception_detected()) { 1.1385 + 1.1386 + state->invalidate_cur_stack_depth(); 1.1387 + if (!in_handler_frame) { 1.1388 + // Not in exception handler. 1.1389 + if(state->is_interp_only_mode()) { 1.1390 + // method exit and frame pop events are posted only in interp mode. 1.1391 + // When these events are enabled code should be in running in interp mode. 1.1392 + JvmtiExport::post_method_exit(thread, method, thread->last_frame()); 1.1393 + // The cached cur_stack_depth might have changed from the 1.1394 + // operations of frame pop or method exit. We are not 100% sure 1.1395 + // the cached cur_stack_depth is still valid depth so invalidate 1.1396 + // it. 1.1397 + state->invalidate_cur_stack_depth(); 1.1398 + } 1.1399 + } else { 1.1400 + // In exception handler frame. Report exception catch. 1.1401 + assert(location != NULL, "must be a known location"); 1.1402 + // Update cur_stack_depth - the frames above the current frame 1.1403 + // have been unwound due to this exception: 1.1404 + assert(!state->is_exception_caught(), "exception must not be caught yet."); 1.1405 + state->set_exception_caught(); 1.1406 + 1.1407 + JvmtiEnvThreadStateIterator it(state); 1.1408 + for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { 1.1409 + if (ets->is_enabled(JVMTI_EVENT_EXCEPTION_CATCH) && (exception_handle() != NULL)) { 1.1410 + EVT_TRACE(JVMTI_EVENT_EXCEPTION_CATCH, 1.1411 + ("JVMTI [%s] Evt ExceptionCatch sent %s.%s @ %d", 1.1412 + JvmtiTrace::safe_get_thread_name(thread), 1.1413 + (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), 1.1414 + (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(), 1.1415 + location - mh()->code_base() )); 1.1416 + 1.1417 + JvmtiEnv *env = ets->get_env(); 1.1418 + JvmtiExceptionEventMark jem(thread, mh, location, exception_handle); 1.1419 + JvmtiJavaThreadEventTransition jet(thread); 1.1420 + jvmtiEventExceptionCatch callback = env->callbacks()->ExceptionCatch; 1.1421 + if (callback != NULL) { 1.1422 + (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), 1.1423 + jem.jni_methodID(), jem.location(), 1.1424 + jem.exception()); 1.1425 + } 1.1426 + } 1.1427 + } 1.1428 + } 1.1429 + } 1.1430 +} 1.1431 + 1.1432 +oop JvmtiExport::jni_GetField_probe(JavaThread *thread, jobject jobj, oop obj, 1.1433 + Klass* klass, jfieldID fieldID, bool is_static) { 1.1434 + if (*((int *)get_field_access_count_addr()) > 0 && thread->has_last_Java_frame()) { 1.1435 + // At least one field access watch is set so we have more work 1.1436 + // to do. This wrapper is used by entry points that allow us 1.1437 + // to create handles in post_field_access_by_jni(). 1.1438 + post_field_access_by_jni(thread, obj, klass, fieldID, is_static); 1.1439 + // event posting can block so refetch oop if we were passed a jobj 1.1440 + if (jobj != NULL) return JNIHandles::resolve_non_null(jobj); 1.1441 + } 1.1442 + return obj; 1.1443 +} 1.1444 + 1.1445 +oop JvmtiExport::jni_GetField_probe_nh(JavaThread *thread, jobject jobj, oop obj, 1.1446 + Klass* klass, jfieldID fieldID, bool is_static) { 1.1447 + if (*((int *)get_field_access_count_addr()) > 0 && thread->has_last_Java_frame()) { 1.1448 + // At least one field access watch is set so we have more work 1.1449 + // to do. This wrapper is used by "quick" entry points that don't 1.1450 + // allow us to create handles in post_field_access_by_jni(). We 1.1451 + // override that with a ResetNoHandleMark. 1.1452 + ResetNoHandleMark rnhm; 1.1453 + post_field_access_by_jni(thread, obj, klass, fieldID, is_static); 1.1454 + // event posting can block so refetch oop if we were passed a jobj 1.1455 + if (jobj != NULL) return JNIHandles::resolve_non_null(jobj); 1.1456 + } 1.1457 + return obj; 1.1458 +} 1.1459 + 1.1460 +void JvmtiExport::post_field_access_by_jni(JavaThread *thread, oop obj, 1.1461 + Klass* klass, jfieldID fieldID, bool is_static) { 1.1462 + // We must be called with a Java context in order to provide reasonable 1.1463 + // values for the klazz, method, and location fields. The callers of this 1.1464 + // function don't make the call unless there is a Java context. 1.1465 + assert(thread->has_last_Java_frame(), "must be called with a Java context"); 1.1466 + 1.1467 + ResourceMark rm; 1.1468 + fieldDescriptor fd; 1.1469 + // if get_field_descriptor finds fieldID to be invalid, then we just bail 1.1470 + bool valid_fieldID = JvmtiEnv::get_field_descriptor(klass, fieldID, &fd); 1.1471 + assert(valid_fieldID == true,"post_field_access_by_jni called with invalid fieldID"); 1.1472 + if (!valid_fieldID) return; 1.1473 + // field accesses are not watched so bail 1.1474 + if (!fd.is_field_access_watched()) return; 1.1475 + 1.1476 + HandleMark hm(thread); 1.1477 + KlassHandle h_klass(thread, klass); 1.1478 + Handle h_obj; 1.1479 + if (!is_static) { 1.1480 + // non-static field accessors have an object, but we need a handle 1.1481 + assert(obj != NULL, "non-static needs an object"); 1.1482 + h_obj = Handle(thread, obj); 1.1483 + } 1.1484 + post_field_access(thread, 1.1485 + thread->last_frame().interpreter_frame_method(), 1.1486 + thread->last_frame().interpreter_frame_bcp(), 1.1487 + h_klass, h_obj, fieldID); 1.1488 +} 1.1489 + 1.1490 +void JvmtiExport::post_field_access(JavaThread *thread, Method* method, 1.1491 + address location, KlassHandle field_klass, Handle object, jfieldID field) { 1.1492 + 1.1493 + HandleMark hm(thread); 1.1494 + methodHandle mh(thread, method); 1.1495 + 1.1496 + JvmtiThreadState *state = thread->jvmti_thread_state(); 1.1497 + if (state == NULL) { 1.1498 + return; 1.1499 + } 1.1500 + EVT_TRIG_TRACE(JVMTI_EVENT_FIELD_ACCESS, ("JVMTI [%s] Trg Field Access event triggered", 1.1501 + JvmtiTrace::safe_get_thread_name(thread))); 1.1502 + JvmtiEnvThreadStateIterator it(state); 1.1503 + for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { 1.1504 + if (ets->is_enabled(JVMTI_EVENT_FIELD_ACCESS)) { 1.1505 + EVT_TRACE(JVMTI_EVENT_FIELD_ACCESS, ("JVMTI [%s] Evt Field Access event sent %s.%s @ %d", 1.1506 + JvmtiTrace::safe_get_thread_name(thread), 1.1507 + (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), 1.1508 + (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(), 1.1509 + location - mh()->code_base() )); 1.1510 + 1.1511 + JvmtiEnv *env = ets->get_env(); 1.1512 + JvmtiLocationEventMark jem(thread, mh, location); 1.1513 + jclass field_jclass = jem.to_jclass(field_klass()); 1.1514 + jobject field_jobject = jem.to_jobject(object()); 1.1515 + JvmtiJavaThreadEventTransition jet(thread); 1.1516 + jvmtiEventFieldAccess callback = env->callbacks()->FieldAccess; 1.1517 + if (callback != NULL) { 1.1518 + (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), 1.1519 + jem.jni_methodID(), jem.location(), 1.1520 + field_jclass, field_jobject, field); 1.1521 + } 1.1522 + } 1.1523 + } 1.1524 +} 1.1525 + 1.1526 +oop JvmtiExport::jni_SetField_probe(JavaThread *thread, jobject jobj, oop obj, 1.1527 + Klass* klass, jfieldID fieldID, bool is_static, 1.1528 + char sig_type, jvalue *value) { 1.1529 + if (*((int *)get_field_modification_count_addr()) > 0 && thread->has_last_Java_frame()) { 1.1530 + // At least one field modification watch is set so we have more work 1.1531 + // to do. This wrapper is used by entry points that allow us 1.1532 + // to create handles in post_field_modification_by_jni(). 1.1533 + post_field_modification_by_jni(thread, obj, klass, fieldID, is_static, sig_type, value); 1.1534 + // event posting can block so refetch oop if we were passed a jobj 1.1535 + if (jobj != NULL) return JNIHandles::resolve_non_null(jobj); 1.1536 + } 1.1537 + return obj; 1.1538 +} 1.1539 + 1.1540 +oop JvmtiExport::jni_SetField_probe_nh(JavaThread *thread, jobject jobj, oop obj, 1.1541 + Klass* klass, jfieldID fieldID, bool is_static, 1.1542 + char sig_type, jvalue *value) { 1.1543 + if (*((int *)get_field_modification_count_addr()) > 0 && thread->has_last_Java_frame()) { 1.1544 + // At least one field modification watch is set so we have more work 1.1545 + // to do. This wrapper is used by "quick" entry points that don't 1.1546 + // allow us to create handles in post_field_modification_by_jni(). We 1.1547 + // override that with a ResetNoHandleMark. 1.1548 + ResetNoHandleMark rnhm; 1.1549 + post_field_modification_by_jni(thread, obj, klass, fieldID, is_static, sig_type, value); 1.1550 + // event posting can block so refetch oop if we were passed a jobj 1.1551 + if (jobj != NULL) return JNIHandles::resolve_non_null(jobj); 1.1552 + } 1.1553 + return obj; 1.1554 +} 1.1555 + 1.1556 +void JvmtiExport::post_field_modification_by_jni(JavaThread *thread, oop obj, 1.1557 + Klass* klass, jfieldID fieldID, bool is_static, 1.1558 + char sig_type, jvalue *value) { 1.1559 + // We must be called with a Java context in order to provide reasonable 1.1560 + // values for the klazz, method, and location fields. The callers of this 1.1561 + // function don't make the call unless there is a Java context. 1.1562 + assert(thread->has_last_Java_frame(), "must be called with Java context"); 1.1563 + 1.1564 + ResourceMark rm; 1.1565 + fieldDescriptor fd; 1.1566 + // if get_field_descriptor finds fieldID to be invalid, then we just bail 1.1567 + bool valid_fieldID = JvmtiEnv::get_field_descriptor(klass, fieldID, &fd); 1.1568 + assert(valid_fieldID == true,"post_field_modification_by_jni called with invalid fieldID"); 1.1569 + if (!valid_fieldID) return; 1.1570 + // field modifications are not watched so bail 1.1571 + if (!fd.is_field_modification_watched()) return; 1.1572 + 1.1573 + HandleMark hm(thread); 1.1574 + 1.1575 + Handle h_obj; 1.1576 + if (!is_static) { 1.1577 + // non-static field accessors have an object, but we need a handle 1.1578 + assert(obj != NULL, "non-static needs an object"); 1.1579 + h_obj = Handle(thread, obj); 1.1580 + } 1.1581 + KlassHandle h_klass(thread, klass); 1.1582 + post_field_modification(thread, 1.1583 + thread->last_frame().interpreter_frame_method(), 1.1584 + thread->last_frame().interpreter_frame_bcp(), 1.1585 + h_klass, h_obj, fieldID, sig_type, value); 1.1586 +} 1.1587 + 1.1588 +void JvmtiExport::post_raw_field_modification(JavaThread *thread, Method* method, 1.1589 + address location, KlassHandle field_klass, Handle object, jfieldID field, 1.1590 + char sig_type, jvalue *value) { 1.1591 + 1.1592 + if (sig_type == 'I' || sig_type == 'Z' || sig_type == 'C' || sig_type == 'S') { 1.1593 + // 'I' instructions are used for byte, char, short and int. 1.1594 + // determine which it really is, and convert 1.1595 + fieldDescriptor fd; 1.1596 + bool found = JvmtiEnv::get_field_descriptor(field_klass(), field, &fd); 1.1597 + // should be found (if not, leave as is) 1.1598 + if (found) { 1.1599 + jint ival = value->i; 1.1600 + // convert value from int to appropriate type 1.1601 + switch (fd.field_type()) { 1.1602 + case T_BOOLEAN: 1.1603 + sig_type = 'Z'; 1.1604 + value->i = 0; // clear it 1.1605 + value->z = (jboolean)ival; 1.1606 + break; 1.1607 + case T_BYTE: 1.1608 + sig_type = 'B'; 1.1609 + value->i = 0; // clear it 1.1610 + value->b = (jbyte)ival; 1.1611 + break; 1.1612 + case T_CHAR: 1.1613 + sig_type = 'C'; 1.1614 + value->i = 0; // clear it 1.1615 + value->c = (jchar)ival; 1.1616 + break; 1.1617 + case T_SHORT: 1.1618 + sig_type = 'S'; 1.1619 + value->i = 0; // clear it 1.1620 + value->s = (jshort)ival; 1.1621 + break; 1.1622 + case T_INT: 1.1623 + // nothing to do 1.1624 + break; 1.1625 + default: 1.1626 + // this is an integer instruction, should be one of above 1.1627 + ShouldNotReachHere(); 1.1628 + break; 1.1629 + } 1.1630 + } 1.1631 + } 1.1632 + 1.1633 + assert(sig_type != '[', "array should have sig_type == 'L'"); 1.1634 + bool handle_created = false; 1.1635 + 1.1636 + // convert oop to JNI handle. 1.1637 + if (sig_type == 'L') { 1.1638 + handle_created = true; 1.1639 + value->l = (jobject)JNIHandles::make_local(thread, (oop)value->l); 1.1640 + } 1.1641 + 1.1642 + post_field_modification(thread, method, location, field_klass, object, field, sig_type, value); 1.1643 + 1.1644 + // Destroy the JNI handle allocated above. 1.1645 + if (handle_created) { 1.1646 + JNIHandles::destroy_local(value->l); 1.1647 + } 1.1648 +} 1.1649 + 1.1650 +void JvmtiExport::post_field_modification(JavaThread *thread, Method* method, 1.1651 + address location, KlassHandle field_klass, Handle object, jfieldID field, 1.1652 + char sig_type, jvalue *value_ptr) { 1.1653 + 1.1654 + HandleMark hm(thread); 1.1655 + methodHandle mh(thread, method); 1.1656 + 1.1657 + JvmtiThreadState *state = thread->jvmti_thread_state(); 1.1658 + if (state == NULL) { 1.1659 + return; 1.1660 + } 1.1661 + EVT_TRIG_TRACE(JVMTI_EVENT_FIELD_MODIFICATION, 1.1662 + ("JVMTI [%s] Trg Field Modification event triggered", 1.1663 + JvmtiTrace::safe_get_thread_name(thread))); 1.1664 + 1.1665 + JvmtiEnvThreadStateIterator it(state); 1.1666 + for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { 1.1667 + if (ets->is_enabled(JVMTI_EVENT_FIELD_MODIFICATION)) { 1.1668 + EVT_TRACE(JVMTI_EVENT_FIELD_MODIFICATION, 1.1669 + ("JVMTI [%s] Evt Field Modification event sent %s.%s @ %d", 1.1670 + JvmtiTrace::safe_get_thread_name(thread), 1.1671 + (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), 1.1672 + (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(), 1.1673 + location - mh()->code_base() )); 1.1674 + 1.1675 + JvmtiEnv *env = ets->get_env(); 1.1676 + JvmtiLocationEventMark jem(thread, mh, location); 1.1677 + jclass field_jclass = jem.to_jclass(field_klass()); 1.1678 + jobject field_jobject = jem.to_jobject(object()); 1.1679 + JvmtiJavaThreadEventTransition jet(thread); 1.1680 + jvmtiEventFieldModification callback = env->callbacks()->FieldModification; 1.1681 + if (callback != NULL) { 1.1682 + (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), 1.1683 + jem.jni_methodID(), jem.location(), 1.1684 + field_jclass, field_jobject, field, sig_type, *value_ptr); 1.1685 + } 1.1686 + } 1.1687 + } 1.1688 +} 1.1689 + 1.1690 +void JvmtiExport::post_native_method_bind(Method* method, address* function_ptr) { 1.1691 + JavaThread* thread = JavaThread::current(); 1.1692 + assert(thread->thread_state() == _thread_in_vm, "must be in vm state"); 1.1693 + 1.1694 + HandleMark hm(thread); 1.1695 + methodHandle mh(thread, method); 1.1696 + 1.1697 + EVT_TRIG_TRACE(JVMTI_EVENT_NATIVE_METHOD_BIND, ("JVMTI [%s] Trg Native Method Bind event triggered", 1.1698 + JvmtiTrace::safe_get_thread_name(thread))); 1.1699 + 1.1700 + if (JvmtiEventController::is_enabled(JVMTI_EVENT_NATIVE_METHOD_BIND)) { 1.1701 + JvmtiEnvIterator it; 1.1702 + for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { 1.1703 + if (env->is_enabled(JVMTI_EVENT_NATIVE_METHOD_BIND)) { 1.1704 + EVT_TRACE(JVMTI_EVENT_NATIVE_METHOD_BIND, ("JVMTI [%s] Evt Native Method Bind event sent", 1.1705 + JvmtiTrace::safe_get_thread_name(thread) )); 1.1706 + 1.1707 + JvmtiMethodEventMark jem(thread, mh); 1.1708 + JvmtiJavaThreadEventTransition jet(thread); 1.1709 + JNIEnv* jni_env = JvmtiEnv::get_phase() == JVMTI_PHASE_PRIMORDIAL? NULL : jem.jni_env(); 1.1710 + jvmtiEventNativeMethodBind callback = env->callbacks()->NativeMethodBind; 1.1711 + if (callback != NULL) { 1.1712 + (*callback)(env->jvmti_external(), jni_env, jem.jni_thread(), 1.1713 + jem.jni_methodID(), (void*)(*function_ptr), (void**)function_ptr); 1.1714 + } 1.1715 + } 1.1716 + } 1.1717 + } 1.1718 +} 1.1719 + 1.1720 +// Returns a record containing inlining information for the given nmethod 1.1721 +jvmtiCompiledMethodLoadInlineRecord* create_inline_record(nmethod* nm) { 1.1722 + jint numstackframes = 0; 1.1723 + jvmtiCompiledMethodLoadInlineRecord* record = (jvmtiCompiledMethodLoadInlineRecord*)NEW_RESOURCE_OBJ(jvmtiCompiledMethodLoadInlineRecord); 1.1724 + record->header.kind = JVMTI_CMLR_INLINE_INFO; 1.1725 + record->header.next = NULL; 1.1726 + record->header.majorinfoversion = JVMTI_CMLR_MAJOR_VERSION_1; 1.1727 + record->header.minorinfoversion = JVMTI_CMLR_MINOR_VERSION_0; 1.1728 + record->numpcs = 0; 1.1729 + for(PcDesc* p = nm->scopes_pcs_begin(); p < nm->scopes_pcs_end(); p++) { 1.1730 + if(p->scope_decode_offset() == DebugInformationRecorder::serialized_null) continue; 1.1731 + record->numpcs++; 1.1732 + } 1.1733 + record->pcinfo = (PCStackInfo*)(NEW_RESOURCE_ARRAY(PCStackInfo, record->numpcs)); 1.1734 + int scope = 0; 1.1735 + for(PcDesc* p = nm->scopes_pcs_begin(); p < nm->scopes_pcs_end(); p++) { 1.1736 + if(p->scope_decode_offset() == DebugInformationRecorder::serialized_null) continue; 1.1737 + void* pc_address = (void*)p->real_pc(nm); 1.1738 + assert(pc_address != NULL, "pc_address must be non-null"); 1.1739 + record->pcinfo[scope].pc = pc_address; 1.1740 + numstackframes=0; 1.1741 + for(ScopeDesc* sd = nm->scope_desc_at(p->real_pc(nm));sd != NULL;sd = sd->sender()) { 1.1742 + numstackframes++; 1.1743 + } 1.1744 + assert(numstackframes != 0, "numstackframes must be nonzero."); 1.1745 + record->pcinfo[scope].methods = (jmethodID *)NEW_RESOURCE_ARRAY(jmethodID, numstackframes); 1.1746 + record->pcinfo[scope].bcis = (jint *)NEW_RESOURCE_ARRAY(jint, numstackframes); 1.1747 + record->pcinfo[scope].numstackframes = numstackframes; 1.1748 + int stackframe = 0; 1.1749 + for(ScopeDesc* sd = nm->scope_desc_at(p->real_pc(nm));sd != NULL;sd = sd->sender()) { 1.1750 + // 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() 1.1751 + assert(sd->method() != NULL, "sd->method() cannot be null."); 1.1752 + record->pcinfo[scope].methods[stackframe] = sd->method()->jmethod_id(); 1.1753 + record->pcinfo[scope].bcis[stackframe] = sd->bci(); 1.1754 + stackframe++; 1.1755 + } 1.1756 + scope++; 1.1757 + } 1.1758 + return record; 1.1759 +} 1.1760 + 1.1761 +void JvmtiExport::post_compiled_method_load(nmethod *nm) { 1.1762 + JavaThread* thread = JavaThread::current(); 1.1763 + 1.1764 + EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD, 1.1765 + ("JVMTI [%s] method compile load event triggered", 1.1766 + JvmtiTrace::safe_get_thread_name(thread))); 1.1767 + 1.1768 + JvmtiEnvIterator it; 1.1769 + for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { 1.1770 + if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_LOAD)) { 1.1771 + 1.1772 + EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD, 1.1773 + ("JVMTI [%s] class compile method load event sent %s.%s ", 1.1774 + JvmtiTrace::safe_get_thread_name(thread), 1.1775 + (nm->method() == NULL) ? "NULL" : nm->method()->klass_name()->as_C_string(), 1.1776 + (nm->method() == NULL) ? "NULL" : nm->method()->name()->as_C_string())); 1.1777 + ResourceMark rm(thread); 1.1778 + HandleMark hm(thread); 1.1779 + 1.1780 + // Add inlining information 1.1781 + jvmtiCompiledMethodLoadInlineRecord* inlinerecord = create_inline_record(nm); 1.1782 + // Pass inlining information through the void pointer 1.1783 + JvmtiCompiledMethodLoadEventMark jem(thread, nm, inlinerecord); 1.1784 + JvmtiJavaThreadEventTransition jet(thread); 1.1785 + jvmtiEventCompiledMethodLoad callback = env->callbacks()->CompiledMethodLoad; 1.1786 + if (callback != NULL) { 1.1787 + (*callback)(env->jvmti_external(), jem.jni_methodID(), 1.1788 + jem.code_size(), jem.code_data(), jem.map_length(), 1.1789 + jem.map(), jem.compile_info()); 1.1790 + } 1.1791 + } 1.1792 + } 1.1793 +} 1.1794 + 1.1795 + 1.1796 +// post a COMPILED_METHOD_LOAD event for a given environment 1.1797 +void JvmtiExport::post_compiled_method_load(JvmtiEnv* env, const jmethodID method, const jint length, 1.1798 + const void *code_begin, const jint map_length, 1.1799 + const jvmtiAddrLocationMap* map) 1.1800 +{ 1.1801 + JavaThread* thread = JavaThread::current(); 1.1802 + EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD, 1.1803 + ("JVMTI [%s] method compile load event triggered (by GenerateEvents)", 1.1804 + JvmtiTrace::safe_get_thread_name(thread))); 1.1805 + if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_LOAD)) { 1.1806 + 1.1807 + EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD, 1.1808 + ("JVMTI [%s] class compile method load event sent (by GenerateEvents), jmethodID=" PTR_FORMAT, 1.1809 + JvmtiTrace::safe_get_thread_name(thread), method)); 1.1810 + 1.1811 + JvmtiEventMark jem(thread); 1.1812 + JvmtiJavaThreadEventTransition jet(thread); 1.1813 + jvmtiEventCompiledMethodLoad callback = env->callbacks()->CompiledMethodLoad; 1.1814 + if (callback != NULL) { 1.1815 + (*callback)(env->jvmti_external(), method, 1.1816 + length, code_begin, map_length, 1.1817 + map, NULL); 1.1818 + } 1.1819 + } 1.1820 +} 1.1821 + 1.1822 +void JvmtiExport::post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) { 1.1823 + assert(name != NULL && name[0] != '\0', "sanity check"); 1.1824 + 1.1825 + JavaThread* thread = JavaThread::current(); 1.1826 + // In theory everyone coming thru here is in_vm but we need to be certain 1.1827 + // because a callee will do a vm->native transition 1.1828 + ThreadInVMfromUnknown __tiv; 1.1829 + 1.1830 + EVT_TRIG_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED, 1.1831 + ("JVMTI [%s] method dynamic code generated event triggered", 1.1832 + JvmtiTrace::safe_get_thread_name(thread))); 1.1833 + JvmtiEnvIterator it; 1.1834 + for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { 1.1835 + if (env->is_enabled(JVMTI_EVENT_DYNAMIC_CODE_GENERATED)) { 1.1836 + EVT_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED, 1.1837 + ("JVMTI [%s] dynamic code generated event sent for %s", 1.1838 + JvmtiTrace::safe_get_thread_name(thread), name)); 1.1839 + JvmtiEventMark jem(thread); 1.1840 + JvmtiJavaThreadEventTransition jet(thread); 1.1841 + jint length = (jint)pointer_delta(code_end, code_begin, sizeof(char)); 1.1842 + jvmtiEventDynamicCodeGenerated callback = env->callbacks()->DynamicCodeGenerated; 1.1843 + if (callback != NULL) { 1.1844 + (*callback)(env->jvmti_external(), name, (void*)code_begin, length); 1.1845 + } 1.1846 + } 1.1847 + } 1.1848 +} 1.1849 + 1.1850 +void JvmtiExport::post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end) { 1.1851 + jvmtiPhase phase = JvmtiEnv::get_phase(); 1.1852 + if (phase == JVMTI_PHASE_PRIMORDIAL || phase == JVMTI_PHASE_START) { 1.1853 + post_dynamic_code_generated_internal(name, code_begin, code_end); 1.1854 + } else { 1.1855 + // It may not be safe to post the event from this thread. Defer all 1.1856 + // postings to the service thread so that it can perform them in a safe 1.1857 + // context and in-order. 1.1858 + MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); 1.1859 + JvmtiDeferredEvent event = JvmtiDeferredEvent::dynamic_code_generated_event( 1.1860 + name, code_begin, code_end); 1.1861 + JvmtiDeferredEventQueue::enqueue(event); 1.1862 + } 1.1863 +} 1.1864 + 1.1865 + 1.1866 +// post a DYNAMIC_CODE_GENERATED event for a given environment 1.1867 +// used by GenerateEvents 1.1868 +void JvmtiExport::post_dynamic_code_generated(JvmtiEnv* env, const char *name, 1.1869 + const void *code_begin, const void *code_end) 1.1870 +{ 1.1871 + JavaThread* thread = JavaThread::current(); 1.1872 + EVT_TRIG_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED, 1.1873 + ("JVMTI [%s] dynamic code generated event triggered (by GenerateEvents)", 1.1874 + JvmtiTrace::safe_get_thread_name(thread))); 1.1875 + if (env->is_enabled(JVMTI_EVENT_DYNAMIC_CODE_GENERATED)) { 1.1876 + EVT_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED, 1.1877 + ("JVMTI [%s] dynamic code generated event sent for %s", 1.1878 + JvmtiTrace::safe_get_thread_name(thread), name)); 1.1879 + JvmtiEventMark jem(thread); 1.1880 + JvmtiJavaThreadEventTransition jet(thread); 1.1881 + jint length = (jint)pointer_delta(code_end, code_begin, sizeof(char)); 1.1882 + jvmtiEventDynamicCodeGenerated callback = env->callbacks()->DynamicCodeGenerated; 1.1883 + if (callback != NULL) { 1.1884 + (*callback)(env->jvmti_external(), name, (void*)code_begin, length); 1.1885 + } 1.1886 + } 1.1887 +} 1.1888 + 1.1889 +// post a DynamicCodeGenerated event while holding locks in the VM. 1.1890 +void JvmtiExport::post_dynamic_code_generated_while_holding_locks(const char* name, 1.1891 + address code_begin, address code_end) 1.1892 +{ 1.1893 + // register the stub with the current dynamic code event collector 1.1894 + JvmtiThreadState* state = JvmtiThreadState::state_for(JavaThread::current()); 1.1895 + // state can only be NULL if the current thread is exiting which 1.1896 + // should not happen since we're trying to post an event 1.1897 + guarantee(state != NULL, "attempt to register stub via an exiting thread"); 1.1898 + JvmtiDynamicCodeEventCollector* collector = state->get_dynamic_code_event_collector(); 1.1899 + guarantee(collector != NULL, "attempt to register stub without event collector"); 1.1900 + collector->register_stub(name, code_begin, code_end); 1.1901 +} 1.1902 + 1.1903 +// Collect all the vm internally allocated objects which are visible to java world 1.1904 +void JvmtiExport::record_vm_internal_object_allocation(oop obj) { 1.1905 + Thread* thread = ThreadLocalStorage::thread(); 1.1906 + if (thread != NULL && thread->is_Java_thread()) { 1.1907 + // Can not take safepoint here. 1.1908 + No_Safepoint_Verifier no_sfpt; 1.1909 + // Can not take safepoint here so can not use state_for to get 1.1910 + // jvmti thread state. 1.1911 + JvmtiThreadState *state = ((JavaThread*)thread)->jvmti_thread_state(); 1.1912 + if (state != NULL ) { 1.1913 + // state is non NULL when VMObjectAllocEventCollector is enabled. 1.1914 + JvmtiVMObjectAllocEventCollector *collector; 1.1915 + collector = state->get_vm_object_alloc_event_collector(); 1.1916 + if (collector != NULL && collector->is_enabled()) { 1.1917 + // Don't record classes as these will be notified via the ClassLoad 1.1918 + // event. 1.1919 + if (obj->klass() != SystemDictionary::Class_klass()) { 1.1920 + collector->record_allocation(obj); 1.1921 + } 1.1922 + } 1.1923 + } 1.1924 + } 1.1925 +} 1.1926 + 1.1927 +void JvmtiExport::post_garbage_collection_finish() { 1.1928 + Thread *thread = Thread::current(); // this event is posted from VM-Thread. 1.1929 + EVT_TRIG_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, 1.1930 + ("JVMTI [%s] garbage collection finish event triggered", 1.1931 + JvmtiTrace::safe_get_thread_name(thread))); 1.1932 + JvmtiEnvIterator it; 1.1933 + for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { 1.1934 + if (env->is_enabled(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH)) { 1.1935 + EVT_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, 1.1936 + ("JVMTI [%s] garbage collection finish event sent ", 1.1937 + JvmtiTrace::safe_get_thread_name(thread))); 1.1938 + JvmtiThreadEventTransition jet(thread); 1.1939 + // JNIEnv is NULL here because this event is posted from VM Thread 1.1940 + jvmtiEventGarbageCollectionFinish callback = env->callbacks()->GarbageCollectionFinish; 1.1941 + if (callback != NULL) { 1.1942 + (*callback)(env->jvmti_external()); 1.1943 + } 1.1944 + } 1.1945 + } 1.1946 +} 1.1947 + 1.1948 +void JvmtiExport::post_garbage_collection_start() { 1.1949 + Thread* thread = Thread::current(); // this event is posted from vm-thread. 1.1950 + EVT_TRIG_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_START, 1.1951 + ("JVMTI [%s] garbage collection start event triggered", 1.1952 + JvmtiTrace::safe_get_thread_name(thread))); 1.1953 + JvmtiEnvIterator it; 1.1954 + for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { 1.1955 + if (env->is_enabled(JVMTI_EVENT_GARBAGE_COLLECTION_START)) { 1.1956 + EVT_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_START, 1.1957 + ("JVMTI [%s] garbage collection start event sent ", 1.1958 + JvmtiTrace::safe_get_thread_name(thread))); 1.1959 + JvmtiThreadEventTransition jet(thread); 1.1960 + // JNIEnv is NULL here because this event is posted from VM Thread 1.1961 + jvmtiEventGarbageCollectionStart callback = env->callbacks()->GarbageCollectionStart; 1.1962 + if (callback != NULL) { 1.1963 + (*callback)(env->jvmti_external()); 1.1964 + } 1.1965 + } 1.1966 + } 1.1967 +} 1.1968 + 1.1969 +void JvmtiExport::post_data_dump() { 1.1970 + Thread *thread = Thread::current(); 1.1971 + EVT_TRIG_TRACE(JVMTI_EVENT_DATA_DUMP_REQUEST, 1.1972 + ("JVMTI [%s] data dump request event triggered", 1.1973 + JvmtiTrace::safe_get_thread_name(thread))); 1.1974 + JvmtiEnvIterator it; 1.1975 + for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { 1.1976 + if (env->is_enabled(JVMTI_EVENT_DATA_DUMP_REQUEST)) { 1.1977 + EVT_TRACE(JVMTI_EVENT_DATA_DUMP_REQUEST, 1.1978 + ("JVMTI [%s] data dump request event sent ", 1.1979 + JvmtiTrace::safe_get_thread_name(thread))); 1.1980 + JvmtiThreadEventTransition jet(thread); 1.1981 + // JNIEnv is NULL here because this event is posted from VM Thread 1.1982 + jvmtiEventDataDumpRequest callback = env->callbacks()->DataDumpRequest; 1.1983 + if (callback != NULL) { 1.1984 + (*callback)(env->jvmti_external()); 1.1985 + } 1.1986 + } 1.1987 + } 1.1988 +} 1.1989 + 1.1990 +void JvmtiExport::post_monitor_contended_enter(JavaThread *thread, ObjectMonitor *obj_mntr) { 1.1991 + oop object = (oop)obj_mntr->object(); 1.1992 + if (!ServiceUtil::visible_oop(object)) { 1.1993 + // Ignore monitor contended enter for vm internal object. 1.1994 + return; 1.1995 + } 1.1996 + JvmtiThreadState *state = thread->jvmti_thread_state(); 1.1997 + if (state == NULL) { 1.1998 + return; 1.1999 + } 1.2000 + 1.2001 + HandleMark hm(thread); 1.2002 + Handle h(thread, object); 1.2003 + 1.2004 + EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTER, 1.2005 + ("JVMTI [%s] montior contended enter event triggered", 1.2006 + JvmtiTrace::safe_get_thread_name(thread))); 1.2007 + 1.2008 + JvmtiEnvThreadStateIterator it(state); 1.2009 + for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { 1.2010 + if (ets->is_enabled(JVMTI_EVENT_MONITOR_CONTENDED_ENTER)) { 1.2011 + EVT_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTER, 1.2012 + ("JVMTI [%s] monitor contended enter event sent", 1.2013 + JvmtiTrace::safe_get_thread_name(thread))); 1.2014 + JvmtiMonitorEventMark jem(thread, h()); 1.2015 + JvmtiEnv *env = ets->get_env(); 1.2016 + JvmtiThreadEventTransition jet(thread); 1.2017 + jvmtiEventMonitorContendedEnter callback = env->callbacks()->MonitorContendedEnter; 1.2018 + if (callback != NULL) { 1.2019 + (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_object()); 1.2020 + } 1.2021 + } 1.2022 + } 1.2023 +} 1.2024 + 1.2025 +void JvmtiExport::post_monitor_contended_entered(JavaThread *thread, ObjectMonitor *obj_mntr) { 1.2026 + oop object = (oop)obj_mntr->object(); 1.2027 + if (!ServiceUtil::visible_oop(object)) { 1.2028 + // Ignore monitor contended entered for vm internal object. 1.2029 + return; 1.2030 + } 1.2031 + JvmtiThreadState *state = thread->jvmti_thread_state(); 1.2032 + if (state == NULL) { 1.2033 + return; 1.2034 + } 1.2035 + 1.2036 + HandleMark hm(thread); 1.2037 + Handle h(thread, object); 1.2038 + 1.2039 + EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, 1.2040 + ("JVMTI [%s] montior contended entered event triggered", 1.2041 + JvmtiTrace::safe_get_thread_name(thread))); 1.2042 + 1.2043 + JvmtiEnvThreadStateIterator it(state); 1.2044 + for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { 1.2045 + if (ets->is_enabled(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED)) { 1.2046 + EVT_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, 1.2047 + ("JVMTI [%s] monitor contended enter event sent", 1.2048 + JvmtiTrace::safe_get_thread_name(thread))); 1.2049 + JvmtiMonitorEventMark jem(thread, h()); 1.2050 + JvmtiEnv *env = ets->get_env(); 1.2051 + JvmtiThreadEventTransition jet(thread); 1.2052 + jvmtiEventMonitorContendedEntered callback = env->callbacks()->MonitorContendedEntered; 1.2053 + if (callback != NULL) { 1.2054 + (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_object()); 1.2055 + } 1.2056 + } 1.2057 + } 1.2058 +} 1.2059 + 1.2060 +void JvmtiExport::post_monitor_wait(JavaThread *thread, oop object, 1.2061 + jlong timeout) { 1.2062 + JvmtiThreadState *state = thread->jvmti_thread_state(); 1.2063 + if (state == NULL) { 1.2064 + return; 1.2065 + } 1.2066 + 1.2067 + HandleMark hm(thread); 1.2068 + Handle h(thread, object); 1.2069 + 1.2070 + EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_WAIT, 1.2071 + ("JVMTI [%s] montior wait event triggered", 1.2072 + JvmtiTrace::safe_get_thread_name(thread))); 1.2073 + 1.2074 + JvmtiEnvThreadStateIterator it(state); 1.2075 + for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { 1.2076 + if (ets->is_enabled(JVMTI_EVENT_MONITOR_WAIT)) { 1.2077 + EVT_TRACE(JVMTI_EVENT_MONITOR_WAIT, 1.2078 + ("JVMTI [%s] monitor wait event sent ", 1.2079 + JvmtiTrace::safe_get_thread_name(thread))); 1.2080 + JvmtiMonitorEventMark jem(thread, h()); 1.2081 + JvmtiEnv *env = ets->get_env(); 1.2082 + JvmtiThreadEventTransition jet(thread); 1.2083 + jvmtiEventMonitorWait callback = env->callbacks()->MonitorWait; 1.2084 + if (callback != NULL) { 1.2085 + (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), 1.2086 + jem.jni_object(), timeout); 1.2087 + } 1.2088 + } 1.2089 + } 1.2090 +} 1.2091 + 1.2092 +void JvmtiExport::post_monitor_waited(JavaThread *thread, ObjectMonitor *obj_mntr, jboolean timed_out) { 1.2093 + oop object = (oop)obj_mntr->object(); 1.2094 + if (!ServiceUtil::visible_oop(object)) { 1.2095 + // Ignore monitor waited for vm internal object. 1.2096 + return; 1.2097 + } 1.2098 + JvmtiThreadState *state = thread->jvmti_thread_state(); 1.2099 + if (state == NULL) { 1.2100 + return; 1.2101 + } 1.2102 + 1.2103 + HandleMark hm(thread); 1.2104 + Handle h(thread, object); 1.2105 + 1.2106 + EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_WAITED, 1.2107 + ("JVMTI [%s] montior waited event triggered", 1.2108 + JvmtiTrace::safe_get_thread_name(thread))); 1.2109 + 1.2110 + JvmtiEnvThreadStateIterator it(state); 1.2111 + for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { 1.2112 + if (ets->is_enabled(JVMTI_EVENT_MONITOR_WAITED)) { 1.2113 + EVT_TRACE(JVMTI_EVENT_MONITOR_WAITED, 1.2114 + ("JVMTI [%s] monitor waited event sent ", 1.2115 + JvmtiTrace::safe_get_thread_name(thread))); 1.2116 + JvmtiMonitorEventMark jem(thread, h()); 1.2117 + JvmtiEnv *env = ets->get_env(); 1.2118 + JvmtiThreadEventTransition jet(thread); 1.2119 + jvmtiEventMonitorWaited callback = env->callbacks()->MonitorWaited; 1.2120 + if (callback != NULL) { 1.2121 + (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), 1.2122 + jem.jni_object(), timed_out); 1.2123 + } 1.2124 + } 1.2125 + } 1.2126 +} 1.2127 + 1.2128 + 1.2129 +void JvmtiExport::post_vm_object_alloc(JavaThread *thread, oop object) { 1.2130 + EVT_TRIG_TRACE(JVMTI_EVENT_VM_OBJECT_ALLOC, ("JVMTI [%s] Trg vm object alloc triggered", 1.2131 + JvmtiTrace::safe_get_thread_name(thread))); 1.2132 + if (object == NULL) { 1.2133 + return; 1.2134 + } 1.2135 + HandleMark hm(thread); 1.2136 + Handle h(thread, object); 1.2137 + JvmtiEnvIterator it; 1.2138 + for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { 1.2139 + if (env->is_enabled(JVMTI_EVENT_VM_OBJECT_ALLOC)) { 1.2140 + EVT_TRACE(JVMTI_EVENT_VM_OBJECT_ALLOC, ("JVMTI [%s] Evt vmobject alloc sent %s", 1.2141 + JvmtiTrace::safe_get_thread_name(thread), 1.2142 + object==NULL? "NULL" : java_lang_Class::as_Klass(object)->external_name())); 1.2143 + 1.2144 + JvmtiVMObjectAllocEventMark jem(thread, h()); 1.2145 + JvmtiJavaThreadEventTransition jet(thread); 1.2146 + jvmtiEventVMObjectAlloc callback = env->callbacks()->VMObjectAlloc; 1.2147 + if (callback != NULL) { 1.2148 + (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), 1.2149 + jem.jni_jobject(), jem.jni_class(), jem.size()); 1.2150 + } 1.2151 + } 1.2152 + } 1.2153 +} 1.2154 + 1.2155 +//////////////////////////////////////////////////////////////////////////////////////////////// 1.2156 + 1.2157 +void JvmtiExport::cleanup_thread(JavaThread* thread) { 1.2158 + assert(JavaThread::current() == thread, "thread is not current"); 1.2159 + MutexLocker mu(JvmtiThreadState_lock); 1.2160 + 1.2161 + if (thread->jvmti_thread_state() != NULL) { 1.2162 + // This has to happen after the thread state is removed, which is 1.2163 + // why it is not in post_thread_end_event like its complement 1.2164 + // Maybe both these functions should be rolled into the posts? 1.2165 + JvmtiEventController::thread_ended(thread); 1.2166 + } 1.2167 +} 1.2168 + 1.2169 +void JvmtiExport::oops_do(OopClosure* f) { 1.2170 + JvmtiCurrentBreakpoints::oops_do(f); 1.2171 + JvmtiVMObjectAllocEventCollector::oops_do_for_all_threads(f); 1.2172 +} 1.2173 + 1.2174 +void JvmtiExport::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) { 1.2175 + JvmtiTagMap::weak_oops_do(is_alive, f); 1.2176 +} 1.2177 + 1.2178 +void JvmtiExport::gc_epilogue() { 1.2179 + JvmtiCurrentBreakpoints::gc_epilogue(); 1.2180 +} 1.2181 + 1.2182 +// Onload raw monitor transition. 1.2183 +void JvmtiExport::transition_pending_onload_raw_monitors() { 1.2184 + JvmtiPendingMonitors::transition_raw_monitors(); 1.2185 +} 1.2186 + 1.2187 +//////////////////////////////////////////////////////////////////////////////////////////////// 1.2188 + 1.2189 +// type for the Agent_OnAttach entry point 1.2190 +extern "C" { 1.2191 + typedef jint (JNICALL *OnAttachEntry_t)(JavaVM*, char *, void *); 1.2192 +} 1.2193 + 1.2194 +jint JvmtiExport::load_agent_library(AttachOperation* op, outputStream* st) { 1.2195 + char ebuf[1024]; 1.2196 + char buffer[JVM_MAXPATHLEN]; 1.2197 + void* library = NULL; 1.2198 + jint result = JNI_ERR; 1.2199 + const char *on_attach_symbols[] = AGENT_ONATTACH_SYMBOLS; 1.2200 + size_t num_symbol_entries = ARRAY_SIZE(on_attach_symbols); 1.2201 + 1.2202 + // get agent name and options 1.2203 + const char* agent = op->arg(0); 1.2204 + const char* absParam = op->arg(1); 1.2205 + const char* options = op->arg(2); 1.2206 + 1.2207 + // The abs paramter should be "true" or "false" 1.2208 + bool is_absolute_path = (absParam != NULL) && (strcmp(absParam,"true")==0); 1.2209 + 1.2210 + // Initially marked as invalid. It will be set to valid if we can find the agent 1.2211 + AgentLibrary *agent_lib = new AgentLibrary(agent, options, is_absolute_path, NULL); 1.2212 + 1.2213 + // Check for statically linked in agent. If not found then if the path is 1.2214 + // absolute we attempt to load the library. Otherwise we try to load it 1.2215 + // from the standard dll directory. 1.2216 + 1.2217 + if (!os::find_builtin_agent(agent_lib, on_attach_symbols, num_symbol_entries)) { 1.2218 + if (is_absolute_path) { 1.2219 + library = os::dll_load(agent, ebuf, sizeof ebuf); 1.2220 + } else { 1.2221 + // Try to load the agent from the standard dll directory 1.2222 + if (os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), 1.2223 + agent)) { 1.2224 + library = os::dll_load(buffer, ebuf, sizeof ebuf); 1.2225 + } 1.2226 + if (library == NULL) { 1.2227 + // not found - try local path 1.2228 + char ns[1] = {0}; 1.2229 + if (os::dll_build_name(buffer, sizeof(buffer), ns, agent)) { 1.2230 + library = os::dll_load(buffer, ebuf, sizeof ebuf); 1.2231 + } 1.2232 + } 1.2233 + } 1.2234 + if (library != NULL) { 1.2235 + agent_lib->set_os_lib(library); 1.2236 + agent_lib->set_valid(); 1.2237 + } 1.2238 + } 1.2239 + // If the library was loaded then we attempt to invoke the Agent_OnAttach 1.2240 + // function 1.2241 + if (agent_lib->valid()) { 1.2242 + // Lookup the Agent_OnAttach function 1.2243 + OnAttachEntry_t on_attach_entry = NULL; 1.2244 + on_attach_entry = CAST_TO_FN_PTR(OnAttachEntry_t, 1.2245 + os::find_agent_function(agent_lib, false, on_attach_symbols, num_symbol_entries)); 1.2246 + if (on_attach_entry == NULL) { 1.2247 + // Agent_OnAttach missing - unload library 1.2248 + if (!agent_lib->is_static_lib()) { 1.2249 + os::dll_unload(library); 1.2250 + } 1.2251 + delete agent_lib; 1.2252 + } else { 1.2253 + // Invoke the Agent_OnAttach function 1.2254 + JavaThread* THREAD = JavaThread::current(); 1.2255 + { 1.2256 + extern struct JavaVM_ main_vm; 1.2257 + JvmtiThreadEventMark jem(THREAD); 1.2258 + JvmtiJavaThreadEventTransition jet(THREAD); 1.2259 + 1.2260 + result = (*on_attach_entry)(&main_vm, (char*)options, NULL); 1.2261 + } 1.2262 + 1.2263 + // Agent_OnAttach may have used JNI 1.2264 + if (HAS_PENDING_EXCEPTION) { 1.2265 + CLEAR_PENDING_EXCEPTION; 1.2266 + } 1.2267 + 1.2268 + // If OnAttach returns JNI_OK then we add it to the list of 1.2269 + // agent libraries so that we can call Agent_OnUnload later. 1.2270 + if (result == JNI_OK) { 1.2271 + Arguments::add_loaded_agent(agent_lib); 1.2272 + } else { 1.2273 + delete agent_lib; 1.2274 + } 1.2275 + 1.2276 + // Agent_OnAttach executed so completion status is JNI_OK 1.2277 + st->print_cr("%d", result); 1.2278 + result = JNI_OK; 1.2279 + } 1.2280 + } 1.2281 + return result; 1.2282 +} 1.2283 + 1.2284 +//////////////////////////////////////////////////////////////////////////////////////////////// 1.2285 + 1.2286 +// Setup current current thread for event collection. 1.2287 +void JvmtiEventCollector::setup_jvmti_thread_state() { 1.2288 + // set this event collector to be the current one. 1.2289 + JvmtiThreadState* state = JvmtiThreadState::state_for(JavaThread::current()); 1.2290 + // state can only be NULL if the current thread is exiting which 1.2291 + // should not happen since we're trying to configure for event collection 1.2292 + guarantee(state != NULL, "exiting thread called setup_jvmti_thread_state"); 1.2293 + if (is_vm_object_alloc_event()) { 1.2294 + _prev = state->get_vm_object_alloc_event_collector(); 1.2295 + state->set_vm_object_alloc_event_collector((JvmtiVMObjectAllocEventCollector *)this); 1.2296 + } else if (is_dynamic_code_event()) { 1.2297 + _prev = state->get_dynamic_code_event_collector(); 1.2298 + state->set_dynamic_code_event_collector((JvmtiDynamicCodeEventCollector *)this); 1.2299 + } 1.2300 +} 1.2301 + 1.2302 +// Unset current event collection in this thread and reset it with previous 1.2303 +// collector. 1.2304 +void JvmtiEventCollector::unset_jvmti_thread_state() { 1.2305 + JvmtiThreadState* state = JavaThread::current()->jvmti_thread_state(); 1.2306 + if (state != NULL) { 1.2307 + // restore the previous event collector (if any) 1.2308 + if (is_vm_object_alloc_event()) { 1.2309 + if (state->get_vm_object_alloc_event_collector() == this) { 1.2310 + state->set_vm_object_alloc_event_collector((JvmtiVMObjectAllocEventCollector *)_prev); 1.2311 + } else { 1.2312 + // this thread's jvmti state was created during the scope of 1.2313 + // the event collector. 1.2314 + } 1.2315 + } else { 1.2316 + if (is_dynamic_code_event()) { 1.2317 + if (state->get_dynamic_code_event_collector() == this) { 1.2318 + state->set_dynamic_code_event_collector((JvmtiDynamicCodeEventCollector *)_prev); 1.2319 + } else { 1.2320 + // this thread's jvmti state was created during the scope of 1.2321 + // the event collector. 1.2322 + } 1.2323 + } 1.2324 + } 1.2325 + } 1.2326 +} 1.2327 + 1.2328 +// create the dynamic code event collector 1.2329 +JvmtiDynamicCodeEventCollector::JvmtiDynamicCodeEventCollector() : _code_blobs(NULL) { 1.2330 + if (JvmtiExport::should_post_dynamic_code_generated()) { 1.2331 + setup_jvmti_thread_state(); 1.2332 + } 1.2333 +} 1.2334 + 1.2335 +// iterate over any code blob descriptors collected and post a 1.2336 +// DYNAMIC_CODE_GENERATED event to the profiler. 1.2337 +JvmtiDynamicCodeEventCollector::~JvmtiDynamicCodeEventCollector() { 1.2338 + assert(!JavaThread::current()->owns_locks(), "all locks must be released to post deferred events"); 1.2339 + // iterate over any code blob descriptors that we collected 1.2340 + if (_code_blobs != NULL) { 1.2341 + for (int i=0; i<_code_blobs->length(); i++) { 1.2342 + JvmtiCodeBlobDesc* blob = _code_blobs->at(i); 1.2343 + JvmtiExport::post_dynamic_code_generated(blob->name(), blob->code_begin(), blob->code_end()); 1.2344 + FreeHeap(blob); 1.2345 + } 1.2346 + delete _code_blobs; 1.2347 + } 1.2348 + unset_jvmti_thread_state(); 1.2349 +} 1.2350 + 1.2351 +// register a stub 1.2352 +void JvmtiDynamicCodeEventCollector::register_stub(const char* name, address start, address end) { 1.2353 + if (_code_blobs == NULL) { 1.2354 + _code_blobs = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiCodeBlobDesc*>(1,true); 1.2355 + } 1.2356 + _code_blobs->append(new JvmtiCodeBlobDesc(name, start, end)); 1.2357 +} 1.2358 + 1.2359 +// Setup current thread to record vm allocated objects. 1.2360 +JvmtiVMObjectAllocEventCollector::JvmtiVMObjectAllocEventCollector() : _allocated(NULL) { 1.2361 + if (JvmtiExport::should_post_vm_object_alloc()) { 1.2362 + _enable = true; 1.2363 + setup_jvmti_thread_state(); 1.2364 + } else { 1.2365 + _enable = false; 1.2366 + } 1.2367 +} 1.2368 + 1.2369 +// Post vm_object_alloc event for vm allocated objects visible to java 1.2370 +// world. 1.2371 +JvmtiVMObjectAllocEventCollector::~JvmtiVMObjectAllocEventCollector() { 1.2372 + if (_allocated != NULL) { 1.2373 + set_enabled(false); 1.2374 + for (int i = 0; i < _allocated->length(); i++) { 1.2375 + oop obj = _allocated->at(i); 1.2376 + if (ServiceUtil::visible_oop(obj)) { 1.2377 + JvmtiExport::post_vm_object_alloc(JavaThread::current(), obj); 1.2378 + } 1.2379 + } 1.2380 + delete _allocated; 1.2381 + } 1.2382 + unset_jvmti_thread_state(); 1.2383 +} 1.2384 + 1.2385 +void JvmtiVMObjectAllocEventCollector::record_allocation(oop obj) { 1.2386 + assert(is_enabled(), "VM object alloc event collector is not enabled"); 1.2387 + if (_allocated == NULL) { 1.2388 + _allocated = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(1, true); 1.2389 + } 1.2390 + _allocated->push(obj); 1.2391 +} 1.2392 + 1.2393 +// GC support. 1.2394 +void JvmtiVMObjectAllocEventCollector::oops_do(OopClosure* f) { 1.2395 + if (_allocated != NULL) { 1.2396 + for(int i=_allocated->length() - 1; i >= 0; i--) { 1.2397 + if (_allocated->at(i) != NULL) { 1.2398 + f->do_oop(_allocated->adr_at(i)); 1.2399 + } 1.2400 + } 1.2401 + } 1.2402 +} 1.2403 + 1.2404 +void JvmtiVMObjectAllocEventCollector::oops_do_for_all_threads(OopClosure* f) { 1.2405 + // no-op if jvmti not enabled 1.2406 + if (!JvmtiEnv::environments_might_exist()) { 1.2407 + return; 1.2408 + } 1.2409 + 1.2410 + // Runs at safepoint. So no need to acquire Threads_lock. 1.2411 + for (JavaThread *jthr = Threads::first(); jthr != NULL; jthr = jthr->next()) { 1.2412 + JvmtiThreadState *state = jthr->jvmti_thread_state(); 1.2413 + if (state != NULL) { 1.2414 + JvmtiVMObjectAllocEventCollector *collector; 1.2415 + collector = state->get_vm_object_alloc_event_collector(); 1.2416 + while (collector != NULL) { 1.2417 + collector->oops_do(f); 1.2418 + collector = (JvmtiVMObjectAllocEventCollector *)collector->get_prev(); 1.2419 + } 1.2420 + } 1.2421 + } 1.2422 +} 1.2423 + 1.2424 + 1.2425 +// Disable collection of VMObjectAlloc events 1.2426 +NoJvmtiVMObjectAllocMark::NoJvmtiVMObjectAllocMark() : _collector(NULL) { 1.2427 + // a no-op if VMObjectAlloc event is not enabled 1.2428 + if (!JvmtiExport::should_post_vm_object_alloc()) { 1.2429 + return; 1.2430 + } 1.2431 + Thread* thread = ThreadLocalStorage::thread(); 1.2432 + if (thread != NULL && thread->is_Java_thread()) { 1.2433 + JavaThread* current_thread = (JavaThread*)thread; 1.2434 + JvmtiThreadState *state = current_thread->jvmti_thread_state(); 1.2435 + if (state != NULL) { 1.2436 + JvmtiVMObjectAllocEventCollector *collector; 1.2437 + collector = state->get_vm_object_alloc_event_collector(); 1.2438 + if (collector != NULL && collector->is_enabled()) { 1.2439 + _collector = collector; 1.2440 + _collector->set_enabled(false); 1.2441 + } 1.2442 + } 1.2443 + } 1.2444 +} 1.2445 + 1.2446 +// Re-Enable collection of VMObjectAlloc events (if previously enabled) 1.2447 +NoJvmtiVMObjectAllocMark::~NoJvmtiVMObjectAllocMark() { 1.2448 + if (was_enabled()) { 1.2449 + _collector->set_enabled(true); 1.2450 + } 1.2451 +}; 1.2452 + 1.2453 +JvmtiGCMarker::JvmtiGCMarker() { 1.2454 + // if there aren't any JVMTI environments then nothing to do 1.2455 + if (!JvmtiEnv::environments_might_exist()) { 1.2456 + return; 1.2457 + } 1.2458 + 1.2459 + if (JvmtiExport::should_post_garbage_collection_start()) { 1.2460 + JvmtiExport::post_garbage_collection_start(); 1.2461 + } 1.2462 + 1.2463 + if (SafepointSynchronize::is_at_safepoint()) { 1.2464 + // Do clean up tasks that need to be done at a safepoint 1.2465 + JvmtiEnvBase::check_for_periodic_clean_up(); 1.2466 + } 1.2467 +} 1.2468 + 1.2469 +JvmtiGCMarker::~JvmtiGCMarker() { 1.2470 + // if there aren't any JVMTI environments then nothing to do 1.2471 + if (!JvmtiEnv::environments_might_exist()) { 1.2472 + return; 1.2473 + } 1.2474 + 1.2475 + // JVMTI notify gc finish 1.2476 + if (JvmtiExport::should_post_garbage_collection_finish()) { 1.2477 + JvmtiExport::post_garbage_collection_finish(); 1.2478 + } 1.2479 +}