/*--------------------------------------------------------------------*/
/*--- Callgrind                                                    ---*/
/*---                                               ct_callstack.c ---*/
/*--------------------------------------------------------------------*/

/*
   This file is part of Callgrind, a Valgrind tool for call tracing.

   Copyright (C) 2002-2011, Josef Weidendorfer (Josef.Weidendorfer@gmx.de)

   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 2 of the
   License, 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, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307, USA.

   The GNU General Public License is contained in the file COPYING.
*/

#include "global.h"

/*------------------------------------------------------------*/
/*--- Call stack, operations                               ---*/
/*------------------------------------------------------------*/

/* Stack of current thread. Gets initialized when switching to 1st thread.
 *
 * The artificial call stack is an array of call_entry's, representing
 * stack frames of the executing program. 
 * Array call_stack and call_stack_esp have same size and grow on demand.
 * Array call_stack_esp holds SPs of corresponding stack frames.
 *
 */

#define N_CALL_STACK_INITIAL_ENTRIES 500

call_stack CLG_(current_call_stack);

void CLG_(init_call_stack)(call_stack* s)
{
  Int i;

  CLG_ASSERT(s != 0);

  s->size = N_CALL_STACK_INITIAL_ENTRIES;   
  s->entry = (call_entry*) CLG_MALLOC("cl.callstack.ics.1",
                                      s->size * sizeof(call_entry));
  s->sp = 0;
  s->entry[0].cxt = 0; /* for assertion in push_cxt() */

  for(i=0; i<s->size; i++) s->entry[i].enter_cost = 0;
}

call_entry* CLG_(get_call_entry)(Int sp)
{
  CLG_ASSERT(sp <= CLG_(current_call_stack).sp);
  return &(CLG_(current_call_stack).entry[sp]);
}

void CLG_(copy_current_call_stack)(call_stack* dst)
{
  CLG_ASSERT(dst != 0);

  dst->size  = CLG_(current_call_stack).size;
  dst->entry = CLG_(current_call_stack).entry;
  dst->sp    = CLG_(current_call_stack).sp;
}

void CLG_(set_current_call_stack)(call_stack* s)
{
  CLG_ASSERT(s != 0);

  CLG_(current_call_stack).size  = s->size;
  CLG_(current_call_stack).entry = s->entry;
  CLG_(current_call_stack).sp    = s->sp;
}


static __inline__
void ensure_stack_size(Int i)
{
  Int oldsize;
  call_stack *cs = &CLG_(current_call_stack);

  if (i < cs->size) return;

  oldsize = cs->size;
  cs->size *= 2;
  while (i > cs->size) cs->size *= 2;

  cs->entry = (call_entry*) VG_(realloc)("cl.callstack.ess.1",
                                         cs->entry,
					 cs->size * sizeof(call_entry));

  for(i=oldsize; i<cs->size; i++)
    cs->entry[i].enter_cost = 0;

  CLG_(stat).call_stack_resizes++;
 
  CLG_DEBUGIF(2)
    VG_(printf)("        call stack enlarged to %d entries\n",
		CLG_(current_call_stack).size);
}



/* Called when function entered nonrecursive */
static void function_entered(fn_node* fn)
{
  CLG_ASSERT(fn != 0);

#if CLG_ENABLE_DEBUG
  if (fn->verbosity >=0) {
    Int old = CLG_(clo).verbose;
    CLG_(clo).verbose = fn->verbosity;
    fn->verbosity = old;
    VG_(message)(Vg_DebugMsg, 
		 "Entering %s: Verbosity set to %d\n",
		 fn->name, CLG_(clo).verbose);
  }
#endif		
	    
  if (fn->dump_before) {
    Char trigger[FN_NAME_LEN];
    VG_(sprintf)(trigger, "--dump-before=%s", fn->name);
    CLG_(dump_profile)(trigger, True);
  }
  else if (fn->zero_before) {
    CLG_(zero_all_cost)(True);
  }

  if (fn->toggle_collect) {
    CLG_(current_state).collect = !CLG_(current_state).collect;
    CLG_DEBUG(2,"   entering %s: toggled collection state to %s\n",
	     fn->name,
	     CLG_(current_state).collect ? "ON" : "OFF");
  }
}	

/* Called when function left (no recursive level active) */
static void function_left(fn_node* fn)
{
  CLG_ASSERT(fn != 0);

  if (fn->dump_after) {
    Char trigger[FN_NAME_LEN];
    VG_(sprintf)(trigger, "--dump-after=%s", fn->name);
    CLG_(dump_profile)(trigger, True);
  }
  if (fn->toggle_collect) {
    CLG_(current_state).collect = !CLG_(current_state).collect;
    CLG_DEBUG(2,"   leaving %s: toggled collection state to %s\n",
	     fn->name,
	     CLG_(current_state).collect ? "ON" : "OFF");
  }

#if CLG_ENABLE_DEBUG
  if (fn->verbosity >=0) {
    Int old = CLG_(clo).verbose;
    CLG_(clo).verbose = fn->verbosity;
    fn->verbosity = old;
    VG_(message)(Vg_DebugMsg, 
		 "Leaving %s: Verbosity set back to %d\n",
		 fn->name, CLG_(clo).verbose);
  }
#endif		
}


