/* 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 <ctype.h>
#include <stdio.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/param.h>

#include "util.h"
#include "Application.h"
#include "Experiment.h"
#include "ExpGroup.h"
#include "Expression.h"
#include "DataObject.h"
#include "Elf.h"
#include "Function.h"
#include "DbeSession.h"
#include "LoadObject.h"
#include "DbeSyncMap.h"
#include "DbeThread.h"
#include "ClassFile.h"
#include "IndexObject.h"
#include "PathTree.h"
#include "Print.h"

// Bison 3.0 doesn't define YY_NULLPTR. I copied this from QLParser.tab.cc.
// Why this is not in QLParser.tab.hh ? YY_NULLPTR is used in QLParser.tab.hh
# ifndef YY_NULLPTR
#  if defined __cplusplus && 201103L <= __cplusplus
#   define YY_NULLPTR nullptr
#  else
#   define YY_NULLPTR 0
#  endif
# endif
#include "QLParser.tab.hh"
#include "DbeView.h"
#include "MemorySpace.h"
#include "Module.h"
#include "SourceFile.h"
#include "StringBuilder.h"
#include "BaseMetric.h"
#include "BaseMetricTreeNode.h"
#include "Command.h"
#include "UserLabel.h"
#include "StringMap.h"
#include "DbeFile.h"
#include "DbeJarFile.h"
#include "IOActivity.h"
#include "HeapActivity.h"

// This is a universal List structure to organize objects
// of various types, even if different.
struct List
{
  List *next;
  void *val;
};

struct Countable
{
  Countable (void *_item)
  {
    item = _item;
    ref_count = 0;
  }

  void *item;
  int ref_count;
};

Platform_t DbeSession::platform =
#if ARCH(SPARC)
	Sparc;
#elif ARCH(Aarch64)
	Aarch64;
#else   // ARCH(Intel)
	Intel;
#endif

// This constant determines the size of the data object name hash table.
static const int HTableSize         = 8192;
static int DEFAULT_TINY_THRESHOLD   = -1;

unsigned int mpmt_debug_opt = 0;
DbeSession *dbeSession = NULL;

DbeSession::DbeSession (Settings *_settings, bool _ipc_mode, bool _rdt_mode)
{
  dbeSession = this;
  ipc_mode = _ipc_mode;
  rdt_mode = _rdt_mode;
  settings = new Settings (_settings);
  views = new Vector<DbeView*>;
  exps = new Vector<Experiment*>;
  lobjs = new Vector<LoadObject*>;
  objs = new Vector<Histable*>;
  dobjs = new Vector<DataObject*>;
  metrics = new Vector<Countable*>;
  reg_metrics = new Vector<BaseMetric*>;
  hwcentries = NULL;
  reg_metrics_tree = NULL; // BaseMetric() requires DbeSession::ql_parse
  idxobjs = new Vector<HashMap<uint64_t, Histable*>*>;
  tmp_files = new Vector<char*>;
  search_path = new Vector<char*>;
  classpath = new Vector<char*>;
  classpath_df = NULL;
  expGroups = new Vector<ExpGroup*>;
  sourcesMap = new HashMap<char*, SourceFile*>;
  sources = new Vector<SourceFile*>;
  comp_lobjs = new HashMap<char*, LoadObject*>;
  comp_dbelines = new HashMap<char*, DbeLine*>;
  comp_sources = new HashMap<char*, SourceFile*>;
  loadObjMap = new DbeSyncMap<LoadObject>;
  f_special = new Vector<Function*>(LastSpecialFunction);
  omp_functions = new Vector<Function*>(OMP_LAST_STATE);
  interactive = false;
  lib_visibility_used = false;

  // Define all known property names
  propNames = new Vector<PropDescr*>;
  propNames_name_store (PROP_NONE, NTXT (""));
  propNames_name_store (PROP_ATSTAMP, NTXT ("ATSTAMP"));
  propNames_name_store (PROP_ETSTAMP, NTXT ("ETSTAMP"));
  propNames_name_store (PROP_TSTAMP, NTXT ("TSTAMP"));
  propNames_name_store (PROP_THRID, NTXT ("THRID"));
  propNames_name_store (PROP_LWPID, NTXT ("LWPID"));
  propNames_name_store (PROP_CPUID, NTXT ("CPUID"));
  propNames_name_store (PROP_FRINFO, NTXT ("FRINFO"));
  propNames_name_store (PROP_EVT_TIME, NTXT ("EVT_TIME"));

  // Samples
  propNames_name_store (PROP_SMPLOBJ, NTXT ("SMPLOBJ"));
  propNames_name_store (PROP_SAMPLE, NTXT ("SAMPLE"));

  // GCEvents
  propNames_name_store (PROP_GCEVENTOBJ, NTXT ("GCEVENTOBJ"));
  propNames_name_store (PROP_GCEVENT, NTXT ("GCEVENT"));

  // Metadata used by some packet types
  propNames_name_store (PROP_VOIDP_OBJ, NTXT ("VOIDP_OBJ"),
			NULL, TYPE_UINT64, DDFLAG_NOSHOW);

  // Clock profiling properties
  propNames_name_store (PROP_UCPU, NTXT ("UCPU"));
  propNames_name_store (PROP_SCPU, NTXT ("SCPU"));
  propNames_name_store (PROP_TRAP, NTXT ("TRAP"));
  propNames_name_store (PROP_TFLT, NTXT ("TFLT"));
  propNames_name_store (PROP_DFLT, NTXT ("DFLT"));
  propNames_name_store (PROP_KFLT, NTXT ("KFLT"));
  propNames_name_store (PROP_ULCK, NTXT ("ULCK"));
  propNames_name_store (PROP_TSLP, NTXT ("TSLP"));
  propNames_name_store (PROP_WCPU, NTXT ("WCPU"));
  propNames_name_store (PROP_TSTP, NTXT ("TSTP"));

  propNames_name_store (PROP_MSTATE, NTXT ("MSTATE"));
  propNames_name_store (PROP_NTICK, NTXT ("NTICK"));
  propNames_name_store (PROP_OMPSTATE, NTXT ("OMPSTATE"));

  // Synchronization tracing properties
  propNames_name_store (PROP_SRQST, NTXT ("SRQST"));
  propNames_name_store (PROP_SOBJ, NTXT ("SOBJ"));

  // Hardware counter profiling properties
  propNames_name_store (PROP_HWCTAG, NTXT ("HWCTAG"));
  propNames_name_store (PROP_HWCINT, NTXT ("HWCINT"));
  propNames_name_store (PROP_VADDR, NTXT ("VADDR"));
  propNames_name_store (PROP_PADDR, NTXT ("PADDR"));
  propNames_name_store (PROP_VIRTPC, NTXT ("VIRTPC"));
  propNames_name_store (PROP_PHYSPC, NTXT ("PHYSPC"));
  propNames_name_store (PROP_LWP_LGRP_HOME, NTXT ("LWP_LGRP_HOME"));
  propNames_name_store (PROP_PS_LGRP_HOME, NTXT ("PS_LGRP_HOME"));
  propNames_name_store (PROP_EA_PAGESIZE, NTXT ("EA_PAGESIZE"));
  propNames_name_store (PROP_EA_LGRP, NTXT ("EA_LGRP"));
  propNames_name_store (PROP_PC_PAGESIZE, NTXT ("PC_PAGESIZE"));
  propNames_name_store (PROP_PC_LGRP, NTXT ("PC_LGRP"));
  propNames_name_store (PROP_HWCDOBJ, NTXT ("HWCDOBJ"));
  propNames_name_store (PROP_MEM_LAT, NTXT ("MEM_LAT"));
  propNames_name_store (PROP_MEM_SRC, NTXT ("MEM_SRC"));

  // Heap tracing properties
  propNames_name_store (PROP_HTYPE, NTXT ("HTYPE"));
  propNames_name_store (PROP_HSIZE, NTXT ("HSIZE"));
  propNames_name_store (PROP_HVADDR, NTXT ("HVADDR"));
  propNames_name_store (PROP_HOVADDR, NTXT ("HOVADDR"));
  propNames_name_store (PROP_HLEAKED, NTXT ("HLEAKED"),
			GTXT ("Leaked bytes"), TYPE_UINT64, 0);
  propNames_name_store (PROP_HMEM_USAGE, NTXT ("HMEM_USAGE"));
  propNames_name_store (PROP_HFREED, NTXT ("HFREED"),
			GTXT ("Freed bytes"), TYPE_UINT64, 0);
  propNames_name_store (PROP_HCUR_ALLOCS, NTXT ("HCUR_ALLOCS"),
			GTXT ("Current allocations"), TYPE_INT64, 0);
  propNames_name_store (PROP_HCUR_NET_ALLOC, NTXT ("HCUR_NET_ALLOC"),
			NULL, TYPE_INT64, DDFLAG_NOSHOW);
  propNames_name_store (PROP_HCUR_LEAKS, NTXT ("HCUR_LEAKS"),
			GTXT ("Current leaks"), TYPE_UINT64, 0);
  propNames_name_store (PROP_DDSCR_LNK, NTXT ("DDSCR_LNK"),
			NULL, TYPE_UINT64, DDFLAG_NOSHOW);

  // IO tracing properties
  propNames_name_store (PROP_IOTYPE, NTXT ("IOTYPE"));
  propNames_name_store (PROP_IOFD, NTXT ("IOFD"));
  propNames_name_store (PROP_IONBYTE, NTXT ("IONBYTE"));
  propNames_name_store (PROP_IORQST, NTXT ("IORQST"));
  propNames_name_store (PROP_IOOFD, NTXT ("IOOFD"));
  propNames_name_store (PROP_IOFNAME, NTXT ("IOFNAME"));
  propNames_name_store (PROP_IOVFD, NTXT ("IOVFD"));
  propNames_name_store (PROP_IOFSTYPE, NTXT ("IOFSTYPE"));

  // omptrace raw properties
  propNames_name_store (PROP_CPRID, NTXT ("CPRID"));
  propNames_name_store (PROP_PPRID, NTXT ("PPRID"));
  propNames_name_store (PROP_TSKID, NTXT ("TSKID"));
  propNames_name_store (PROP_PTSKID, NTXT ("PTSKID"));
  propNames_name_store (PROP_PRPC, NTXT ("PRPC"));

  // Data race detection properties
  propNames_name_store (PROP_RID, NTXT ("RID"));
  propNames_name_store (PROP_RTYPE, NTXT ("RTYPE"));
  propNames_name_store (PROP_LEAFPC, NTXT ("LEAFPC"));
  propNames_name_store (PROP_RVADDR, NTXT ("RVADDR"));
  propNames_name_store (PROP_RCNT, NTXT ("RCNT"));

  // Deadlock detection properties
  propNames_name_store (PROP_DID, NTXT ("DID"));
  propNames_name_store (PROP_DLTYPE, NTXT ("DLTYPE"));
  propNames_name_store (PROP_DTYPE, NTXT ("DTYPE"));
  propNames_name_store (PROP_DVADDR, NTXT ("DVADDR"));

  // Synthetic properties (queries only)
  propNames_name_store (PROP_STACK, NTXT ("STACK"));
  propNames_name_store (PROP_MSTACK, NTXT ("MSTACK"));
  propNames_name_store (PROP_USTACK, NTXT ("USTACK"));
  propNames_name_store (PROP_XSTACK, NTXT ("XSTACK"));
  propNames_name_store (PROP_HSTACK, NTXT ("HSTACK"));
  propNames_name_store (PROP_STACKID, NTXT ("STACKID"));
  //propNames_name_store( PROP_CPRID,   NTXT("CPRID") );
  //propNames_name_store( PROP_TSKID,   NTXT("TSKID") );
  propNames_name_store (PROP_JTHREAD, NTXT ("JTHREAD"),
			GTXT ("Java thread number"), TYPE_UINT64, 0);

  propNames_name_store (PROP_LEAF, NTXT ("LEAF"));
  propNames_name_store (PROP_DOBJ, NTXT ("DOBJ"));
  propNames_name_store (PROP_SAMPLE_MAP, NTXT ("SAMPLE_MAP"));
  propNames_name_store (PROP_GCEVENT_MAP, NTXT ("GCEVENT_MAP"));
  propNames_name_store (PROP_PID, NTXT ("PID"),
			GTXT ("Process id"), TYPE_UINT64, 0);
  propNames_name_store (PROP_EXPID, NTXT ("EXPID"),
			GTXT ("Experiment id"), TYPE_UINT64, DDFLAG_NOSHOW);
  propNames_name_store (PROP_EXPID_CMP, NTXT ("EXPID_CMP"),
			GTXT ("Comparable Experiment Id"), TYPE_UINT64,
			DDFLAG_NOSHOW); //YXXX find better description
  propNames_name_store (PROP_EXPGRID, NTXT ("EXPGRID"),
			GTXT ("Comparison Group id"), TYPE_UINT64, 0);
  propNames_name_store (PROP_PARREG, NTXT ("PARREG"));
  propNames_name_store (PROP_TSTAMP_LO, NTXT ("TSTAMP_LO"),
			GTXT ("Start Timestamp (nanoseconds)"), TYPE_UINT64, 0);
  propNames_name_store (PROP_TSTAMP_HI, NTXT ("TSTAMP_HI"),
			GTXT ("End Timestamp (nanoseconds)"), TYPE_UINT64, 0);
  propNames_name_store (PROP_TSTAMP2, NTXT ("TSTAMP2"),
			GTXT ("End Timestamp (nanoseconds)"), TYPE_UINT64,
			DDFLAG_NOSHOW);
  propNames_name_store (PROP_FREQ_MHZ, NTXT ("FREQ_MHZ"),
			GTXT ("CPU Frequency, MHz"), TYPE_UINT32, 0);
  propNames_name_store (PROP_NTICK_USEC, NTXT ("NTICK_USEC"),
			GTXT ("Clock Profiling Interval, Microseconds"),
			TYPE_UINT64, 0);

  propNames_name_store (PROP_IOHEAPBYTES, NTXT ("IOHEAPBYTES"));

  propNames_name_store (PROP_STACKL, NTXT ("STACKL"));
  propNames_name_store (PROP_MSTACKL, NTXT ("MSTACKL"));
  propNames_name_store (PROP_USTACKL, NTXT ("USTACKL"));
  propNames_name_store (PROP_XSTACKL, NTXT ("XSTACKL"));

  propNames_name_store (PROP_STACKI, NTXT ("STACKI"));
  propNames_name_store (PROP_MSTACKI, NTXT ("MSTACKI"));
  propNames_name_store (PROP_USTACKI, NTXT ("USTACKI"));
  propNames_name_store (PROP_XSTACKI, NTXT ("XSTACKI"));

  // Make sure predefined names are not used for dynamic properties
  propNames_name_store (PROP_LAST, NTXT (""));

  localized_SP_UNKNOWN_NAME = GTXT ("(unknown)");

  // define Index objects
  dyn_indxobj = new Vector<IndexObjType_t*>();
  dyn_indxobj_indx = 0;
  char *s = dbe_sprintf (NTXT ("((EXPID_CMP<<%llu) | THRID)"),
			 (unsigned long long) IndexObject::INDXOBJ_EXPID_SHIFT);
  indxobj_define (NTXT ("Threads"), GTXT ("Threads"), s, NULL, NULL);
  free (s);
  indxobj_define (NTXT ("CPUs"), GTXT ("CPUs"), NTXT ("(CPUID)"), NULL, NULL);
  indxobj_define (NTXT ("Samples"), GTXT ("Samples"), NTXT ("(SAMPLE_MAP)"),
		  NULL, NULL);
  indxobj_define (NTXT ("GCEvents"), GTXT ("GCEvents"), NTXT ("(GCEVENT_MAP)"),
		  NULL, NULL);
  indxobj_define (NTXT ("Seconds"), GTXT ("Seconds"),
		  NTXT ("(TSTAMP/1000000000)"), NULL, NULL);
  indxobj_define (NTXT ("Processes"), GTXT ("Processes"), NTXT ("(EXPID_CMP)"),
		  NULL, NULL);
  s = dbe_sprintf (NTXT ("((EXPGRID<<%llu) | (EXPID<<%llu))"),
		   (unsigned long long) IndexObject::INDXOBJ_EXPGRID_SHIFT,
		   (unsigned long long) IndexObject::INDXOBJ_EXPID_SHIFT);
  indxobj_define (NTXT ("Experiment_IDs"), GTXT ("Experiment_IDs"), s, NULL, NULL);
  free (s);
  indxobj_define (NTXT ("Datasize"), GTXT ("Datasize"),
		  "(IOHEAPBYTES==0?0:"
		  "((IOHEAPBYTES<=(1<<0)?(1<<0):"
		  "((IOHEAPBYTES<=(1<<2)?(1<<2):"
		  "((IOHEAPBYTES<=(1<<4)?(1<<4):"
		  "((IOHEAPBYTES<=(1<<6)?(1<<6):"
		  "((IOHEAPBYTES<=(1<<8)?(1<<8):"
		  "((IOHEAPBYTES<=(1<<10)?(1<<10):"
		  "((IOHEAPBYTES<=(1<<12)?(1<<12):"
		  "((IOHEAPBYTES<=(1<<14)?(1<<14):"
		  "((IOHEAPBYTES<=(1<<16)?(1<<16):"
		  "((IOHEAPBYTES<=(1<<18)?(1<<18):"
		  "((IOHEAPBYTES<=(1<<20)?(1<<20):"
		  "((IOHEAPBYTES<=(1<<22)?(1<<22):"
		  "((IOHEAPBYTES<=(1<<24)?(1<<24):"
		  "((IOHEAPBYTES<=(1<<26)?(1<<26):"
		  "((IOHEAPBYTES<=(1<<28)?(1<<28):"
		  "((IOHEAPBYTES<=(1<<30)?(1<<30):"
		  "((IOHEAPBYTES<=(1<<32)?(1<<32):"
		  "((IOHEAPBYTES<=(1<<34)?(1<<34):"
		  "((IOHEAPBYTES<=(1<<36)?(1<<36):"
		  "((IOHEAPBYTES<=(1<<38)?(1<<38):"
		  "((IOHEAPBYTES<=(1<<40)?(1<<40):"
		  "((IOHEAPBYTES<=(1<<42)?(1<<42):"
		  "((IOHEAPBYTES<=(1<<44)?(1<<44):"
		  "((IOHEAPBYTES<=(1<<46)?(1<<46):"
		  "((IOHEAPBYTES<=(1<<48)?(1<<48):"
		  "((IOHEAPBYTES<=(1<<50)?(1<<50):"
		  "(IOHEAPBYTES==-1?-1:(1<<50|1)"
		  "))))))))))))))))))))))))))))))))))))))))))))))))))))))",
		  NULL, NULL);
  indxobj_define (NTXT ("Duration"), GTXT ("Duration"),
		  "((TSTAMP_HI-TSTAMP_LO)==0?0:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=1000?1000:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=10000?10000:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=100000?100000:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=1000000?1000000:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=10000000?10000000:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=100000000?100000000:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=1000000000?1000000000:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=10000000000?10000000000:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=100000000000?100000000000:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=1000000000000?1000000000000:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=10000000000000?10000000000000:"
		  "(10000000000001))))))))))))))))))))))))", NULL, NULL);
  dyn_indxobj_indx_fixed = dyn_indxobj_indx;
  Elf::elf_init ();
  defExpName = NULL;
  mach_model_loaded = NULL;
  tmp_dir_name = NULL;
  settings->read_rc (ipc_mode || rdt_mode);

  init ();
}

DbeSession::~DbeSession ()
{
  Destroy (views);
  Destroy (exps);
  Destroy (dobjs);
  Destroy (metrics);
  Destroy (search_path);
  Destroy (classpath);
  Destroy (propNames);
  Destroy (expGroups);
  Destroy (userLabels);
  if (hwcentries)
    {
      for (long i = 0, sz = hwcentries->size (); i < sz; i++)
	{
	  Hwcentry *h = hwcentries->get (i);
	  free (h->int_name);
	  free (h->name);
	  delete h;
	}
      delete hwcentries;
    }

  if (idxobjs)
    {
      for (int i = 0; i < idxobjs->size (); ++i)
	{
	  HashMap<uint64_t, Histable*> *hMap = idxobjs->get (i);
	  if (hMap)
	    {
	      hMap->values ()->destroy ();
	      delete hMap;
	    }
	}
      delete idxobjs;
    }

  for (int i = 0; i < HTableSize; i++)
    {
      List *list = dnameHTable[i];
      while (list)
	{
	  List *tmp = list;
	  list = list->next;
	  delete tmp;
	}
    }
  delete[] dnameHTable;
  delete classpath_df;
  Destroy (objs);
  Destroy (reg_metrics);
  Destroy (dyn_indxobj);
  delete lobjs;
  delete f_special;
  destroy_map (DbeFile *, dbeFiles);
  destroy_map (DbeJarFile *, dbeJarFiles);
  delete loadObjMap;
  delete omp_functions;
  delete sourcesMap;
  delete sources;
  delete comp_lobjs;
  delete comp_dbelines;
  delete comp_sources;
  delete reg_metrics_tree;
  delete settings;
  free (mach_model_loaded);

  if (defExpName != NULL)
    {
      StringBuilder *sb = new StringBuilder ();
      sb->append (NTXT ("/bin/rm -rf "));
      sb->append (defExpName);
      char *cmd = sb->toString ();
      system (cmd);
      free (cmd);
      delete sb;
      free (defExpName);
    }
  unlink_tmp_files ();
  delete tmp_files;
  dbeSession = NULL;
}

void
DbeSession::unlink_tmp_files ()
{
  if (tmp_files)
    {
      for (int i = 0, sz = tmp_files->size (); i < sz; i++)
	unlink (tmp_files->fetch (i));
      tmp_files->destroy ();
      delete tmp_files;
      tmp_files = NULL;
    }
  if (tmp_dir_name)
    {
      char *cmd = dbe_sprintf (NTXT ("/bin/rm -rf %s"), tmp_dir_name);
      system (cmd);
      free (cmd);
      free (tmp_dir_name);
      tmp_dir_name = NULL;
    }
}

char *
DbeSession::get_tmp_file_name (const char *nm, bool for_java)
{
  if (tmp_dir_name == NULL)
    {
      tmp_dir_name = dbe_sprintf (NTXT ("/tmp/analyzer.%llu.%lld"),
			 (unsigned long long) getuid (), (long long) getpid ());
      mkdir (tmp_dir_name, S_IRWXU);
    }
  char *fnm = dbe_sprintf (NTXT ("%s/%s"), tmp_dir_name, nm);
  if (for_java)
    for (char *s = fnm + strlen (tmp_dir_name) + 1; *s; s++)
      if (*s == '/')
	*s = '.';
  return fnm;
}

void
DbeSession::init ()
{
  user_exp_id_counter = 0;
  status_ompavail = 0;
  archive_mode = 0;

#if DEBUG
  char *s = getenv (NTXT ("MPMT_DEBUG"));
  if (s)
    mpmt_debug_opt = atoi (s);
#endif /* DEBUG */
  dbeFiles = new StringMap<DbeFile*>();
  dbeJarFiles = new StringMap<DbeJarFile*>(128, 128);

  // set up the initial (after .rc file reading) search path
  set_search_path (settings->str_search_path, true);
  userLabels = NULL;

  // Preset all objects as they may reuse each other
  lo_unknown = NULL;
  f_unknown = NULL;
  j_unknown = NULL;
  lo_total = NULL;
  sf_unknown = NULL;
  f_total = NULL;
  f_jvm = NULL;
  d_total = NULL;
  d_scalars = NULL;
  d_unknown = NULL;
  expGroups->destroy ();
  f_special->reset ();
  for (int i = 0; i < LastSpecialFunction; i++)
    f_special->append (NULL);

  lo_omp = NULL;
  omp_functions->reset ();
  for (int i = 0; i < OMP_LAST_STATE; i++)
    omp_functions->append (NULL);

  // make sure the metric list is initialized
  register_metric (Metric::SIZES);
  register_metric (Metric::ADDRESS);
  register_metric (Metric::ONAME);

  // This is needed only to maintain loadobject id's
  // for <Total> and <Unknown> in tests
  (void) get_Unknown_LoadObject ();
  (void) get_Total_LoadObject ();

  // Create the data object name hash table.
  dnameHTable = new List*[HTableSize];
  for (int i = 0; i < HTableSize; i++)
    dnameHTable[i] = NULL;

  d_total = createDataObject ();
  d_total->set_name (NTXT ("<Total>"));

  // XXXX <Scalars> only appropriate for Program/Data-oriented analyses
  d_scalars = createDataObject ();
  d_scalars->set_name (GTXT ("<Scalars>"));

  d_unknown = createDataObject ();
  d_unknown->set_name (GTXT ("<Unknown>"));

  // assign d_unknown's children so data_olayout has consistent sorting
  for (unsigned pp_code = 1; pp_code < NUM_ABS_PP_CODES + 2; pp_code++)
    {
      char *errcode;
      DataObject* dobj = createDataObject ();
      switch (pp_code)
	{
	case NUM_ABS_PP_CODES + 1:
	  errcode = PTXT (DOBJ_UNDETERMINED);
	  break;
	case NUM_ABS_PP_CODES:
	  errcode = PTXT (DOBJ_UNSPECIFIED);
	  break;
	case NUM_ABS_PP_CODES - 1:
	  errcode = PTXT (DOBJ_UNIDENTIFIED);
	  break;
	default:
	  errcode = PTXT (ABS_PP_CODES[pp_code]);
	}
      dobj->parent = d_unknown;
      dobj->set_dobjname (errcode, NULL); // dobj->parent must already be set
    }

  for (unsigned rt_code = 1; rt_code < NUM_ABS_RT_CODES - 1; rt_code++)
    {
      DataObject* dobj = createDataObject ();
      dobj->parent = d_unknown;
      dobj->set_dobjname (PTXT (ABS_RT_CODES[rt_code]), NULL); // dobj->parent must already be set
    }
}

