/* Copyright (C) 2021-2025 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.  */

#include "config.h"
#include <assert.h>

#include "util.h"
#include "DefaultMap.h"
#include "DbeSession.h"
#include "Experiment.h"
#include "DataObject.h"
#include "Function.h"
#include "Hist_data.h"
#include "Histable.h"
#include "MemObject.h"
#include "IndexObject.h"
#include "MetricList.h"
#include "Metric.h"
#include "Module.h"
#include "LoadObject.h"
#include "Settings.h"
#include "StringBuilder.h"
#include "ExpGroup.h"
#include "PathTree.h"
#include "DbeView.h"
#include "FileData.h"

Hist_data::HistItem::HistItem (long n)
{
  obj = NULL;
  type = 0;
  size = n;
  value = new TValue[n];
  memset (value, 0, sizeof (TValue) * n);
}

Hist_data::HistItem::~HistItem ()
{
  for (long i = 0; i < size; i++)
    if (value[i].tag == VT_LABEL)
      free (value[i].l);
  delete[] value;
}

long
Hist_data::size ()
{
  // If the data values have not been computed, do so
  // Return the total number of items
  return hist_items->size ();
}

Hist_data::HistItem *
Hist_data::fetch (long index)
{
  return (index < VecSize (hist_items)) ? hist_items->get (index) : NULL;
}

int
Hist_data::sort_compare (HistItem *hi_1, HistItem *hi_2, Sort_type stype,
			 long ind, Hist_data *hdata)
{
  // Sort the data depending upon order and type
  int result = 0;
  Histable::Type type = hi_1->obj->get_type ();
  if (stype == ALPHA)
    {
      if (type != Histable::MEMOBJ && type != Histable::INDEXOBJ
	      && type != Histable::IOACTVFD && type != Histable::IOACTFILE
	      && type != Histable::IOCALLSTACK)
	{
	  char *nm1 = hi_1->obj->get_name ();
	  char *nm2 = hi_2->obj->get_name ();
	  if (nm1 != NULL && nm2 != NULL)
	    result = strcoll (nm1, nm2);
	}
      else if (type == Histable::IOCALLSTACK || type == Histable::IOACTVFD
	       || type == Histable::IOACTFILE)
	{
	  uint64_t idx1, idx2;
	  idx1 = ((FileData *) (hi_1->obj))->get_index ();
	  idx2 = ((FileData *) (hi_2->obj))->get_index ();
	  if (idx1 < idx2)
	    result = -1;
	  else if (idx1 > idx2)
	    result = 1;
	  else
	    result = 0;
	}
      else
	{
	  // for memory and index objects, "alphabetic" is really by index
	  // <Total> has index -2, and always comes first
	  // <Unknown> has index -1, and always comes second.
	  uint64_t i1, i2;
	  bool needsStringCompare = false;
	  if (type == Histable::MEMOBJ)
	    {
	      i1 = ((MemObj *) (hi_1->obj))->get_index ();
	      i2 = ((MemObj *) (hi_2->obj))->get_index ();
	    }
	  else if (type == Histable::INDEXOBJ)
	    {
	      i1 = ((IndexObject *) (hi_1->obj))->get_index ();
	      i2 = ((IndexObject *) (hi_2->obj))->get_index ();
	      needsStringCompare =
		      ((IndexObject *) (hi_1->obj))->requires_string_sort ();
	    }
	  else
	    abort ();
	  if (i1 == (uint64_t) - 2)
	    result = -1;
	  else if (i2 == (uint64_t) - 2)
	    result = 1;
	  else if (i1 == (uint64_t) - 1)
	    result = -1;
	  else if (i2 == (uint64_t) - 1)
	    result = 1;
	  else if (needsStringCompare)
	    {
	      char *nm1 = hi_1->obj->get_name ();
	      char *nm2 = hi_2->obj->get_name ();
	      if (nm1 != NULL && nm2 != NULL)
		{
		  char nm1_lead = nm1[0];
		  char nm2_lead = nm2[0];
		  // put "(unknown)" and friends at end of list
		  if (nm1_lead == '(' && nm1_lead != nm2_lead)
		    result = 1;
		  else if (nm2_lead == '(' && nm1_lead != nm2_lead)
		    result = -1;
		  else
		    result = strcoll (nm1, nm2);
		}
	    }
	  if (result == 0)
	    { // matches, resolve by index
	      if (i1 < i2)
		result = -1;
	      else if (i1 > i2)
		result = 1;
	    }
	}
    }
  else if (stype == AUX)
    {
      switch (type)
	{
	case Histable::INSTR:
	  {
	    DbeInstr *instr1 = (DbeInstr*) hi_1->obj;
	    DbeInstr *instr2 = (DbeInstr*) hi_2->obj;
	    result = instr1 ? instr1->pc_cmp (instr2) : instr2 ? 1 : 0;
	    break;
	  }
	case Histable::LINE:
	  {
	    DbeLine *dbl1 = (DbeLine*) hi_1->obj;
	    DbeLine *dbl2 = (DbeLine*) hi_2->obj;
	    result = dbl1->line_cmp (dbl2);
	  }
	  break;
	default:
	  assert (0);
	}
    }
  else if (stype == VALUE)
    {
      Metric *m = hdata->get_metric_list ()->get (ind);
      if ((m->get_visbits () & (VAL_DELTA | VAL_RATIO)) != 0)
	{
	  TValue v1, v2;
	  int first_ind = hdata->hist_metrics[ind].indFirstExp;
	  if ((m->get_visbits () & VAL_DELTA) != 0)
	    {
	      v1.make_delta (hi_1->value + ind, hi_1->value + first_ind);
	      v2.make_delta (hi_2->value + ind, hi_2->value + first_ind);
	    }
	  else
	    {
	      v1.make_ratio (hi_1->value + ind, hi_1->value + first_ind);
	      v2.make_ratio (hi_2->value + ind, hi_2->value + first_ind);
	    }
	  result = v1.compare (&v2);
	}
      else
	result = hi_1->value[ind].compare (hi_2->value + ind);
    }
  return result;
}

