/* Copyright (C) 2021-2025 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of GNU Binutils.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "config.h"
#include <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;
#elif ARCH(RISCV)
	RISCV;
#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 ()];
  for (int j = 0, jsz = exp_names->size (); j < jsz; j++)
    {
      t_exp_list[j] = NULL;

      char *lineage_name = exp_names->fetch (j);
      dbe_stat_t 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;
      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*) xmalloc (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);
}