void
DbeSession::reset_data ()
{
  for (long i = 0, sz = VecSize (idxobjs); i < sz; ++i)
    if (idxobjs->get (i))
      idxobjs->get (i)->reset ();
}

void
DbeSession::reset ()
{
  loadObjMap->reset ();
  DbeView *dbev;
  int index;

  Vec_loop (DbeView*, views, index, dbev)
  {
    dbev->reset ();
  }

  destroy_map (DbeFile *, dbeFiles);
  destroy_map (DbeJarFile *, dbeJarFiles);
  exps->destroy ();
  lobjs->reset ();      // all LoadObjects belong to objs
  dobjs->destroy ();    // deletes d_unknown and d_total as well
  objs->destroy ();
  comp_lobjs->clear ();
  comp_dbelines->clear ();
  comp_sources->clear ();
  sourcesMap->clear ();
  sources->reset ();

  // Delete the data object name hash table.
  for (int i = 0; i < HTableSize; i++)
    {
      List *list = dnameHTable[i];
      while (list)
	{
	  List *tmp = list;
	  list = list->next;
	  delete tmp;
	}
    }
  delete[] dnameHTable;

  // IndexObect definitions remain, objects themselves may go
  for (int i = 0; i < idxobjs->size (); ++i)
    {
      HashMap<uint64_t, Histable*> *v = idxobjs->fetch (i);
      if (v != NULL)
	{
	  v->values ()->destroy ();
	  v->clear ();
	}
    }
  init ();
}

Vector<SourceFile*> *
DbeSession::get_sources ()
{
  return sources;
}

