/*--------------------------------------------------------------------*/
/*--- Callgrind                                                    ---*/
/*---                                                   ct_jumps.c ---*/
/*--------------------------------------------------------------------*/

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

   Copyright (C) 2002-2006, 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"

#define N_JCC_INITIAL_ENTRIES  4437

/*------------------------------------------------------------*/
/*--- Jump Cost Center (JCC) operations, including Calls   ---*/
/*------------------------------------------------------------*/

#define N_JCC_INITIAL_ENTRIES  4437

jcc_hash current_jccs;

void CLG_(init_jcc_hash)(jcc_hash* jccs)
{
   Int i;

   CLG_ASSERT(jccs != 0);

   jccs->size    = N_JCC_INITIAL_ENTRIES;
   jccs->entries = 0;
   jccs->table = (jCC**) CLG_MALLOC(jccs->size * sizeof(jCC*));
   jccs->spontaneous = 0;

   for (i = 0; i < jccs->size; i++)
     jccs->table[i] = 0;
}


void CLG_(copy_current_jcc_hash)(jcc_hash* dst)
{
  CLG_ASSERT(dst != 0);

  dst->size        = current_jccs.size;
  dst->entries     = current_jccs.entries;
  dst->table       = current_jccs.table;
  dst->spontaneous = current_jccs.spontaneous;
}

void CLG_(set_current_jcc_hash)(jcc_hash* h)
{
  CLG_ASSERT(h != 0);

  current_jccs.size        = h->size;
  current_jccs.entries     = h->entries;
  current_jccs.table       = h->table;
  current_jccs.spontaneous = h->spontaneous;
}

__inline__
static UInt jcc_hash_idx(BBCC* from, UInt jmp, BBCC* to, UInt size)
{
  return (UInt) ( (UWord)from + 7* (UWord)to + 13*jmp) % size;
} 

/* double size of jcc table  */
static void resize_jcc_table(void)
{
    Int i, new_size, conflicts1 = 0, conflicts2 = 0;
    jCC** new_table;
    UInt new_idx;
    jCC *curr_jcc, *next_jcc;

    new_size  = 2* current_jccs.size +3;
    new_table = (jCC**) CLG_MALLOC(new_size * sizeof(jCC*));
 
    if (!new_table) return;
 
    for (i = 0; i < new_size; i++)
      new_table[i] = NULL;
 
    for (i = 0; i < current_jccs.size; i++) {
	if (current_jccs.table[i] == NULL) continue;
 
	curr_jcc = current_jccs.table[i];
	while (NULL != curr_jcc) {
	    next_jcc = curr_jcc->next_hash;

	    new_idx = jcc_hash_idx(curr_jcc->from, curr_jcc->jmp,
				    curr_jcc->to, new_size);

	    curr_jcc->next_hash = new_table[new_idx];
	    new_table[new_idx] = curr_jcc;
	    if (curr_jcc->next_hash) {
		conflicts1++;
		if (curr_jcc->next_hash->next_hash)
		    conflicts2++;
	    }

	    curr_jcc = next_jcc;
	}
    }

    VG_(free)(current_jccs.table);


    CLG_DEBUG(0, "Resize JCC Hash: %d => %d (entries %d, conflicts %d/%d)\n",
	     current_jccs.size, new_size,
	     current_jccs.entries, conflicts1, conflicts2);

    current_jccs.size  = new_size;
    current_jccs.table = new_table;
    CLG_(stat).jcc_hash_resizes++;
}



/* new jCC structure: a call was done to a BB of a BBCC 
 * for a spontaneous call, from is 0 (i.e. caller unknown)
 */
static jCC* new_jcc(BBCC* from, UInt jmp, BBCC* to)
{
   jCC* new;
   UInt new_idx;

   /* check fill degree of jcc hash table and resize if needed (>80%) */
   current_jccs.entries++;
   if (10 * current_jccs.entries / current_jccs.size > 8)
       resize_jcc_table();

   new = (jCC*) CLG_MALLOC(sizeof(jCC));

   new->from      = from;
   new->jmp       = jmp;
   new->to        = to;
   new->jmpkind   = Ijk_Call;
   new->call_counter = 0;
   new->cost = 0;

   /* insert into JCC chain of calling BBCC.
    * This list is only used at dumping time */

   if (from) {
       new->next_from = from->jmp[jmp].jcc_list;
       from->jmp[jmp].jcc_list = new;
   }
   else {
       new->next_from = current_jccs.spontaneous;
       current_jccs.spontaneous = new;
   }

   /* insert into JCC hash table */
   new_idx = jcc_hash_idx(from, jmp, to, current_jccs.size);
   new->next_hash = current_jccs.table[new_idx];
   current_jccs.table[new_idx] = new;

   CLG_(stat).distinct_jccs++;

   CLG_DEBUGIF(3) {
     VG_(printf)("  new_jcc (now %d): %p\n",
		 CLG_(stat).distinct_jccs, new);
   }

   return new;
}


/* get the jCC for a call arc (BBCC->BBCC) */
jCC* CLG_(get_jcc)(BBCC* from, UInt jmp, BBCC* to)
{
    jCC* jcc;
    UInt idx;

    CLG_DEBUG(5, "+ get_jcc(bbcc %p/%d => bbcc %p)\n",
		from, jmp, to);

    /* first check last recently used JCC */
    jcc = to->lru_to_jcc;
    if (jcc && (jcc->from == from) && (jcc->jmp == jmp)) {
	CLG_ASSERT(to == jcc->to);
	CLG_DEBUG(5,"- get_jcc: [LRU to] jcc %p\n", jcc);
	return jcc;
    }

    jcc = from->lru_from_jcc;
    if (jcc && (jcc->to == to) && (jcc->jmp == jmp)) {
	CLG_ASSERT(from == jcc->from);
	CLG_DEBUG(5, "- get_jcc: [LRU from] jcc %p\n", jcc);
	return jcc;
    }

    CLG_(stat).jcc_lru_misses++;

    idx = jcc_hash_idx(from, jmp, to, current_jccs.size);
    jcc = current_jccs.table[idx];

    while(jcc) {
	if ((jcc->from == from) &&
	    (jcc->jmp == jmp) &&
	    (jcc->to == to)) break;
	jcc = jcc->next_hash;
    }

    if (!jcc)
	jcc = new_jcc(from, jmp, to);

    /* set LRU */
    from->lru_from_jcc = jcc;
    to->lru_to_jcc = jcc;

    CLG_DEBUG(5, "- get_jcc(bbcc %p => bbcc %p)\n",
		from, to);

    return jcc;
}

