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

#include "util.h"
#include "CacheMap.h"
#include "CallStack.h"
#include "DbeSession.h"
#include "DbeView.h"
#include "DbeLinkList.h"
#include "Experiment.h"
#include "Exp_Layout.h"
#include "Function.h"
#include "LoadObject.h"
#include "Module.h"

Descendants::Descendants ()
{
  count = 0;
  limit = sizeof (first_data) / sizeof (CallStackNode *);
  data = first_data;
}

Descendants::~Descendants ()
{
  if (data != first_data)
    free (data);
}

CallStackNode *
Descendants::find (Histable *hi, int *index)
{
  int cnt = count;
  int left = 0;
  for (int right = cnt - 1; left <= right;)
    {
      int ind = (left + right) / 2;
      CallStackNode *node = data[ind];
      Histable *instr = node->get_instr ();
      if (instr == hi)
	{
	  if (index)
	    *index = ind;
	  return node;
	}
      if (instr->id < hi->id)
	right = ind - 1;
      else
	left = ind + 1;
    }
  if (index)
    *index = left;
  return NULL;
}

void
Descendants::append (CallStackNode* item)
{
  if (count < limit)
    data[count++] = item;
  else
    insert (count, item);
}

void
Descendants::insert (int ind, CallStackNode* item)
{
  CallStackNode **old_data = data;
  int old_cnt = count;
  if (old_cnt + 1 >= limit)
    {
      int new_limit = (limit == 0) ? DELTA : limit * 2;
      CallStackNode **new_data = (CallStackNode **) xmalloc (new_limit * sizeof (CallStackNode *));
      for (int i = 0; i < ind; i++)
	new_data[i] = old_data[i];
      new_data[ind] = item;
      for (int i = ind; i < old_cnt; i++)
	new_data[i + 1] = old_data[i];
      limit = new_limit;
      data = new_data;
      if (old_data != first_data)
	free (old_data);
    }
  else
    {
      for (int i = ind; i < old_cnt; i++)
	old_data[i + 1] = old_data[i];
      old_data[ind] = item;
    }
  count++;
}

/*
 *    Private implementation of CallStack interface
 */

// When performing pipeline optimization on resolve_frame_info + add_stack
// cstk_ctx structure contains the state (or context) for one iteration to pass on
// from Phase 2 to Phase 3 (More details in Experiment.cc)
class CallStackP : public CallStack
{
public:
  CallStackP (Experiment *exp);

  virtual ~CallStackP ();

  virtual void add_stack (DataDescriptor *dDscr, long idx, FramePacket *frp, cstk_ctx_chunk *cstCtxChunk);
  virtual void *add_stack (Vector<Histable*> *objs);
  virtual CallStackNode *get_node (int n);
  virtual void print (FILE *);

private:

  static const int CHUNKSZ = 16384;

  Experiment *experiment;
  CallStackNode *root;
  CallStackNode *jvm_node;
  int nodes;
  int nchunks;
  CallStackNode **chunks;
  Map<uint64_t, CallStackNode *> *cstackMap;
  DbeLock *cstackLock;

  CallStackNode *add_stack (long start, long end, Vector<Histable*> *objs, CallStackNode *myRoot);
  CallStackNode *new_Node (CallStackNode*, Histable*);
  CallStackNode *find_preg_stack (uint64_t);
  // objs are in the root..leaf order
  void *add_stack_d (Vector<Histable*> *objs);
  void add_stack_java (DataDescriptor *dDscr, long idx, FramePacket *frp,
	hrtime_t tstamp, uint32_t thrid, Vector<Histable*>* natpcs,
	bool natpc_added, cstk_ctx_chunk *cstCtxChunk);
  void add_stack_java_epilogue (DataDescriptor *dDscr, long idx,
	FramePacket *frp, hrtime_t tstamp, uint32_t thrid,
	Vector<Histable*>* natpcs, Vector<Histable*>* jpcs, bool natpc_added);

  // Adjust HW counter event to find better trigger PC, etc.
  DbeInstr *adjustEvent (DbeInstr *leafPC, DbeInstr * candPC,
			 Vaddr &eventEA, int abst_type);
  Vector<Histable*> *natpcsP;
  Vector<Histable*> *jpcsP;
};

CallStackP::CallStackP (Experiment *exp)
{
  experiment = exp;
  nchunks = 0;
  chunks = NULL;
  nodes = 0;
  cstackMap = new CacheMap<uint64_t, CallStackNode *>;
  cstackLock = new DbeLock ();
  Function *total = dbeSession->get_Total_Function ();
  root = new_Node (0, total->find_dbeinstr (0, 0));
  jvm_node = NULL;
  natpcsP = NULL;
  jpcsP = NULL;
}

CallStackP::~CallStackP ()
{
  delete cstackLock;
  if (chunks)
    {
      for (int i = 0; i < nodes; i++)
	{
	  CallStackNode *node = get_node (i);
	  node->~CallStackNode ();
	}
      for (int i = 0; i < nchunks; i++)
	free (chunks[i]);
      free (chunks);
    }
  delete natpcsP;
  delete jpcsP;
  destroy_map (CallStackNode *, cstackMap);
}