DbeFile *
DbeSession::getDbeFile (char *filename, int filetype)
{
  Dprintf (DEBUG_DBE_FILE, NTXT ("DbeSession::getDbeFile  filetype=0x%x %s\n"), filetype, filename);
  if (strncmp (filename, NTXT ("./"), 2) == 0)
    filename += 2;
  DbeFile *dbeFile = dbeFiles->get (filename);
  if (dbeFile == NULL)
    {
      dbeFile = new DbeFile (filename);
      dbeFiles->put (filename, dbeFile);
    }
  dbeFile->filetype |= filetype;
  return dbeFile;
}

LoadObject *
DbeSession::get_Total_LoadObject ()
{
  if (lo_total == NULL)
    {
      lo_total = createLoadObject (NTXT ("<Total>"));
      lo_total->dbeFile->filetype |= DbeFile::F_FICTION;
    }
  return lo_total;
}

Function *
DbeSession::get_Total_Function ()
{
  if (f_total == NULL)
    {
      f_total = createFunction ();
      f_total->flags |= FUNC_FLAG_SIMULATED | FUNC_FLAG_NO_OFFSET;
      f_total->set_name (NTXT ("<Total>"));
      Module *mod = get_Total_LoadObject ()->noname;
      f_total->module = mod;
      mod->functions->append (f_total);
    }
  return f_total;
}

LoadObject *
DbeSession::get_Unknown_LoadObject ()
{
  if (lo_unknown == NULL)
    {
      lo_unknown = createLoadObject (GTXT ("<Unknown>"));
      lo_unknown->type = LoadObject::SEG_TEXT; // makes it expandable
      lo_unknown->dbeFile->filetype |= DbeFile::F_FICTION;

      // force creation of the <Unknown> function
      (void) get_Unknown_Function ();
    }
  return lo_unknown;
}

SourceFile *
DbeSession::get_Unknown_Source ()
{
  if (sf_unknown == NULL)
    {
      sf_unknown = createSourceFile (localized_SP_UNKNOWN_NAME);
      sf_unknown->dbeFile->filetype |= DbeFile::F_FICTION;
      sf_unknown->flags |= SOURCE_FLAG_UNKNOWN;
    }
  return sf_unknown;
}

Function *
DbeSession::get_Unknown_Function ()
{
  if (f_unknown == NULL)
    {
      f_unknown = createFunction ();
      f_unknown->flags |= FUNC_FLAG_SIMULATED;
      f_unknown->set_name (GTXT ("<Unknown>"));
      Module *mod = get_Unknown_LoadObject ()->noname;
      f_unknown->module = mod;
      mod->functions->append (f_unknown);
    }
  return f_unknown;
}

// LIBRARY_VISIBILITY

Function *
DbeSession::create_hide_function (LoadObject *lo)
{
  Function *h_function = createFunction ();
  h_function->set_name (lo->get_name ());
  h_function->module = lo->noname;
  h_function->isHideFunc = true;
  lo->noname->functions->append (h_function);
  return h_function;
}

Function *
DbeSession::get_JUnknown_Function ()
{
  if (j_unknown == NULL)
    {
      j_unknown = createFunction ();
      j_unknown->flags |= FUNC_FLAG_SIMULATED;
      j_unknown->set_name (GTXT ("<no Java callstack recorded>"));
      Module *mod = get_Unknown_LoadObject ()->noname;
      j_unknown->module = mod;
      mod->functions->append (j_unknown);
    }
  return j_unknown;
}

Function *
DbeSession::get_jvm_Function ()
{
  if (f_jvm == NULL)
    {
      f_jvm = createFunction ();
      f_jvm->flags |= FUNC_FLAG_SIMULATED | FUNC_FLAG_NO_OFFSET;
      f_jvm->set_name (GTXT ("<JVM-System>"));

      // Find the JVM LoadObject
      LoadObject *jvm = get_Unknown_LoadObject ();
      for (int i = 0; i < lobjs->size (); ++i)
	{
	  LoadObject *lo = lobjs->fetch (i);
	  if (lo->flags & SEG_FLAG_JVM)
	    {
	      jvm = lo;
	      break;
	    }
	}
      Module *mod = jvm->noname;
      f_jvm->module = mod;
      mod->functions->append (f_jvm);
      // XXXX is it required? no consistency among all special functions
      // jvm->functions->append( f_jvm );
    }
  return f_jvm;
}

Function *
DbeSession::getSpecialFunction (SpecialFunction kind)
{
  if (kind < 0 || kind >= LastSpecialFunction)
    return NULL;

  Function *func = f_special->fetch (kind);
  if (func == NULL)
    {
      char *fname;
      switch (kind)
	{
	case TruncatedStackFunc:
	  fname = GTXT ("<Truncated-stack>");
	  break;
	case FailedUnwindFunc:
	  fname = GTXT ("<Stack-unwind-failed>");
	  break;
	default:
	  return NULL;
	}
      func = createFunction ();
      func->flags |= FUNC_FLAG_SIMULATED | FUNC_FLAG_NO_OFFSET;
      Module *mod = get_Total_LoadObject ()->noname;
      func->module = mod;
      mod->functions->append (func);
      func->set_name (fname);
      f_special->store (kind, func);
    }
  return func;
}

LoadObject *
DbeSession::get_OMP_LoadObject ()
{
  if (lo_omp == NULL)
    {
      for (int i = 0, sz = lobjs->size (); i < sz; i++)
	{
	  LoadObject *lo = lobjs->fetch (i);
	  if (lo->flags & SEG_FLAG_OMP)
	    {
	      lo_omp = lo;
	      return lo_omp;
	    }
	}
      lo_omp = createLoadObject (GTXT ("<OMP>"));
      lo_omp->type = LoadObject::SEG_TEXT;
      lo_omp->dbeFile->filetype |= DbeFile::F_FICTION;
    }
  return lo_omp;
}

Function *
DbeSession::get_OMP_Function (int n)
{
  if (n < 0 || n >= OMP_LAST_STATE)
    return NULL;

  Function *func = omp_functions->fetch (n);
  if (func == NULL)
    {
      char *fname;
      switch (n)
	{
	case OMP_OVHD_STATE:
	  fname = GTXT ("<OMP-overhead>");
	  break;
	case OMP_IDLE_STATE:
	  fname = GTXT ("<OMP-idle>");
	  break;
	case OMP_RDUC_STATE:
	  fname = GTXT ("<OMP-reduction>");
	  break;
	case OMP_IBAR_STATE:
	  fname = GTXT ("<OMP-implicit_barrier>");
	  break;
	case OMP_EBAR_STATE:
	  fname = GTXT ("<OMP-explicit_barrier>");
	  break;
	case OMP_LKWT_STATE:
	  fname = GTXT ("<OMP-lock_wait>");
	  break;
	case OMP_CTWT_STATE:
	  fname = GTXT ("<OMP-critical_section_wait>");
	  break;
	case OMP_ODWT_STATE:
	  fname = GTXT ("<OMP-ordered_section_wait>");
	  break;
	case OMP_ATWT_STATE:
	  fname = GTXT ("<OMP-atomic_wait>");
	  break;
	default:
	  return NULL;
	}
      func = createFunction ();
      func->flags |= FUNC_FLAG_SIMULATED | FUNC_FLAG_NO_OFFSET;
      func->set_name (fname);

      LoadObject *omp = get_OMP_LoadObject ();
      func->module = omp->noname;
      omp->noname->functions->append (func);
      omp->functions->append (func);
      omp_functions->store (n, func);
    }
  return func;
}

// Divide the original createExperiment() into two steps
// In part1, we just create the data structure, in part2, if
// we decide to keep the experiment around, add it to various
// lists in DbeSession
Experiment *
DbeSession::createExperimentPart1 ()
{
  Experiment *exp = new Experiment ();
  return exp;
}

void
DbeSession::createExperimentPart2 (Experiment *exp)
{
  int ind = expGroups->size ();
  if (ind > 0)
    {
      ExpGroup *gr = expGroups->fetch (ind - 1);
      exp->groupId = gr->groupId;
      gr->append (exp);
    }
  exp->setExpIdx (exps->size ());
  exp->setUserExpId (++user_exp_id_counter);
  exps->append (exp);
}

Experiment *
DbeSession::createExperiment ()
{
  Experiment *exp = new Experiment ();
  append (exp);
  return exp;
}

void
DbeSession::append (Experiment *exp)
{
  exp->setExpIdx (exps->size ());
  exp->setUserExpId (++user_exp_id_counter);
  exps->append (exp);
  if (exp->founder_exp)
    {
      if (exp->founder_exp->children_exps == NULL)
	exp->founder_exp->children_exps = new Vector<Experiment *>;
      exp->founder_exp->children_exps->append (exp);
      if (exp->founder_exp->groupId > 0)
	{
	  exp->groupId = exp->founder_exp->groupId;
	  expGroups->get (exp->groupId - 1)->append (exp);
	}
    }
  if (exp->groupId == 0)
    {
      long ind = VecSize (expGroups);
      if (ind > 0)
	{
	  ExpGroup *gr = expGroups->get (ind - 1);
	  exp->groupId = gr->groupId;
	  gr->append (exp);
	}
    }
}

void
DbeSession::append (Hwcentry *h)
{
  if (hwcentries == NULL)
    hwcentries = new Vector<Hwcentry*>;
  hwcentries->append (h);
}

int
DbeSession::ngoodexps ()
{
  return exps->size ();
}

int
DbeSession::createView (int index, int cloneindex)
{
  // ensure that there is no view with that index
  DbeView *dbev = getView (index);
  if (dbev != NULL)
    abort ();

  // find the view to be cloned
  dbev = getView (cloneindex);
  DbeView *newview;
  if (dbev == NULL)
    newview = new DbeView (theApplication, settings, index);
  else
    newview = new DbeView (dbev, index);
  views->append (newview);
  return index;
}

DbeView *
DbeSession::getView (int index)
{
  int i;
  DbeView *dbev;
  Vec_loop (DbeView*, views, i, dbev)
  {
    if (dbev->vindex == index)
      return dbev;
  }
  return NULL;
}

void
DbeSession::dropView (int index)
{
  int i;
  DbeView *dbev;

  Vec_loop (DbeView*, views, i, dbev)
  {
    if (dbev->vindex == index)
      {
	views->remove (i);
	delete dbev;
	return;
      }
  }
  // view not found; ignore for now
}

Vector<char*> *
DbeSession::get_group_or_expt (char *path)
{
  Vector<char*> *exp_list = new Vector<char*>;
  FILE *fptr;
  char *new_path, buf[MAXPATHLEN], name[MAXPATHLEN];

  fptr = fopen (path, NTXT ("r"));
  if (!fptr || !fgets (buf, (int) sizeof (buf), fptr)
      || strncmp (buf, SP_GROUP_HEADER, strlen (SP_GROUP_HEADER)))
    {
      // it's not an experiment group
      new_path = dbe_strdup (path);
      new_path = canonical_path (new_path);
      exp_list->append (new_path);
    }
  else
    {
      // it is an experiment group, read the list to get them all
      while (fgets (buf, (int) sizeof (buf), fptr))
	{
	  if ((*buf != '#') && (sscanf (buf, NTXT ("%s"), name) == 1))
	    {
	      new_path = dbe_strdup (name);
	      new_path = canonical_path (new_path);
	      exp_list->append (new_path);
	    }
	}
    }
  if (fptr)
    fclose (fptr);
  return exp_list;
}

#define GET_INT_VAL(v, s, len) \
    for (v = len = 0; isdigit(*s); s++, len++) { v = v * 10 + (*s -'0'); }

static int
dir_name_cmp (const void *a, const void *b)
{
  char *s1 = *((char **) a);
  char *s2 = *((char **) b);
  while (*s1)
    {
      if (isdigit (*s1) && isdigit (*s2))
	{
	  int v1, v2, len1, len2;
	  GET_INT_VAL (v1, s1, len1);
	  GET_INT_VAL (v2, s2, len2);
	  if (v1 != v2)
	    return v1 - v2;
	  if (len1 != len2)
	    return len2 - len1;
	  continue;
	}
      if (*s1 != *s2)
	break;
      s1++;
      s2++;
    }
  return *s1 - *s2;
}

static int
read_experiment_data_in_parallel (void *arg)
{
  exp_ctx *ctx = (exp_ctx *) arg;
  Experiment *dexp = ctx->exp;
  bool read_ahead = ctx->read_ahead;
  dexp->read_experiment_data (read_ahead);
  free (ctx);
  return 0;
}

