< 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 >