CallStackNode *
CallStackP::new_Node (CallStackNode *anc, Histable *pcval)
{
  // cstackLock->aquireLock(); // Caller already locked it
  if (nodes >= nchunks * CHUNKSZ)
    {
      CallStackNode **old_chunks = chunks;
      nchunks++;

      // Reallocate Node chunk array
      chunks = (CallStackNode **) xmalloc (nchunks * sizeof (CallStackNode *));
      for (int i = 0; i < nchunks - 1; i++)
	chunks[i] = old_chunks[i];
      free (old_chunks);
      // Allocate new chunk for nodes.
      chunks[nchunks - 1] = (CallStackNode *) xmalloc (CHUNKSZ * sizeof (CallStackNode));
    }
  nodes++;
  CallStackNode *node = get_node (nodes - 1);
  new (node) CallStackNode (anc, pcval);
  // cstackLock->releaseLock();
  return node;
}

CallStackNode *
CallStackP::find_preg_stack (uint64_t prid)
{
  DataView *dview = experiment->getOpenMPdata ();
  dview->sort (PROP_CPRID);
  Datum tval;
  tval.setUINT64 (prid);
  long idx = dview->getIdxByVals (&tval, DataView::REL_EQ);
  if (idx < 0)
    return root;
  CallStackNode *node = (CallStackNode*) dview->getObjValue (PROP_USTACK, idx);
  if (node != NULL)
    return node;
  uint64_t pprid = dview->getLongValue (PROP_PPRID, idx);
  if (pprid == prid)
    return root;
  void *nat_stack = dview->getObjValue (PROP_MSTACK, idx);
  Vector<Histable*> *pcs = getStackPCs (nat_stack);

  // Find the bottom frame
  int btm;
  bool inOMP = false;
  DbeInstr *instr;
  Histable *hist;
  for (btm = 0; btm < pcs->size (); btm++)
    {
      hist = pcs->fetch (btm);
      if (hist->get_type () == Histable::INSTR)
	instr = (DbeInstr *) hist;
      else    // DBELINE
	instr = (DbeInstr *) hist->convertto (Histable::INSTR);
      LoadObject *lo = instr->func->module->loadobject;
      if (!inOMP)
	{
	  if (lo->flags & SEG_FLAG_OMP)
	    inOMP = true;
	}
      else if (!(lo->flags & SEG_FLAG_OMP))
	break;
    }

  // Find the top frame
  dview->sort (PROP_CPRID);
  int top;
  tval.setUINT64 (pprid);
  long pidx = dview->getIdxByVals (&tval, DataView::REL_EQ);
  if (pidx < 0)     // No parent. Process the entire nat_stack
    top = pcs->size () - 1;
  else
    {
      uint32_t thrid = (uint32_t) dview->getIntValue (PROP_THRID, idx);
      uint32_t pthrid = (uint32_t) dview->getIntValue (PROP_THRID, pidx);
      if (thrid != pthrid)
	{
	  // Parent is on a different stack.
	  // Process the entire nat_stack. Skip libthread.
	  for (top = pcs->size () - 1; top >= 0; top--)
	    {
	      hist = pcs->fetch (top);
	      if (hist->get_type () == Histable::INSTR)
		instr = (DbeInstr *) hist;
	      else // DBELINE
		instr = (DbeInstr *) hist->convertto (Histable::INSTR);
	      if (instr->func->module->loadobject->flags & SEG_FLAG_OMP)
		break;
	    }
	  if (top < 0)  // None found. May be incomplete call stack (x86)
	    top = pcs->size () - 1;
	}
      else
	{
	  // Parent is on the same stack. Find match.
	  top = pcs->size () - 1;
	  void *pnat_stack = dview->getObjValue (PROP_MSTACK, pidx);
	  Vector<Histable*> *ppcs = getStackPCs (pnat_stack);
	  for (int ptop = ppcs->size () - 1; top >= 0 && ptop >= 0;
		  top--, ptop--)
	    {
	      if (pcs->fetch (top) != ppcs->fetch (ptop))
		break;
	    }
	  delete ppcs;
	}
    }

  // Process the found range
  Vector<Histable*> *upcs = new Vector<Histable*>(128);
  for (int i = btm; i <= top; ++i)
    {
      hist = (DbeInstr*) pcs->fetch (i);
      if (hist->get_type () == Histable::INSTR)
	instr = (DbeInstr *) hist;
      else // DBELINE
	instr = (DbeInstr *) hist->convertto (Histable::INSTR);

      if (instr->func->module->loadobject->flags & SEG_FLAG_OMP)
	// Skip all frames from libmtsk
	continue;
      upcs->append (instr);
    }
  delete pcs;
  node = find_preg_stack (pprid);
  while (node != root)
    {
      upcs->append (node->instr);
      node = node->ancestor;
    }
  node = (CallStackNode *) add_stack (upcs);
  dview->setObjValue (PROP_USTACK, idx, node);
  delete upcs;
  return node;
}

#define JNI_MARKER -3

