< prev index next >

src/hotspot/share/prims/jvmtiExport.cpp

Print this page
rev 49643 : [mq]: heap8
rev 49644 : [mq]: event_rebased
rev 49645 : [mq]: heap9
rev 49646 : [mq]: heap11
rev 49647 : [mq]: heap12
rev 49648 : [mq]: heap13

*** 1029,1044 **** } } return k; } ! class JvmtiVMObjectAllocEventMark : public JvmtiClassEventMark { private: jobject _jobj; jlong _size; public: ! JvmtiVMObjectAllocEventMark(JavaThread *thread, oop obj) : JvmtiClassEventMark(thread, oop_to_klass(obj)) { _jobj = (jobject)to_jobject(obj); _size = obj->size() * wordSize; }; jobject jni_jobject() { return _jobj; } jlong size() { return _size; } --- 1029,1044 ---- } } return k; } ! class JvmtiObjectAllocEventMark : public JvmtiClassEventMark { private: jobject _jobj; jlong _size; public: ! JvmtiObjectAllocEventMark(JavaThread *thread, oop obj) : JvmtiClassEventMark(thread, oop_to_klass(obj)) { _jobj = (jobject)to_jobject(obj); _size = obj->size() * wordSize; }; jobject jni_jobject() { return _jobj; } jlong size() { return _size; }
*** 1199,1208 **** --- 1199,1209 ---- bool JvmtiExport::_should_post_garbage_collection_start = false; bool JvmtiExport::_should_post_garbage_collection_finish = false; bool JvmtiExport::_should_post_object_free = false; bool JvmtiExport::_should_post_resource_exhausted = false; bool JvmtiExport::_should_post_vm_object_alloc = false; + bool JvmtiExport::_should_post_sampled_object_alloc = false; bool JvmtiExport::_should_post_on_exceptions = false; ////////////////////////////////////////////////////////////////////////////////////////////////
*** 2281,2291 **** // Can not take safepoint here. NoSafepointVerifier no_sfpt; // Can not take safepoint here so can not use state_for to get // jvmti thread state. JvmtiThreadState *state = ((JavaThread*)thread)->jvmti_thread_state(); ! if (state != NULL ) { // state is non NULL when VMObjectAllocEventCollector is enabled. JvmtiVMObjectAllocEventCollector *collector; collector = state->get_vm_object_alloc_event_collector(); if (collector != NULL && collector->is_enabled()) { // Don't record classes as these will be notified via the ClassLoad --- 2282,2292 ---- // Can not take safepoint here. NoSafepointVerifier no_sfpt; // Can not take safepoint here so can not use state_for to get // jvmti thread state. JvmtiThreadState *state = ((JavaThread*)thread)->jvmti_thread_state(); ! if (state != NULL) { // state is non NULL when VMObjectAllocEventCollector is enabled. JvmtiVMObjectAllocEventCollector *collector; collector = state->get_vm_object_alloc_event_collector(); if (collector != NULL && collector->is_enabled()) { // Don't record classes as these will be notified via the ClassLoad
*** 2296,2305 **** --- 2297,2336 ---- } } } } + // Collect all the vm internally allocated objects which are visible to java world + void JvmtiExport::record_sampled_internal_object_allocation(oop obj) { + Thread* thread = Thread::current_or_null(); + if (thread != NULL && thread->is_Java_thread()) { + // Can not take safepoint here. + NoSafepointVerifier no_sfpt; + // Can not take safepoint here so can not use state_for to get + // jvmti thread state. + JvmtiThreadState *state = ((JavaThread*)thread)->jvmti_thread_state(); + if (state != NULL) { + // check if there is a VM event collector, if there is defer to it. + // this allows both VM and Sampling collector to be enabled at the same. + JvmtiVMObjectAllocEventCollector *vm_collector; + vm_collector = state->get_vm_object_alloc_event_collector(); + + if (vm_collector != NULL && vm_collector->is_enabled()) { + return; + } + + // state is non NULL when SampledObjectAllocEventCollector is enabled. + JvmtiSampledObjectAllocEventCollector *collector; + collector = state->get_sampled_object_alloc_event_collector(); + + if (collector != NULL && collector->is_enabled()) { + collector->record_allocation(obj); + } + } + } + } + void JvmtiExport::post_garbage_collection_finish() { Thread *thread = Thread::current(); // this event is posted from VM-Thread. EVT_TRIG_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, ("[%s] garbage collection finish event triggered", JvmtiTrace::safe_get_thread_name(thread)));
*** 2485,2495 **** } } } } - void JvmtiExport::post_vm_object_alloc(JavaThread *thread, oop object) { EVT_TRIG_TRACE(JVMTI_EVENT_VM_OBJECT_ALLOC, ("[%s] Trg vm object alloc triggered", JvmtiTrace::safe_get_thread_name(thread))); if (object == NULL) { return; --- 2516,2525 ----
*** 2501,2521 **** if (env->is_enabled(JVMTI_EVENT_VM_OBJECT_ALLOC)) { EVT_TRACE(JVMTI_EVENT_VM_OBJECT_ALLOC, ("[%s] Evt vmobject alloc sent %s", JvmtiTrace::safe_get_thread_name(thread), object==NULL? "NULL" : object->klass()->external_name())); ! JvmtiVMObjectAllocEventMark jem(thread, h()); JvmtiJavaThreadEventTransition jet(thread); jvmtiEventVMObjectAlloc callback = env->callbacks()->VMObjectAlloc; if (callback != NULL) { (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_jobject(), jem.jni_class(), jem.size()); } } } } //////////////////////////////////////////////////////////////////////////////////////////////// void JvmtiExport::cleanup_thread(JavaThread* thread) { assert(JavaThread::current() == thread, "thread is not current"); MutexLocker mu(JvmtiThreadState_lock); --- 2531,2588 ---- if (env->is_enabled(JVMTI_EVENT_VM_OBJECT_ALLOC)) { EVT_TRACE(JVMTI_EVENT_VM_OBJECT_ALLOC, ("[%s] Evt vmobject alloc sent %s", JvmtiTrace::safe_get_thread_name(thread), object==NULL? "NULL" : object->klass()->external_name())); ! JvmtiObjectAllocEventMark jem(thread, h()); JvmtiJavaThreadEventTransition jet(thread); jvmtiEventVMObjectAlloc callback = env->callbacks()->VMObjectAlloc; if (callback != NULL) { (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_jobject(), jem.jni_class(), jem.size()); } } } } + void JvmtiExport::post_sampled_object_alloc(JavaThread *thread, oop object) { + EVT_TRIG_TRACE(JVMTI_EVENT_SAMPLED_OBJECT_ALLOC, + ("[%s] Trg sampled object alloc triggered", + JvmtiTrace::safe_get_thread_name(thread))); + if (object == NULL) { + return; + } + + JvmtiThreadState *state = thread->jvmti_thread_state(); + if (state == NULL) { + return; + } + + HandleMark hm(thread); + Handle h(thread, object); + JvmtiObjectAllocEventMark jem(thread, h()); + JvmtiEnvThreadStateIterator it(state); + for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { + if (ets->is_enabled(JVMTI_EVENT_SAMPLED_OBJECT_ALLOC)) { + JvmtiEnvIterator it; + for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { + JvmtiThreadEventTransition jet(thread); + + jvmtiEventSampledObjectAlloc callback = env->callbacks()->SampledObjectAlloc; + if (callback != NULL) { + (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), + jem.jni_jobject(), jem.jni_class(), jem.size()); + EVT_TRACE(JVMTI_EVENT_SAMPLED_OBJECT_ALLOC, + ("[%s] Evt sampled object alloc sent %s", + JvmtiTrace::safe_get_thread_name(thread), + object == NULL ? "NULL" : object->klass()->external_name())); + } + } + } + } + } + //////////////////////////////////////////////////////////////////////////////////////////////// void JvmtiExport::cleanup_thread(JavaThread* thread) { assert(JavaThread::current() == thread, "thread is not current"); MutexLocker mu(JvmtiThreadState_lock);
*** 2537,2547 **** } } void JvmtiExport::oops_do(OopClosure* f) { JvmtiCurrentBreakpoints::oops_do(f); ! JvmtiVMObjectAllocEventCollector::oops_do_for_all_threads(f); } void JvmtiExport::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) { JvmtiTagMap::weak_oops_do(is_alive, f); } --- 2604,2614 ---- } } void JvmtiExport::oops_do(OopClosure* f) { JvmtiCurrentBreakpoints::oops_do(f); ! JvmtiObjectAllocEventCollector::oops_do_for_all_threads(f); } void JvmtiExport::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) { JvmtiTagMap::weak_oops_do(is_alive, f); }
*** 2670,2679 **** --- 2737,2749 ---- _prev = state->get_vm_object_alloc_event_collector(); state->set_vm_object_alloc_event_collector((JvmtiVMObjectAllocEventCollector *)this); } else if (is_dynamic_code_event()) { _prev = state->get_dynamic_code_event_collector(); state->set_dynamic_code_event_collector((JvmtiDynamicCodeEventCollector *)this); + } else if (is_sampled_object_alloc_event()) { + _prev = state->get_sampled_object_alloc_event_collector(); + state->set_sampled_object_alloc_event_collector((JvmtiSampledObjectAllocEventCollector*)this); } } // Unset current event collection in this thread and reset it with previous // collector.
*** 2686,2703 **** state->set_vm_object_alloc_event_collector((JvmtiVMObjectAllocEventCollector *)_prev); } else { // this thread's jvmti state was created during the scope of // the event collector. } ! } else { ! if (is_dynamic_code_event()) { if (state->get_dynamic_code_event_collector() == this) { state->set_dynamic_code_event_collector((JvmtiDynamicCodeEventCollector *)_prev); } else { // this thread's jvmti state was created during the scope of // the event collector. } } } } } --- 2756,2778 ---- state->set_vm_object_alloc_event_collector((JvmtiVMObjectAllocEventCollector *)_prev); } else { // this thread's jvmti state was created during the scope of // the event collector. } ! } else if (is_dynamic_code_event()) { if (state->get_dynamic_code_event_collector() == this) { state->set_dynamic_code_event_collector((JvmtiDynamicCodeEventCollector *)_prev); } else { // this thread's jvmti state was created during the scope of // the event collector. } + } else if (is_sampled_object_alloc_event()) { + if (state->get_sampled_object_alloc_event_collector() == this) { + state->set_sampled_object_alloc_event_collector((JvmtiSampledObjectAllocEventCollector*)_prev); + } else { + // this thread's jvmti state was created during the scope of + // the event collector. } } } }
*** 2731,2796 **** } _code_blobs->append(new JvmtiCodeBlobDesc(name, start, end)); } // Setup current thread to record vm allocated objects. ! JvmtiVMObjectAllocEventCollector::JvmtiVMObjectAllocEventCollector() : _allocated(NULL) { ! if (JvmtiExport::should_post_vm_object_alloc()) { ! _enable = true; ! setup_jvmti_thread_state(); ! } else { ! _enable = false; ! } } // Post vm_object_alloc event for vm allocated objects visible to java // world. ! JvmtiVMObjectAllocEventCollector::~JvmtiVMObjectAllocEventCollector() { if (_allocated != NULL) { set_enabled(false); ! for (int i = 0; i < _allocated->length(); i++) { oop obj = _allocated->at(i); ! JvmtiExport::post_vm_object_alloc(JavaThread::current(), obj); } ! delete _allocated; } - unset_jvmti_thread_state(); } ! void JvmtiVMObjectAllocEventCollector::record_allocation(oop obj) { ! assert(is_enabled(), "VM object alloc event collector is not enabled"); if (_allocated == NULL) { _allocated = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(1, true); } _allocated->push(obj); } // GC support. ! void JvmtiVMObjectAllocEventCollector::oops_do(OopClosure* f) { ! if (_allocated != NULL) { ! for(int i=_allocated->length() - 1; i >= 0; i--) { if (_allocated->at(i) != NULL) { f->do_oop(_allocated->adr_at(i)); } } } } ! void JvmtiVMObjectAllocEventCollector::oops_do_for_all_threads(OopClosure* f) { // no-op if jvmti not enabled if (!JvmtiEnv::environments_might_exist()) { return; } for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jthr = jtiwh.next(); ) { JvmtiThreadState *state = jthr->jvmti_thread_state(); if (state != NULL) { ! JvmtiVMObjectAllocEventCollector *collector; collector = state->get_vm_object_alloc_event_collector(); while (collector != NULL) { collector->oops_do(f); ! collector = (JvmtiVMObjectAllocEventCollector *)collector->get_prev(); } } } } --- 2806,2872 ---- } _code_blobs->append(new JvmtiCodeBlobDesc(name, start, end)); } // Setup current thread to record vm allocated objects. ! JvmtiObjectAllocEventCollector::JvmtiObjectAllocEventCollector() : ! _allocated(NULL), _enable(false), _post_callback(NULL) { } // Post vm_object_alloc event for vm allocated objects visible to java // world. ! void JvmtiObjectAllocEventCollector::generate_call_for_allocated() { if (_allocated != NULL) { set_enabled(false); ! ! for (int i = 0; _allocated && i < _allocated->length(); i++) { oop obj = _allocated->at(i); ! _post_callback(JavaThread::current(), obj); } ! delete _allocated, _allocated = NULL; } } ! void JvmtiObjectAllocEventCollector::record_allocation(oop obj) { ! assert(is_enabled(), "Object alloc event collector is not enabled"); if (_allocated == NULL) { _allocated = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(1, true); } _allocated->push(obj); } // GC support. ! void JvmtiObjectAllocEventCollector::oops_do(OopClosure* f) { ! if (_perform_oops_do && _allocated != NULL) { ! for(int i = _allocated->length() - 1; i >= 0; i--) { if (_allocated->at(i) != NULL) { f->do_oop(_allocated->adr_at(i)); } } } } ! void JvmtiObjectAllocEventCollector::oops_do_for_all_threads(OopClosure* f) { // no-op if jvmti not enabled if (!JvmtiEnv::environments_might_exist()) { return; } for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jthr = jtiwh.next(); ) { JvmtiThreadState *state = jthr->jvmti_thread_state(); if (state != NULL) { ! JvmtiObjectAllocEventCollector *collector; collector = state->get_vm_object_alloc_event_collector(); while (collector != NULL) { collector->oops_do(f); ! collector = (JvmtiObjectAllocEventCollector*) collector->get_prev(); ! } ! ! collector = state->get_sampled_object_alloc_event_collector(); ! while (collector != NULL) { ! collector->oops_do(f); ! collector = (JvmtiObjectAllocEventCollector*) collector->get_prev(); } } } }
*** 2821,2830 **** --- 2897,2962 ---- if (was_enabled()) { _collector->set_enabled(true); } }; + // Setup current thread to record vm allocated objects. + JvmtiVMObjectAllocEventCollector::JvmtiVMObjectAllocEventCollector() { + if (JvmtiExport::should_post_vm_object_alloc()) { + _enable = true; + _perform_oops_do = true; + _post_callback = JvmtiExport::post_vm_object_alloc; + setup_jvmti_thread_state(); + } + } + + JvmtiVMObjectAllocEventCollector::~JvmtiVMObjectAllocEventCollector() { + generate_call_for_allocated(); + unset_jvmti_thread_state(); + } + + // Setup current thread to record sampled allocated objects. + JvmtiSampledObjectAllocEventCollector::JvmtiSampledObjectAllocEventCollector() { + if (JvmtiExport::should_post_sampled_object_alloc()) { + _enable = true; + // In the case of the sampled object collector, we don't want to perform the + // oops_do because the object in the collector is still stored in registers + // on the VM stack. + _perform_oops_do = false; + _post_callback = JvmtiExport::post_sampled_object_alloc; + setup_jvmti_thread_state(); + } + // Set the sampling collector as present in assertion mode only. + assert(JavaThread::current()->heap_sampler().add_sampling_collector(), + "Should never return false."); + } + + JvmtiSampledObjectAllocEventCollector::~JvmtiSampledObjectAllocEventCollector() { + // Note: we set ourselves in the thread state only if we should post but + // always unset in case the user has disabled the posting but we were set. + unset_jvmti_thread_state(); + // Set the sampling collector as present in assertion mode only. + assert(JavaThread::current()->heap_sampler().remove_sampling_collector(), + "Should never return false."); + } + + oop JvmtiSampledObjectAllocEventCollector::post_event(oop obj) { + if (JvmtiExport::should_post_sampled_object_alloc()) { + if (_allocated) { + // There should only be one object in this collector. + assert(_allocated->length() == 1, "Should only be an object in the collector"); + oop obj = _allocated->at(0); + JavaThread* thread = JavaThread::current(); + HandleMark hm(thread); + Handle handle(thread, (oop) obj); + _post_callback(JavaThread::current(), obj); + return handle(); + } + } + return obj; + } + JvmtiGCMarker::JvmtiGCMarker() { // if there aren't any JVMTI environments then nothing to do if (!JvmtiEnv::environments_might_exist()) { return; }
< prev index next >