1 /*
  2  * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
  3  *
  4  * This code is free software; you can redistribute it and/or modify it
  5  * under the terms of the GNU General Public License version 2 only, as
  6  * published by the Free Software Foundation.
  7  *
  8  * This code is distributed in the hope that it will be useful, but WITHOUT
  9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 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/epsilon/epsilonMonitoringSupport.hpp"
 26 #include "gc/epsilon/epsilonHeap.hpp"
 27 #include "gc/shared/generationCounters.hpp"
 28 #include "memory/allocation.hpp"
 29 #include "memory/allocation.inline.hpp"
 30 #include "memory/metaspaceCounters.hpp"
 31 #include "memory/resourceArea.hpp"
 32 #include "services/memoryService.hpp"
 33 
 34 class EpsilonSpaceCounters: public CHeapObj<mtGC> {
 35   friend class VMStructs;
 36 
 37 private:
 38   PerfVariable* _capacity;
 39   PerfVariable* _used;
 40   char*         _name_space;
 41 
 42 public:
 43   EpsilonSpaceCounters(const char* name,
 44                  int ordinal,
 45                  size_t max_size,
 46                  size_t initial_capacity,
 47                  GenerationCounters* gc) {
 48     if (UsePerfData) {
 49       EXCEPTION_MARK;
 50       ResourceMark rm;
 51 
 52       const char* cns = PerfDataManager::name_space(gc->name_space(), "space", ordinal);
 53 
 54       _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtGC);
 55       strcpy(_name_space, cns);
 56 
 57       const char* cname = PerfDataManager::counter_name(_name_space, "name");
 58       PerfDataManager::create_string_constant(SUN_GC, cname, name, CHECK);
 59 
 60       cname = PerfDataManager::counter_name(_name_space, "maxCapacity");
 61       PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes, (jlong)max_size, CHECK);
 62 
 63       cname = PerfDataManager::counter_name(_name_space, "capacity");
 64       _capacity = PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes, initial_capacity, CHECK);
 65 
 66       cname = PerfDataManager::counter_name(_name_space, "used");
 67       _used = PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes, (jlong) 0, CHECK);
 68 
 69       cname = PerfDataManager::counter_name(_name_space, "initCapacity");
 70       PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes, initial_capacity, CHECK);
 71     }
 72   }
 73 
 74   ~EpsilonSpaceCounters() {
 75     FREE_C_HEAP_ARRAY(char, _name_space);
 76   }
 77 
 78   inline void update_all(size_t capacity, size_t used) {
 79     _capacity->set_value(capacity);
 80     _used->set_value(used);
 81   }
 82 };
 83 
 84 class EpsilonGenerationCounters : public GenerationCounters {
 85 private:
 86   EpsilonHeap* _heap;
 87 public:
 88   EpsilonGenerationCounters(EpsilonHeap* heap) :
 89           GenerationCounters("Heap", 1, 1, 0, heap->max_capacity(), heap->capacity()),
 90           _heap(heap)
 91   {};
 92 
 93   virtual void update_all() {
 94     _current_size->set_value(_heap->capacity());
 95   }
 96 };
 97 
 98 EpsilonMonitoringSupport::EpsilonMonitoringSupport(EpsilonHeap* heap) {
 99   _heap_counters  = new EpsilonGenerationCounters(heap);
100   _space_counters = new EpsilonSpaceCounters("Heap", 0, heap->max_capacity(), 0, _heap_counters);
101 }
102 
103 void EpsilonMonitoringSupport::update_counters() {
104   MemoryService::track_memory_usage();
105 
106   if (UsePerfData) {
107     EpsilonHeap* heap = EpsilonHeap::heap();
108     size_t used = heap->used();
109     size_t capacity = heap->capacity();
110     _heap_counters->update_all();
111     _space_counters->update_all(capacity, used);
112     MetaspaceCounters::update_performance_counters();
113     CompressedClassSpaceCounters::update_performance_counters();
114   }
115 }
116