// This is one iteration if the third stage of
// resolve_frame_info + add_stack pipeline. Works on building the java
// stacks
void
CallStackP::add_stack_java (DataDescriptor *dDscr, long idx, FramePacket *frp,
			    hrtime_t tstamp, uint32_t thrid,
			    Vector<Histable*>* natpcs, bool natpc_added,
			    cstk_ctx_chunk *cstCtxChunk)
{
  Vector<Histable*> *jpcs = NULL;
  cstk_ctx *cstctx = NULL;
  if (cstCtxChunk != NULL)
    {
      cstctx = cstCtxChunk->cstCtxAr[idx % CSTCTX_CHUNK_SZ];
      jpcs = cstctx->jpcs;
      jpcs->reset ();
    }
  if (jpcs == NULL)
    {
      // this is when we are not doing the pipeline optimization
      // Temporary array for resolved addresses
      // [leaf_pc .. root_pc] == [0..stack_size-1]
      // Leave room for a possible "truncated" frame
      if (jpcsP == NULL)
	jpcsP = new Vector<Histable*>;
      jpcs = jpcsP;
      jpcs->reset ();
    }

  //
  // Construct the user stack
  //
  // Construct Java user stack
  int jstack_size = frp->stackSize (true);
  if (jstack_size)
    {
      // jpcs = new Vector<Histable*>( jstack_size );
      if (frp->isTruncatedStack (true))
	{
	  Function *truncf = dbeSession->getSpecialFunction (DbeSession::TruncatedStackFunc);
	  jpcs->append (truncf->find_dbeinstr (0, 0));
	}

      int nind = natpcs->size () - 1; // first native frame
      for (int jind = jstack_size - 1; jind >= 0; jind--)
	{
	  bool jleaf = (jind == 0); // is current java frame a leaf?
	  Vaddr mid = frp->getMthdFromStack (jind);
	  int bci = frp->getBciFromStack (jind);
	  DbeInstr *cur_instr = experiment->map_jmid_to_PC (mid, bci, tstamp);
	  jpcs->append (cur_instr);
	  if (bci == JNI_MARKER)
	    {
	      JMethod *j_method = (JMethod*) cur_instr->func;
	      // Find matching native function on the native stack
	      bool found = false;
	      for (; nind >= 0; nind--)
		{
		  DbeInstr *nat_addr = (DbeInstr *) natpcs->fetch (nind);
		  if (0 == nat_addr)
		    continue;
		  Function *nat_func = nat_addr->func;
		  if (!found && j_method->jni_match (nat_func))
		    found = true;
		  if (found)
		    {
		      // XXX omazur: the following will skip JNI native method
		      // implemented in JVM itself.
		      // If we are back in JVM switch to processing Java
		      // frames if there are any.
		      if ((nat_func->module->loadobject->flags & SEG_FLAG_JVM) && !jleaf)
			break;
		      jpcs->append (nat_addr);
		    }
		}
	    }
	}
    }
  add_stack_java_epilogue (dDscr, idx, frp, tstamp, thrid, natpcs, jpcs, natpc_added);
}

// This is one iteration if the fourth stage of
// resolve_frame_info + add_stack pipeline.
// It adds the native and java stacks to the stackmap

void
CallStackP::add_stack_java_epilogue (DataDescriptor *dDscr, long idx,
	FramePacket *frp, hrtime_t tstamp, uint32_t thrid,
	Vector<Histable*>* natpcs, Vector<Histable*> *jpcs, bool natpc_added)
{
  CallStackNode *node = NULL;
  if (!natpc_added)
    {
      node = (CallStackNode *) add_stack (natpcs);
      dDscr->setObjValue (PROP_MSTACK, idx, node);
      dDscr->setObjValue (PROP_XSTACK, idx, node);
      dDscr->setObjValue (PROP_USTACK, idx, node);
    }

  int jstack_size = frp->stackSize (true);
  if (jstack_size)
    {
      if (jpcs != NULL)
	node = (CallStackNode *) add_stack_d (jpcs);
      if (node == NULL)
	node = (CallStackNode*) dDscr->getObjValue (PROP_USTACK, idx);
      dDscr->setObjValue (PROP_USTACK, idx, node);
      Function *func = (Function*) node->instr->convertto (Histable::FUNCTION);
      if (func != dbeSession->get_JUnknown_Function ())
	dDscr->setObjValue (PROP_XSTACK, idx, node);
    }

  JThread *jthread = experiment->map_pckt_to_Jthread (thrid, tstamp);
  if (jthread == JTHREAD_NONE && jstack_size != 0 && node != NULL)
    {
      Function *func = (Function*) node->instr->convertto (Histable::FUNCTION);
      if (func != dbeSession->get_JUnknown_Function ())
	jthread = JTHREAD_DEFAULT;
    }
  dDscr->setObjValue (PROP_JTHREAD, idx, jthread);
  if (jthread == JTHREAD_NONE || (jthread != JTHREAD_DEFAULT && jthread->is_system ()))
    {
      if (jvm_node == NULL)
	{
	  Function *jvm = dbeSession->get_jvm_Function ();
	  if (jvm)
	    {
	      jvm_node = new_Node (root, jvm->find_dbeinstr (0, 0));
	      CommonPacket::jvm_overhead = jvm_node;
	    }
	}
      dDscr->setObjValue (PROP_USTACK, idx, jvm_node);
    }
}