int
Hist_data::sort_compare_all (const void *a, const void *b, const void *arg)
{
  HistItem *hi_1 = *((HistItem **) a);
  HistItem *hi_2 = *((HistItem **) b);

  Hist_data *hdata = (Hist_data*) arg;
  int result = sort_compare (hi_1, hi_2, hdata->sort_type, hdata->sort_ind, hdata);
  if (hdata->sort_order == DESCEND)
    result = -result;

  // Use the name as the 2d sort key (always ASCEND)
  // except for MemoryObjects and  IndexObjects, where the index is used
  // For the Alphabetic sort
  if (result == 0)
    {
      result = sort_compare (hi_1, hi_2, ALPHA, 0, NULL);
      if (result == 0)
	{
	  for (long i = 0, sz = hdata->metrics->size (); i < sz; i++)
	    {
	      Metric *m = hdata->metrics->get (i);
	      if (m->get_type () != Metric::ONAME)
		{
		  result = sort_compare (hi_1, hi_2, VALUE, i, hdata);
		  if (result != 0)
		    {
		      if (hdata->sort_order == DESCEND)
			result = -result;
		      break;
		    }
		}
	    }
	}
    }

  // Use the address as the 3d sort key
  // ( FUNCTION only, always ASCEND )
  if (result == 0 && hi_1->obj->get_type () == Histable::FUNCTION)
    {
      Function *f1 = (Function*) hi_1->obj;
      Function *f2 = (Function*) hi_2->obj;
      if (f1->get_addr () < f2->get_addr ())
	result = -1;
      else if (f1->get_addr () > f2->get_addr ())
	result = 1;
    }

  // Use the Histable id (ID of function, line, etc.) as the 4th sort key
  // Note that IDs are not guaranteed to be stable,
  if (result == 0)
    {
      if (hi_1->obj->id < hi_2->obj->id)
	result = -1;
      else if (hi_1->obj->id > hi_2->obj->id)
	result = 1;
    }

  if (result == 0)
    return result; // shouldn't happen in most cases; line allows for breakpoint
  if (hdata->rev_sort)
    result = -result;
  return result;
}

int
Hist_data::sort_compare_dlayout (const void *a, const void *b, const void *arg)
{
  assert ((a != (const void *) NULL));
  assert ((b != (const void *) NULL));
  HistItem *hi_1 = *((HistItem **) a);
  HistItem *hi_2 = *((HistItem **) b);
  DataObject * dobj1 = (DataObject *) (hi_1->obj);
  DataObject * dobj2 = (DataObject *) (hi_2->obj);
  DataObject * parent1 = dobj1->parent;
  DataObject * parent2 = dobj2->parent;

  Hist_data *hdata = (Hist_data*) arg;

  // are the two items members of the same object?
  if (parent1 == parent2)
    {
      // yes
      if (parent1)
	{
	  // and they have real parents...
	  if (parent1->get_typename ())
	    { // element
	      // use dobj1/dobj2 offset for sorting
	      uint64_t off1 = dobj1->get_offset ();
	      uint64_t off2 = dobj2->get_offset ();
	      if (off1 < off2)
		return -1;
	      if (off1 > off2)
		return 1;
	      return 0;
	    }
	}
    }
  else
    { // parents differ
      if (parent1)
	{
	  if (parent1 == dobj2)
	    // sorting an object and its parent: parent always first
	    return 1;
	  dobj1 = parent1;
	}
      if (parent2)
	{
	  if (parent2 == dobj1)
	    return -1;
	  dobj2 = parent2;
	}
    }
  //  Either two unknowns, or two scalars, or two parents
  hi_1 = hdata->hi_map->get (dobj1);
  hi_2 = hdata->hi_map->get (dobj2);
  return sort_compare_all ((const void*) &hi_1, (const void*) &hi_2, hdata);
}