void
DbeSession::open_experiment (Experiment *exp, char *path)
{
  exp->open (path);
  if (exp->get_status () != Experiment::FAILURE)
    exp->read_experiment_data (false);
  exp->open_epilogue ();

  // Update all DbeViews
  for (int i = 0, sz = views->size (); i < sz; i++)
    {
      DbeView *dbev = views->fetch (i);
      dbev->add_experiment (exp->getExpIdx (), true);
    }

  if (exp->get_status () == Experiment::FAILURE)
    {
      check_tab_avail ();
      return;
    }

  char *discard_tiny = getenv (NTXT ("SP_ANALYZER_DISCARD_TINY_EXPERIMENTS"));
  int user_specified_tiny_threshold = DEFAULT_TINY_THRESHOLD; // in milliseconds
  if (discard_tiny != NULL)
    {
      user_specified_tiny_threshold = (atoi (discard_tiny));
      if (user_specified_tiny_threshold < 0)
	user_specified_tiny_threshold = DEFAULT_TINY_THRESHOLD;
    }

  // Open descendant experiments
  DIR *exp_dir = opendir (path);
  if (exp_dir == NULL)
    {
      check_tab_avail ();
      return;
    }

  Vector<char*> *exp_names = new Vector<char*>();
  struct dirent *entry = NULL;
  while ((entry = readdir (exp_dir)) != NULL)
    {
      if (entry->d_name[0] != '_')
	continue;
      size_t len = strlen (entry->d_name);
      if (len < 3 || strcmp (entry->d_name + len - 3, NTXT (".er")) != 0)
	continue;
      exp_names->append (dbe_strdup (entry->d_name));
    }
  closedir (exp_dir);
  exp_names->sort (dir_name_cmp);
  Experiment **t_exp_list = new Experiment *[exp_names->size ()];
  int nsubexps = 0;

  for (int j = 0, jsz = exp_names->size (); j < jsz; j++)
    {
      t_exp_list[j] = NULL;

      char *lineage_name = exp_names->fetch (j);
      struct stat64 sbuf;
      char *dpath = dbe_sprintf (NTXT ("%s/%s"), path, lineage_name);

      // look for experiments with no profile collected
      if (user_specified_tiny_threshold == DEFAULT_TINY_THRESHOLD)
	{
	  char *frinfoname = dbe_sprintf (NTXT ("%s/%s"), dpath, "data." SP_FRINFO_FILE);
	  int st = dbe_stat (frinfoname, &sbuf);
	  free (frinfoname);
	  if (st == 0)
	    {
	      // if no profile/trace data do not process this experiment any further
	      if (sbuf.st_size == 0)
		{
		  free (dpath);
		  continue;
		}
	    }
	}
      else
	{ // check if dpath is a directory
	  if (dbe_stat (dpath, &sbuf) != 0)
	    {
	      free (dpath);
	      continue;
	    }
	  else if (!S_ISDIR (sbuf.st_mode))
	    {
	      free (dpath);
	      continue;
	    }
	}
      size_t lineage_name_len = strlen (lineage_name);
      lineage_name[lineage_name_len - 3] = 0; /* remove .er */
      Experiment *dexp = new Experiment ();
      dexp->founder_exp = exp;
      if (user_specified_tiny_threshold > DEFAULT_TINY_THRESHOLD)
	{
	  dexp->setTinyThreshold (user_specified_tiny_threshold);
	  dexp->open (dpath);
	  if (dexp->isDiscardedTinyExperiment ())
	    {
	      delete dexp;
	      free (dpath);
	      continue;
	    }
	}
      else
	dexp->open (dpath);
      append (dexp);
      t_exp_list[j] = dexp;
      nsubexps++;
      dexp->set_clock (exp->clock);

      // DbeView add_experiment() is split into two parts
      // add_subexperiment() is called repeeatedly for
      // all sub_experiments, later add_experiment_epilogue() finishes up the task
      for (int i = 0, sz = views->size (); i < sz; i++)
	{
	  DbeView *dbev = views->fetch (i);
	  bool enabled = settings->check_en_desc (lineage_name, dexp->utargname);
	  dbev->add_subexperiment (dexp->getExpIdx (), enabled);
	}
      free (dpath);
    }

  for (int i = 0, sz = views->size (); i < sz; i++)
    {
      DbeView *dbev = views->fetch (i);
      dbev->add_experiment_epilogue ();
    }

  DbeThreadPool * threadPool = new DbeThreadPool (-1);
  for (int j = 0, jsz = exp_names->size (); j < jsz; j++)
    {
      if (t_exp_list[j] == NULL) continue;
      Experiment *dexp = t_exp_list[j];
      exp_ctx *new_ctx = (exp_ctx*) malloc (sizeof (exp_ctx));
      new_ctx->path = NULL;
      new_ctx->exp = dexp;
      new_ctx->ds = this;
      new_ctx->read_ahead = true;
      DbeQueue *q = new DbeQueue (read_experiment_data_in_parallel, new_ctx);
      threadPool->put_queue (q);
    }
  threadPool->wait_queues ();
  delete threadPool;

  for (long j = 0, jsz = exp_names->size (); j < jsz; j++)
    {
      if (t_exp_list[j] == NULL) continue;
      Experiment *dexp = t_exp_list[j];
      dexp->open_epilogue ();
    }
  exp_names->destroy ();
  delete[] t_exp_list;
  delete exp_names;

  // update setting for leaklist and dataspace
  check_tab_avail ();
}

void
DbeSession::append_mesgs (StringBuilder *sb, char *path, Experiment *exp)
{
  if (exp->fetch_errors () != NULL)
    {
      // yes, there were errors
      char *ststr = pr_mesgs (exp->fetch_errors (), NTXT (""), NTXT (""));
      sb->append (path);
      sb->append (NTXT (": "));
      sb->append (ststr);
      free (ststr);
    }

  Emsg *m = exp->fetch_warnings ();
  if (m != NULL)
    {
      sb->append (path);
      sb->append (NTXT (": "));
      if (!is_interactive ())
	sb->append (GTXT ("Experiment has warnings, see header for details\n"));
      else
	sb->append (GTXT ("Experiment has warnings, see experiment panel for details\n"));
    }

  // Check for descendant experiments that are not loaded
  int num_desc = VecSize (exp->children_exps);
  if ((num_desc > 0) && !settings->check_en_desc (NULL, NULL))
    {
      char *s;
      if (!is_interactive ())
	s = dbe_sprintf (GTXT ("Has %d descendant(s), use commands controlling selection to load descendant data\n"), num_desc);
      else
	s = dbe_sprintf (GTXT ("Has %d descendant(s), use filter panel to load descendant data\n"), num_desc);
      sb->append (path);
      sb->append (NTXT (": "));
      sb->append (s);
      free (s);
    }
}

Experiment *
DbeSession::get_exp (int exp_ind)
{
  if (exp_ind < 0 || exp_ind >= exps->size ())
    return NULL;
  Experiment *exp = exps->fetch (exp_ind);
  exp->setExpIdx (exp_ind);
  return exp;
}

Vector<Vector<char*>*> *
DbeSession::getExperimensGroups ()
{
  if (dbeSession->expGroups == NULL || dbeSession->expGroups->size () == 0)
    return NULL;
  bool compare_mode = expGroups->size () > 1;
  Vector<Vector<char*>*> *groups = new Vector<Vector<char*>*> (
					 compare_mode ? expGroups->size () : 1);
  for (int i = 0; i < expGroups->size (); i++)
    {
      ExpGroup *grp = expGroups->fetch (i);
      Vector<Experiment*> *founders = grp->get_founders ();
      if (founders && founders->size () != 0)
	{
	  Vector<char *> *names = new Vector<char*> (founders->size ());
	  for (int j = 0; j < founders->size (); j++)
	    {
	      Experiment *exp = founders->fetch (j);
	      names->append (dbe_strdup (exp->get_expt_name ()));
	    }
	  if (compare_mode || groups->size () == 0)
	    groups->append (names);
	  else
	    groups->fetch (0)->addAll (names);
	}
      delete founders;
    }
  return groups;
}

char *
DbeSession::setExperimentsGroups (Vector<Vector<char*>*> *groups)
{
  StringBuilder sb;
  for (int i = 0; i < groups->size (); i++)
    {
      Vector<char *> *names = groups->fetch (i);
      ExpGroup *grp;
      if (names->size () == 1)
	grp = new ExpGroup (names->fetch (0));
      else
	{
	  char *nm = dbe_sprintf (GTXT ("Group %d"), i + 1);
	  grp = new ExpGroup (nm);
	  free (nm);
	}
      expGroups->append (grp);
      grp->groupId = expGroups->size ();

      for (int j = 0; j < names->size (); j++)
	{
	  char *path = names->fetch (j);
	  size_t len = strlen (path);
	  if ((len > 4) && !strcmp (path + len - 4, NTXT (".erg")))
	    {
	      Vector<char*> *lst = get_group_or_expt (path);
	      for (int j1 = 0; j1 < lst->size (); j1++)
		{
		  Experiment *exp = new Experiment ();
		  append (exp);
		  open_experiment (exp, lst->get (j1));
		  if (exp->get_status () == Experiment::FAILURE)
		    append_mesgs (&sb, path, exp);
		}
	      lst->destroy ();
	      delete lst;
	    }
	  else
	    {
	      Experiment *exp = new Experiment ();
	      append (exp);
	      open_experiment (exp, path);
	      if (exp->get_status () == Experiment::FAILURE)
		append_mesgs (&sb, path, exp);
	    }
	}
    }

  for (int i = 0, sz = views->size (); i < sz; i++)
    {
      DbeView *dbev = views->fetch (i);
      dbev->update_advanced_filter ();
      int cmp = dbev->get_settings ()->get_compare_mode ();
      dbev->set_compare_mode (CMP_DISABLE);
      dbev->set_compare_mode (cmp);
    }
  return sb.length () == 0 ? NULL : sb.toString ();
}

char *
DbeSession::drop_experiment (int exp_ind)
{
  DbeView *dbev;
  int index;
  Experiment *exp2;

  status_ompavail = -1;
  Experiment *exp = exps->fetch (exp_ind);

  // If this is a sub experiment, don't do it
  if (exp->founder_exp != NULL)     // this is a sub experiment; don't do it
    return (dbe_strdup (GTXT ("Can not drop subexperiments")));

  if (VecSize (exp->children_exps) > 0)
    for (;;)
      {
	// search the list of experiments to find all that have this one as founder
	bool found = false;
	Vec_loop (Experiment*, exps, index, exp2)
	{
	  if (exp2->founder_exp == exp)
	    {
	      exp2->founder_exp = NULL;
	      drop_experiment (index);
	      found = true;
	      break;
	    }
	}
	if (found == false)
	  break;
      }

  // then proceed to finish the drop
  Vec_loop (DbeView*, views, index, dbev)
  {
    dbev->drop_experiment (exp_ind);
  }

  int old_cnt = expGroups->size ();
  for (int i = 0; i < old_cnt; i++)
    {
      ExpGroup *gr = expGroups->fetch (i);
      if (gr->groupId == exp->groupId)
	{
	  gr->drop_experiment (exp);
	  if ((gr->founder == NULL) && (gr->exps->size () == 0))
	    {
	      delete gr;
	      expGroups->remove (i);
	    }
	  break;
	}
    }
  delete exps->remove (exp_ind);
  if (old_cnt != expGroups->size ())
    {
      for (int i = 0, sz = expGroups->size (); i < sz; i++)
	{
	  ExpGroup *gr = expGroups->fetch (i);
	  gr->groupId = i + 1;
	  Vector<Experiment*> *expList = gr->exps;
	  for (int i1 = 0, sz1 = expList->size (); i1 < sz1; i1++)
	    expList->fetch (i1)->groupId = gr->groupId;
	}
      for (int i = 0, sz = views->size (); i < sz; i++)
	{
	  dbev = views->fetch (i);
	  int cmp = dbev->get_compare_mode ();
	  dbev->set_compare_mode (CMP_DISABLE);
	  dbev->set_compare_mode (cmp);
	}
    }
  check_tab_avail ();   // update tab availability
  return NULL;
}

int
DbeSession::find_experiment (char *path)
{
  Experiment *exp;
  int index;
  Vec_loop (Experiment*, exps, index, exp)
  {
    if (strcmp (exp->get_expt_name (), path) == 0)
      return exp->getExpIdx ();
  }
  return -1;
}

LoadObject *
DbeSession::createLoadObject (const char *nm, int64_t cksum)
{
  return loadObjMap->sync_create_item (nm, cksum);
}

LoadObject *
DbeSession::createLoadObject (const char *nm, const char *runTimePath, DbeFile *df)
{
  return loadObjMap->sync_create_item (nm, runTimePath, df);
}

void
DbeSession::append (LoadObject *lobj)
{
  Histable *obj = lobj; // workaround for a C++ problem
  objs->append (obj);
  lobj->id = objs->size () - 1;
  lobjs->append (lobj);
  lobj->seg_idx = lobjs->size () - 1;
  char *loname = lobj->get_pathname ();
  dbeFiles->put (loname, lobj->dbeFile);
}

DbeJarFile *
DbeSession::get_JarFile (const char *name)
{
  DbeJarFile *jf = dbeJarFiles->get (name);
  if (jf == NULL)
    {
      jf = new DbeJarFile (name);
      dbeJarFiles->put (name, jf);
    }
  return jf;
}

Module *
DbeSession::createModule (LoadObject *lo, const char *nm)
{
  Module *mod = new Module ();
  Histable *obj = mod; // workaround for a C++ problem
  objs->append (obj);
  mod->id = objs->size () - 1;
  mod->loadobject = lo;
  mod->set_name (dbe_strdup (nm ? nm : localized_SP_UNKNOWN_NAME));
  lo->seg_modules->append (mod);
  return mod;
}

Module *
DbeSession::createUnknownModule (LoadObject *lo)
{
  Module *mod = createModule (lo, localized_SP_UNKNOWN_NAME);
  mod->flags |= MOD_FLAG_UNKNOWN;
  mod->set_file_name (dbe_strdup (localized_SP_UNKNOWN_NAME));
  return mod;
}

SourceFile *
DbeSession::createSourceFile (const char *_path)
{
  char *path = (char *) _path;
  if (strncmp (path, NTXT ("./"), 2) == 0)
    path += 2;
  SourceFile *source = sourcesMap->get (path);
  if (source == NULL)
    {
      source = new SourceFile (path);
      (void) sourcesMap->put (path, source);
      append (source);
    }
  return source;
}

Function *
DbeSession::createFunction ()
{
  Function *func = new Function (objs->size ());
  Histable *obj = func; // workaround for a C++ problem
  objs->append (obj);
  return func;
}

JMethod *
DbeSession::createJMethod ()
{
  JMethod *jmthd = new JMethod (objs->size ());
  Histable *obj = jmthd; // workaround for a C++ problem
  objs->append (obj);
  return jmthd;
}

Module *
DbeSession::createClassFile (char *className)
{
  ClassFile *cls = new ClassFile ();
  cls->set_name (className);
  char *clpath = cls->get_java_file_name (className, true);
  cls->dbeFile = getDbeFile (clpath, DbeFile::F_JAVACLASS);
  free (clpath);
  Histable *obj = cls; // workaround for a C++ problem
  objs->append (obj);
  cls->id = objs->size () - 1;
  return cls;
}