// This is one iteration of the 2nd stage of
// resolve_frame_info + add_stack() pipeline. Builds the stack for a given framepacket.
// When pipeline optimization is turnd off, cstctxchunk passed is NULL
void
CallStackP::add_stack (DataDescriptor *dDscr, long idx, FramePacket *frp,
		       cstk_ctx_chunk* cstCtxChunk)
{
  Vector<Histable*> *natpcs = NULL;
  cstk_ctx *cstctx = NULL;
  int stack_size = frp->stackSize ();
  if (cstCtxChunk != NULL)
    {
      cstctx = cstCtxChunk->cstCtxAr[idx % CSTCTX_CHUNK_SZ];
      natpcs = cstctx->natpcs;
      natpcs->reset ();
    }
  if (natpcs == NULL)
    {
      // this is when we are not doing the pipeline optimization
      // Temporary array for resolved addresses
      // [leaf_pc .. root_pc] == [0..stack_size-1]
      // Leave room for a possible "truncated" frame
      if (natpcsP == NULL)
	natpcsP = new Vector<Histable*>;
      natpcs = natpcsP;
      natpcs->reset ();
    }

  bool leaf = true;
  hrtime_t tstamp = (hrtime_t) dDscr->getLongValue (PROP_TSTAMP, idx);
  uint32_t thrid = (uint32_t) dDscr->getIntValue (PROP_THRID, idx);

  enum
  {
    NONE,
    CHECK_O7,
    USE_O7,
    SKIP_O7
  } state = NONE;

  Vaddr o7_to_skip = 0;
  for (int index = 0; index < stack_size; index++)
    {
      if (frp->isLeafMark (index))
	{
	  state = CHECK_O7;
	  continue;
	}

      if (state == SKIP_O7)
	{
	  // remember this bad o7 value since OMP might not recognize it
	  o7_to_skip = frp->getFromStack (index);
	  state = NONE;
	  continue;
	}

      Vaddr va = frp->getFromStack (index);
      DbeInstr *cur_instr = experiment->map_Vaddr_to_PC (va, tstamp);
      // We need to adjust return addresses on intel
      // in order to attribute inclusive metrics to proper instructions.
      if (experiment->platform == Intel && cur_instr->addr != 0)
	cur_instr = cur_instr->func->find_dbeinstr (0, cur_instr->addr - 1);

      // Skip PC's from PLT, update leaf and state accordingly
      if ((cur_instr->func->flags & FUNC_FLAG_PLT)
	   && (leaf || state == CHECK_O7))
	{
	  if (state == CHECK_O7)
	    state = USE_O7;
	  leaf = false;
	  continue;
	}
      if (state == CHECK_O7)
	{
	  state = USE_O7;
	  uint64_t saddr = cur_instr->func->save_addr;
	  if (cur_instr->func->isOutlineFunction)
	    // outline functions assume 'save' instruction
	    // Note: they accidentally have saddr == FUNC_ROOT
	    state = SKIP_O7;
	  else if (saddr == FUNC_ROOT)
	    {
	      // If a function is statically determined as a root
	      // but dynamically appears not, don't discard o7.
	      // One such case is __misalign_trap_handler on sparcv9.
	      if (stack_size == 3)
		state = SKIP_O7;
	    }
	  else if (saddr != FUNC_NO_SAVE && cur_instr->addr > saddr)
	    state = SKIP_O7;
	}
      else if (state == USE_O7)
	{
	  state = NONE;
	  if (cur_instr->flags & PCInvlFlag)
	    continue;
	}
      if (leaf)
	{
	  Vaddr evpc = (Vaddr) dDscr->getLongValue (PROP_VIRTPC, idx);
	  if (evpc != 0
	      && !(index > 0 && frp->isLeafMark (index - 1)
		   && evpc == (Vaddr) (-1)))
	    {
	      /* contains hwcprof info */
	      cur_instr->func->module->read_hwcprof_info ();

	      // complete ABS validation of candidate eventPC/eventEA
	      // and correction/adjustment of collected callstack leaf PC
	      DbeInstr *candPC = experiment->map_Vaddr_to_PC (evpc, tstamp);
	      Vaddr vaddr = (Vaddr) dDscr->getLongValue (PROP_VADDR, idx);
	      Vaddr tmp_vaddr = vaddr;
	      int abst_type;
	      uint32_t tag = dDscr->getIntValue (PROP_HWCTAG, idx);
	      if (tag < 0 || tag >= MAX_HWCOUNT)
		abst_type = ABST_NOPC;
	      else
		abst_type = experiment->coll_params.hw_tpc[tag];

	      // We need to adjust addresses for ABST_EXACT_PEBS_PLUS1
	      // (Nehalem/SandyBridge PEBS identifies PC+1, not PC)
	      if (abst_type == ABST_EXACT_PEBS_PLUS1 && candPC->addr != 0)
		candPC = candPC->func->find_dbeinstr (0, candPC->func->find_previous_addr (candPC->addr));

	      cur_instr = adjustEvent (cur_instr, candPC, tmp_vaddr, abst_type);
	      if (vaddr != tmp_vaddr)
		{
		  if (tmp_vaddr < ABS_CODE_RANGE)
		    {
		      /* post processing backtrack failed */
		      dDscr->setValue (PROP_VADDR, idx, tmp_vaddr);
		      dDscr->setValue (PROP_PADDR, idx, ABS_NULL);
		      /* hwcp->eventVPC =  xxxxx leave eventPC alone,
		       *   or can we set it to leafpc? */
		      dDscr->setValue (PROP_PHYSPC, idx, ABS_NULL);
		    }
		  else
		    {
		      /* internal error: why would post-processing modify vaddr? */
		      dDscr->setValue (PROP_PADDR, idx, (Vaddr) (-1));
		      dDscr->setValue (PROP_PHYSPC, idx, (Vaddr) (-1));
		    }
		}
	    }
	}
      natpcs->append (cur_instr);
      leaf = false;

      // A hack to deceive the user into believing that outlined code
      // is called from the base function
      DbeInstr *drvd = cur_instr->func->derivedNode;
      if (drvd != NULL)
	natpcs->append (drvd);
    }
  if (frp->isTruncatedStack ())
    {
      Function *truncf = dbeSession->getSpecialFunction (DbeSession::TruncatedStackFunc);
      natpcs->append (truncf->find_dbeinstr (0, 0));
    }
  else if (frp->isFailedUnwindStack ())
    {
      Function *funwf = dbeSession->getSpecialFunction (DbeSession::FailedUnwindFunc);
      natpcs->append (funwf->find_dbeinstr (0, 0));
    }

  CallStackNode *node = (CallStackNode*) add_stack (natpcs);
  dDscr->setObjValue (PROP_MSTACK, idx, node);
  dDscr->setObjValue (PROP_XSTACK, idx, node);
  dDscr->setObjValue (PROP_USTACK, idx, node);

  // OpenMP 3.0 stacks
  stack_size = frp->ompstack->size ();
  if (stack_size > 0 || frp->omp_state == OMP_IDLE_STATE)
    {
      Function *func;
      Vector<Histable*> *omppcs = new Vector<Histable*>(stack_size);
      Vector<Histable*> *ompxpcs = new Vector<Histable*>(stack_size);
      switch (frp->omp_state)
	{
	case OMP_IDLE_STATE:
	case OMP_RDUC_STATE:
	case OMP_IBAR_STATE:
	case OMP_EBAR_STATE:
	case OMP_LKWT_STATE:
	case OMP_CTWT_STATE:
	case OMP_ODWT_STATE:
	case OMP_ATWT_STATE:
	  {
	    func = dbeSession->get_OMP_Function (frp->omp_state);
	    DbeInstr *instr = func->find_dbeinstr (0, 0);
	    omppcs->append (instr);
	    ompxpcs->append (instr);
	    break;
	  }
	}
      Vector<Vaddr> *stck = frp->ompstack;
      leaf = true;
      for (int index = 0; index < stack_size; index++)
	{
	  if (stck->fetch (index) == SP_LEAF_CHECK_MARKER)
	    {
	      state = CHECK_O7;
	      continue;
	    }
	  if (state == SKIP_O7)
	    {
	      state = NONE;
	      continue;
	    }

	  // The OMP stack might not have enough information to know to discard a bad o7.
	  // So just remember what the native stack skipped.
	  if (o7_to_skip == stck->fetch (index))
	    {
	      state = NONE;
	      continue;
	    }
	  Vaddr va = stck->fetch (index);
	  DbeInstr *cur_instr = experiment->map_Vaddr_to_PC (va, tstamp);

	  // Skip PC's from PLT, update leaf and state accordingly
	  if ((cur_instr->func->flags & FUNC_FLAG_PLT) &&
	      (leaf || state == CHECK_O7))
	    {
	      if (state == CHECK_O7)
		state = USE_O7;
	      leaf = false;
	      continue;
	    }
	  if (state == CHECK_O7)
	    {
	      state = USE_O7;
	      uint64_t saddr = cur_instr->func->save_addr;
	      if (cur_instr->func->isOutlineFunction)
		// outline functions assume 'save' instruction
		// Note: they accidentally have saddr == FUNC_ROOT
		state = SKIP_O7;
	      else if (saddr == FUNC_ROOT)
		{
		  // If a function is statically determined as a root
		  // but dynamically appears not, don't discard o7.
		  // One such case is __misalign_trap_handler on sparcv9.
		  if (stack_size == 3)
		    state = SKIP_O7;
		}
	      else if (saddr != FUNC_NO_SAVE && cur_instr->addr > saddr)
		state = SKIP_O7;
	    }
	  else if (state == USE_O7)
	    {
	      state = NONE;
	      if (cur_instr->flags & PCInvlFlag)
		continue;
	    }

	  DbeLine *dbeline = (DbeLine*) cur_instr->convertto (Histable::LINE);
	  if (cur_instr->func->usrfunc)
	    {
	      dbeline = dbeline->sourceFile->find_dbeline (cur_instr->func->usrfunc, dbeline->lineno);
	      omppcs->append (dbeline);
	    }
	  else if (dbeline->lineno > 0)
	    omppcs->append (dbeline);
	  else
	    omppcs->append (cur_instr);
	  if (dbeline->is_set (DbeLine::OMPPRAGMA) &&
	      frp->omp_state == OMP_WORK_STATE)
	    dDscr->setValue (PROP_OMPSTATE, idx, OMP_OVHD_STATE);
	  ompxpcs->append (cur_instr);
	  leaf = false;
	}
      if (frp->omptruncated == SP_TRUNC_STACK_MARKER)
	{
	  func = dbeSession->getSpecialFunction (DbeSession::TruncatedStackFunc);
	  DbeInstr *instr = func->find_dbeinstr (0, 0);
	  omppcs->append (instr);
	  ompxpcs->append (instr);
	}
      else if (frp->omptruncated == SP_FAILED_UNWIND_MARKER)
	{
	  func = dbeSession->getSpecialFunction (DbeSession::FailedUnwindFunc);
	  DbeInstr *instr = func->find_dbeinstr (0, 0);
	  omppcs->append (instr);
	  ompxpcs->append (instr);
	}

      // User model call stack
      node = (CallStackNode*) add_stack (omppcs);
      dDscr->setObjValue (PROP_USTACK, idx, node);
      delete omppcs;

      // Expert call stack
      node = (CallStackNode*) add_stack (ompxpcs);
      dDscr->setObjValue (PROP_XSTACK, idx, node);
      delete ompxpcs;
      dDscr->setObjValue (PROP_JTHREAD, idx, JTHREAD_DEFAULT);
      return;
    }

  // OpenMP 2.5 stacks
  if (frp->omp_cprid || frp->omp_state)
    {
      DataView *dview = experiment->getOpenMPdata ();
      if (dview == NULL)
	{
	  // It appears we may get OMP_SERL_STATE from a passive libmtsk
	  dDscr->setObjValue (PROP_JTHREAD, idx, JTHREAD_DEFAULT);
	  return;
	}
      if (dview->getDataDescriptor () == dDscr)
	{
	  // Don't process the user stack for OpenMP fork events yet
	  dDscr->setObjValue (PROP_USTACK, idx, (void*) NULL);
	  dDscr->setObjValue (PROP_JTHREAD, idx, JTHREAD_DEFAULT);
	  return;
	}
      Vector<Histable*> *omppcs = new Vector<Histable*>(stack_size);

      // Construct OMP user stack
      // Find the bottom frame
      int btm = 0;
      switch (frp->omp_state)
	{
	case OMP_IDLE_STATE:
	  {
	    Function *func = dbeSession->get_OMP_Function (frp->omp_state);
	    omppcs->append (func->find_dbeinstr (0, 0));
	    // XXX: workaround for inconsistency between OMP_IDLE_STATE
	    // and omp_cprid != 0
	    frp->omp_cprid = 0;
	    btm = natpcs->size ();
	    break;
	  }
	case OMP_RDUC_STATE:
	case OMP_IBAR_STATE:
	case OMP_EBAR_STATE:
	case OMP_LKWT_STATE:
	case OMP_CTWT_STATE:
	case OMP_ODWT_STATE:
	case OMP_ATWT_STATE:
	  {
	    Function *func = dbeSession->get_OMP_Function (frp->omp_state);
	    omppcs->append (func->find_dbeinstr (0, 0));
	    bool inOMP = false;
	    for (btm = 0; btm < natpcs->size (); btm++)
	      {
		DbeInstr *instr = (DbeInstr *) natpcs->fetch (btm);
		LoadObject *lo = instr->func->module->loadobject;
		if (!inOMP)
		  {
		    if (lo->flags & SEG_FLAG_OMP)
		      inOMP = true;
		  }
		else if (!(lo->flags & SEG_FLAG_OMP))
		  break;
	      }
	    break;
	  }
	case OMP_NO_STATE:
	case OMP_WORK_STATE:
	case OMP_SERL_STATE:
	default:
	  break;
	}

      // Find the top frame
      int top = -1;
      switch (frp->omp_state)
	{
	case OMP_IDLE_STATE:
	  break;
	default:
	  {
	    dview->sort (PROP_CPRID);
	    Datum tval;
	    tval.setUINT64 (frp->omp_cprid);
	    long pidx = dview->getIdxByVals (&tval, DataView::REL_EQ);
	    if (pidx < 0)   // No parent. Process the entire nat_stack
	      top = natpcs->size () - 1;
	    else
	      {
		uint32_t pthrid = (uint32_t) dview->getIntValue (PROP_THRID, pidx);
		if (thrid != pthrid)
		  {
		    // Parent is on a different stack.
		    // Process the entire nat_stack. Skip libthread.
		    for (top = natpcs->size () - 1; top >= 0; top--)
		      {
			DbeInstr *instr = (DbeInstr *) natpcs->fetch (top);
			if (instr->func->module->loadobject->flags & SEG_FLAG_OMP)
			  break;
		      }
		    if (top < 0) // None found. May be incomplete call stack
		      top = natpcs->size () - 1;
		  }
		else
		  {
		    // Parent is on the same stack. Find match.
		    top = natpcs->size () - 1;
		    void *pnat_stack = dview->getObjValue (PROP_MSTACK, pidx);
		    Vector<Histable*> *ppcs = getStackPCs (pnat_stack);
		    for (int ptop = ppcs->size () - 1; top >= 0 && ptop >= 0;
			    top--, ptop--)
		      {
			if (natpcs->fetch (top) != ppcs->fetch (ptop))
			  break;
		      }
		    delete ppcs;
		  }
	      }
	    // If no frames are found for Barrier/Reduction save at least one
	    if ((frp->omp_state == OMP_RDUC_STATE
		 || frp->omp_state == OMP_IBAR_STATE
		 || frp->omp_state == OMP_EBAR_STATE)
		&& top < btm && btm < natpcs->size ())
	      top = btm;
	  }
	}
      for (int i = btm; i <= top; ++i)
	{
	  DbeInstr *instr = (DbeInstr *) natpcs->fetch (i);
	  if (instr->func->module->loadobject->flags & SEG_FLAG_OMP)
	    continue; // Skip all frames from libmtsk
	  omppcs->append (instr);
	}
      node = find_preg_stack (frp->omp_cprid);
      while (node != root)
	{
	  omppcs->append (node->instr);
	  node = node->ancestor;
	}
      node = (CallStackNode *) add_stack (omppcs);
      dDscr->setObjValue (PROP_USTACK, idx, node);
      delete omppcs;
      dDscr->setObjValue (PROP_JTHREAD, idx, JTHREAD_DEFAULT);
      return;
    }

  // Construct Java user stack
  add_stack_java (dDscr, idx, frp, tstamp, thrid, natpcs, true, NULL);
}

