/* Copyright (C) 2021-2024 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,
		      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;
      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 ();
}