Histable *
DbeSession::createHistObject (Histable::Type type)
{
  switch (type)
    {
    case Histable::DOBJECT:
      {
	DataObject *dataobj = new DataObject ();
	dobjs->append (dataobj);
	dataobj->id = dobjs->size () - 1;
	return dataobj;
      }
    default:
      assert (0);
    }
  return NULL;
}

DataObject *
DbeSession::createDataObject ()
{
  DataObject *dataobj = new DataObject ();
  dobjs->append (dataobj);
  dataobj->id = dobjs->size () - 1;
  return dataobj;
}

DataObject *
DbeSession::createDataObject (DataObject *dobj, DataObject *parent)
{
  DataObject *dataobj = new DataObject ();
  dataobj->size = dobj->size;
  dataobj->offset = dobj->offset;
  dataobj->parent = parent;
  dataobj->set_dobjname (dobj->get_typename (), dobj->get_instname ());
  dobjs->append (dataobj);
  dataobj->id = dobjs->size () - 1;
  return dataobj;
}

DataObject *
DbeSession::createMasterDataObject (DataObject *dobj)
{
  DataObject *parent = NULL;
  if (dobj->parent)
    { // define master parent first
      parent = find_dobj_master (dobj->parent);
      if (!parent)
	{ // clone master from this dataobject parent
	  parent = createDataObject (dobj->parent);
	  parent->scope = NULL; // master is scope-less
	  Dprintf (DEBUG_DATAOBJ,
		   "Master DataObject(%llu) cloned from (%llu) %s\n",
		   (ull_t) parent->id, (ull_t) dobj->parent->id,
		   dobj->parent->get_name ());
	  // clone master DataObject elements
	  Vector<DataObject*> *delem = get_dobj_elements (dobj->parent);
	  int element_index = 0;
	  DataObject *element = NULL;
	  Vec_loop (DataObject*, delem, element_index, element)
	  {
	    DataObject *master_element = createDataObject (element, parent);
	    master_element->scope = NULL; // master is scope-less
	    Dprintf (DEBUG_DATAOBJ,
		     "Member DataObject(%llu) cloned from (%llu) %s\n",
		     (ull_t) master_element->id, (ull_t) element->id,
		     element->get_name ());
	  }
	}
      else
	Dprintf (DEBUG_DATAOBJ, "Master DataObject(%llu) clone found (%llu) %s\n",
		 (ull_t) parent->id, (ull_t) dobj->parent->id,
		 dobj->parent->get_name ());
    }

  DataObject *master = find_dobj_master (dobj);
  if (!master)
    { // clone master from this dataobject
      master = createDataObject (dobj, parent);
      master->scope = NULL; // master is scope-less
      Dprintf (DEBUG_DATAOBJ, "Master DataObject(%llu) cloned from (%llu) %s\n",
	       (ull_t) master->id, (ull_t) dobj->id, dobj->get_name ());
    }
  else
    Dprintf (DEBUG_DATAOBJ, "Master DataObject(%llu) clone found (%llu) %s\n",
	     (ull_t) master->id, (ull_t) dobj->id, dobj->get_name ());
  return master;
}

void
DbeSession::insert_metric (BaseMetric *mtr, Vector<BaseMetric*> *mlist)
{
  if ((mtr->get_flavors () & Metric::STATIC) == 0)
    {
      // insert in front of the first STATIC
      for (int i = 0, mlist_sz = mlist->size (); i < mlist_sz; i++)
	{
	  BaseMetric *m = mlist->fetch (i);
	  if (m->get_flavors () & Metric::STATIC)
	    {
	      mlist->insert (i, mtr);
	      return;
	    }
	}
    }
  mlist->append (mtr);
}

BaseMetricTreeNode*
DbeSession::get_reg_metrics_tree ()
{
  if (reg_metrics_tree == NULL)
    // Can't init earlier because BaseMetric() requires DbeSession::ql_parse
    reg_metrics_tree = new BaseMetricTreeNode ();
  return reg_metrics_tree;
}

void
DbeSession::update_metric_tree (BaseMetric *m)
{
  get_reg_metrics_tree ()->register_metric (m);
}

BaseMetric *
DbeSession::register_metric_expr (BaseMetric::Type type, char *cmd, char *expr_spec)
{
  BaseMetric *m = find_metric (type, cmd, expr_spec);
  if (m)
    return m;
  BaseMetric *bm = find_metric (type, cmd, NULL); // clone this version
  m = new BaseMetric (*bm);
  m->set_expr_spec (expr_spec);
  insert_metric (m, reg_metrics);
  return m;
}

BaseMetric *
DbeSession::register_metric (BaseMetric::Type type)
{
  BaseMetric *m = find_metric (type, NULL, NULL);
  if (m)
    return m;
  m = new BaseMetric (type);
  insert_metric (m, reg_metrics);
  update_metric_tree (m);
  return m;
}

BaseMetric *
DbeSession::register_metric (Hwcentry *ctr, const char* aux, const char* username)
{
  BaseMetric *m = find_metric (BaseMetric::HWCNTR, aux, NULL);
  if (m)
    // That may be a problem when metrics aren't an exact match.
    // For example, memoryspace is disabled in one experiment and not in another.
    return m;
  if (ctr->timecvt)
    {
      char *time_cmd = dbe_sprintf (NTXT ("t%s"), aux);
      char *time_username = dbe_sprintf (GTXT ("%s Time"),
				       ctr->metric ? ctr->metric :
				       (ctr->name ? ctr->name : ctr->int_name));
      BaseMetric *m1;
      if (ipc_mode)
	{
	  // Two visible metrics are presented in GUI
	  m1 = new BaseMetric (ctr, aux, time_cmd, time_username, VAL_TIMEVAL);
	  insert_metric (m1, reg_metrics);
	  update_metric_tree (m1);
	  m = new BaseMetric (ctr, aux, username, VAL_VALUE, m1);
	}
      else
	{
	  // Only one visible metric is presented in er_print
	  m1 = new BaseMetric (ctr, aux, time_cmd, time_username, VAL_TIMEVAL | VAL_INTERNAL);
	  insert_metric (m1, reg_metrics);
	  m = new BaseMetric (ctr, aux, username, VAL_TIMEVAL | VAL_VALUE, m1);
	}
      free (time_cmd);
      free (time_username);
    }
  else
    m = new BaseMetric (ctr, aux, username, VAL_VALUE);
  insert_metric (m, reg_metrics);
  update_metric_tree (m);
  return m;
}

BaseMetric *
DbeSession::register_metric (char *name, char *username, char *_def)
{
  BaseMetric *m = find_metric (BaseMetric::DERIVED, name, NULL);
  if (m)
    return m;
  Definition *p = Definition::add_definition (_def);
  if (p == NULL)
    return NULL;
  m = new BaseMetric (name, username, p);
  insert_metric (m, reg_metrics);
  update_metric_tree (m);
  return m;
}

void
DbeSession::drop_metric (BaseMetric *mtr)
{
  Countable *cnt;
  int index;

  Vec_loop (Countable*, metrics, index, cnt)
  {
    if (mtr == (BaseMetric *) cnt->item)
      {
	cnt->ref_count--;
	if (cnt->ref_count == 0)
	  {
	    // Remove this metric from all views
	    DbeView *dbev;
	    int index2;
	    Vec_loop (DbeView*, views, index2, dbev)
	    {
	      dbev->reset_metrics ();
	    }
	    delete metrics->remove (index);
	    delete mtr;
	    return;
	  }
      }
  }
}

BaseMetric *
DbeSession::find_metric (BaseMetric::Type type, const char *cmd, const char *expr_spec)
{
  for (int i = 0, sz = reg_metrics->size (); i < sz; i++)
    {
      BaseMetric *bm = reg_metrics->fetch (i);
      if (bm->get_type () == type && dbe_strcmp (bm->get_expr_spec (), expr_spec) == 0)
	{
	  if ((type == BaseMetric::DERIVED || type == BaseMetric::HWCNTR)
	       && dbe_strcmp (bm->get_cmd (), cmd) != 0)
	    continue;
	  return bm;
	}
    }
  return NULL;
}

BaseMetric *
DbeSession::find_base_reg_metric (char * mcmd)
{
  for (int i = 0, sz = reg_metrics->size (); i < sz; i++)
    {
      BaseMetric *bm = reg_metrics->fetch (i);
      if (bm->get_expr_spec () != NULL)
	continue; // skip compare metrics
      if (dbe_strcmp (bm->get_cmd (), mcmd) == 0)
	return bm;
    }
  return NULL;
}

Vector<BaseMetric*> *
DbeSession::get_base_reg_metrics ()
{
  Vector<BaseMetric*> *mlist = new Vector<BaseMetric*>;
  Vector<BaseMetric*> *ml = get_all_reg_metrics ();
  for (int i = 0, sz = ml->size (); i < sz; i++)
    {
      BaseMetric *m = ml->fetch (i);
      if (m->get_expr_spec () == NULL)
	mlist->append (m);
    }
  return mlist;
}

void
DbeSession::check_tab_avail ()
{
  DbeView *dbev;
  int index;
  // tell the views to update their tab lists
  Vec_loop (DbeView*, views, index, dbev)
  {
    dbev->get_settings ()->updateTabAvailability ();
  }
}

bool
DbeSession::is_datamode_available ()
{
  Experiment *exp;
  int index;
  Vec_loop (Experiment*, exps, index, exp)
  {
    if (exp->dataspaceavail)
      return true;
  }
  return false;
}

bool
DbeSession::is_leaklist_available ()
{
  Experiment *exp;
  int index;
  Vec_loop (Experiment*, exps, index, exp)
  {
    if (exp->leaklistavail)
      return true;
  }
  return false;
}

bool
DbeSession::is_heapdata_available ()
{
  Experiment *exp;
  int index;
  Vec_loop (Experiment*, exps, index, exp)
  {
    if (exp->heapdataavail)
      return true;
  }
  return false;
}

bool
DbeSession::is_iodata_available ()
{
  Experiment *exp;
  int index;
  Vec_loop (Experiment*, exps, index, exp)
  {
    if (exp->iodataavail)
      return true;
  }
  return false;
}

bool
DbeSession::is_racelist_available ()
{
  Experiment *exp;
  int index;
  Vec_loop (Experiment*, exps, index, exp)
  {
    if (exp->racelistavail)
      return true;
  }
  return false;
}

bool
DbeSession::is_deadlocklist_available ()
{
  Experiment *exp;
  int index;
  Vec_loop (Experiment*, exps, index, exp)
  {
    if (exp->deadlocklistavail)
      return true;
  }
  return false;
}

bool
DbeSession::is_timeline_available ()
{
  Experiment *exp;
  int index;
  Vec_loop (Experiment*, exps, index, exp)
  {
    if (exp->timelineavail)
      return true;
  }
  return false;
}

bool
DbeSession::is_ifreq_available ()
{
  Experiment *exp;
  int index;
  Vec_loop (Experiment*, exps, index, exp)
  {
    if (exp->ifreqavail)
      return true;
  }
  return false;
}

bool
DbeSession::is_omp_available ()
{
  if (status_ompavail == -1)
    {
      status_ompavail = 0;
      for (int i = 0, sz = exps ? exps->size () : 0; i < sz; i++)
	{
	  Experiment *exp = exps->fetch (i);
	  if (exp->ompavail)
	    {
	      status_ompavail = 1;
	      break;
	    }
	}
    }
  return status_ompavail == 1;
}

bool
DbeSession::has_java ()
{
  int status_has_java = 0;
  for (int i = 0, sz = exps ? exps->size () : 0; i < sz; i++)
    {
      Experiment *exp = exps->fetch (i);
      if (exp->has_java)
	{
	  status_has_java = 1;
	  break;
	}
    }
  return status_has_java == 1;
}

bool
DbeSession::has_ompavail ()
{
  int status_has_ompavail = 0;
  for (int i = 0, sz = exps ? exps->size () : 0; i < sz; i++)
    {
      Experiment *exp = exps->fetch (i);
      if (exp->ompavail)
	{
	  status_has_ompavail = 1;
	  break;
	}
    }
  return status_has_ompavail == 1;
}

int
DbeSession::get_clock (int whichexp)
{
  // XXXX clock frequency should be an attribute of each CPU,
  // XXX  and not a property of the session
  // if whichexp is -1, pick the first exp that has a clock
  // otherwise return the clock from the numbered experiment
  Experiment *exp;
  if (whichexp != -1)
    {
      exp = get_exp (whichexp);
      if (exp != NULL)
	return exp->clock;
      return 0;
    }
  int n = nexps ();
  for (int i = 0; i < n; i++)
    {
      exp = get_exp (i);
      if (exp != NULL && exp->clock != 0)
	return exp->clock;
    }
  return 0;
}

LoadObject *
DbeSession::find_lobj_by_name (const char *lobj_name, int64_t cksum)
{
  return loadObjMap->get (lobj_name, cksum);
}

static unsigned
hash (char *s)
{
  unsigned res = 0;
  for (int i = 0; i < 64 && *s; i++)
    res = res * 13 + *s++;
  return res;
}

// This method is introduced to fix performance
// problems with the data space profiling in the
// current release. A better design is desired.
void
DbeSession::dobj_updateHT (DataObject *dobj)
{
  unsigned index = hash (dobj->get_unannotated_name ()) % HTableSize;
  List *list = new List;
  list->val = (void*) dobj;
  list->next = dnameHTable[index];
  dnameHTable[index] = list;
}

DataObject *
DbeSession::find_dobj_by_name (char *dobj_name)
{
  unsigned index = hash (dobj_name) % HTableSize;
  List *list = dnameHTable[index];
  for (; list; list = list->next)
    {
      DataObject *d = (DataObject*) list->val;
      if (strcmp (d->get_unannotated_name (), dobj_name) == 0)
	return d;
    }
  return (DataObject *) NULL;
}