// adjustment of leafPC/eventVA for XHWC packets with candidate eventPC
//  Called from CallStack during initial processing of the events
DbeInstr *
CallStackP::adjustEvent (DbeInstr *leafPC, DbeInstr *candPC, Vaddr &eventVA,
			 int abst_type)
{
  // increment counter of dataspace events
  experiment->dsevents++;
  bool isPrecise;
  if (abst_type == ABST_EXACT_PEBS_PLUS1)
    isPrecise = true;
  else if (abst_type == ABST_EXACT)
    isPrecise = true;
  else
    isPrecise = false;

  if (isPrecise)
    /* precise backtracking */
    /* assume within 1 instruction of leaf (this could be checked here) */
    // no change to eventVA or candPC
    return candPC;

  Function *func = leafPC->func;
  unsigned int bt_entries = func->module->bTargets.size ();
  DbeInstr *bestPC = NULL;

  // bt == branch target (potential destination of a branch
  if (bt_entries == 0)
    { // no XHWCprof info for this module
      // increment counter
      experiment->dsnoxhwcevents++;

      // see if event is to be processed anyway
      if (!dbeSession->check_ignore_no_xhwcprof ())
	{
	  // Don't ignore error
	  // XXX -- set error code in event VA -- replace with other mechanism
	  if (eventVA > ABS_CODE_RANGE)
	    eventVA = ABS_NULL;
	  eventVA |= ABS_NO_CTI_INFO; // => effective address can't be validated
	  bestPC = leafPC; // => no PC correction possible
	}
      else
	bestPC = candPC; // assume the event valid
    }
  else
    {
      // we have the info to verify the backtracking
      target_info_t *bt;
      int bt_entry = bt_entries;
      uint64_t leafPC_offset = func->img_offset + leafPC->addr;
      uint64_t candPC_offset = candPC->func->img_offset + candPC->addr;
      do
	{
	  bt_entry--;
	  bt = func->module->bTargets.fetch (bt_entry);
	  /* bts seem to be sorted by offset, smallest to largest */
	}
      while (bt_entry > 0 && bt->offset > leafPC_offset);
      /* if bt_entry == 0, all items have been checked */

      if (bt->offset > leafPC_offset)
	{ /* XXXX isn't is possible that all bt's are after leafPC_offset? */
	  bestPC = leafPC; // actual event PC can't be determined
	  if (eventVA > ABS_CODE_RANGE)
	    eventVA = ABS_NULL;
	  eventVA |= ABS_INFO_FAILED; // effective address can't be validated
	}
      else if (bt->offset > candPC_offset)
	{
	  // use synthetic PC corresponding to bTarget
	  bestPC = func->find_dbeinstr (PCTrgtFlag, bt->offset - func->img_offset);
	  if (eventVA > ABS_CODE_RANGE)
	    eventVA = ABS_NULL;
	  eventVA |= ABS_CTI_TARGET; // effective  address can't be validated
	}
      else
	bestPC = candPC;    // accept provided virtual address as valid
    }
  return bestPC;
}

