/* 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.  */

#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
  char *tname = NTXT ("<Total>");
  for (int i = 0; i < hist_items->size (); ++i)
    {
      HistItem *hi = hist_items->fetch (i);
      char *name = hi->obj->get_name ();
      if (name != NULL && streq (name, tname))
	{
	  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, 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;
      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;
	  sb->appendf (NTXT ("%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 ();
}