DataObject *
DbeSession::find_dobj_match (DataObject *dobj)
{
  char *dobj_name = dobj->get_unannotated_name ();
  unsigned index = hash (dobj_name) % HTableSize;
  List *list = dnameHTable[index];
  for (; list; list = list->next)
    {
      DataObject *d = (DataObject*) list->val;
      if (strcmp (d->get_unannotated_name (), dobj_name) == 0
	  && d->size == dobj->size && d->offset == dobj->offset
	  && d->scope == dobj->scope)
	return d;
    }
  return (DataObject *) NULL;
}

DataObject *
DbeSession::find_dobj_master (DataObject *dobj)
{
  char *dobj_name = dobj->get_unannotated_name ();
  unsigned index = hash (dobj_name) % HTableSize;
  List *list = dnameHTable[index];
  for (; list; list = list->next)
    {
      DataObject *d = (DataObject*) list->val;
      // XXXX should parent also match?
      if (strcmp (d->get_unannotated_name (), dobj_name) == 0
	  && d->size == dobj->size && d->offset == dobj->offset
	  && d->master == NULL && d->scope == NULL)
	return d;
    }
  return (DataObject *) NULL;
}

Vector<DataObject*>*
DbeSession::get_dobj_elements (DataObject *dobj)
{
  DataObject *d;
  int index;
  Vector<DataObject*> *elements = new Vector<DataObject*>;
  if (dobj == d_total)
    return elements;
  Vec_loop (DataObject*, dobjs, index, d)
  {
    if (d->get_parent () && d->get_parent () == dobj)
      elements->append (d);
  }
  return elements;
}

Vector<LoadObject*>*
DbeSession::get_text_segments ()
{
  LoadObject *lo;
  int index;
  Vector<LoadObject*> *tlobjs = new Vector<LoadObject*>;
  Vec_loop (LoadObject*, lobjs, index, lo)
  {
    if (lo->type == LoadObject::SEG_TEXT)
      tlobjs->append (lo);
  }
  return tlobjs;
}

static long long
getNumber (const char *s, char * &last)
{
  long long val;
  char *sp;
  errno = 0;
  val = strtoll (s, &sp, 0);
  if (errno == EINVAL)
    last = NULL;
  else
    {
      while (isspace (*sp))
	sp++;
      last = sp;
    }
  return (val);
}

bool
DbeSession::find_obj (FILE *dis_file, FILE *inp_file, Histable *&obj,
		      char *name, const char *sel, Histable::Type type, bool xdefault)
{
  Vector<Histable*> *obj_lst;
  int which = -1;
  char *last = NULL;
  if (type != Histable::FUNCTION && sel)
    {
      // check that a number has been provided
      which = (int) getNumber (sel, last);
      if (last == NULL || *last != '\0')
	{
	  fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), sel);
	  sel = NULL;
	  which = 0;
	}
      which--;
    }
  obj_lst = new Vector<Histable*>;
  switch (type)
    {
    case Histable::FUNCTION:
      obj = map_NametoFunction (name, obj_lst, sel);
      break;
    case Histable::MODULE:
      obj = map_NametoModule (name, obj_lst, which);
      break;
    case Histable::LOADOBJECT:
      obj = map_NametoLoadObject (name, obj_lst, which);
      break;
    case Histable::DOBJECT:
      obj = map_NametoDataObject (name, obj_lst, which);
      break;
    default:
      abort (); // unexpected Histable!
    }

  if ((obj == NULL) && (obj_lst->size () > 0))
    {
      if (obj_lst->size () == 1)
	which = 0;
      else
	{
	  if (sel && (which < 0 || which >= obj_lst->size ()))
	    fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), sel);
	  if (xdefault)
	    {
	      fprintf (stderr, GTXT ("Default selection \"1\" made\n"));
	      which = 0;
	    }
	  else
	    {
	      which = ask_which (dis_file, inp_file, obj_lst, name);
	      if (which == -1)
		{
		  delete obj_lst;
		  return false;
		}
	    }
	}
      obj = obj_lst->fetch (which);
    }
  delete obj_lst;
  return true;
}

int
DbeSession::ask_which (FILE *dis_file, FILE *inp_file,
		       Vector<Histable*> *list, char *name)
{
  Histable *hitem;
  Function *func;
  Module *module;
  int which, index, index1;
  char *item_name, *lo_name, *fname, *last;
  char buf[BUFSIZ];
  for (;;)
    {
      fprintf (dis_file, GTXT ("Available name list:\n"));
      fprintf (dis_file, GTXT ("%8d) Cancel\n"), 0);
      Vec_loop (Histable*, list, index, hitem)
      {
	index1 = index + 1;
	item_name = hitem->get_name ();
	switch (hitem->get_type ())
	  {
	  case Histable::FUNCTION:
	    func = (Function *) hitem;
	    module = func->module;

	    // id == -1 indicates er_src invocation
	    if (module == NULL || (module->lang_code == Sp_lang_java
				   && module->loadobject->id == -1))
		fprintf (dis_file, NTXT ("%8d) %s\n"), index1, item_name);
	    else
	      {
		lo_name = module->loadobject->get_pathname ();
		fname = (module->file_name && *module->file_name) ?
			module->file_name : module->get_name ();
		if (fname && *fname)
		  fprintf (dis_file, NTXT ("%8d) %s %s:0x%llx (%s)\n"), index1,
			   item_name, lo_name, (ull_t) func->img_offset, fname);
		else
		  fprintf (dis_file, NTXT ("%8d) %s %s:0x%llx\n"), index1,
			   item_name, lo_name, (ull_t) func->img_offset);
	      }
	    break;
	  case Histable::MODULE:
	    module = (Module *) hitem;
	    lo_name = module->loadobject->get_pathname ();
	    if (name[strlen (name) - 1] ==
		module->file_name[strlen (module->file_name) - 1])
	      fprintf (dis_file, NTXT ("%8d) %s(%s)\n"), index1,
		       module->file_name, lo_name);
	    else
	      fprintf (dis_file, NTXT ("%8d) %s(%s)\n"), index1, item_name,
		       lo_name);
	    break;
	  default:
	    fprintf (dis_file, NTXT ("%8d) %s\n"), index1, item_name);
	    break;
	  }
      }
      if (inp_file != stdin)
	return -1;
      fprintf (dis_file, GTXT ("Enter selection: "));
      if (fgets (buf, (int) sizeof (buf), inp_file) == NULL)
	{
	  fprintf (stderr, GTXT ("Error: Invalid number entered:\n"));
	  return -1;
	}
      which = (int) getNumber (buf, last);
      if (last && *last == '\0')
	if (which >= 0 && which <= list->size ())
	  return which - 1;
      fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), buf);
    }
}

static bool
match_basename (char *name, char *full_name, int len = -1)
{
  if (full_name == NULL)
    return false;
  if (!strchr (name, '/'))
    full_name = get_basename (full_name);
  if (len == -1)
    return streq (name, full_name);
  return strncmp (name, full_name, len) == 0;
}

LoadObject *
DbeSession::map_NametoLoadObject (char *name, Vector<Histable*> *list, int which)
{
  // Search the tree to find the first module whose module name
  //	matches "name" or whose source file name matches "name"
  //  Issues: is the name a pathname, or a base name?
  //	Should we look at suffix to disambiguate?
  LoadObject *loitem;
  int index;
  Vec_loop (LoadObject*, lobjs, index, loitem)
  {
    // try pathname first
    // if failed, try object name next
    if (match_basename (name, loitem->get_pathname ()) ||
	match_basename (name, loitem->get_name ()))
      {
	if (which == list->size ())
	  return loitem;
	list->append (loitem);
      }
  }
  return (LoadObject *) NULL;
}

Module *
DbeSession::map_NametoModule (char *name, Vector<Histable*> *list, int which)
{
  // Search the tree to find the first loadobject whose loadobject name
  //	matches "name".

  //  Issues: is the name a pathname, or a base name?
  //	Should we look at suffix to disambiguate?
  LoadObject *loitem;
  Module *mitem;
  int index1, index2;
  Vec_loop (LoadObject*, lobjs, index1, loitem)
  {
    Vec_loop (Module*, loitem->seg_modules, index2, mitem)
    {
      // try source name first
      // if failed, try object name next
      if (match_basename (name, mitem->file_name) ||
	  match_basename (name, mitem->get_name ()))
	{
	  if (which == list->size ())
	    return mitem;
	  list->append (mitem);
	}
    }
  }
  return (Module *) NULL;
}

Function *
DbeSession::map_NametoFunction (char *name, Vector<Histable*> *list,
				const char *sel)
{
  // Search the tree to find the first function whose
  //	name matches "name".
  //  Issues: is the name a full name, or a short name?
  //	Is it a demangled name?  If so, what about spaces
  //		within the name?
  //	Is there a way to return all names that match?
  //	How can the user specify a particular function of that name?
  LoadObject *loitem;
  Function *fitem, *main_func = NULL;
  Module *mitem, *main_mod = NULL;
  int index1, index2, index3, which = -1;
  if (sel)
    {
      char *last = NULL;
      if (*sel == '@')
	{ // 'sel' is "@seg_num:address"
	  which = (int) getNumber (sel + 1, last);
	  if (last == NULL || *last != ':' || (which < 0) || (which >= lobjs->size ()))
	    {
	      fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), sel);
	      return NULL;
	    }
	  uint64_t address = getNumber (last + 1, last);
	  if (last == NULL || *last != '\0')
	    {
	      fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), sel);
	      return NULL;
	    }
	  loitem = lobjs->fetch (which);
	  Vec_loop (Module*, loitem->seg_modules, index2, mitem)
	  {
	    Vec_loop (Function*, mitem->functions, index3, fitem)
	    {
	      if (address == fitem->img_offset && match_FName (name, fitem))
		return fitem;
	    }
	  }
	  return NULL;
	}

      which = (int) getNumber (sel, last);
      if (last == NULL || *last != '\0')
	{
	  fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), sel);
	  return NULL;
	}
      which--;
    }

  int len_path = 0;
  char *with_path = name;
  name = StrRchr (name, '`');
  if (name != with_path)
    len_path = (int) (name - with_path);
  else
    with_path = NULL;

  Vec_loop (LoadObject*, lobjs, index1, loitem)
  {
    Vec_loop (Module*, loitem->seg_modules, index2, mitem)
    {
      if (with_path)
	{ // with file name
	  // try source name first
	  // if failed, try object name next
	  if (!match_basename (with_path, mitem->file_name, len_path) &&
	      !match_basename (with_path, mitem->get_name (), len_path))
	    continue;
	}
      Vec_loop (Function*, mitem->functions, index3, fitem)
      {
	if (match_FName (name, fitem))
	  {
	    if (which == list->size ())
	      return fitem;
	    list->append (fitem);
	    continue;
	  }
	if (streq (fitem->get_name (), NTXT ("MAIN_")) && mitem->is_fortran ())
	  {
	    main_func = fitem;
	    main_mod = mitem;
	  }
      }
    }
  }

  if (main_mod && main_func)
    {
      main_mod->read_stabs ();
      if (streq (main_func->get_match_name (), name) && which <= 1)
	return main_func;
    }
  return (Function *) NULL;
}

DataObject *
DbeSession::map_NametoDataObject (char *name, Vector<Histable*> *list,
				  int which)
{
  // Search master list to find dataobjects whose names match "name"
  // selecting only the entry corresponding to "which" if it is not -1.
  // Issues: is the name fully qualified or only partially?
  DataObject *ditem = NULL;
  int index;
  char *full_name;
  Vec_loop (DataObject*, dobjs, index, ditem)
  {
    if (ditem->scope) continue; // skip non-master dataobjects

    // try fully-qualified dataobject name first
    if ((full_name = ditem->get_name ()) != NULL)
      {
	if (streq (name, full_name))
	  {
	    if (which == list->size ())
	      return ditem;
	    list->append (ditem);
	  }
      }
  }
  if (list->size () > 0)
    return ditem; // return fully-qualified match

  // if fully-qualified name doesn't match anything, try a partial match
  Vec_loop (DataObject*, dobjs, index, ditem)
  {
    if (ditem->scope) continue; // skip non-master dataobjects

    // try fully-qualified dataobject name first
    if ((full_name = ditem->get_name ()) != NULL)
      {
	if (strstr (full_name, name))
	  {
	    if (which == list->size ())
	      return ditem;
	    list->append (ditem);
	  }
      }
  }
  return (DataObject *) NULL;
}

bool
DbeSession::match_FName (char *name, Function *func)
{
  size_t len;
  char buf[MAXDBUF];
  char *full_name;
  if (streq (func->get_name (), name)) // try full name comparison
    return true;
  if (streq (func->get_mangled_name (), name)) // try mangled name
    return true;
  if (streq (func->get_match_name (), name)) // try match name
    return true;

  Module *md = func->module; // try FORTRAN name
  if (md && md->is_fortran ())
    {
      char *mangled_name = func->get_mangled_name ();
      len = strlen (name);
      if (((len + 1) == strlen (mangled_name)) &&
	  (strncmp (name, mangled_name, len) == 0))
	return true;
    }
  snprintf (buf, sizeof (buf), NTXT ("%s"), func->get_name ());
  full_name = buf;
  char *arg = NULL; // find modifier and C++ class name
  int i = get_paren (buf);
  if (i >= 0)
    {
      arg = buf + i;
      *arg = '\0';
    }

  char *mod = strchr (full_name, ' ');
  char *cls = strchr (full_name, ':');

  if (mod)
    {
      len = mod - full_name + 1;
      if (!strncmp (full_name, name, len))
	name += len;
      full_name += len;
      if (streq (full_name, name)) // try without modifier
	return true;
    }

  size_t len_cmp = strlen (name);
  if (arg)
    {
      *arg = '(';
      len = arg - full_name; // try without 'args'
      if (len_cmp == len && !strncmp (full_name, name, len))
	return true;
      if (cls)
	{
	  len = arg - cls - 2; // and without 'class name'
	  if ((len_cmp == len) && !strncmp (cls + 2, name, len))
	    return true;
	}
    }

  if (cls)
    {
      len = cls - full_name; // try C++ class name only
      if (len_cmp == len && !strncmp (full_name, name, len))
	return true;
      if (streq (cls + 2, name)) // try without 'class name'
	return true;
    }
  return false;
}