/* Push call on call stack.
 *
 * Increment the usage count for the function called.
 * A jump from <from> to <to>, with <sp>.
 * If <skip> is true, this is a call to a function to be skipped;
 * for this, we set jcc = 0.
 */
void CLG_(push_call_stack)(BBCC* from, UInt jmp, BBCC* to, Addr sp, Bool skip)
{
    jCC* jcc;
    UInt* pdepth;
    call_entry* current_entry;
    Addr ret_addr;

    /* Ensure a call stack of size <current_sp>+1.
     * The +1 is needed as push_cxt will store the
     * context at [current_sp]
     */
    ensure_stack_size(CLG_(current_call_stack).sp +1);
    current_entry = &(CLG_(current_call_stack).entry[CLG_(current_call_stack).sp]);

    if (skip) {
	jcc = 0;
    }
    else {
	fn_node* to_fn = to->cxt->fn[0];

	if (CLG_(current_state).nonskipped) {
	    /* this is a jmp from skipped to nonskipped */
	    CLG_ASSERT(CLG_(current_state).nonskipped == from);
	}

	/* As push_cxt() has to be called before push_call_stack if not
	 * skipping, the old context should already be saved on the stack */
	CLG_ASSERT(current_entry->cxt != 0);
	CLG_(copy_cost_lz)( CLG_(sets).full, &(current_entry->enter_cost),
			   CLG_(current_state).cost );

	jcc = CLG_(get_jcc)(from, jmp, to);
	CLG_ASSERT(jcc != 0);

	pdepth = CLG_(get_fn_entry)(to_fn->number);
	if (CLG_(clo).skip_direct_recursion) {
	    /* only increment depth if another function is called */
	  if (jcc->from->cxt->fn[0] != to_fn) (*pdepth)++;
	}
	else (*pdepth)++;

	if (*pdepth>1)
	  CLG_(stat).rec_call_counter++;
	
	jcc->call_counter++;
	CLG_(stat).call_counter++;

	if (*pdepth == 1) function_entered(to_fn);
    }

    /* return address is only is useful with a real call;
     * used to detect RET w/o CALL */
    if (from->bb->jmp[jmp].jmpkind == jk_Call) {
      UInt instr = from->bb->jmp[jmp].instr;
      ret_addr = bb_addr(from->bb) +
	from->bb->instr[instr].instr_offset +
	from->bb->instr[instr].instr_size;
    }
    else
      ret_addr = 0;

    /* put jcc on call stack */
    current_entry->jcc = jcc;
    current_entry->sp = sp;
    current_entry->ret_addr = ret_addr;
    current_entry->nonskipped = CLG_(current_state).nonskipped;

    CLG_(current_call_stack).sp++;

    /* To allow for above assertion we set context of next frame to 0 */
    CLG_ASSERT(CLG_(current_call_stack).sp < CLG_(current_call_stack).size);
    current_entry++;
    current_entry->cxt = 0;

    if (!skip)
	CLG_(current_state).nonskipped = 0;
    else if (!CLG_(current_state).nonskipped) {
	/* a call from nonskipped to skipped */
	CLG_(current_state).nonskipped = from;
	if (!CLG_(current_state).nonskipped->skipped) {
	  CLG_(init_cost_lz)( CLG_(sets).full,
			     &CLG_(current_state).nonskipped->skipped);
	  CLG_(stat).distinct_skips++;
	}
    }

#if CLG_ENABLE_DEBUG
    CLG_DEBUGIF(0) {
	if (CLG_(clo).verbose<2) {
	  if (jcc && jcc->to && jcc->to->bb) {
	    char spaces[][41] = { "   .   .   .   .   .   .   .   .   .   .",
				  "  .   .   .   .   .   .   .   .   .   . ",
				  " .   .   .   .   .   .   .   .   .   .  ",
				  ".   .   .   .   .   .   .   .   .   .   " };

	    int s = CLG_(current_call_stack).sp;
	    Int* pars = (Int*) sp;

	    BB* bb = jcc->to->bb;
	    if (s>40) s=40;
	    VG_(printf)("%s> %s(0x%x, 0x%x, ...) [%s / %#lx]\n", spaces[s%4]+40-s, bb->fn->name,
                        pars ? pars[1]:0,
			pars ? pars[2]:0,
			bb->obj->name + bb->obj->last_slash_pos,
			bb->offset);
	  }
	}
	else if (CLG_(clo).verbose<4) {
	    VG_(printf)("+ %2d ", CLG_(current_call_stack).sp);
	    CLG_(print_short_jcc)(jcc);
	    VG_(printf)(", SP %#lx, RA %#lx\n", sp, ret_addr);
	}
	else {
	    VG_(printf)("  Pushed ");
	    CLG_(print_stackentry)(3, CLG_(current_call_stack).sp-1);
	}
    }
#endif

}