Hist_data::Hist_data (MetricList *_metrics, Histable::Type _type,
		      Hist_data::Mode _mode, bool _viewowned)
{
  hist_items = new Vector<HistItem*>;
  metrics = _metrics;
  nmetrics = metrics->get_items ()->size ();
  type = _type;
  mode = _mode;
  gprof_item = new_hist_item (NULL);
  viewowned = _viewowned;
  sort_ind = -1;
  rev_sort = false;

  Histable *tobj = new Other;
  tobj->name = dbe_strdup (NTXT ("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
  minimum = new_hist_item (tobj);

  tobj = new Other;
  tobj->name = dbe_strdup (NTXT (""));
  maximum = new_hist_item (tobj);

  tobj = new Other;
  tobj->name = dbe_strdup (NTXT ("xxxxxxxxxxxxxxxxxxxxxx"));
  maximum_inc = new_hist_item (tobj);

  tobj = new Other;
  tobj->name = dbe_strdup (NTXT ("<Total>"));
  total = new_hist_item (tobj);

  tobj = new Other;
  tobj->name = dbe_strdup (NTXT ("XXXX Threshold XXXX"));
  threshold = new_hist_item (tobj);

  hi_map = new HashMap<Histable*, HistItem*>;
  callsite_mark = new DefaultMap<Histable*, int>;
  hist_metrics = new Metric::HistMetric[metrics->size ()];
  for (long i = 0, sz = metrics->size (); i < sz; i++)
    {
      Metric::HistMetric *h = hist_metrics + i;
      h->init ();
      Metric *m = metrics->get (i);
      if (0 != (m->get_visbits () & (VAL_DELTA | VAL_RATIO)))
	h->indFirstExp =
	      metrics->get_listorder (m->get_cmd (),
				      m->get_subtype (), "EXPGRID==1");
      if (m->is_tvisible () && m->get_type () == BaseMetric::HWCNTR
	  && m->get_dependent_bm ())
	h->indTimeVal =
	      metrics->get_listorder (m->get_dependent_bm ()->get_cmd (),
				      m->get_subtype (), m->get_expr_spec ());
    }
  status = NO_DATA;
}

Hist_data::~Hist_data ()
{
  delete[] hist_metrics;
  if (hist_items)
    {
      hist_items->destroy ();
      delete hist_items;
      hist_items = NULL;
    }
  if (gprof_item)
    {
      delete gprof_item;
      gprof_item = NULL;
    }
  if (maximum)
    {
      delete maximum->obj;
      delete maximum;
      maximum = NULL;
    }
  if (maximum_inc)
    {
      delete maximum_inc->obj;
      delete maximum_inc;
      maximum_inc = NULL;
    }
  if (minimum)
    {
      delete minimum->obj;
      delete minimum;
      minimum = NULL;
    }
  if (total)
    {
      delete total->obj;
      delete total;
      total = NULL;
    }
  if (threshold)
    {
      delete threshold->obj;
      delete threshold;
      threshold = NULL;
    }
  delete metrics;
  delete hi_map;
  delete callsite_mark;
}

void
Hist_data::dump (char *msg, FILE *f)
{
  fprintf (f, "   Hist_data dump:  %s\n", msg);
  fprintf (f, "      %d=%d metrics\n", (int) nmetrics, (int) metrics->size ());
  for (int i = 0; i < nmetrics; i++)
    {
      Metric *m = metrics->get_items ()->fetch (i);
      char *s = m->get_expr_spec ();
      fprintf (f, "          %4d %15s %4d %15s\n", i, m->get_mcmd (0),
	       m->get_id (), s ? s : "(NULL)");
    }

  fprintf (f, NTXT ("      HistItem listing\n"));
  int n = hist_items->size ();
  for (int j = -1; j < n; j++)
    {
      HistItem *hi;
      if (j < 0)
	{
	  hi = total;
	  fprintf (f, NTXT ("                         total"));
	}
      else
	{
	  hi = hist_items->fetch (j);
	  fprintf (f, NTXT ("%30s"), hi->obj->get_name ());
	}
      for (int i = 0; i < nmetrics; i++)
	{
	  char *stmp = hi->value[i].l;
	  switch (hi->value[i].tag)
	    {
	    case VT_SHORT: fprintf (f, NTXT (" %d"), hi->value[i].s);
	      break;
	    case VT_INT: fprintf (f, NTXT (" %d"), hi->value[i].i);
	      break;
	    case VT_LLONG: fprintf (f, NTXT (" %12lld"), hi->value[i].ll);
	      break;
	    case VT_FLOAT: fprintf (f, NTXT (" %f"), hi->value[i].f);
	      break;
	    case VT_DOUBLE: fprintf (f, NTXT (" %12.6lf"), hi->value[i].d);
	      break;
	    case VT_HRTIME: fprintf (f, NTXT (" %12llu"), hi->value[i].ull);
	      break;
	    case VT_LABEL: fprintf (f, NTXT (" %s"), stmp ? stmp: "(unnamed)");
	      break;
	    case VT_ADDRESS: fprintf (f, NTXT (" %12lld"), hi->value[i].ll);
	      break;
	    case VT_OFFSET: fprintf (f, NTXT (" %p"), hi->value[i].p);
	      break;
	    case VT_ULLONG: fprintf (f, NTXT (" %12llu"), hi->value[i].ull);
	      break;
	    default: fprintf (f, NTXT ("     "));
	      break;
	    }
	}
      fprintf (f, NTXT ("\n"));
    }
}

void
Hist_data::sort (long ind, bool reverse)
{
  if (mode != MODL && ind != -1 && ind == sort_ind && reverse == rev_sort)
    // there's no change to the sorting
    return;

  if (mode == MODL)
    {
      sort_type = AUX;
      sort_order = ASCEND;
    }
  else
    {
      if (ind == -1)
	return;
      Metric::Type mtype = metrics->get_items ()->fetch (ind)->get_type ();
      sort_type = mtype == Metric::ONAME ? ALPHA : VALUE;
      sort_order = (mtype == Metric::ONAME || mtype == Metric::ADDRESS) ?
	      ASCEND : DESCEND;
      sort_ind = ind;
      rev_sort = reverse;
    }

  if (mode == Hist_data::LAYOUT || mode == Hist_data::DETAIL)
    hist_items->sort ((CompareFunc) sort_compare_dlayout, this);
  else
    hist_items->sort ((CompareFunc) sort_compare_all, this);

  // ensure that <Total> comes first/last
  for (int i = 0; i < hist_items->size (); ++i)
    {
      HistItem *hi = hist_items->fetch (i);
      char *name = hi->obj->get_name ();
      if (name != NULL && strncmp (name, "<Total>", 7) == 0)
	{
	  int idx0 = rev_sort ? hist_items->size () - 1 : 0;
	  if (i != idx0)
	    {
	      hist_items->remove (i);
	      hist_items->insert (idx0, hi);
	    }
	  break;
	}
    }
}

void
Hist_data::resort (MetricList *mlist)
{
  if (mlist->get_type () != metrics->get_type ())
    if (metrics->get_type () == MET_CALL)
      // wrong type of list -- internal error
      abort ();

  // get the new sort order
  int ind = mlist->get_sort_ref_index ();
  bool reverse = mlist->get_sort_rev ();
  sort (ind, reverse);
}

void
Hist_data::compute_minmax ()
{
  HistItem *hi;
  int index;

  for (int mind = 0; mind < nmetrics; mind++)
    {
      Metric *mtr = metrics->get_items ()->fetch (mind);
      if (mtr->get_subtype () == Metric::STATIC)
	continue;
      if (!mtr->is_visible () && !mtr->is_tvisible () && !mtr->is_pvisible ())
	continue;
      ValueTag vtype = mtr->get_vtype2 ();

      switch (vtype)
	{
	case VT_INT:
	  minimum->value[mind].tag = VT_INT;
	  minimum->value[mind].i = 0;
	  maximum->value[mind].tag = VT_INT;
	  maximum->value[mind].i = 0;
	  maximum_inc->value[mind].tag = VT_INT;
	  maximum_inc->value[mind].i = 0;

	  Vec_loop (HistItem *, hist_items, index, hi)
	  {
	    if (metrics->get_type () == MET_SRCDIS
		&& callsite_mark->get (hi->obj))
	      {
		if (hi->value[mind].i > maximum_inc->value[mind].i)
		  maximum_inc->value[mind].i = hi->value[mind].i;
		// ignore ones that has inclusive time for src/dis view
	      }
	    else if (hi->value[mind].i > maximum->value[mind].i)
	      maximum->value[mind].i = hi->value[mind].i;
	    if (hi->value[mind].i < minimum->value[mind].i)
	      minimum->value[mind].i = hi->value[mind].i;
	  }
	  break;
	case VT_DOUBLE:
	  minimum->value[mind].tag = VT_DOUBLE;
	  minimum->value[mind].d = 0.0;
	  maximum->value[mind].tag = VT_DOUBLE;
	  maximum->value[mind].d = 0.0;
	  maximum_inc->value[mind].tag = VT_DOUBLE;
	  maximum_inc->value[mind].d = 0.0;
	  Vec_loop (HistItem*, hist_items, index, hi)
	  {
	    if (metrics->get_type () == MET_SRCDIS && callsite_mark->get (hi->obj))
	      {
		if (hi->value[mind].d > maximum_inc->value[mind].d)
		  {
		    maximum_inc->value[mind].d = hi->value[mind].d;
		    maximum_inc->value[mind].sign = hi->value[mind].sign;
		  }
		// ignore ones that has inclusive time for src/dis view
	      }
	    else
	      {
		if (hi->value[mind].d > maximum->value[mind].d)
		  {
		    maximum->value[mind].d = hi->value[mind].d;
		    maximum->value[mind].sign = hi->value[mind].sign;
		  }
		if (hi->value[mind].d < minimum->value[mind].d)
		  {
		    minimum->value[mind].d = hi->value[mind].d;
		    minimum->value[mind].sign = hi->value[mind].sign;
		  }
	      }
	  }
	  break;
	case VT_LLONG:
	case VT_ULLONG:
	case VT_ADDRESS:
	  minimum->value[mind].tag = vtype;
	  minimum->value[mind].ll = 0;
	  maximum->value[mind].tag = vtype;
	  maximum->value[mind].ll = 0;
	  maximum_inc->value[mind].tag = vtype;
	  maximum_inc->value[mind].ll = 0;
	  Vec_loop (HistItem*, hist_items, index, hi)
	  {
	    if (metrics->get_type () == MET_SRCDIS && callsite_mark->get (hi->obj))
	      {
		if (hi->value[mind].ll > maximum_inc->value[mind].ll)
		  {
		    maximum_inc->value[mind].ll = hi->value[mind].ll;
		    maximum_inc->value[mind].sign = hi->value[mind].sign;
		  }
		// ignore ones that has inclusive time for src/dis view
	      }
	    else
	      {
		if (hi->value[mind].ll > maximum->value[mind].ll)
		  {
		    maximum->value[mind].ll = hi->value[mind].ll;
		    maximum->value[mind].sign = hi->value[mind].sign;
		  }
		if (hi->value[mind].ll < minimum->value[mind].ll)
		  {
		    minimum->value[mind].ll = hi->value[mind].ll;
		    minimum->value[mind].sign = hi->value[mind].sign;
		  }
	      }
	  }
	  break;
	default:
	  break;
	}
    }
}

Hist_data::HistItem *
Hist_data::new_hist_item (Histable *obj)
{
  long sz = get_metric_list ()->size ();
  HistItem *hi = new HistItem (sz);
  hi->obj = obj;

  // We precalculate all metrics as integer values
  // and convert them to appropriate types later.
  for (long i = 0; i < sz; i++)
    {
      hi->value[i].tag = VT_INT;
      hi->value[i].i = 0;
    }
  return hi;
}

Hist_data::HistItem *
Hist_data::new_hist_item (Histable *obj, int itype, TValue *value)
{
  long sz = get_metric_list ()->size ();
  HistItem *hi = new HistItem (sz);
  hi->obj = obj;
  hi->type = itype;
  if (value)
    for (long i = 0; i < sz; i++)
      hi->value[i] = value[i];

  return hi;
}

Hist_data::HistItem *
Hist_data::find_hist_item (Histable *obj)
{
  if (obj == NULL)
    return NULL;
  return hi_map->get (obj);
}

Hist_data::HistItem *
Hist_data::append_hist_item (Histable *obj)
{
  if (obj == NULL)
    return NULL;
  HistItem *hi = hi_map->get (obj);
  if (hi == NULL)
    {
      hi = new_hist_item (obj);
      hist_items->append (hi);
      hi_map->put (obj, hi);
    }
  if (status == NO_DATA)
    status = SUCCESS;
  return hi;
}

void
Hist_data::append_hist_item (HistItem *hi)
{
  hist_items->append (hi);
}

bool
Hist_data::above_threshold (HistItem* hi)
{
  bool mark = false;
  int index;
  Metric *mitem;

  Vec_loop (Metric*, metrics->get_items (), index, mitem)
  {
    if (mitem->get_subtype () == Metric::STATIC)
      continue;
    switch (hi->value[index].tag)
      {
      case VT_DOUBLE:
	if (hi->value[index].d > threshold->value[index].d)
	  mark = true;
	break;
      case VT_INT:
	if (hi->value[index].i > threshold->value[index].i)
	  mark = true;
	break;
      case VT_LLONG:
	if (hi->value[index].ll > threshold->value[index].ll)
	  mark = true;
	break;
      case VT_ULLONG:
	if (hi->value[index].ull > threshold->value[index].ull)
	  mark = true;
	break;
	// ignoring the following cases (why?)
      case VT_SHORT:
      case VT_FLOAT:
      case VT_HRTIME:
      case VT_LABEL:
      case VT_ADDRESS:
      case VT_OFFSET:
	break;
      }
  }
  return mark;
}

void
Hist_data::set_threshold (double proportion)
{
  int index;
  Metric *mitem;
  Vec_loop (Metric*, metrics->get_items (), index, mitem)
  {
    TValue *thresh = &threshold->value[index];
    TValue *mtotal = &total->value[index];
    thresh->tag = mitem->get_vtype ();

    if (mitem->get_subtype () == Metric::STATIC)
      continue;
    switch (thresh->tag)
      {
      case VT_INT:
	thresh->i = (int) (proportion * (double) mtotal->i);
	break;
      case VT_DOUBLE:
	thresh->d = proportion * mtotal->d;
	break;
      case VT_LLONG:
      case VT_ULLONG:
	thresh->ull = (unsigned long long) (proportion * (double) mtotal->ll);
	break;
      case VT_SHORT:
      case VT_FLOAT:
      case VT_HRTIME:
      case VT_LABEL:
      case VT_ADDRESS:
      case VT_OFFSET:
	break;
      }
  }
}

double
Hist_data::get_percentage (double value, int mindex)
{
  double total_value;
  if (value == 0.0)
    return 0.0;

  // Get the total value of this sample set.
  // The value must be greater than 0.
  total_value = total->value[mindex].to_double ();

  // Find out what percentage of the total value this item is.
  // Make sure we don't divide by zero.
  if (total_value == 0.0)
    return 0.0;
  return value / total_value;
}

int
Hist_data::print_label (FILE *out_file, Metric::HistMetric *hist_metric,
			int space)
{
  int name_offset = 0;
  StringBuilder sb, sb1, sb2, sb3;
  if (space > 0)
    {
      char *fmt = NTXT ("%*s");
      sb.appendf (fmt, space, NTXT (""));
      sb1.appendf (fmt, space, NTXT (""));
      sb2.appendf (fmt, space, NTXT (""));
      sb3.appendf (fmt, space, NTXT (""));
    }
  for (int i = 0; i < nmetrics; i++)
    {
      Metric *m = metrics->get (i);
      Metric::HistMetric *hm = &hist_metric[i];
      int len = hm->width;
      char *fmt = NTXT ("%-*s");
      if ((i > 0) && (m->get_type () == Metric::ONAME))
	{
	  name_offset = sb1.length ();
	  fmt = NTXT (" %-*s");
	  len--;
	}
      sb.appendf (fmt, len, m->legend ? m->legend : NTXT (""));
      sb1.appendf (fmt, len, hm->legend1);
      sb2.appendf (fmt, len, hm->legend2);
      sb3.appendf (fmt, len, hm->legend3);
    }
  sb.trim ();
  if (sb.length () != 0)
    {
      sb.toFileLn (out_file);
    }
  sb1.toFileLn (out_file);
  sb2.toFileLn (out_file);
  sb3.toFileLn (out_file);
  return name_offset;
}

void
Hist_data::print_content (FILE *out_file, Metric::HistMetric *hist_metric, int limit)
{
  StringBuilder sb;
  int cnt = VecSize (hist_items);
  if (cnt > limit && limit > 0)
    cnt = limit;
  for (int i = 0; i < cnt; i++)
    {
      sb.setLength (0);
      print_row (&sb, i, hist_metric, NTXT (" "));
      sb.toFileLn (out_file);
    }
}

static void
append_str (StringBuilder *sb, char *s, size_t len, int vis_bits)
{
  if ((vis_bits & VAL_RATIO) != 0)
    {
      if (*s != 'N')    // Nan
	sb->appendf (NTXT ("x "));
      else
	sb->appendf (NTXT ("  "));
      sb->appendf (NTXT ("%*s"), (int) (len - 2), s);
    }
  else
    sb->appendf (NTXT ("%*s"), (int) len, s);
}

void
Hist_data::print_row (StringBuilder *sb, int row, Metric::HistMetric *hmp,
		      const char *mark)
{
  TValue res;
  char buf[256];
  // Print only a list of user's metrics. ( nmetrics <= mlist->size() )
  for (long i = 0; i < nmetrics; i++)
    {
      // Print only a list of user's metrics.
      Metric *m = metrics->get (i);
      if (!m->is_any_visible ())
	continue;
      Metric::HistMetric *hm = hmp + i;
      int len = sb->length ();
      if (m->is_tvisible ())
	{
	  TValue *v = get_value (&res, hist_metrics[i].indTimeVal, row);
	  char *s = v->to_str (buf, sizeof (buf));
	  append_str (sb, s, hm->maxtime_width, m->get_visbits ());
	}
      if (m->is_visible ())
	{
	  TValue *v = get_value (&res, i, row);
	  char *s = v->to_str (buf, sizeof (buf));
	  if (m->get_type () == BaseMetric::ONAME)
	    {
	      sb->append (mark);
	      if (i + 1 == nmetrics)
		sb->appendf (NTXT ("%s"), s);
	      else
		sb->appendf (NTXT ("%-*s "), (int) hm->maxvalue_width, s);
	      continue;
	    }
	  else
	    {
	      if (len != sb->length ())
		sb->append (' ');
	      append_str (sb, s, hm->maxvalue_width, m->get_visbits ());
	    }
	}
      if (m->is_pvisible ())
	{
	  if (len != sb->length ())
	    sb->append (' ');
	  long met_ind = i;
	  if (m->is_tvisible () && !m->is_visible ())
	    met_ind = hist_metrics[i].indTimeVal;
	  TValue *v = get_real_value (&res, met_ind, row);
	  double percent = get_percentage (v->to_double (), met_ind);
	  if (percent == 0.0)
	    // adjust to change format from xx.yy%
	    sb->append (NTXT ("  0.  "));
	  else
	    // adjust format below to change format from xx.yy%
	    sb->appendf (NTXT ("%6.2f"), (100.0 * percent));
	}
      len = sb->length () - len;
      if (hm->width > len && i + 1 != nmetrics)
	sb->appendf (NTXT ("%*s"), (int) (hm->width - len), NTXT (" "));
    }
}

TValue *
Hist_data::get_real_value (TValue *res, int met_index, int row)
{
  HistItem *hi = hist_items->get (row);
  Metric *m = metrics->get (met_index);
  if (m->get_type () == BaseMetric::ONAME)
    {
      res->l = dbe_strdup (hi->obj->get_name ());
      res->tag = VT_LABEL;
      return res;
    }
  return hi->value + met_index;
}

TValue *
Hist_data::get_value (TValue *res, int met_index, int row)
{
  HistItem *hi = hist_items->get (row);
  Metric *m = metrics->get (met_index);
  if ((m->get_visbits () & (VAL_DELTA | VAL_RATIO)) != 0)
    {
      int ind = hist_metrics[met_index].indFirstExp;
      if ((m->get_visbits () & VAL_DELTA) != 0)
	res->make_delta (hi->value + met_index, hi->value + ind);
      else
	res->make_ratio (hi->value + met_index, hi->value + ind);
      return res;
    }
  return get_real_value (res, met_index, row);
}

TValue *
Hist_data::get_value (TValue *res, int met_index, HistItem *hi)
{
  Metric *m = metrics->get (met_index);
  if ((m->get_visbits () & (VAL_DELTA | VAL_RATIO)) != 0)
    {
      int ind = hist_metrics[met_index].indFirstExp;
      if ((m->get_visbits () & VAL_DELTA) != 0)
	res->make_delta (hi->value + met_index, hi->value + ind);
      else
	res->make_ratio (hi->value + met_index, hi->value + ind);
      return res;
    }
  if (m->get_type () == BaseMetric::ONAME)
    {
      res->l = dbe_strdup (hi->obj->get_name ());
      res->tag = VT_LABEL;
      return res;
    }
  return hi->value + met_index;
}

Metric::HistMetric *
Hist_data::get_histmetrics ()
{
  // find the width for each column.
  for (long i = 0, sz = metrics->size (); i < sz; i++)
    {
      Metric *m = metrics->get (i);
      Metric::HistMetric *hm = hist_metrics + i;
      if (m->is_value_visible ())
	{
	  TValue res;
	  for (long i1 = 0, sz1 = VecSize(hist_items); i1 < sz1; i1++)
	    {
	      TValue *v = get_value (&res, i, i1);
	      long len = v->get_len ();
	      if (hm->maxvalue_width < len)
		hm->maxvalue_width = len;
	    }
	  if ((m->get_visbits () & VAL_RATIO) != 0)
	    hm->maxvalue_width += 2; // "x "
	}
    }

  for (long i = 0, sz = metrics->size (); i < sz; i++)
    {
      Metric *m = metrics->get (i);
      Metric::HistMetric *hm = hist_metrics + i;
      if (m->is_time_visible ())
	// take a value from depended metric
	hm->maxtime_width = hist_metrics[hm->indTimeVal].maxvalue_width;
      m->legend_width (hm, 2);
    }
  return hist_metrics;
}

void
Hist_data::update_total (Hist_data::HistItem *new_total)
{
  for (long i = 0, sz = metrics->size (); i < sz; i++)
    total->value[i] = new_total->value[i];
}

void
Hist_data::update_max (Metric::HistMetric *hm_tmp)
{
  Metric::HistMetric *hms = get_histmetrics ();
  for (int i = 0; i < nmetrics; i++)
    {
      Metric::HistMetric *hm = hms + i;
      Metric::HistMetric *hm1 = hm_tmp + i;
      if (hm1->maxtime_width < hm->maxtime_width)
	hm1->maxtime_width = hm->maxtime_width;
      if (hm1->maxvalue_width < hm->maxvalue_width)
	hm1->maxvalue_width = hm->maxvalue_width;
    }
}

void
Hist_data::update_legend_width (Metric::HistMetric *hm_tmp)
{
  for (int i = 0; i < nmetrics; i++)
    {
      Metric *m = metrics->get (i);
      m->legend_width (hm_tmp + i, 2);
    }
}

void
Metric::HistMetric::update_max (Metric::HistMetric *hm)
{
  if (maxtime_width < hm->maxtime_width)
    maxtime_width = hm->maxtime_width;
  if (maxvalue_width < hm->maxvalue_width)
    maxvalue_width = hm->maxvalue_width;
}

void
Metric::HistMetric::init ()
{
  width = 0;
  maxvalue_width = 0;
  maxtime_width = 0;
  legend1[0] = 0;
  legend2[0] = 0;
  legend3[0] = 0;
  indFirstExp = -1;
  indTimeVal = -1;
}

size_t
Hist_data::value_maxlen (int mindex)
{
  size_t maxlen = maximum->value[mindex].get_len ();
  size_t minlen = minimum->value[mindex].get_len ();
  // minlen can be bigger than maxlen only for negative value
  return minlen > maxlen ? minlen : maxlen;
}

size_t
Hist_data::time_len (TValue *value, int clock)
{
  TValue tm_value;
  tm_value.tag = VT_DOUBLE;
  tm_value.sign = value->sign;
  tm_value.d = 1.e-6 * value->ll / clock;
  return tm_value.get_len ();
}

size_t
Hist_data::time_maxlen (int mindex, int clock)
{
  size_t maxlen = time_len (&(maximum->value[mindex]), clock);
  size_t minlen = time_len (&(minimum->value[mindex]), clock);
  // minlen can be bigger than maxlen only for negative value
  return minlen > maxlen ? minlen : maxlen;
}

size_t
Hist_data::name_len (HistItem *item)
{
  char *name = item->obj->get_name ();
  return strlen (name);
}

size_t
Hist_data::name_maxlen ()
{
  size_t res = 0;
  for (long i = 0; i < size (); i++)
    {
      HistItem *hi = fetch (i);
      size_t len = name_len (hi);
      if (res < len)
	res = len;
    }
  return res;
}

// Returns vector of object ids for the vector of selections
//	returns NULL if no valid selections
Vector<uint64_t> *
Hist_data::get_object_indices (Vector<int> *selections)
{
  // if no selections, return NULL
  if (selections == NULL || selections->size () == 0)
    return NULL;

  Vector<uint64_t> *indices = new Vector<uint64_t>;
  for (long i = 0, sz = selections->size (); i < sz; i++)
    {
      int sel = selections->get (i);
      HistItem *hi = hist_items->get (sel);
      if (hi == NULL || hi->obj == NULL)
	continue;
      Vector<Histable*> *v = hi->obj->get_comparable_objs ();
      for (long i1 = 0, sz1 = v ? v->size () : 0; i1 < sz1; i1++)
	{
	  Histable *h1 = v->get (i1);
	  if (h1 && (indices->find_r (h1->id) < 0))
	    indices->append (h1->id);
	}
      if (indices->find_r (hi->obj->id) < 0)
	indices->append (hi->obj->id);
    }
  return indices;
}

DbeInstr::DbeInstr (uint64_t _id, int _flags, Function *_func, uint64_t _addr)
{
  id = _id;
  flags = _flags;
  addr = _addr;
  func = _func;
  img_offset = addr + func->img_offset;
  lineno = -1;
  size = 0;
  current_name_format = NA;
  isUsed = false;
  inlinedInd = -1;
}

int
DbeInstr::pc_cmp (DbeInstr *instr2)
{
  int result = 0;
  if (instr2 == NULL)
    return -1;

  // All PC's with the Line flag go to the
  // end of the list. See Module::init_index()
  if (flags & PCLineFlag)
    {
      if (instr2->flags & PCLineFlag)
	{
	  if (addr < instr2->addr)
	    result = -1;
	  else if (addr > instr2->addr)
	    result = 1;
	  else
	    result = 0;
	}
      else
	result = 1;
    }
  else if (instr2->flags & PCLineFlag)
    result = -1;
  else if (func == instr2->func)
    {
      if (size == 0)
	{
	  if (addr < instr2->addr)
	    result = -1;
	  else if (addr == instr2->addr)
	    result = 0;
	  else if (addr >= instr2->addr + instr2->size)
	    result = 1;
	  else
	    result = 0;
	}
      else if (instr2->size == 0)
	{
	  if (addr > instr2->addr)
	    result = 1;
	  else if (addr + size <= instr2->addr)
	    result = -1;
	  else
	    result = 0;
	}
      else if (addr < instr2->addr)
	result = -1;
      else if (addr > instr2->addr)
	result = 1;
      else
	result = 0;

      if (result == 0)
	{
	  if (flags & PCTrgtFlag)
	    {
	      if (!(instr2->flags & PCTrgtFlag))
		result = -1;
	    }
	  else if (instr2->flags & PCTrgtFlag)
	    result = 1;
	}
    }
  else
    result = func->func_cmp (instr2->func);
  return result;
}

char *
DbeInstr::get_name (NameFormat nfmt)
{
  if (name && (nfmt == current_name_format || nfmt == Histable::NA))
    return name;

  free (name);
  name = NULL;
  current_name_format = nfmt;
  char *fname = func->get_name (nfmt);

  if (func->flags & FUNC_FLAG_NO_OFFSET)
    name = dbe_strdup (fname);
  else if (addr == (uint64_t) - 1
	   && func != dbeSession->get_JUnknown_Function ())
    // We use three heuristics above to recognize this special case.
    // Once the original problem with bci == -1 is fixed, we don't
    // need it any more.
    name = dbe_sprintf (GTXT ("<Function %s: HotSpot-compiled leaf instructions>"),
			fname);
  else if (addr == (uint64_t) - 3)
    name = dbe_sprintf (GTXT ("%s <Java native method>"), fname);
  else
    {
      char buf[64], *typetag = NTXT (""), *alloc_typetag = NULL;
      StringBuilder sb;
      sb.append (fname);
      if (func != dbeSession->get_JUnknown_Function ())
	{
	  if (addr <= 0xFFFFFFFFU)
	    snprintf (buf, sizeof (buf), " + 0x%08X", (unsigned int) addr);
	  else
	    snprintf (buf, sizeof (buf), " + 0x%016llX",
		      (unsigned long long) addr);
	}
      else
	{
	  char *subname;
	  switch ((long int) addr)
	    {
	    case -1:
	      subname = GTXT ("agent error");
	      break;
	    case -2:
	      subname = GTXT ("GC active");
	      break;
	    case -3:
	      subname = GTXT ("unknown non-Java frame");
	      break;
	    case -4:
	      subname = GTXT ("unwalkable non-Java frame");
	      break;
	    case -5:
	      subname = GTXT ("unknown Java frame");
	      break;
	    case -6:
	      subname = GTXT ("unwalkable Java frame");
	      break;
	    case -7:
	      subname = GTXT ("unknown thread state");
	      break;
	    case -8:
	      subname = GTXT ("thread in exit");
	      break;
	    case -9:
	      subname = GTXT ("deopt in process ticks");
	      break;
	    case -10:
	      subname = GTXT ("safepoint synchronizing ticks");
	      break;
	    default:
	      subname = GTXT ("unexpected error");
	      break;
	    }
	  snprintf (buf, sizeof (buf), "<%s (%d)>", subname, (int) addr);
	}
      sb.append (buf);
      if (flags & PCTrgtFlag)
	// annotate synthetic instruction
	sb.append ('*'); // special distinguishing marker

      DbeLine *dbeline = mapPCtoLine (NULL);
      char *str = NULL;
      if (dbeline && dbeline->lineno > 0)
	str = strrchr (dbeline->get_name (nfmt), ',');
      if (str)
	sb.append (str);
      if (strlen (typetag) > 0)
	{ // include padding for alignment
	  do
	    {
	      sb.append (' ');
	    }
	  while (sb.length () < 40);
	  sb.append (typetag);
	  delete alloc_typetag;
	}
      if (inlinedInd >= 0)
	add_inlined_info (&sb);
      name = sb.toString ();
    }
  return name;
}

DbeLine*
DbeInstr::mapPCtoLine (SourceFile *sf)
{
  if (inlinedInd == -1)
    {
      inlinedInd = -2;
      for (int i = 0; i < func->inlinedSubrCnt; i++)
	{
	  InlinedSubr *p = func->inlinedSubr + i;
	  if (p->level == 0)
	    {
	      if (addr < p->low_pc)
		break;
	      if (p->contains (addr))
		{
		  inlinedInd = i;
		  break;
		}
	    }
	}
    }
  if (inlinedInd >= 0)
    {
      DbeLine *dl = func->inlinedSubr[inlinedInd].dbeLine;
      if (dl)
	return dl->sourceFile->find_dbeline (func, dl->lineno);
    }
  return func->mapPCtoLine (addr, sf);
}

void
DbeInstr::add_inlined_info (StringBuilder *sb)
{
  do
    {
      sb->append (' ');
    }
  while (sb->length () < 40);
  sb->append (NTXT ("<-- "));

  InlinedSubr *last = NULL;
  for (int i = inlinedInd; i < func->inlinedSubrCnt; i++)
    {
      InlinedSubr *p = func->inlinedSubr + i;
      if (p->level == 0 && i > inlinedInd)
	break;
      if (!p->contains (addr))
	continue;
      if (last)
	{
	  if (last->fname)
	    {
	      sb->append (last->fname);
	      sb->append (' ');
	    }
	  DbeLine *dl = p->dbeLine;
	  if (dl)
	    sb->appendf ("%s:%lld <-- ", get_basename (dl->sourceFile->get_name ()),
		     (long long) dl->lineno);
	}
      last = p;
    }
  if (last)
    {
      if (last->fname)
	{
	  sb->append (last->fname);
	  sb->append (' ');
	}
    }
  DbeLine *dl = func->mapPCtoLine (addr, NULL);
  sb->appendf ("%s:%lld ", get_basename (dl->sourceFile->get_name ()),
	       (long long) dl->lineno);
}

char *
DbeInstr::get_descriptor ()
{
  char *typetag = NTXT ("");
  if ((flags & PCTrgtFlag) == 0)  // not synthetic instruction
    { // use memop descriptor, if available
      Module *mod = func->module;
      if (mod->hwcprof  && mod->infoList)
	{
	  long i;
	  inst_info_t *info = NULL;
	  Vec_loop (inst_info_t*, mod->infoList, i, info)
	  {
	    if (info->offset == func->img_offset + addr) break;
	  }
	  if (info)
	    {
	      long t;
	      datatype_t *dtype = NULL;
	      Vec_loop (datatype_t*, mod->datatypes, t, dtype)
	      {
		if (dtype->datatype_id == info->memop->datatype_id)
		  break;
	      }
	      if (dtype && dtype->dobj)
		typetag = dtype->dobj->get_name ();
	    }
	}
    }
  return dbe_strdup (typetag);
}

int64_t
DbeInstr::get_size ()
{
  //    Function *func = (Function*)dbeSession->get_hobj( pc );
  //    Module   *mod  = func ? func->module : NULL;
  //    return mod ? mod->instrSize( func->img_offset + addr ) : 0;
  return size;
}

uint64_t
DbeInstr::get_addr ()
{
  return func->get_addr () + addr;
}

Histable *
DbeInstr::convertto (Type type, Histable *obj)
{
  Histable *res = NULL;
  SourceFile *source = (SourceFile*) obj;
  switch (type)
    {
    case INSTR:
      res = this;
      break;
    case LINE:
      res = mapPCtoLine (source);
      break;
    case SOURCEFILE:
      res = mapPCtoLine (source);
      if (res)
	res = ((DbeLine*) res)->sourceFile;
      break;
    case FUNCTION:
      res = func;
      break;
    default:
      assert (0);
    }
  return res;
}

char *
DbeEA::get_name (NameFormat)
{
  if (name == NULL)
    // generate one
    name = dbe_strdup (dbeSession->localized_SP_UNKNOWN_NAME);
  return name;
}

Histable *
DbeEA::convertto (Type type, Histable *obj)
{
  Histable *res = NULL;
  assert (obj == NULL);
  switch (type)
    {
    case EADDR:
      res = this;
      break;
    case DOBJECT:
      res = dobj;
      break;
    default:
      assert (0);
    }
  return res;
}

DbeLine::DbeLine (Function *_func, SourceFile *sf, int _lineno)
{
  func = _func;
  lineno = _lineno;
  sourceFile = sf;
  id = sf->id + _lineno;
  offset = 0;
  size = 0;
  flags = 0;
  include = NULL;
  dbeline_func_next = NULL;
  dbeline_base = this;
  current_name_format = Histable::NA;
}

DbeLine::~DbeLine ()
{
  delete dbeline_func_next;
}

int
DbeLine::line_cmp (DbeLine *dbl)
{
  return lineno - dbl->lineno;
}

void
DbeLine::init_Offset (uint64_t p_offset)
{
  if (offset == 0)
    offset = p_offset;
  if (dbeline_base && dbeline_base->offset == 0)
    dbeline_base->offset = p_offset;
}

char *
DbeLine::get_name (NameFormat nfmt)
{
  char *srcname = NULL, *basename, *fname;

  if (func == NULL)
    {
      if (name)
	return name;
      srcname = sourceFile->get_name ();
      basename = get_basename (srcname);
      name = dbe_sprintf (GTXT ("line %u in \"%s\""), lineno, basename);
      return name;
    }

  if (name && (nfmt == current_name_format || nfmt == Histable::NA))
    return name;

  current_name_format = nfmt;
  free (name);
  fname = func->get_name (nfmt);
  if (func->flags & (FUNC_FLAG_SIMULATED | FUNC_FLAG_NO_OFFSET))
    {
      name = dbe_strdup (fname);
      return name;
    }

  if (sourceFile)
    srcname = sourceFile->get_name ();
  if (!srcname || strlen (srcname) == 0)
    srcname = func->getDefSrcName ();
  basename = get_basename (srcname);

  if (lineno != 0)
    {
      if (sourceFile == func->getDefSrc ())
	name = dbe_sprintf (GTXT ("%s, line %u in \"%s\""), fname, lineno,
			    basename);
      else
	name = dbe_sprintf (GTXT ("%s, line %u in alternate source context \"%s\""),
			    fname, lineno, basename);
    }
  else if (sourceFile == NULL || (sourceFile->flags & SOURCE_FLAG_UNKNOWN) != 0)
    name = dbe_sprintf (GTXT ("<Function: %s, instructions without line numbers>"),
			fname);
  else
    name = dbe_sprintf (GTXT ("<Function: %s, instructions from source file %s>"),
			  fname, basename);
  return name;
}

int64_t
DbeLine::get_size ()
{
  return size;
}

uint64_t
DbeLine::get_addr ()
{
  if (func == NULL && dbeline_func_next == NULL)
    return (uint64_t) 0;
  Function *f = func ? func : dbeline_func_next->func;
  return f->get_addr () + offset;
}

Histable *
DbeLine::convertto (Type type, Histable *obj)
{
  Histable *res = NULL;
  switch (type)
    {
    case INSTR:
      {
	Function *f = (Function *) convertto (FUNCTION, NULL);
	if (f)
	  res = f->find_dbeinstr (0, offset);
	break;
      }
    case LINE:
      res = dbeline_base;
      break;
    case FUNCTION:
      if (func)
	{
	  res = func;
	  break;
	}
      else
	{
	  int not_found = 1;
	  for (DbeLine *dl = dbeline_base; dl; dl = dl->dbeline_func_next)
	    {
	      Function *f = dl->func;
	      not_found = (obj == NULL // XXXX pass dbeview as Histable*
			   || ((DbeView*) obj)->get_path_tree ()->get_func_nodeidx (f) == 0);
	      if (f && f->def_source == sourceFile && (!not_found))
		{
		  res = f;
		  break;
		}
	    }
	  if (res == NULL && dbeline_func_next)
	    {
	      for (DbeLine *dl = dbeline_base; dl; dl = dl->dbeline_func_next)
		{
		  Function *f = dl->func;
		  if (f && f->def_source == sourceFile)
		    {
		      res = f;
		      break;
		    }
		}
	    }
	  if (res == NULL && dbeline_func_next)
	    res = dbeline_func_next->func;
	}
      break;
    case SOURCEFILE:
      res = (include) ? include : sourceFile;
      break;
    default:
      assert (0);
    }
  return res;
}

CStack_data::CStack_data (MetricList *_metrics)
{
  metrics = _metrics;
  total = new_cstack_item ();
  cstack_items = new Vector<CStack_item*>;
}

CStack_data::CStack_item::CStack_item (long n)
{
  stack = NULL;
  count = 0;
  val = 0;
  value = new TValue[n];
  memset (value, 0, sizeof (TValue) * n);
}

CStack_data::CStack_item::~CStack_item ()
{
  delete stack;
  delete[] value;
}

CStack_data::CStack_item *
CStack_data::new_cstack_item ()
{
  int nmetrics = metrics->get_items ()->size ();
  CStack_item *item = new CStack_item (nmetrics);

  // We precalculate all metrics as integer values
  // and convert them to appropriate types later.
  for (int i = 0; i < nmetrics; i++)
    item->value[i].tag = metrics->get_items ()->fetch (i)->get_vtype ();
  return item;
}

HistableFile::HistableFile ()
{
  dbeFile = NULL;
  isUsed = false;
}

Histable::Histable ()
{
  name = NULL;
  id = 0;
  comparable_objs = NULL;
  phaseCompareIdx = -1;
}

Histable::~Histable ()
{
  delete_comparable_objs ();
  free (name);
}

void
Histable::delete_comparable_objs ()
{
  if (comparable_objs)
    {
      Vector<Histable*> *v = comparable_objs;
      for (int i = 0; i < v->size (); i++)
	{
	  Histable *h = v->fetch (i);
	  if (h)
	    {
	      h->comparable_objs = NULL;
	      h->phaseCompareIdx = phaseCompareIdx;
	    }
	}
      delete v;
    }
}

void
Histable::update_comparable_objs ()
{
  if (phaseCompareIdx != ExpGroup::phaseCompareIdx)
    {
      phaseCompareIdx = ExpGroup::phaseCompareIdx;
      delete_comparable_objs ();
    }
}

Vector<Histable*> *
Histable::get_comparable_objs ()
{
  return comparable_objs;
}

Histable *
Histable::get_compare_obj ()
{
  Vector<Histable*> *v = get_comparable_objs ();
  for (long i = 0, sz = VecSize (v); i < sz; i++)
    {
      Histable *h = v->get (i);
      if (h)
	return h;
    }
  return this;
}

#define CASE_S(x)   case x: return (char *) #x

char *
Histable::type_to_string ()
{
  switch (get_type ())
    {
      CASE_S (INSTR);
      CASE_S (LINE);
      CASE_S (FUNCTION);
      CASE_S (MODULE);
      CASE_S (LOADOBJECT);
      CASE_S (EADDR);
      CASE_S (MEMOBJ);
      CASE_S (INDEXOBJ);
      CASE_S (PAGE);
      CASE_S (DOBJECT);
      CASE_S (SOURCEFILE);
      CASE_S (EXPERIMENT);
      CASE_S (OTHER);
    default:
      break;
    }
  return NTXT ("ERROR");
}

void
Histable::dump_comparable_objs ()
{
  Dprintf (DEBUG_COMPARISON,
	   "# Histable::dump_comparable_objs type=%s(%d) 0x%lx id=%lld %s\n",
	   type_to_string (), get_type (), (unsigned long) this, (long long) id,
	   STR (get_name ()));
  for (int i = 0, sz = comparable_objs ? comparable_objs->size () : 0; i < sz; i++)
    {
      Histable *h = comparable_objs->fetch (i);
      Dprintf (DEBUG_COMPARISON, "  %d type=%s(%d) 0x%lx id=%lld %s\n", i,
	       h ? h->type_to_string () : "", h ? h->get_type () : -1,
	       (unsigned long) h, (long long) (h ? h->id : 0),
	       h ? STR (h->get_name ()) : NTXT (""));
    }
}

char *
Histable::dump ()
{
  StringBuilder sb;
  sb.appendf (sizeof (long) == 32
	      ? " 0x%08lx : type=%s(%d) id=%lld %s"
	      : " 0x%016lx : type=%s(%d) id=%lld %s",
	      (unsigned long) this, type_to_string (), get_type (),
	      (long long) id, STR (get_name ()));
  switch (get_type ())
    {
    case INSTR:
      {
	DbeInstr *o = (DbeInstr *) this;
	sb.appendf (sizeof (long) == 32
		    ? "   func=0x%08lx lineno=%lld"
		    : "   func=0x%016lx lineno=%lld",
		    (unsigned long) o->func, (long long) o->lineno);
	break;
      }
    case LINE:
      {
	DbeLine *o = (DbeLine *) this;
	sb.appendf (sizeof (long) == 32
		    ? "   func=0x%08lx sourceFile=0x%08lx lineno=%lld"
		    : "   func=0x%016lx sourceFile=0x%016lx lineno=%lld",
		    (unsigned long) o->func, (unsigned long) o->sourceFile,
		    (long long) o->lineno);
	break;
      }
    default:
      break;
    }
  return sb.toString ();
}