bool
DbeSession::add_path (char *path)
{
  return add_path (path, get_search_path ());
}

bool
DbeSession::add_classpath (char *path)
{
  return add_path (path, classpath);
}

Vector<DbeFile*> *
DbeSession::get_classpath ()
{
  if (classpath_df == NULL)
    classpath_df = new Vector<DbeFile*>;
  for (int i = classpath_df->size (), sz = classpath->size (); i < sz; i++)
    classpath_df->store (i, getDbeFile (classpath->fetch (i),
					DbeFile::F_DIR_OR_JAR));
  return classpath_df;
}

bool
DbeSession::add_path (char *path, Vector<char*> *pathes)
{
  bool result = false;
  Vector <char *> *tokens = split_str (path, ':');
  for (long j = 0, jsz = VecSize (tokens); j < jsz; j++)
    {
      char *spath = tokens->get (j);
      // Don't append path if it's already there
      bool got = false;
      for (int i = 0, sz = pathes->size (); i < sz; i++)
	{
	  char *nm = pathes->get (i);
	  if (streq (nm, spath))
	    {
	      got = true;
	      break;
	    }
	}
      if (!got)
	{
	  pathes->append (spath);
	  result = true;
	}
      else
	free (spath);
    }
  delete tokens;
  return result;
}

void
DbeSession::set_need_refind ()
{
  Vector<DbeFile*> *f_list = dbeFiles->values ();
  for (long i = 0, sz = f_list == NULL ? 0 : f_list->size (); i < sz; i++)
    {
      DbeFile *f = f_list->get (i);
      f->set_need_refind (true);
    }
  delete f_list;
  for (long i = 0, sz = sources == NULL ? 0 : sources->size (); i < sz; i++)
    {
      SourceFile *f = sources->get (i);
      if (f && f->dbeFile)
	f->dbeFile->set_need_refind (true);
    }
}

void
DbeSession::set_search_path (Vector<char*> *path, bool reset)
{
  if (reset)
    search_path->destroy ();
  for (int i = 0, sz = path == NULL ? 0 : path->size (); i < sz; i++)
    {
      char *name = path->fetch (i);
      if (add_path (name))
	reset = true;
    }
  if (reset)
    {
      set_need_refind ();

      // now reset the string setting for it
      StringBuilder sb;
      for (int i = 0, sz = search_path == NULL ? 0 : search_path->size (); i < sz; i++)
	{
	  char *name = search_path->fetch (i);
	  if (sb.length () != 0)
	    sb.append (':');
	  sb.append (name);
	}
      free (settings->str_search_path);
      settings->str_search_path = sb.toString ();
    }
}

void
DbeSession::set_search_path (char *_lpath, bool reset)
{
  Vector<char *> *path = new Vector<char*>;
  char *lpath = dbe_strdup (_lpath);
  for (char *s = lpath; s;)
    {
      path->append (s);
      s = strchr (s, ':');
      if (s)
	{
	  *s = 0;
	  s++;
	}
    }
  set_search_path (path, reset);
  delete path;
  free (lpath);
}

void
DbeSession::set_pathmaps (Vector<pathmap_t*> *newPathMap)
{
  set_need_refind ();
  settings->set_pathmaps (newPathMap);
}

Vector<pathmap_t*> *
DbeSession::get_pathmaps ()
{
  return settings->pathmaps;
}

void
DbeSession::mobj_define (MemObjType_t *mobj)
{
  settings->mobj_define (mobj, false);
  DbeView *dbev;
  int index;
  Vec_loop (DbeView*, views, index, dbev)
  {
    dbev->get_settings ()->mobj_define (mobj, false);
  }
}

void
DbeSession::dump_segments (FILE *out)
{
  int index;
  LoadObject *loitem;
  Vec_loop (LoadObject*, lobjs, index, loitem)
  {
    fprintf (out, NTXT ("Segment %d -- %s -- %s\n\n"),
	     index, loitem->get_name (), loitem->get_pathname ());
    loitem->dump_functions (out);
    fprintf (out, NTXT ("\n End Segment %d -- %s -- %s\n\n"),
	     index, loitem->get_name (), loitem->get_pathname ());
  }
}

void
DbeSession::dump_dataobjects (FILE *out)
{
  DataObject *ditem;
  int index;

  fprintf (out, NTXT ("\nMaster list of DataObjects:\n"));
  Vec_loop (DataObject*, dobjs, index, ditem)
  {
    Histable* scope = ditem->get_scope ();
    DataObject* parent = ditem->get_parent ();
    DataObject* master = ditem->get_master ();
    if (parent != NULL)
      fprintf (out, "id %6lld: [%4lld] parent = %6lld, offset = %+4lld %s\n",
	       (ll_t) ditem->id, (ll_t) ditem->get_size (),
	       (ll_t) parent->id, (ll_t) ditem->get_offset (),
	       ditem->get_name ());
    else
      {
	// parent is NULL
	fprintf (out, NTXT ("id %6lld: [%4lld] %s "),
		 (ll_t) ditem->id, (ll_t) ditem->get_size (),
		 ditem->get_name ());
	if (master != NULL)
	  fprintf (out, NTXT (" master=%lld "), (ll_t) master->id);
	else if (scope != NULL)
	  fprintf (out, NTXT (" master=?? "));
	else
	  fprintf (out, NTXT (" MASTER "));
#if DEBUG
	if (scope != NULL)
	  {
	    switch (scope->get_type ())
	      {
	      case Histable::LOADOBJECT:
	      case Histable::FUNCTION:
		fprintf (out, NTXT ("%s"), scope->get_name ());
		break;
	      case Histable::MODULE:
		{
		  char *filename = get_basename (scope->get_name ());
		  fprintf (out, NTXT ("%s"), filename);
		  break;
		}
	      default:
		fprintf (out, NTXT (" Unexpected scope %d:%s"),
			 scope->get_type (), scope->get_name ());
	      }
	  }
#endif
	fprintf (out, NTXT ("\n"));
      }
  }
}

void
DbeSession::dump_map (FILE *out)
{
  Experiment *exp;
  int index;
  Vec_loop (Experiment*, exps, index, exp)
  {
    exp->dump_map (out);
  }
}

void
DbeSession::dump_stacks (FILE *outfile)
{
  Experiment *exp;
  int n = nexps ();
  FILE *f = (outfile == NULL ? stderr : outfile);
  for (int i = 0; i < n; i++)
    {
      exp = get_exp (i);
      fprintf (f, GTXT ("Experiment %d -- %s\n"), i, exp->get_expt_name ());
      exp->dump_stacks (f);
    }
}

void
DbeSession::propNames_name_store (int propId, const char *propName)
{
  PropDescr *prop = new PropDescr (propId, propName);
  prop->flags = PRFLAG_NOSHOW; // do not show descriptions
  propNames->store (propId, prop);
}

void
DbeSession::propNames_name_store (int propId, const char* propName,
				  const char* propUname, VType_type dataType,
				  int flags)
{
  PropDescr *prop = new PropDescr (propId, propName);
  prop->vtype = dataType;
  prop->uname = dbe_strdup (propUname);
  prop->flags = flags;
  propNames->store (propId, prop);
}

char *
DbeSession::propNames_name_fetch (int i)
{
  PropDescr *prop = propNames->fetch (i);
  if (prop)
    return prop->name;
  return NULL;
}

int
DbeSession::registerPropertyName (const char *name)
{
  if (name == NULL)
    return PROP_NONE;
  for (int i = 0; i < propNames->size (); i++)
    {
      char *pname = propNames_name_fetch (i);
      if (pname && strcasecmp (pname, name) == 0)
	return i;
    }
  int propId = propNames->size ();
  propNames_name_store (propId, name);
  return propId;
}

int
DbeSession::getPropIdByName (const char *name)
{
  if (name == NULL)
    return PROP_NONE;
  for (int i = 0; i < propNames->size (); i++)
    {
      char *pname = propNames_name_fetch (i);
      if (pname && strcasecmp (pname, name) == 0)
	return i;
    }
  return PROP_NONE;
}

char *
DbeSession::getPropName (int propId)
{
  if (!propNames)
    return NULL;
  if (propId < 0 || propId >= propNames->size ())
    return NULL;
  return dbe_strdup (propNames_name_fetch (propId));
}

char *
DbeSession::getPropUName (int propId)
{
  if (!propNames)
    return NULL;
  if (propId < 0 || propId >= propNames->size ())
    return NULL;
  PropDescr *prop = propNames->fetch (propId);
  if (prop)
    return dbe_strdup (prop->uname);
  return NULL;
}

void
DbeSession::append (UserLabel *lbl)
{
  if (lbl->expr)
    {
      if (userLabels == NULL)
	 userLabels = new Vector<UserLabel*> ();
      userLabels->append (lbl);
    }
}

void
DbeSession::append (SourceFile *sf)
{
  sources->append (sf);
  objs->append (sf);
}

UserLabel *
DbeSession::findUserLabel (const char *name)
{
  for (int i = 0, sz = userLabels ? userLabels->size () : 0; i < sz; i++)
    {
      UserLabel *lbl = userLabels->fetch (i);
      if (strcasecmp (lbl->name, name) == 0)
	return lbl;
    }
  return NULL;
}

Expression *
DbeSession::findObjDefByName (const char *name)
{
  Expression *expr = NULL;

  MemObjType_t *mot = MemorySpace::findMemSpaceByName (name);
  if (mot != NULL)
    {
      char *index_expr_str = mot->index_expr;
      expr = ql_parse (index_expr_str);
    }

  if (expr == NULL)
    {
      int indxtype = findIndexSpaceByName (name);
      expr = getIndexSpaceExpr (indxtype);
    }
  if (expr == NULL)
    {
      UserLabel *ulbl = findUserLabel (name);
      if (ulbl)
	expr = ulbl->expr;
    }
  return expr;
}

Expression *
DbeSession::ql_parse (const char *expr_spec)
{
  if (expr_spec == NULL)
    expr_spec = "";
  QL::Result result (expr_spec);
  QL::Parser qlparser (result);
  if (qlparser.parse () != 0)
    return NULL;
  return result ();
}

Vector<void*> *
DbeSession::getIndxObjDescriptions ()
{
  int size = dyn_indxobj_indx;
  if (size == 0)
    return NULL;
  Vector<int> *type = new Vector<int>(dyn_indxobj_indx);
  Vector<char*> *desc = new Vector<char*>(dyn_indxobj_indx);
  Vector<char*> *i18ndesc = new Vector<char*>(dyn_indxobj_indx);
  Vector<char> *mnemonic = new Vector<char>(dyn_indxobj_indx);
  Vector<int> *orderList = new Vector<int>(dyn_indxobj_indx);
  Vector<char*> *exprList = new Vector<char*>(dyn_indxobj_indx);
  Vector<char*> *sdesc = new Vector<char*>(dyn_indxobj_indx);
  Vector<char*> *ldesc = new Vector<char*>(dyn_indxobj_indx);

  for (long i = 0, sz = VecSize (dyn_indxobj); i < sz; i++)
    {
      IndexObjType_t *tot = dyn_indxobj->get (i);
      if (tot->memObj == NULL)
	{
	  type->append ((int) tot->type);
	  desc->append (dbe_strdup (tot->name));
	  i18ndesc->append (dbe_strdup (tot->i18n_name));
	  sdesc->append (dbe_strdup (tot->short_description));
	  ldesc->append (dbe_strdup (tot->long_description));
	  mnemonic->append (tot->mnemonic);
	  orderList->append (settings->indx_tab_order->fetch (i));
	  exprList->append (dbe_strdup (tot->index_expr_str));
	}
    }
  Vector<void*> *res = new Vector<void*>(8);
  res->store (0, type);
  res->store (1, desc);
  res->store (2, mnemonic);
  res->store (3, i18ndesc);
  res->store (4, orderList);
  res->store (5, exprList);
  res->store (6, sdesc);
  res->store (7, ldesc);
  return (res);
}

// Static function to get a vector of custom index object definitions
Vector<void*> *
DbeSession::getCustomIndxObjects ()
{
  Vector<char*> *name = new Vector<char*>;
  Vector<char*> *formula = new Vector<char*>;
  for (long i = dyn_indxobj_indx_fixed, sz = VecSize (dyn_indxobj); i < sz; i++)
    {
      IndexObjType_t *tot = dyn_indxobj->get (i);
      if (tot->memObj == NULL)
	{
	  name->append (dbe_strdup (tot->name));
	  formula->append (dbe_strdup (tot->index_expr_str));
	}
    }
  Vector<void*> *res = new Vector<void*>(2);
  res->store (0, name);
  res->store (1, formula);
  return (res);
}

