< prev index next >

src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegionCounters.cpp

Print this page
rev 9501 : [backport] Update ShenandoahHeapSampling to avoid double counting.
rev 9504 : [backport] Implement early update references phase.
rev 9514 : [backport] Update region sampling to include TLAB/GCLAB allocation data
rev 9515 : [backport] Region sampling may not be enabled because last timetick is uninitialized
rev 9547 : [backport] Trim down native GC footprint
rev 9560 : [backport] Account "shared" out-of-LAB allocations separately


  11  * version 2 for more details (a copy is included in the LICENSE file that
  12  * accompanied this code).
  13  *
  14  * You should have received a copy of the GNU General Public License version
  15  * 2 along with this work; if not, write to the Free Software Foundation,
  16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  17  *
  18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  19  * or visit www.oracle.com if you need additional information or have any
  20  * questions.
  21  *
  22  */
  23 
  24 #include "precompiled.hpp"
  25 #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp"
  26 #include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp"
  27 #include "gc_implementation/shenandoah/shenandoahHeapRegionSet.hpp"
  28 #include "gc_implementation/shenandoah/shenandoahHeapRegionCounters.hpp"
  29 #include "runtime/perfData.hpp"
  30 
  31 ShenandoahHeapRegionCounters::ShenandoahHeapRegionCounters() {
  32 
  33   if (UsePerfData) {

  34     EXCEPTION_MARK;
  35     ResourceMark rm;
  36     ShenandoahHeap* heap = ShenandoahHeap::heap();
  37     size_t max_regions = heap->max_regions();
  38     const char* cns = PerfDataManager::name_space("shenandoah", "regions");
  39     _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtGC);
  40     strcpy(_name_space, cns);
  41 
  42     const char* cname = PerfDataManager::counter_name(_name_space, "timestamp");
  43     _timestamp = PerfDataManager::create_long_variable(SUN_GC, cname, PerfData::U_None, CHECK);
  44 
  45     cname = PerfDataManager::counter_name(_name_space, "max_regions");
  46     PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_None, max_regions, CHECK);
  47 
  48     cname = PerfDataManager::counter_name(_name_space, "region_size");
  49     PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_None, ShenandoahHeapRegion::region_size_bytes() >> 10, CHECK);
  50 
  51     cname = PerfDataManager::counter_name(_name_space, "status");
  52     _status = PerfDataManager::create_long_variable(SUN_GC, cname,
  53                                                     PerfData::U_None, CHECK);
  54 
  55     _regions_data = NEW_C_HEAP_ARRAY(PerfVariable*, max_regions, mtGC);
  56     for (uint i = 0; i < max_regions; i++) {
  57       const char* reg_name = PerfDataManager::name_space(_name_space, "region", i);
  58       const char* data_name = PerfDataManager::counter_name(reg_name, "data");
  59       const char* ns = PerfDataManager::ns_to_string(SUN_GC);
  60       const char* fullname = PerfDataManager::counter_name(ns, data_name);
  61       assert(!PerfDataManager::exists(fullname), "must not exist");
  62       _regions_data[i] = PerfDataManager::create_long_variable(SUN_GC, data_name,
  63                                                                PerfData::U_None, CHECK);
  64 
  65     }
  66   }
  67 }
  68 
  69 ShenandoahHeapRegionCounters::~ShenandoahHeapRegionCounters() {
  70   if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtGC);
  71 }
  72 
  73 void ShenandoahHeapRegionCounters::update() {
  74   if (ShenandoahRegionSampling) {
  75     jlong current = os::javaTimeMillis();
  76     if (current - _last_sample_millis > ShenandoahRegionSamplingRate) {



  77       ShenandoahHeap* heap = ShenandoahHeap::heap();
  78       jlong status = 0;
  79       if (heap->concurrent_mark_in_progress()) status |= 1;
  80       if (heap->is_evacuation_in_progress()) status |= 2;

  81       _status->set_value(status);
  82 
  83       _timestamp->set_value(os::elapsed_counter());
  84 
  85       size_t num_regions = heap->num_regions();
  86       size_t max_regions = heap->max_regions();
  87       ShenandoahHeapRegionSet* regions = heap->regions();

  88       for (uint i = 0; i < max_regions; i++) {
  89         if (i < num_regions) {
  90           ShenandoahHeapRegion* r = regions->get(i);
  91           jlong data = ((r->used() >> 10) & USED_MASK) << USED_SHIFT;
  92           data |= ((r->get_live_data_bytes() >> 10) & LIVE_MASK) << LIVE_SHIFT;




  93           jlong flags = 0;
  94           if (r->in_collection_set())     flags |= 1 << 1;
  95           if (r->is_humongous())          flags |= 1 << 2;
  96           if (r->is_recently_allocated()) flags |= 1 << 3;
  97           if (r->is_pinned())             flags |= 1 << 4;
  98           data |= (flags & FLAGS_MASK) << FLAGS_SHIFT;
  99           _regions_data[i]->set_value(data);
 100         } else {
 101           jlong flags = 1 << 0;
 102           flags = (flags & FLAGS_MASK) << FLAGS_SHIFT;
 103           _regions_data[i]->set_value(flags);
 104         }
 105       }
 106       _last_sample_millis = current;
 107     }
 108   }
 109 }


  11  * version 2 for more details (a copy is included in the LICENSE file that
  12  * accompanied this code).
  13  *
  14  * You should have received a copy of the GNU General Public License version
  15  * 2 along with this work; if not, write to the Free Software Foundation,
  16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  17  *
  18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  19  * or visit www.oracle.com if you need additional information or have any
  20  * questions.
  21  *
  22  */
  23 
  24 #include "precompiled.hpp"
  25 #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp"
  26 #include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp"
  27 #include "gc_implementation/shenandoah/shenandoahHeapRegionSet.hpp"
  28 #include "gc_implementation/shenandoah/shenandoahHeapRegionCounters.hpp"
  29 #include "runtime/perfData.hpp"
  30 
  31 ShenandoahHeapRegionCounters::ShenandoahHeapRegionCounters() :
  32   _last_sample_millis(0)
  33 {
  34   if (UsePerfData && ShenandoahRegionSampling) {
  35     EXCEPTION_MARK;
  36     ResourceMark rm;
  37     ShenandoahHeap* heap = ShenandoahHeap::heap();
  38     size_t max_regions = heap->max_regions();
  39     const char* cns = PerfDataManager::name_space("shenandoah", "regions");
  40     _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtGC);
  41     strcpy(_name_space, cns);
  42 
  43     const char* cname = PerfDataManager::counter_name(_name_space, "timestamp");
  44     _timestamp = PerfDataManager::create_long_variable(SUN_GC, cname, PerfData::U_None, CHECK);
  45 
  46     cname = PerfDataManager::counter_name(_name_space, "max_regions");
  47     PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_None, max_regions, CHECK);
  48 
  49     cname = PerfDataManager::counter_name(_name_space, "region_size");
  50     PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_None, ShenandoahHeapRegion::region_size_bytes() >> 10, CHECK);
  51 
  52     cname = PerfDataManager::counter_name(_name_space, "status");
  53     _status = PerfDataManager::create_long_variable(SUN_GC, cname,
  54                                                     PerfData::U_None, CHECK);
  55 
  56     _regions_data = NEW_C_HEAP_ARRAY(PerfVariable*, max_regions, mtGC);
  57     for (uint i = 0; i < max_regions; i++) {
  58       const char* reg_name = PerfDataManager::name_space(_name_space, "region", i);
  59       const char* data_name = PerfDataManager::counter_name(reg_name, "data");
  60       const char* ns = PerfDataManager::ns_to_string(SUN_GC);
  61       const char* fullname = PerfDataManager::counter_name(ns, data_name);
  62       assert(!PerfDataManager::exists(fullname), "must not exist");
  63       _regions_data[i] = PerfDataManager::create_long_variable(SUN_GC, data_name,
  64                                                                PerfData::U_None, CHECK);

  65     }
  66   }
  67 }
  68 
  69 ShenandoahHeapRegionCounters::~ShenandoahHeapRegionCounters() {
  70   if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtGC);
  71 }
  72 
  73 void ShenandoahHeapRegionCounters::update() {
  74   if (ShenandoahRegionSampling) {
  75     jlong current = os::javaTimeMillis();
  76     jlong last = _last_sample_millis;
  77     if (current - last > ShenandoahRegionSamplingRate &&
  78             Atomic::cmpxchg(current, &_last_sample_millis, last) == last) {
  79 
  80       ShenandoahHeap* heap = ShenandoahHeap::heap();
  81       jlong status = 0;
  82       if (heap->concurrent_mark_in_progress()) status |= 1 << 0;
  83       if (heap->is_evacuation_in_progress())   status |= 1 << 1;
  84       if (heap->is_update_refs_in_progress())  status |= 1 << 2;
  85       _status->set_value(status);
  86 
  87       _timestamp->set_value(os::elapsed_counter());
  88 
  89       size_t num_regions = heap->num_regions();
  90       size_t max_regions = heap->max_regions();
  91       ShenandoahHeapRegionSet* regions = heap->regions();
  92       size_t rs = ShenandoahHeapRegion::region_size_bytes();
  93       for (uint i = 0; i < max_regions; i++) {
  94         if (i < num_regions) {
  95           ShenandoahHeapRegion* r = regions->get(i);
  96           jlong data = 0;
  97           data |= ((100 * r->used() / rs)                & PERCENT_MASK) << USED_SHIFT;
  98           data |= ((100 * r->get_live_data_bytes() / rs) & PERCENT_MASK) << LIVE_SHIFT;
  99           data |= ((100 * r->get_tlab_allocs()  / rs)    & PERCENT_MASK) << TLAB_SHIFT;
 100           data |= ((100 * r->get_gclab_allocs() / rs)    & PERCENT_MASK) << GCLAB_SHIFT;
 101           data |= ((100 * r->get_shared_allocs() / rs)   & PERCENT_MASK) << SHARED_SHIFT;
 102           jlong flags = 0;
 103           if (r->in_collection_set())     flags |= 1 << 1;
 104           if (r->is_humongous())          flags |= 1 << 2;
 105           if (r->is_pinned())             flags |= 1 << 3;

 106           data |= (flags & FLAGS_MASK) << FLAGS_SHIFT;
 107           _regions_data[i]->set_value(data);
 108         } else {
 109           jlong flags = 1 << 0;
 110           flags = (flags & FLAGS_MASK) << FLAGS_SHIFT;
 111           _regions_data[i]->set_value(flags);
 112         }
 113       }

 114     }
 115   }
 116 }
< prev index next >