/* Copyright (C) 2021 Free Software Foundation, Inc. Contributed by Oracle. This file is part of GNU Binutils. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _HIST_DATA_H #define _HIST_DATA_H // A Hist_data object is used to obtain data used for constructing // a histogram display. #include #include #include #include #include "dbe_structs.h" #include "Histable.h" #include "DerivedMetrics.h" class DbeLine; class MetricList; class Hist_data { public: friend class DbeView; friend class er_print_histogram; friend class PathTree; friend class DataSpace; friend class MemorySpace; friend class IOActivity; friend class HeapActivity; // HistItem contains all the data about a single histogram item. struct HistItem { HistItem (long n); ~HistItem (); Histable *obj; // info on the object int type; // annotated src/dis: type TValue *value; // numeric values long size; }; enum Hist_status { SUCCESS = 0, NO_DATA }; enum Mode { ALL, CALLERS, CALLEES, SELF, MODL, LAYOUT, DETAIL }; enum Sort_order { ASCEND, DESCEND }; enum Sort_type { ALPHA, VALUE, AUX }; Hist_data (MetricList *, Histable::Type, Mode, bool _viewowned = false); virtual ~Hist_data (); void dump (char *msg, FILE *f); Hist_status get_status (void) { return status; } // Return the view ownership flag bool isViewOwned (void) { return viewowned; } // Return the total number of items long size (void); // Append a new HistItem for the specified Histable HistItem *append_hist_item (Histable *obj); void append_hist_item (HistItem *hi); TValue *get_real_value (TValue *res, int met_index, int row); TValue *get_value (TValue *res, int met_index, int row); TValue *get_value (TValue *res, int met_index, HistItem *hi); void print_row(StringBuilder *sb, int row, Metric::HistMetric *hist_metric, const char *mark); void print_content (FILE *out_file, Metric::HistMetric *hist_metric, int limit); int print_label (FILE *out_file, Metric::HistMetric *hist_metric, int space); void update_total (Hist_data::HistItem *new_total); void update_max (Metric::HistMetric *hm_tmp); void update_legend_width (Metric::HistMetric *hm_tmp); // Find an existing HistItem HistItem *find_hist_item (Histable *obj); // sort the data void sort (long ind, bool reverse); // resort the data, if metric sort or direction has changed void resort (MetricList *mlist); // compute minima and maxima void compute_minmax (void); // fetch() takes a hist item index and returns a ptr to the item HistItem *fetch (long index); HistItem * get_maximums (void) { return maximum; } HistItem * get_maximums_inc (void) { return maximum_inc; } HistItem * get_minimums (void) { return minimum; } HistItem * get_totals (void) { return total; } Vector * get_hist_items (void) { return hist_items; } void set_status (Hist_status st) { status = st; } MetricList * get_metric_list (void) { return metrics; } Map * get_callsite_mark () { return callsite_mark; } Metric::HistMetric *get_histmetrics (); void set_threshold (double proportion); bool above_threshold (HistItem *hi); double get_percentage (double value, int mindex); size_t value_maxlen (int mindex); // Return the drawing length size_t time_len (TValue *value, int clock); size_t time_maxlen (int mindex, int clock); size_t name_len (HistItem *item); size_t name_maxlen (); HistItem *new_hist_item (Histable *obj, int itype, TValue *value); HistItem *update_hist_item (HistItem *hi, TValue *value); Vector *get_object_indices (Vector *selections); private: Metric::HistMetric *hist_metrics; Vector *hist_items; // Actual histogram values HashMap*hi_map; // map: Histable -> HistItem Map*callsite_mark; Hist_status status; int nmetrics; // number of metrics MetricList *metrics; Histable::Type type; Sort_order sort_order; Sort_type sort_type; int sort_ind; bool rev_sort; // true if sort is reversed Mode mode; HistItem *gprof_item; // used for gprof-style info Histable *spontaneous; // Private state variables HistItem *maximum; HistItem *minimum; HistItem *maximum_inc; HistItem *total; HistItem *threshold; // Perform the sort operation with this function static int sort_compare_all (const void *a, const void *b, const void *arg); static int sort_compare_dlayout (const void *a, const void *b, const void *arg); static int sort_compare (HistItem *hi_1, HistItem *hi_2, Sort_type stype, long ind, Hist_data *hdata); // Allocate a new structure of dynamic size HistItem *new_hist_item (Histable *obj); // Flag indicating whether or not the Hist_data structure // is owned by a DbeView, which has responsibility for // deleting it, or not, in which case the last user deletes it. // XXX this is very ugly, and arises from the inconsistent handling // XXX of the Hist_data structure in various bits of code. bool viewowned; }; // This structure is destined to merge with Hist_data. // We currently use it to present callstack data such as // leak and allocation lists. class DbeInstr; struct CStack_data { struct CStack_item { CStack_item (long n); ~CStack_item (); long count; int64_t val; Vector *stack; TValue *value; // numeric values }; Vector *cstack_items; CStack_item *total; CStack_item *new_cstack_item (); CStack_data (MetricList *); long size () { return cstack_items->size (); } CStack_item * fetch (long i) { return cstack_items->fetch (i); } ~CStack_data () { cstack_items->destroy (); delete cstack_items; delete total; } MetricList *metrics; }; #endif /* _HIST_DATA_H */