// Static function to define a new index object type
char *
DbeSession::indxobj_define (const char *mname, char *i18nname, const char *index_expr_str, char *short_description, char *long_description)
{
  if (mname == NULL)
    return dbe_strdup (GTXT ("No index object type name has been specified."));
  if (isalpha ((int) (mname[0])) == 0)
    return dbe_sprintf (GTXT ("Index Object type name %s does not begin with an alphabetic character"),
			  mname);
  const char *p = mname;
  while (*p != 0)
    {
      if ((isalnum ((int) (*p)) == 0) && (*p != '_'))
	return dbe_sprintf (GTXT ("Index Object type name %s contains a non-alphanumeric character"),
			    mname);
      p++;
    }

  // make sure the name is not in use
  if (MemorySpace::findMemSpaceByName (mname) != NULL)
    return dbe_sprintf (GTXT ("Memory/Index Object type name %s is already defined"),
			  mname);

  int idxx = findIndexSpaceByName (mname);
  if (idxx >= 0)
    {
      IndexObjType_t *mt = dyn_indxobj->fetch (idxx);
      if (strcmp (mt->index_expr_str, index_expr_str) == 0)
	// It's a redefinition, but the new definition is the same
	return NULL;
      return dbe_sprintf (GTXT ("Memory/Index Object type name %s is already defined"),
			  mname);
    }
  if (index_expr_str == NULL)
    return dbe_strdup (GTXT ("No index-expr has been specified."));
  if (strlen (index_expr_str) == 0)
    return dbe_sprintf (GTXT ("Index Object index expression is invalid: %s"),
			index_expr_str);

  // verify that the index expression parses correctly
  char *expr_str = dbe_strdup (index_expr_str);
  Expression *expr = ql_parse (expr_str);
  if (expr == NULL)
    return dbe_sprintf (GTXT ("Index Object index expression is invalid: %s"),
			expr_str);

  // It's OK, create the new table entry
  IndexObjType_t *tot = new IndexObjType_t;
  tot->type = dyn_indxobj_indx++;
  tot->name = dbe_strdup (mname);
  tot->i18n_name = dbe_strdup (i18nname);
  tot->short_description = dbe_strdup (short_description);
  tot->long_description = dbe_strdup (long_description);
  tot->index_expr_str = expr_str;
  tot->index_expr = expr;
  tot->mnemonic = mname[0];

  // add it to the list
  dyn_indxobj->append (tot);
  idxobjs->append (new HashMap<uint64_t, Histable*>);

  // tell the session
  settings->indxobj_define (tot->type, false);

  DbeView *dbev;
  int index;
  Vec_loop (DbeView*, views, index, dbev)
  {
    dbev->addIndexSpace (tot->type);
  }
  return NULL;
}

char *
DbeSession::getIndexSpaceName (int index)
{
  if (index < 0 || index >= dyn_indxobj->size ())
    return NULL;
  return dyn_indxobj->fetch (index)->name;
}

char *
DbeSession::getIndexSpaceDescr (int index)
{
  if (index < 0 || index >= dyn_indxobj->size ())
    return NULL;
  return dyn_indxobj->fetch (index)->i18n_name;
}

Expression *
DbeSession::getIndexSpaceExpr (int index)
{
  if (index < 0 || index >= dyn_indxobj->size ())
    return NULL;
  return dyn_indxobj->fetch (index)->index_expr;
}

char *
DbeSession::getIndexSpaceExprStr (int index)
{
  if (index < 0 || index >= dyn_indxobj->size ())
    return NULL;
  return dyn_indxobj->fetch (index)->index_expr_str;
}

int
DbeSession::findIndexSpaceByName (const char *mname)
{
  int idx;
  IndexObjType_t *mt;
  Vec_loop (IndexObjType_t*, dyn_indxobj, idx, mt)
  {
    if (strcasecmp (mt->name, mname) == 0)
      return idx;
  }
  return -1;
}

void
DbeSession::removeIndexSpaceByName (const char *mname)
{
  IndexObjType_t *indObj = findIndexSpace (mname);
  if (indObj)
    indObj->name[0] = 0;
}

IndexObjType_t *
DbeSession::getIndexSpace (int index)
{
  return ((index < 0) || (index >= VecSize (dyn_indxobj))) ? NULL : dyn_indxobj->get (index);
}

IndexObjType_t *
DbeSession::findIndexSpace (const char *mname)
{
  return getIndexSpace (findIndexSpaceByName (mname));
}

void
DbeSession::get_filter_keywords (Vector<void*> *res)
{
  Vector <char*> *kwCategory = (Vector<char*>*) res->fetch (0);
  Vector <char*> *kwCategoryI18N = (Vector<char*>*) res->fetch (1);
  Vector <char*> *kwDataType = (Vector<char*>*) res->fetch (2);
  Vector <char*> *kwKeyword = (Vector<char*>*) res->fetch (3);
  Vector <char*> *kwFormula = (Vector<char*>*) res->fetch (4);
  Vector <char*> *kwDescription = (Vector<char*>*) res->fetch (5);
  Vector <void*> *kwEnumDescs = (Vector<void*>*) res->fetch (6);

  char *vtypeNames[] = VTYPE_TYPE_NAMES;
  for (long i = 0, sz = userLabels ? userLabels->size () : 0; i < sz; i++)
    {
      UserLabel *lbl = userLabels->fetch (i);
      kwCategory->append (dbe_strdup (NTXT ("FK_LABEL")));
      kwCategoryI18N->append (dbe_strdup (GTXT ("Labels")));
      kwDataType->append (dbe_strdup (vtypeNames[TYPE_BOOL]));
      kwKeyword->append (dbe_strdup (lbl->name));
      kwFormula->append (dbe_strdup (lbl->str_expr));
      kwDescription->append (dbe_strdup (lbl->comment));
      kwEnumDescs->append (NULL);
    }

  for (long i = 0, sz = propNames ? propNames->size () : 0; i < sz; i++)
    {
      PropDescr *prop = propNames->fetch (i);
      char *pname = prop ? prop->name : NULL;
      if (pname == NULL || *pname == 0 || prop->flags & PRFLAG_NOSHOW)
	continue;
      int vtypeNum = prop->vtype;
      if (vtypeNum < 0 || vtypeNum >= TYPE_LAST)
	vtypeNum = TYPE_NONE;
      kwCategory->append (dbe_strdup (NTXT ("FK_EVTPROP"))); //Event Property
      kwCategoryI18N->append (dbe_strdup (GTXT ("Misc. Definitions")));
      kwDataType->append (dbe_strdup (vtypeNames[vtypeNum]));
      kwKeyword->append (dbe_strdup (pname));
      kwFormula->append (NULL);
      kwDescription->append (dbe_strdup (prop->uname));
      kwEnumDescs->append (NULL);
    }

  for (long i = 0, sz = dyn_indxobj ? dyn_indxobj->size () : 0; i < sz; i++)
    {
      IndexObjType_t *obj = dyn_indxobj->get (i);
      if (obj->memObj)
	continue;
      kwCategory->append (dbe_strdup (NTXT ("FK_IDXOBJ")));
      kwCategoryI18N->append (dbe_strdup (GTXT ("Index Object Definitions")));
      kwDataType->append (dbe_strdup (vtypeNames[TYPE_INT64]));
      kwKeyword->append (dbe_strdup (obj->name));
      kwFormula->append (dbe_strdup (obj->index_expr_str));
      kwDescription->append (dbe_strdup (obj->i18n_name));
      kwEnumDescs->append (NULL);
    }
}

Histable *
DbeSession::findIndexObject (int idxtype, uint64_t idx)
{
  HashMap<uint64_t, Histable*> *iobjs = idxobjs->fetch (idxtype);
  return iobjs->get (idx);
}

Histable *
DbeSession::createIndexObject (int idxtype, int64_t idx)
{
  HashMap<uint64_t, Histable*> *iobjs = idxobjs->fetch (idxtype);

  Histable *idxobj = iobjs->get (idx);
  if (idxobj == NULL)
    {
      idxobj = new IndexObject (idxtype, idx);
      if (idx == -1)
	idxobj->set_name (dbe_strdup (GTXT ("<Unknown>")));
      iobjs->put (idx, idxobj);
    }

  return idxobj;
}

Histable *
DbeSession::createIndexObject (int idxtype, Histable *hobj)
{
  HashMap<uint64_t, Histable*> *iobjs = idxobjs->fetch (idxtype);
  int64_t idx = hobj ? hobj->id : -1;
  Histable *idxobj = iobjs->get (idx);
  if (idxobj == NULL)
    {
      idxobj = new IndexObject (idxtype, hobj);
      if (idx == -1)
	idxobj->set_name (dbe_strdup (GTXT ("<Unknown>")));
      iobjs->put (idx, idxobj);
    }

  return idxobj;
}

Histable *
DbeSession::findObjectById (Histable::Type type, int subtype, uint64_t id)
{
  switch (type)
    {
    case Histable::FUNCTION:
    case Histable::MODULE:
    case Histable::LOADOBJECT:
      return ( id < (uint64_t) objs->size ()) ? objs->fetch ((int) id) : NULL;
    case Histable::INDEXOBJ:
      return findIndexObject (subtype, id);
      // ignoring the following cases
    case Histable::INSTR:
    case Histable::LINE:
    case Histable::EADDR:
    case Histable::MEMOBJ:
    case Histable::PAGE:
    case Histable::DOBJECT:
    case Histable::SOURCEFILE:
    case Histable::IOACTFILE:
    case Histable::IOACTVFD:
    case Histable::IOCALLSTACK:
    case Histable::HEAPCALLSTACK:
    case Histable::OTHER:
    case Histable::EXPERIMENT:
      break;
    }
  return NULL;
}

// return a vector of Functions that match the regular expression input string
Vector<JThread *> *
DbeSession::match_java_threads (char *ustr, int matchParent,
				Vector<uint64_t> * &grids,
				Vector<uint64_t> * &expids)
{
  if (ustr == NULL)
    return NULL;

  char *str = dbe_sprintf (NTXT ("^%s$"), ustr);
  regex_t regex_desc;
  int rc = regcomp (&regex_desc, str, REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
  free (str);
  if (rc)   // syntax error in parsing string
    return NULL;

  // allocate the new vector
  Vector<JThread *> *ret = new Vector<JThread*>;
  grids = new Vector<uint64_t>;
  expids = new Vector<uint64_t>;

  int index;
  JThread *jthread;
  int expid;
  Experiment* exp;
  Vec_loop (Experiment*, exps, expid, exp)
  {

    Vec_loop (JThread*, exp->get_jthreads (), index, jthread)
    {
      const char * name;
      if (matchParent)
	name = jthread->parent_name;
      else
	name = jthread->group_name;
      if (name == NULL)
	name = "";
      if (!regexec (&regex_desc, name, 0, NULL, 0))
	{
	  // this one matches
	  ret->append (jthread);
	  grids->append (exp->groupId);
	  expids->append (exp->getUserExpId ());
	}
    }
  }

  regfree (&regex_desc);
  return ret;
}

// return a vector of Functions that match the regular expression input string
Vector<Function *> *
DbeSession::match_func_names (const char *ustr, Histable::NameFormat nfmt)
{
  if (ustr == NULL)
    return NULL;
  char *str = dbe_sprintf (NTXT ("^%s$"), ustr);
  regex_t regex_desc;
  int rc = regcomp (&regex_desc, str, REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
  free (str);
  if (rc)   // syntax error in parsing string
    return NULL;

  // allocate the new vector
  Vector<Function *> *ret = new Vector<Function*>;

  int index;
  Histable *obj;
  Vec_loop (Histable*, objs, index, obj)
  {
    if (obj->get_type () == Histable::FUNCTION)
      {
	Function *func = (Function*) obj;
	if (!regexec (&regex_desc, func->get_name (nfmt), 0, NULL, 0))
	  // this one matches
	  ret->append (func);
      }
  }
  regfree (&regex_desc);
  return ret;
}

// return a vector of Functions that match the regular expression input string
Vector<FileData *> *
DbeSession::match_file_names (char *ustr, Histable::NameFormat nfmt)
{
  if (ustr == NULL)
    return NULL;
  char *str = dbe_sprintf (NTXT ("^%s$"), ustr);
  regex_t regex_desc;
  int rc = regcomp (&regex_desc, str, REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
  free (str);
  if (rc)   // syntax error in parsing string
    return NULL;

  // allocate the new vector
  Vector<FileData *> *ret = new Vector<FileData*>;
  int numExps = nexps ();
  DefaultMap<int64_t, FileData*>* fDataMap;
  Vector<FileData *> *fDataObjs;
  FileData *fData;
  int size;
  for (int i = 0; i < numExps; i++)
    {
      Experiment *exp = get_exp (i);
      fDataMap = exp->getFDataMap ();
      fDataObjs = fDataMap->values ();
      size = fDataObjs->size ();
      for (int j = 0; j < size; j++)
	{
	  fData = fDataObjs->fetch (j);
	  if (fData
	      && !regexec (&regex_desc, fData->get_raw_name (nfmt), 0, NULL, 0))
	    // this one matches
	    ret->append (fData);
	}
    }
  regfree (&regex_desc);
  return ret;
}

// return a vector of DataObjects that match the regular expression input string
Vector<DataObject *> *
DbeSession::match_dobj_names (char *ustr)
{
  if (ustr == NULL)
    return NULL;
  char *str = dbe_sprintf (NTXT ("^%s$"), ustr);
  regex_t regex_desc;
  int rc = regcomp (&regex_desc, str, REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
  free (str);
  if (rc)   // syntax error in parsing string
    return NULL;

  // allocate the new vector
  Vector<DataObject *> *ret = new Vector<DataObject*>;
  int index;
  DataObject *ditem;
  Vec_loop (DataObject*, dobjs, index, ditem)
  {
    // does this one match
    if (!regexec (&regex_desc, ditem->get_name (), 0, NULL, 0))
      // this one matches
      ret->append (ditem);
  }
  regfree (&regex_desc);
  return ret;
}

void
DbeSession::dump (char *msg, Vector<BaseMetric*> *mlist)
{
  if (msg)
    fprintf (stderr, "%s\n", msg);
  int sz = mlist ? mlist->size () : -1;
  for (int i = 0; i < sz; i++)
    {
      BaseMetric *m = mlist->fetch (i);
      char *s = m->dump ();
      fprintf (stderr, "%2d %s\n", i, s);
      free (s);
    }
  fprintf (stderr, "======END of mlist[%d] =========\n", sz);
}

void
DbeSession::dump (char *msg, Vector<Metric*> *mlist)
{
  if (msg)
    fprintf (stderr, "%s\n", msg);
  int sz = mlist ? mlist->size () : -1;
  for (int i = 0; i < sz; i++)
    {
      Metric *m = mlist->fetch (i);
      char *s = m->dump ();
      fprintf (stderr, "%2d %s\n", i, s);
      free (s);
    }
  fprintf (stderr, "======END of mlist[%d] =========\n", sz);
}