void *
CallStackP::add_stack_d (Vector<Histable*> *objs)
{
  // objs: root..leaf
  // Reverse objs
  for (int i = 0, j = objs->size () - 1; i < j; ++i, --j)
    objs->swap (i, j);
  return add_stack (objs);
}

CallStackNode::CallStackNode (CallStackNode *_ancestor, Histable *_instr)
{
  ancestor = _ancestor;
  instr = _instr;
  alt_node = NULL;
}

CallStackNode::~CallStackNode () { }

bool
CallStackNode::compare (long start, long end, Vector<Histable*> *objs, CallStackNode *mRoot)
{
  CallStackNode *p = this;
  for (long i = start; i < end; i++, p = p->get_ancestor ())
    if (p == NULL || p->get_instr () != objs->get (i))
      return false;
  return p == mRoot;
}

void
CallStackNode::dump ()
{
  const char *s = "";
  int sz = 0;
  for (CallStackNode *p = this; p; p = p->get_ancestor ())
    {
      fprintf (stderr, NTXT ("%.*s 0x%08llx id=0x%08llx %s\n"), sz, s,
	       (long long) p, (long long) p->get_instr ()->id,
	       STR (p->get_instr ()->get_name ()));
      s = "-";
      sz += 1;
    }
}

long total_calls_add_stack, total_stacks, total_nodes, call_stack_size[201];

