1/* Copyright (C) 2021 Free Software Foundation, Inc.
2   Contributed by Oracle.
3
4   This file is part of GNU Binutils.
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 3, or (at your option)
9   any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, 51 Franklin Street - Fifth Floor, Boston,
19   MA 02110-1301, USA.  */
20
21#ifndef _HIST_DATA_H
22#define _HIST_DATA_H
23
24// A Hist_data object is used to obtain data used for constructing
25// a histogram display.
26
27#include <sys/types.h>
28
29#include <vec.h>
30#include <Map.h>
31#include <HashMap.h>
32
33#include "dbe_structs.h"
34#include "Histable.h"
35#include "DerivedMetrics.h"
36
37class DbeLine;
38class MetricList;
39
40class Hist_data
41{
42public:
43  friend class DbeView;
44  friend class er_print_histogram;
45  friend class PathTree;
46  friend class DataSpace;
47  friend class MemorySpace;
48  friend class IOActivity;
49  friend class HeapActivity;
50
51  // HistItem contains all the data about a single histogram item.
52  struct HistItem
53  {
54    HistItem (long n);
55    ~HistItem ();
56    Histable *obj;  // info on the object
57    int type;       // annotated src/dis: type
58    TValue *value;  // numeric values
59    long size;
60  };
61
62  enum Hist_status
63  {
64    SUCCESS = 0,
65    NO_DATA
66  };
67
68  enum Mode
69  {
70    ALL,
71    CALLERS,
72    CALLEES,
73    SELF,
74    MODL,
75    LAYOUT,
76    DETAIL
77  };
78
79  enum Sort_order
80  {
81    ASCEND,
82    DESCEND
83  };
84
85  enum Sort_type
86  {
87    ALPHA,
88    VALUE,
89    AUX
90  };
91
92  Hist_data (MetricList *, Histable::Type, Mode, bool _viewowned = false);
93
94  virtual ~Hist_data ();
95  void dump (char *msg, FILE *f);
96
97  Hist_status
98  get_status (void)
99  {
100    return status;
101  }
102
103  // Return the view ownership flag
104  bool
105  isViewOwned (void)
106  {
107    return viewowned;
108  }
109
110  // Return the total number of items
111  long size (void);
112
113  // Append a new HistItem for the specified Histable
114  HistItem *append_hist_item (Histable *obj);
115  void append_hist_item (HistItem *hi);
116  TValue *get_real_value (TValue *res, int met_index, int row);
117  TValue *get_value (TValue *res, int met_index, int row);
118  TValue *get_value (TValue *res, int met_index, HistItem *hi);
119  void print_row(StringBuilder *sb, int row, Metric::HistMetric *hist_metric,
120		 const char *mark);
121  void print_content (FILE *out_file, Metric::HistMetric *hist_metric, int limit);
122  int print_label (FILE *out_file, Metric::HistMetric *hist_metric, int space);
123  void update_total (Hist_data::HistItem *new_total);
124  void update_max (Metric::HistMetric *hm_tmp);
125  void update_legend_width (Metric::HistMetric *hm_tmp);
126
127  // Find an existing HistItem
128  HistItem *find_hist_item (Histable *obj);
129
130  // sort the data
131  void sort (long ind, bool reverse);
132
133  // resort the data, if metric sort or direction has changed
134  void resort (MetricList *mlist);
135
136  // compute minima and maxima
137  void compute_minmax (void);
138
139  // fetch() takes a hist item index and returns a ptr to the item
140  HistItem *fetch (long index);
141
142  HistItem *
143  get_maximums (void)
144  {
145    return maximum;
146  }
147
148  HistItem *
149  get_maximums_inc (void)
150  {
151    return maximum_inc;
152  }
153
154  HistItem *
155  get_minimums (void)
156  {
157    return minimum;
158  }
159
160  HistItem *
161  get_totals (void)
162  {
163    return total;
164  }
165
166  Vector<HistItem*> *
167  get_hist_items (void)
168  {
169    return hist_items;
170  }
171
172  void
173  set_status (Hist_status st)
174  {
175    status = st;
176  }
177
178  MetricList *
179  get_metric_list (void)
180  {
181    return metrics;
182  }
183
184  Map<Histable*, int> *
185  get_callsite_mark ()
186  {
187    return callsite_mark;
188  }
189
190  Metric::HistMetric *get_histmetrics ();
191  void set_threshold (double proportion);
192  bool above_threshold (HistItem *hi);
193  double get_percentage (double value, int mindex);
194  size_t value_maxlen (int mindex); // Return the drawing length
195  size_t time_len (TValue *value, int clock);
196  size_t time_maxlen (int mindex, int clock);
197  size_t name_len (HistItem *item);
198  size_t name_maxlen ();
199  HistItem *new_hist_item (Histable *obj, int itype, TValue *value);
200  HistItem *update_hist_item (HistItem *hi, TValue *value);
201  Vector<uint64_t> *get_object_indices (Vector<int> *selections);
202
203private:
204
205  Metric::HistMetric *hist_metrics;
206  Vector<HistItem*> *hist_items;        // Actual histogram values
207  HashMap<Histable*, HistItem*>*hi_map; // map: Histable -> HistItem
208  Map<Histable*, int>*callsite_mark;
209  Hist_status status;
210  int nmetrics;             // number of metrics
211  MetricList *metrics;
212  Histable::Type type;
213  Sort_order sort_order;
214  Sort_type sort_type;
215  int sort_ind;
216  bool rev_sort;            // true if sort is reversed
217
218  Mode mode;
219  HistItem *gprof_item;     // used for gprof-style info
220  Histable *spontaneous;
221
222  // Private state variables
223  HistItem *maximum;
224  HistItem *minimum;
225  HistItem *maximum_inc;
226  HistItem *total;
227  HistItem *threshold;
228
229  // Perform the sort operation with this function
230  static int sort_compare_all (const void *a, const void *b, const void *arg);
231  static int sort_compare_dlayout (const void *a, const void *b, const void *arg);
232  static int sort_compare (HistItem *hi_1, HistItem *hi_2, Sort_type stype,
233			   long ind, Hist_data *hdata);
234
235  // Allocate a new structure of dynamic size
236  HistItem *new_hist_item (Histable *obj);
237
238  // Flag indicating whether or not the Hist_data structure
239  //	is owned by a DbeView, which has responsibility for
240  //	deleting it, or not, in which case the last user deletes it.
241  //	XXX this is very ugly, and arises from the inconsistent handling
242  //	XXX of the Hist_data structure in various bits of code.
243  bool viewowned;
244};
245
246// This structure is destined to merge with Hist_data.
247// We currently use it to present callstack data such as
248// leak and allocation lists.
249
250class DbeInstr;
251
252struct CStack_data
253{
254
255  struct CStack_item
256  {
257    CStack_item (long n);
258    ~CStack_item ();
259    long count;
260    int64_t val;
261    Vector<DbeInstr*> *stack;
262    TValue *value;      // numeric values
263  };
264
265  Vector<CStack_item*> *cstack_items;
266  CStack_item *total;
267
268  CStack_item *new_cstack_item ();
269  CStack_data (MetricList *);
270
271  long
272  size ()
273  {
274    return cstack_items->size ();
275  }
276
277  CStack_item *
278  fetch (long i)
279  {
280    return cstack_items->fetch (i);
281  }
282
283  ~CStack_data ()
284  {
285    cstack_items->destroy ();
286    delete cstack_items;
287    delete total;
288  }
289
290  MetricList *metrics;
291};
292
293#endif /* _HIST_DATA_H */
294