--- old/src/share/vm/services/memBaseline.cpp Thu May 16 16:29:30 2013 +++ new/src/share/vm/services/memBaseline.cpp Thu May 16 16:29:29 2013 @@ -23,9 +23,12 @@ */ #include "precompiled.hpp" #include "memory/allocation.hpp" +#include "runtime/safepoint.hpp" +#include "runtime/thread.hpp" #include "services/memBaseline.hpp" #include "services/memTracker.hpp" + MemType2Name MemBaseline::MemType2NameMap[NUMBER_OF_MEMORY_TYPE] = { {mtJavaHeap, "Java Heap"}, {mtClass, "Class"}, @@ -150,6 +153,15 @@ return true; } +// check if there is a safepoint in progress, if so, block the thread +// for the safepoint +void MemBaseline::check_safepoint(JavaThread* thr) { + if (SafepointSynchronize::is_synchronizing()) { + // grab and drop the SR_lock to honor the safepoint protocol + MutexLocker ml(thr->SR_lock()); + } +} + // baseline mmap'd memory records, generate overall summary and summaries by // memory types bool MemBaseline::baseline_vm_summary(const MemPointerArray* vm_records) { @@ -307,7 +319,7 @@ committed_rec->pc() != vm_ptr->pc()) { if (!_vm_map->append(vm_ptr)) { return false; - } + } committed_rec = (VMMemRegionEx*)_vm_map->at(_vm_map->length() - 1); } else { committed_rec->expand_region(vm_ptr->addr(), vm_ptr->size()); @@ -345,16 +357,27 @@ // baseline a snapshot. If summary_only = false, memory usages aggregated by // callsites are also baselined. +// The method call can be lengthy, especially when detail tracking info is +// requested. So the method checks for safepoint explicitly. bool MemBaseline::baseline(MemSnapshot& snapshot, bool summary_only) { - MutexLockerEx snapshot_locker(snapshot._lock, true); + Thread* THREAD = Thread::current(); + assert(THREAD->is_Java_thread(), "must be a JavaThread"); + MutexLocker snapshot_locker(snapshot._lock); reset(); - _baselined = baseline_malloc_summary(snapshot._alloc_ptrs) && - baseline_vm_summary(snapshot._vm_ptrs); + _baselined = baseline_malloc_summary(snapshot._alloc_ptrs); + if (_baselined) { + check_safepoint((JavaThread*)THREAD); + _baselined = baseline_vm_summary(snapshot._vm_ptrs); + } _number_of_classes = snapshot.number_of_classes(); if (!summary_only && MemTracker::track_callsite() && _baselined) { - _baselined = baseline_malloc_details(snapshot._alloc_ptrs) && - baseline_vm_details(snapshot._vm_ptrs); + check_safepoint((JavaThread*)THREAD); + _baselined = baseline_malloc_details(snapshot._alloc_ptrs); + if (_baselined) { + check_safepoint((JavaThread*)THREAD); + _baselined = baseline_vm_details(snapshot._vm_ptrs); + } } return _baselined; }