void *
CallStackP::add_stack (Vector<Histable*> *objs)
{
  // objs: leaf..root
  uint64_t hash = objs->size ();
  for (long i = objs->size () - 1; i >= 0; --i)
    hash ^= (unsigned long long) objs->get (i);

  uint64_t key = hash ? hash : 1;
  CallStackNode *node = cstackMap->get (key);
#ifdef DEBUG
  if (DUMP_CALL_STACK)
    {
      total_calls_add_stack++;
      call_stack_size[objs->size () > 200 ? 200 : objs->size ()]++;
      Dprintf (DUMP_CALL_STACK,
	       "add_stack: %lld size=%lld  key=0x%08llx cashNode=0x%08llx\n",
	       (long long) total_calls_add_stack, (long long) objs->size (),
	       (long long) key, (long long) node);
      for (long i = 0, sz = VecSize (objs); i < sz; i++)
	Dprintf (DUMP_CALL_STACK, "  add_stack: %.*s 0x%08llx id=0x%08llx %s\n",
		 (int) i, NTXT (" "), (long long) objs->get (i),
		 (long long) objs->get (i)->id, STR (objs->get (i)->get_name ()));
    }
#endif
  if (node && node->compare (0, objs->size (), objs, root))
    {
      Dprintf (DUMP_CALL_STACK, NTXT ("STACK FOUND: key=0x%08llx 0x%08llx id=0x%08llx %s\n"),
	       (long long) key, (long long) node,
	       (long long) node->get_instr ()->id,
	       STR (node->get_instr ()->get_name ()));
      return node;
    }
  node = root;
  for (long i = objs->size () - 1; i >= 0; i--)
    {
      Histable *instr = objs->get (i);
      int old_count = node->count;
      int left;
      CallStackNode *nd = node->find (instr, &left);
      if (nd)
	{
	  node = nd;
	  continue;
	}
      cstackLock->aquireLock (); // Use one lock for all nodes
      // node->aquireLock();
      if (old_count != node->count)
	{
	  nd = node->find (instr, &left);
	  if (nd)
	    { // the other thread has created this node
	      cstackLock->releaseLock ();
	      // node->releaseLock();
	      node = nd;
	      continue;
	    }
	}
      // New Call Stack
      total_stacks++;
      nd = node;
      CallStackNode *first = NULL;
      do
	{
	  CallStackNode *anc = node;
	  total_nodes++;
	  node = new_Node (anc, objs->get (i));
	  if (first)
	    anc->append (node);
	  else
	    first = node;
	}
      while (i-- > 0);
      nd->insert (left, first);
      cstackLock->releaseLock ();
      // nd->releaseLock();
      break;
    }
  cstackMap->put (key, node);
  if (DUMP_CALL_STACK)
    node->dump ();
  return node;
}

