1.1 --- a/src/share/vm/services/memTrackWorker.cpp Fri Dec 07 10:55:16 2012 -0800 1.2 +++ b/src/share/vm/services/memTrackWorker.cpp Tue Jan 08 14:04:25 2013 -0500 1.3 @@ -29,6 +29,16 @@ 1.4 #include "utilities/decoder.hpp" 1.5 #include "utilities/vmError.hpp" 1.6 1.7 + 1.8 +void GenerationData::reset() { 1.9 + _number_of_classes = 0; 1.10 + while (_recorder_list != NULL) { 1.11 + MemRecorder* tmp = _recorder_list; 1.12 + _recorder_list = _recorder_list->next(); 1.13 + MemTracker::release_thread_recorder(tmp); 1.14 + } 1.15 +} 1.16 + 1.17 MemTrackWorker::MemTrackWorker() { 1.18 // create thread uses cgc thread type for now. We should revisit 1.19 // the option, or create new thread type. 1.20 @@ -39,7 +49,7 @@ 1.21 if (!has_error()) { 1.22 _head = _tail = 0; 1.23 for(int index = 0; index < MAX_GENERATIONS; index ++) { 1.24 - _gen[index] = NULL; 1.25 + ::new ((void*)&_gen[index]) GenerationData(); 1.26 } 1.27 } 1.28 NOT_PRODUCT(_sync_point_count = 0;) 1.29 @@ -49,10 +59,7 @@ 1.30 1.31 MemTrackWorker::~MemTrackWorker() { 1.32 for (int index = 0; index < MAX_GENERATIONS; index ++) { 1.33 - MemRecorder* rc = _gen[index]; 1.34 - if (rc != NULL) { 1.35 - delete rc; 1.36 - } 1.37 + _gen[index].reset(); 1.38 } 1.39 } 1.40 1.41 @@ -90,12 +97,7 @@ 1.42 { 1.43 // take a recorder from earliest generation in buffer 1.44 ThreadCritical tc; 1.45 - rec = _gen[_head]; 1.46 - if (rec != NULL) { 1.47 - _gen[_head] = rec->next(); 1.48 - } 1.49 - assert(count_recorder(_gen[_head]) <= MemRecorder::_instance_count, 1.50 - "infinite loop after dequeue"); 1.51 + rec = _gen[_head].next_recorder(); 1.52 } 1.53 if (rec != NULL) { 1.54 // merge the recorder into staging area 1.55 @@ -109,16 +111,20 @@ 1.56 // no more recorder to merge, promote staging area 1.57 // to snapshot 1.58 if (_head != _tail) { 1.59 + long number_of_classes; 1.60 { 1.61 ThreadCritical tc; 1.62 - if (_gen[_head] != NULL || _head == _tail) { 1.63 + if (_gen[_head].has_more_recorder() || _head == _tail) { 1.64 continue; 1.65 } 1.66 + number_of_classes = _gen[_head].number_of_classes(); 1.67 + _gen[_head].reset(); 1.68 + 1.69 // done with this generation, increment _head pointer 1.70 _head = (_head + 1) % MAX_GENERATIONS; 1.71 } 1.72 // promote this generation data to snapshot 1.73 - if (!snapshot->promote()) { 1.74 + if (!snapshot->promote(number_of_classes)) { 1.75 // failed to promote, means out of memory 1.76 MemTracker::shutdown(MemTracker::NMT_out_of_memory); 1.77 } 1.78 @@ -126,8 +132,8 @@ 1.79 snapshot->wait(1000); 1.80 ThreadCritical tc; 1.81 // check if more data arrived 1.82 - if (_gen[_head] == NULL) { 1.83 - _gen[_head] = MemTracker::get_pending_recorders(); 1.84 + if (!_gen[_head].has_more_recorder()) { 1.85 + _gen[_head].add_recorders(MemTracker::get_pending_recorders()); 1.86 } 1.87 } 1.88 } 1.89 @@ -147,7 +153,7 @@ 1.90 // 1. add all recorders in pending queue to current generation 1.91 // 2. increase generation 1.92 1.93 -void MemTrackWorker::at_sync_point(MemRecorder* rec) { 1.94 +void MemTrackWorker::at_sync_point(MemRecorder* rec, int number_of_classes) { 1.95 NOT_PRODUCT(_sync_point_count ++;) 1.96 assert(count_recorder(rec) <= MemRecorder::_instance_count, 1.97 "pending queue has infinite loop"); 1.98 @@ -155,23 +161,15 @@ 1.99 bool out_of_generation_buffer = false; 1.100 // check shutdown state inside ThreadCritical 1.101 if (MemTracker::shutdown_in_progress()) return; 1.102 + 1.103 + _gen[_tail].set_number_of_classes(number_of_classes); 1.104 // append the recorders to the end of the generation 1.105 - if( rec != NULL) { 1.106 - MemRecorder* cur_head = _gen[_tail]; 1.107 - if (cur_head == NULL) { 1.108 - _gen[_tail] = rec; 1.109 - } else { 1.110 - while (cur_head->next() != NULL) { 1.111 - cur_head = cur_head->next(); 1.112 - } 1.113 - cur_head->set_next(rec); 1.114 - } 1.115 - } 1.116 - assert(count_recorder(rec) <= MemRecorder::_instance_count, 1.117 + _gen[_tail].add_recorders(rec); 1.118 + assert(count_recorder(_gen[_tail].peek()) <= MemRecorder::_instance_count, 1.119 "after add to current generation has infinite loop"); 1.120 // we have collected all recorders for this generation. If there is data, 1.121 // we need to increment _tail to start a new generation. 1.122 - if (_gen[_tail] != NULL || _head == _tail) { 1.123 + if (_gen[_tail].has_more_recorder() || _head == _tail) { 1.124 _tail = (_tail + 1) % MAX_GENERATIONS; 1.125 out_of_generation_buffer = (_tail == _head); 1.126 } 1.127 @@ -194,7 +192,7 @@ 1.128 int MemTrackWorker::count_pending_recorders() const { 1.129 int count = 0; 1.130 for (int index = 0; index < MAX_GENERATIONS; index ++) { 1.131 - MemRecorder* head = _gen[index]; 1.132 + MemRecorder* head = _gen[index].peek(); 1.133 if (head != NULL) { 1.134 count += count_recorder(head); 1.135 }