/* Pop call stack and update inclusive sums.
 * Returns modified fcc.
 *
 * If the JCC becomes inactive, call entries are freed if possible
 */
void CLG_(pop_call_stack)()
{
    jCC* jcc;
    Int depth = 0;
    call_entry* lower_entry;

    if (CLG_(current_state).sig >0) {
	/* Check if we leave a signal handler; this can happen when
	 * calling longjmp() in the handler */
	CLG_(run_post_signal_on_call_stack_bottom)();
    }

    lower_entry =
	&(CLG_(current_call_stack).entry[CLG_(current_call_stack).sp-1]);

    CLG_DEBUG(4,"+ pop_call_stack: frame %d, jcc %p\n", 
		CLG_(current_call_stack).sp, lower_entry->jcc);

    /* jCC item not any more on real stack: pop */
    jcc = lower_entry->jcc;
    CLG_(current_state).nonskipped = lower_entry->nonskipped;

    if (jcc) {
	fn_node* to_fn  = jcc->to->cxt->fn[0];
	UInt* pdepth =  CLG_(get_fn_entry)(to_fn->number);
	if (CLG_(clo).skip_direct_recursion) {
	    /* only decrement depth if another function was called */
	  if (jcc->from->cxt->fn[0] != to_fn) (*pdepth)--;
	}
	else (*pdepth)--;
	depth = *pdepth;

	/* add cost difference to sum */
	if ( CLG_(add_diff_cost_lz)( CLG_(sets).full, &(jcc->cost),
				    lower_entry->enter_cost,
				    CLG_(current_state).cost) ) {
	    
	  /* only count this call if it attributed some cost.
	   * the ret_counter is used to check if a BBCC dump is needed.
	   */
	  jcc->from->ret_counter++;
	}
	CLG_(stat).ret_counter++;

	/* restore context */
	CLG_(current_state).cxt  = lower_entry->cxt;
	CLG_(current_fn_stack).top =
	  CLG_(current_fn_stack).bottom + lower_entry->fn_sp;
	CLG_ASSERT(CLG_(current_state).cxt != 0);

	if (depth == 0) function_left(to_fn);
    }

    /* To allow for an assertion in push_call_stack() */
    lower_entry->cxt = 0;

    CLG_(current_call_stack).sp--;

#if CLG_ENABLE_DEBUG
    CLG_DEBUGIF(1) {
	if (CLG_(clo).verbose<4) {
	    if (jcc) {
		/* popped JCC target first */
		VG_(printf)("- %2d %#lx => ",
			    CLG_(current_call_stack).sp,
			    bb_addr(jcc->to->bb));
		CLG_(print_addr)(bb_jmpaddr(jcc->from->bb));
		VG_(printf)(", SP %#lx\n",
			    CLG_(current_call_stack).entry[CLG_(current_call_stack).sp].sp);
		CLG_(print_cost)(10, CLG_(sets).full, jcc->cost);
	    }
	    else
		VG_(printf)("- %2d [Skipped JCC], SP %#lx\n",
			    CLG_(current_call_stack).sp,
			    CLG_(current_call_stack).entry[CLG_(current_call_stack).sp].sp);
	}
	else {
	    VG_(printf)("  Popped ");
	    CLG_(print_stackentry)(7, CLG_(current_call_stack).sp);
	    if (jcc) {
		VG_(printf)("       returned to ");
		CLG_(print_addr_ln)(bb_jmpaddr(jcc->from->bb));
	    }
	}
    }
#endif

}


/* Unwind enough CallStack items to sync with current stack pointer.
 * Returns the number of stack frames unwinded.
 */
Int CLG_(unwind_call_stack)(Addr sp, Int minpops)
{
    Int csp;
    Int unwind_count = 0;
    CLG_DEBUG(4,"+ unwind_call_stack(sp %#lx, minpops %d): frame %d\n",
	      sp, minpops, CLG_(current_call_stack).sp);

    /* We pop old stack frames.
     * For a call, be p the stack address with return address.
     *  - call_stack_esp[] has SP after the CALL: p-4
     *  - current sp is after a RET: >= p
     */
    
    while( (csp=CLG_(current_call_stack).sp) >0) {
	call_entry* top_ce = &(CLG_(current_call_stack).entry[csp-1]);

	if ((top_ce->sp < sp) ||
	    ((top_ce->sp == sp) && minpops>0)) {

	    minpops--;
	    unwind_count++;
	    CLG_(pop_call_stack)();
	    csp=CLG_(current_call_stack).sp;
	    continue;
	}
	break;
    }

    CLG_DEBUG(4,"- unwind_call_stack\n");
    return unwind_count;
}