CallStackNode *
CallStackP::get_node (int n)
{
  if (n < nodes)
    return &chunks[n / CHUNKSZ][n % CHUNKSZ];
  return NULL;
}

/*
 *  Debugging methods
 */
void
CallStackP::print (FILE *fd)
{
  FILE *f = (fd == NULL ? stderr : fd);
  fprintf (f, GTXT ("CallStack: nodes = %d\n\n"), nodes);
  int maxdepth = 0;
  int maxwidth = 0;
  const char *t;
  char *n;
  for (int i = 0; i < nodes; i++)
    {
      CallStackNode *node = &chunks[i / CHUNKSZ][i % CHUNKSZ];
      Histable *instr = node->instr;
      if (instr->get_type () == Histable::LINE)
	{
	  t = "L";
	  n = ((DbeLine *) instr)->func->get_name ();
	}
      else if (instr->get_type () == Histable::INSTR)
	{
	  t = "I";
	  n = ((DbeInstr *) instr)->func->get_name ();
	}
      else
	{
	  t = "O";
	  n = instr->get_name ();
	}
      long long addr = (long long) instr->get_addr ();
      fprintf (f, GTXT ("node: 0x%016llx anc: 0x%016llx -- 0x%016llX:  %s %s\n"),
	       (unsigned long long) node, (unsigned long long) node->ancestor,
	       addr, t, n);
    }
  fprintf (f, GTXT ("md = %d, mw = %d\n"), maxdepth, maxwidth);
}

/*
 *  Static CallStack methods
 */
CallStack *
CallStack::getInstance (Experiment *exp)
{
  return new CallStackP (exp);
}

int
CallStack::stackSize (void *stack)
{
  CallStackNode *node = (CallStackNode *) stack;
  int sz = 0;
  for (; node; node = node->ancestor)
    sz++;
  return sz - 1; // don't count the root node
}

Histable *
CallStack::getStackPC (void *stack, int n)
{
  CallStackNode *node = (CallStackNode *) stack;
  while (n-- && node)
    node = node->ancestor;
  if (node == NULL)
    return dbeSession->get_Unknown_Function ()->find_dbeinstr (PCInvlFlag, 0);
  return node->instr;
}

Vector<Histable*> *
CallStack::getStackPCs (void *stack, bool get_hide_stack)
{
  Vector<Histable*> *res = new Vector<Histable*>;
  CallStackNode *node = (CallStackNode *) stack;
  if (get_hide_stack && node->alt_node != NULL)
    node = node->alt_node;
  while (node && node->ancestor)
    { // skip the root node
      res->append (node->instr);
      node = node->ancestor;
    }
  return res;
}

int
CallStack::compare (void *stack1, void *stack2)
{
  // Quick comparision
  if (stack1 == stack2)
    return 0;

  CallStackNode *node1 = (CallStackNode *) stack1;
  CallStackNode *node2 = (CallStackNode *) stack2;
  while (node1 != NULL && node2 != NULL)
    {
      //to keep the result const on different platforms
      //we use instr->id instead of instr
      if (node1->instr->id < node2->instr->id)
	return -1;
      else if (node1->instr->id > node2->instr->id)
	return 1;
      node1 = node1->ancestor;
      node2 = node2->ancestor;
    }
  if (node1 == NULL && node2 != NULL)
    return -1;
  else if (node1 != NULL && node2 == NULL)
    return 1;
  else
    return 0;
}

// LIBRARY VISIBILITY

void
CallStack::setHideStack (void *stack, void *hideStack)
{
  CallStackNode *hNode = (CallStackNode *) stack;
  hNode->alt_node = (CallStackNode *) hideStack;
}
