diff src/share/vm/services/memTrackWorker.cpp @ 7464:ecd24264898b

8005048: NMT: #loaded classes needs to just show the # defined classes Summary: Count number of instance classes so that it matches class metadata size Reviewed-by: coleenp, acorn
author zgu
date Tue, 08 Jan 2013 14:04:25 -0500
parents 33143ee07800
children 4102b59539ce
line wrap: on
line diff
--- a/src/share/vm/services/memTrackWorker.cpp	Fri Dec 07 10:55:16 2012 -0800
+++ b/src/share/vm/services/memTrackWorker.cpp	Tue Jan 08 14:04:25 2013 -0500
@@ -29,6 +29,16 @@
 #include "utilities/decoder.hpp"
 #include "utilities/vmError.hpp"
 
+
+void GenerationData::reset() {
+  _number_of_classes = 0;
+  while (_recorder_list != NULL) {
+    MemRecorder* tmp = _recorder_list;
+    _recorder_list = _recorder_list->next();
+    MemTracker::release_thread_recorder(tmp);
+  }
+}
+
 MemTrackWorker::MemTrackWorker() {
   // create thread uses cgc thread type for now. We should revisit
   // the option, or create new thread type.
@@ -39,7 +49,7 @@
   if (!has_error()) {
     _head = _tail = 0;
     for(int index = 0; index < MAX_GENERATIONS; index ++) {
-      _gen[index] = NULL;
+      ::new ((void*)&_gen[index]) GenerationData();
     }
   }
   NOT_PRODUCT(_sync_point_count = 0;)
@@ -49,10 +59,7 @@
 
 MemTrackWorker::~MemTrackWorker() {
   for (int index = 0; index < MAX_GENERATIONS; index ++) {
-    MemRecorder* rc = _gen[index];
-    if (rc != NULL) {
-      delete rc;
-    }
+    _gen[index].reset();
   }
 }
 
@@ -90,12 +97,7 @@
     {
       // take a recorder from earliest generation in buffer
       ThreadCritical tc;
-      rec = _gen[_head];
-      if (rec != NULL) {
-        _gen[_head] = rec->next();
-      }
-      assert(count_recorder(_gen[_head]) <= MemRecorder::_instance_count,
-        "infinite loop after dequeue");
+      rec = _gen[_head].next_recorder();
     }
     if (rec != NULL) {
       // merge the recorder into staging area
@@ -109,16 +111,20 @@
       // no more recorder to merge, promote staging area
       // to snapshot
       if (_head != _tail) {
+        long number_of_classes;
         {
           ThreadCritical tc;
-          if (_gen[_head] != NULL || _head == _tail) {
+          if (_gen[_head].has_more_recorder() || _head == _tail) {
             continue;
           }
+          number_of_classes = _gen[_head].number_of_classes();
+          _gen[_head].reset();
+
           // done with this generation, increment _head pointer
           _head = (_head + 1) % MAX_GENERATIONS;
         }
         // promote this generation data to snapshot
-        if (!snapshot->promote()) {
+        if (!snapshot->promote(number_of_classes)) {
           // failed to promote, means out of memory
           MemTracker::shutdown(MemTracker::NMT_out_of_memory);
         }
@@ -126,8 +132,8 @@
         snapshot->wait(1000);
         ThreadCritical tc;
         // check if more data arrived
-        if (_gen[_head] == NULL) {
-          _gen[_head] = MemTracker::get_pending_recorders();
+        if (!_gen[_head].has_more_recorder()) {
+          _gen[_head].add_recorders(MemTracker::get_pending_recorders());
         }
       }
     }
@@ -147,7 +153,7 @@
 //   1. add all recorders in pending queue to current generation
 //   2. increase generation
 
-void MemTrackWorker::at_sync_point(MemRecorder* rec) {
+void MemTrackWorker::at_sync_point(MemRecorder* rec, int number_of_classes) {
   NOT_PRODUCT(_sync_point_count ++;)
   assert(count_recorder(rec) <= MemRecorder::_instance_count,
     "pending queue has infinite loop");
@@ -155,23 +161,15 @@
   bool out_of_generation_buffer = false;
   // check shutdown state inside ThreadCritical
   if (MemTracker::shutdown_in_progress()) return;
+
+  _gen[_tail].set_number_of_classes(number_of_classes);
   // append the recorders to the end of the generation
-  if( rec != NULL) {
-    MemRecorder* cur_head = _gen[_tail];
-    if (cur_head == NULL) {
-      _gen[_tail] = rec;
-    } else {
-      while (cur_head->next() != NULL) {
-        cur_head = cur_head->next();
-      }
-      cur_head->set_next(rec);
-    }
-  }
-  assert(count_recorder(rec) <= MemRecorder::_instance_count,
+  _gen[_tail].add_recorders(rec);
+  assert(count_recorder(_gen[_tail].peek()) <= MemRecorder::_instance_count,
     "after add to current generation has infinite loop");
   // we have collected all recorders for this generation. If there is data,
   // we need to increment _tail to start a new generation.
-  if (_gen[_tail] != NULL || _head == _tail) {
+  if (_gen[_tail].has_more_recorder()  || _head == _tail) {
     _tail = (_tail + 1) % MAX_GENERATIONS;
     out_of_generation_buffer = (_tail == _head);
   }
@@ -194,7 +192,7 @@
 int MemTrackWorker::count_pending_recorders() const {
   int count = 0;
   for (int index = 0; index < MAX_GENERATIONS; index ++) {
-    MemRecorder* head = _gen[index];
+    MemRecorder* head = _gen[index].peek();
     if (head != NULL) {
       count += count_recorder(head);
     }