1 /*
2  * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  *
23  */
24 
25 #ifndef SHARE_UTILITIES_HISTOGRAM_HPP
26 #define SHARE_UTILITIES_HISTOGRAM_HPP
27 
28 #include "memory/allocation.hpp"
29 #include "runtime/os.hpp"
30 #include "utilities/growableArray.hpp"
31 
32 // This class provides a framework for collecting various statistics.
33 // The current implementation is oriented towards counting invocations
34 // of various types, but that can be easily changed.
35 //
36 // To use it, you need to declare a Histogram*, and a subtype of
37 // HistogramElement:
38 //
39 //  HistogramElement* MyHistogram;
40 //
41 //  class MyHistogramElement : public HistogramElement {
42 //    public:
43 //      MyHistogramElement(char* name);
44 //  };
45 //
46 //  MyHistogramElement::MyHistogramElement(char* elementName) {
47 //    _name = elementName;
48 //
49 //    if(MyHistogram == NULL)
50 //      MyHistogram = new Histogram("My Call Counts",100);
51 //
52 //    MyHistogram->add_element(this);
53 //  }
54 //
55 //  #define MyCountWrapper(arg) static MyHistogramElement* e = new MyHistogramElement(arg); e->increment_count()
56 //
57 // This gives you a simple way to count invocations of specfic functions:
58 //
59 // void a_function_that_is_being_counted() {
60 //   MyCountWrapper("FunctionName");
61 //   ...
62 // }
63 //
64 // To print the results, invoke print() on your Histogram*.
65 
66 #ifdef ASSERT
67 
68 class HistogramElement : public CHeapObj<mtInternal> {
69  protected:
70   jint _count;
71   const char* _name;
72 
73  public:
74   HistogramElement();
75   virtual int count();
76   virtual const char* name();
77   virtual void increment_count();
78   void print_on(outputStream* st) const;
79   virtual int compare(HistogramElement* e1,HistogramElement* e2);
80 };
81 
82 class Histogram : public CHeapObj<mtInternal> {
83  protected:
84   GrowableArray<HistogramElement*>* _elements;
elements()85   GrowableArray<HistogramElement*>* elements() { return _elements; }
86   const char* _title;
title()87   const char* title() { return _title; }
88   static int sort_helper(HistogramElement** e1,HistogramElement** e2);
89   virtual void print_header(outputStream* st);
90   virtual void print_elements(outputStream* st);
91 
92  public:
93   Histogram(const char* title,int estimatedSize);
94   virtual void add_element(HistogramElement* element);
95   void print_on(outputStream* st) const;
96 };
97 
98 #endif
99 
100 #endif // SHARE_UTILITIES_HISTOGRAM_HPP
101