예제 #1
0
ULong* CLG_(get_costarray)(Int size)
{
  ULong* ptr;

  if (!cost_chunk_current ||
      (cost_chunk_current->size - cost_chunk_current->used < size)) {
    CostChunk* cc  = (CostChunk*) CLG_MALLOC(sizeof(CostChunk) +
					      COSTCHUNK_SIZE * sizeof(ULong));
    cc->size = COSTCHUNK_SIZE;
    cc->used = 0;
    cc->next = 0;

    if (cost_chunk_current)
      cost_chunk_current->next = cc;
    cost_chunk_current = cc;

    if (!cost_chunk_base) cost_chunk_base = cc;

    CLG_(costarray_chunks)++;
  }
  
  ptr = &(cost_chunk_current->data[cost_chunk_current->used]);
  cost_chunk_current->used += size;

  CLG_(costarray_entries) += size;

  return ptr;
}
예제 #2
0
void CLG_(print_bbno)(void)
{
  if (bb_written != CLG_(stat).bb_executions) {
    bb_written = CLG_(stat).bb_executions;
    VG_(printf)("BB# %llu\n",CLG_(stat).bb_executions);
  }
}
예제 #3
0
/* Lookup for a BBCC in hash.
 */ 
static
BBCC* lookup_bbcc(BB* bb, Context* cxt)
{
   BBCC* bbcc = bb->last_bbcc;
   UInt  idx;

   /* check LRU */
   if (bbcc->cxt == cxt) {
       if (!CLG_(clo).separate_threads) {
	   /* if we don't dump threads separate, tid doesn't have to match */
	   return bbcc;
       }
       if (bbcc->tid == CLG_(current_tid)) return bbcc;
   }

   CLG_(stat).bbcc_lru_misses++;

   idx = bbcc_hash_idx(bb, cxt, current_bbccs.size);
   bbcc = current_bbccs.table[idx];
   while (bbcc &&
	  (bb      != bbcc->bb ||
	   cxt     != bbcc->cxt)) {
       bbcc = bbcc->next;
   }
   
   CLG_DEBUG(2,"  lookup_bbcc(BB %#lx, Cxt %d, fn '%s'): %p (tid %d)\n",
	    bb_addr(bb), cxt->base_number, cxt->fn[0]->name, 
	    bbcc, bbcc ? bbcc->tid : 0);

   CLG_DEBUGIF(2)
     if (bbcc) CLG_(print_bbcc)(-2,bbcc);

   return bbcc;
}
예제 #4
0
/*
 * Zero all costs of a BBCC
 */
void CLG_(zero_bbcc)(BBCC* bbcc)
{
  Int i;
  jCC* jcc;

  CLG_ASSERT(bbcc->cxt != 0);
  CLG_DEBUG(1, "  zero_bbcc: BB %#lx, Cxt %d "
	   "(fn '%s', rec %d)\n", 
	   bb_addr(bbcc->bb),
	   bbcc->cxt->base_number + bbcc->rec_index,
	   bbcc->cxt->fn[0]->name,
	   bbcc->rec_index);

  if ((bbcc->ecounter_sum ==0) &&
      (bbcc->ret_counter ==0)) return;

  for(i=0;i<bbcc->bb->cost_count;i++)
    bbcc->cost[i] = 0;
  for(i=0;i <= bbcc->bb->cjmp_count;i++) {
    bbcc->jmp[i].ecounter = 0;
    for(jcc=bbcc->jmp[i].jcc_list; jcc; jcc=jcc->next_from)
	CLG_(init_cost)( CLG_(sets).full, jcc->cost );
  }
  bbcc->ecounter_sum = 0;
  bbcc->ret_counter = 0;
}
예제 #5
0
static
void CLG_(post_syscalltime)(ThreadId tid, UInt syscallno, SysRes res)
{
    if (CLG_(clo).collect_systime) {
        Int o = CLG_(sets).off_full_systime;
#if CLG_MICROSYSTIME
        struct vki_timeval tv_now;
        ULong diff;

        VG_(do_syscall)(__NR_gettimeofday, (UInt)&tv_now, (UInt)NULL);
        diff = (tv_now.tv_sec * 1000000ULL + tv_now.tv_usec) - syscalltime[tid];
#else
        UInt diff = VG_(read_millisecond_timer)() - syscalltime[tid];
#endif

        CLG_DEBUG(0,"   Time (Off %d) for Syscall %d: %ull\n", o, syscallno, diff);

        if (o<0) return;

        CLG_(current_state).cost[o] ++;
        CLG_(current_state).cost[o+1] += diff;
        if (!CLG_(current_state).bbcc->skipped)
            CLG_(init_cost_lz)(CLG_(sets).full,
                               &(CLG_(current_state).bbcc->skipped));
        CLG_(current_state).bbcc->skipped[o] ++;
        CLG_(current_state).bbcc->skipped[o+1] += diff;
    }
}
예제 #6
0
static void print_call_stack()
{
    int c;

    VG_(printf)("Call Stack:\n");
    for(c=0;c<CLG_(current_call_stack).sp;c++)
      CLG_(print_stackentry)(-2, c);
}
예제 #7
0
void CLG_(print_context)(void)
{
  BBCC* bbcc;

  CLG_DEBUG(0,"In tid %d [%d] ",
	   CLG_(current_tid),  CLG_(current_call_stack).sp);
  bbcc =  CLG_(current_state).bbcc;
  print_mangled_cxt(CLG_(current_state).cxt,
		    bbcc ? bbcc->rec_index : 0);
  VG_(printf)("\n");
}
예제 #8
0
Bool CLG_(is_equal_cost)(EventSet* es, ULong* c1, ULong* c2)
{
    Int i;

    if (!c1) return CLG_(is_zero_cost)(es, c2);
    if (!c2) return CLG_(is_zero_cost)(es, c1);

    for(i=0; i<es->size; i++)
	if (c1[i] != c2[i]) return False;

    return True;
}
예제 #9
0
void CLG_(zero_all_cost)(Bool only_current_thread)
{
    if (VG_(clo_verbosity) > 1)
        VG_(message)(Vg_DebugMsg, "  Zeroing costs...");

    if (only_current_thread)
        zero_thread_cost(CLG_(get_current_thread)());
    else
        CLG_(forall_threads)(zero_thread_cost);

    if (VG_(clo_verbosity) > 1)
        VG_(message)(Vg_DebugMsg, "  ...done");
}
예제 #10
0
void CLG_(print_short_jcc)(jCC* jcc)
{
    if (jcc)
	VG_(printf)("%#lx => %#lx [%llu/%llu,%llu,%llu]",
		    bb_jmpaddr(jcc->from->bb),
		    bb_addr(jcc->to->bb),
		    jcc->call_counter,
		    jcc->cost ? jcc->cost[CLG_(sets).off_sim_Ir]:0,
		    jcc->cost ? jcc->cost[CLG_(sets).off_sim_Dr]:0,
		    jcc->cost ? jcc->cost[CLG_(sets).off_sim_Dw]:0);
    else
	VG_(printf)("[Skipped JCC]");
}
예제 #11
0
static
void unwind_thread(thread_info* t)
{
    /* unwind signal handlers */
    while(CLG_(current_state).sig !=0)
        CLG_(post_signal)(CLG_(current_tid),CLG_(current_state).sig);

    /* unwind regular call stack */
    while(CLG_(current_call_stack).sp>0)
        CLG_(pop_call_stack)();

    /* reset context and function stack for context generation */
    CLG_(init_exec_state)( &CLG_(current_state) );
    CLG_(current_fn_stack).top = CLG_(current_fn_stack).bottom;
}
예제 #12
0
파일: debug.c 프로젝트: AmesianX/pathgrind
void CLG_(print_eventset)(int s, EventSet* es)
{
    int i, j;
    UInt mask;
    EventGroup* eg;

    if (s<0) {
	s = -s;
	print_indent(s);
    }

    if (!es) {
	VG_(printf)("(EventSet not set)\n");
	return;
    }

    VG_(printf)("EventSet %d (%d groups, size %d):",
		es->mask, es->count, es->size);

    if (es->count == 0) {
	VG_(printf)("-\n");
	return;
    }

    for(i=0, mask=1; i<MAX_EVENTGROUP_COUNT; i++, mask=mask<<1) {
	if ((es->mask & mask)==0) continue;
	eg = CLG_(get_event_group)(i);
	if (!eg) continue;
	VG_(printf)(" (%d: %s", i, eg->name[0]);
	for(j=1; j<eg->size; j++)
	    VG_(printf)(" %s", eg->name[j]);
	VG_(printf)(")");
    }
    VG_(printf)("\n");
}
예제 #13
0
void CLG_(print_bbcc)(int s, BBCC* bbcc, Bool jumpaddr)
{
  BB* bb;

  if (s<0) {
    s = -s;
    print_indent(s);
  }
  
  if (!bbcc) {
    VG_(printf)("BBCC 0x0\n");
    return;
  }
 
  bb = bbcc->bb;
  CLG_ASSERT(bb!=0);

#if 0 
  if (jumpaddr)
    VG_(printf)("%s +%p=%p, ",
	      bb->obj->name + bb->obj->last_slash_pos,
	      bb->jmp_offset, bb_jmpaddr(bb));
  else
#endif
    VG_(printf)("%s +%p=%p, ",
		bb->obj->name + bb->obj->last_slash_pos,
		bb->offset, bb_addr(bb));
  CLG_(print_cxt)(s+8, bbcc->cxt, bbcc->rec_index);
}
예제 #14
0
/* dump out an address with source info if available */
void CLG_(print_addr)(Addr addr)
{
    Char fl_buf[FILENAME_LEN];
    Char fn_buf[FN_NAME_LEN];
    const UChar* obj_name;
    DebugInfo* di;
    int ln, i=0, opos=0;
	
    if (addr == 0) {
	VG_(printf)("%08lx", addr);
	return;
    }

    CLG_(get_debug_info)(addr, fl_buf, fn_buf, &ln, &di);

    if (VG_(strcmp)(fn_buf,"???")==0)
	VG_(printf)("%#lx", addr);
    else
	VG_(printf)("%#lx %s", addr, fn_buf);

    if (di) {
      obj_name = VG_(seginfo_filename)(di);
      if (obj_name) {
	while(obj_name[i]) {
	  if (obj_name[i]=='/') opos = i+1;
	  i++;
	}
	if (obj_name[0])
	  VG_(printf)(" %s", obj_name+opos);
      }
    }

    if (ln>0)
    	VG_(printf)(" (%s:%u)", fl_buf,ln);
}
예제 #15
0
void CLG_(print_bbcc_cost)(int s, BBCC* bbcc)
{
  BB* bb;
  Int i, cjmpNo;
  ULong ecounter;

  if (s<0) {
    s = -s;
    print_indent(s);
  }
  
  if (!bbcc) {
    VG_(printf)("BBCC 0x0\n");
    return;
  }
 
  bb = bbcc->bb;
  CLG_ASSERT(bb!=0);
    
  CLG_(print_bbcc)(s, bbcc);

  ecounter = bbcc->ecounter_sum;

  print_indent(s+2);
  VG_(printf)("ECounter: sum %llu ", ecounter);
  for(i=0; i<bb->cjmp_count; i++) {
      VG_(printf)("[%d]=%llu ",
		  bb->jmp[i].instr, bbcc->jmp[i].ecounter);
  }
  VG_(printf)("\n");

  cjmpNo = 0; 
  for(i=0; i<bb->instr_count; i++) {
      InstrInfo* ii = &(bb->instr[i]);
      print_indent(s+2);
      VG_(printf)("[%2d] IOff %2d ecnt %3llu ",
		  i, ii->instr_offset, ecounter);
      CLG_(print_cost)(s+5, ii->eventset, bbcc->cost + ii->cost_offset);

      /* update execution counter */
      if (cjmpNo < bb->cjmp_count)
	  if (bb->jmp[cjmpNo].instr == i) {
	      ecounter -= bbcc->jmp[cjmpNo].ecounter;
	      cjmpNo++;
	  }
  }
}
예제 #16
0
void CLG_(add_cost_lz)(EventSet* es, ULong** pdst, ULong* src)
{
    Int i;
    ULong* dst;

    if (!src) return;
    CLG_ASSERT(pdst != 0);

    dst = *pdst;
    if (!dst) {
	dst = *pdst = CLG_(get_eventset_cost)(es);
	CLG_(copy_cost)(es, dst, src);
	return;
    }

    for(i=0; i<es->size; i++)
	dst[i] += src[i];
}
예제 #17
0
void CLG_(copy_cost_lz)(EventSet* es, ULong** pdst, ULong* src)
{
    Int i;
    ULong* dst;

    CLG_ASSERT(pdst != 0);

    if (!src) {
	CLG_(zero_cost)(es, *pdst);
	return;
    }
    dst = *pdst;
    if (!dst)
	dst = *pdst = CLG_(get_eventset_cost)(es);
  
    for(i=0;i<es->size;i++)
	dst[i] = src[i];
}
예제 #18
0
/* dump out the current call stack */
void CLG_(print_stackentry)(int s, int sp)
{
    call_entry* ce;

    if (s<0) {
	s = -s;
	print_indent(s);
    }

    ce = CLG_(get_call_entry)(sp);
    VG_(printf)("[%-2d] SP %#lx, RA %#lx", sp, ce->sp, ce->ret_addr);
    if (ce->nonskipped)
	VG_(printf)(" NonSkipped BB %#lx / %s",
		    bb_addr(ce->nonskipped->bb),
		    ce->nonskipped->cxt->fn[0]->name);
    VG_(printf)("\n");
    print_indent(s+5);
    CLG_(print_jcc)(5,ce->jcc);
}
예제 #19
0
/* Set all costs of an event set to zero */
void CLG_(init_cost_lz)(EventSet* es, ULong** cost)
{
    Int i;

    CLG_ASSERT(cost != 0);
    if (!(*cost))
	*cost = CLG_(get_eventset_cost)(es);

    for(i=0; i<es->size; i++)
	(*cost)[i] = 0;
}
예제 #20
0
void CLG_(print_jcc)(int s, jCC* jcc)
{
    if (s<0) {
	s = -s;
	print_indent(s);
    }

    if (!jcc) {
	VG_(printf)("JCC to skipped function\n");
	return;
    }
    VG_(printf)("JCC %p from ", jcc);
    CLG_(print_bbcc)(s+9, jcc->from);
    print_indent(s+4);    
    VG_(printf)("to   ");
    CLG_(print_bbcc)(s+9, jcc->to);
    print_indent(s+4);
    VG_(printf)("Calls %llu\n", jcc->call_counter);
    print_indent(s+4);
    CLG_(print_cost)(s+9, CLG_(sets).full, jcc->cost);
}
예제 #21
0
static
void CLG_(pre_syscalltime)(ThreadId tid, UInt syscallno)
{
    if (CLG_(clo).collect_systime) {
#if CLG_MICROSYSTIME
        struct vki_timeval tv_now;
        VG_(do_syscall)(__NR_gettimeofday, (UInt)&tv_now, (UInt)NULL);
        syscalltime[tid] = tv_now.tv_sec * 1000000ULL + tv_now.tv_usec;
#else
        syscalltime[tid] = VG_(read_millisecond_timer)();
#endif
    }
}
예제 #22
0
static
Bool CLG_(handle_client_request)(ThreadId tid, UWord *args, UWord *ret)
{
    if (!VG_IS_TOOL_USERREQ('C','T',args[0]))
        return False;

    switch(args[0]) {
    case VG_USERREQ__DUMP_STATS:
        CLG_(dump_profile)("Client Request", True);
        *ret = 0;                 /* meaningless */
        break;

    case VG_USERREQ__DUMP_STATS_AT:
    {
        Char buf[512];
        VG_(sprintf)(buf,"Client Request: %s", args[1]);
        CLG_(dump_profile)(buf, True);
        *ret = 0;                 /* meaningless */
    }
    break;

    case VG_USERREQ__ZERO_STATS:
        CLG_(zero_all_cost)(True);
        *ret = 0;                 /* meaningless */
        break;

    case VG_USERREQ__TOGGLE_COLLECT:
        CLG_(current_state).collect = !CLG_(current_state).collect;
        CLG_DEBUG(2, "Client Request: toggled collection state to %s\n",
                  CLG_(current_state).collect ? "ON" : "OFF");
        *ret = 0;                 /* meaningless */
        break;

    case VG_USERREQ__START_INSTRUMENTATION:
        CLG_(set_instrument_state)("Client Request", True);
        *ret = 0;                 /* meaningless */
        break;

    case VG_USERREQ__STOP_INSTRUMENTATION:
        CLG_(set_instrument_state)("Client Request", False);
        *ret = 0;                 /* meaningless */
        break;

    default:
        return False;
    }

    return True;
}
예제 #23
0
static void clg_start_client_code_callback ( ThreadId tid, ULong blocks_done )
{
   static ULong last_blocks_done = 0;

   if (0)
      VG_(printf)("%d R %llu\n", (Int)tid, blocks_done);

   /* throttle calls to CLG_(run_thread) by number of BBs executed */
   if (blocks_done - last_blocks_done < 5000) return;
   last_blocks_done = blocks_done;

   CLG_(run_thread)( tid );
}
예제 #24
0
void CLG_(copy_cost)(EventSet* es, ULong* dst, ULong* src)
{
    Int i;

    if (!src) {
	CLG_(zero_cost)(es, dst);
	return;
    }
    CLG_ASSERT(dst != 0);
  
    for(i=0;i<es->size;i++)
	dst[i] = src[i];
}
예제 #25
0
void CLG_(set_instrument_state)(Char* reason, Bool state)
{
    if (CLG_(instrument_state) == state) {
        CLG_DEBUG(2, "%s: instrumentation already %s\n",
                  reason, state ? "ON" : "OFF");
        return;
    }
    CLG_(instrument_state) = state;
    CLG_DEBUG(2, "%s: Switching instrumentation %s ...\n",
              reason, state ? "ON" : "OFF");

    VG_(discard_translations)( (Addr64)0x1000, (ULong) ~0xfffl);

    /* reset internal state: call stacks, simulator */
    CLG_(forall_threads)(unwind_thread);
    (*CLG_(cachesim).clear)();
    if (0)
        CLG_(forall_threads)(zero_thread_cost);

    if (VG_(clo_verbosity) > 1)
        VG_(message)(Vg_DebugMsg, "%s: instrumentation switched %s",
                     reason, state ? "ON" : "OFF");
}
예제 #26
0
/* double size of hash table 1 (addr->BBCC) */
static void resize_bbcc_hash(void)
{
    Int i, new_size, conflicts1 = 0, conflicts2 = 0;
    BBCC** new_table;
    UInt new_idx;
    BBCC *curr_BBCC, *next_BBCC;

    new_size = 2*current_bbccs.size+3;
    new_table = (BBCC**) CLG_MALLOC("cl.bbcc.rbh.1",
                                    new_size * sizeof(BBCC*));
 
    if (!new_table) return;
 
    for (i = 0; i < new_size; i++)
      new_table[i] = NULL;
 
    for (i = 0; i < current_bbccs.size; i++) {
	if (current_bbccs.table[i] == NULL) continue;
 
	curr_BBCC = current_bbccs.table[i];
	while (NULL != curr_BBCC) {
	    next_BBCC = curr_BBCC->next;

	    new_idx = bbcc_hash_idx(curr_BBCC->bb,
				    curr_BBCC->cxt,
				    new_size);

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

	    curr_BBCC = next_BBCC;
	}
    }

    VG_(free)(current_bbccs.table);


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

    current_bbccs.size = new_size;
    current_bbccs.table = new_table;
    CLG_(stat).bbcc_hash_resizes++;
}
예제 #27
0
파일: debug.c 프로젝트: AmesianX/pathgrind
void CLG_(print_cost)(int s, EventSet* es, ULong* c)
{
    Int i, j, pos, off;
    UInt mask;
    EventGroup* eg;

    if (s<0) {
	s = -s;
	print_indent(s);
    }

    if (!es) {
      VG_(printf)("Cost (Nothing, EventSet not set)\n");
      return;
    }
    if (!c) {
      VG_(printf)("Cost (Null, EventSet %d)\n", es->mask);
      return;
    }

    if (es->size == 0) {
      VG_(printf)("Cost (Nothing, EventSet with len 0)\n");
      return;
    } 

    pos = s;
    pos += VG_(printf)("Cost [%p]: ", c);
    off = 0;
    for(i=0, mask=1; i<MAX_EVENTGROUP_COUNT; i++, mask=mask<<1) {
	if ((es->mask & mask)==0) continue;
	eg = CLG_(get_event_group)(i);
	if (!eg) continue;
	for(j=0; j<eg->size; j++) {

	    if (off>0) {
		if (pos > 70) {
		    VG_(printf)(",\n");
		    print_indent(s+5);
		    pos = s+5;
		}
		else
		    pos += VG_(printf)(", ");
	    }

	    pos += VG_(printf)("%s %llu", eg->name[j], c[off++]);
	}
    }
    VG_(printf)("\n");
}
예제 #28
0
Bool CLG_(add_diff_cost_lz)(EventSet* es, ULong** pdst, ULong* old, ULong* new_cost)
{
    Int i;
    ULong* dst;
    Bool is_nonzero = False;

    CLG_ASSERT((es != 0) && (pdst != 0));
    CLG_ASSERT(old && new_cost);

    dst = *pdst;
    if (!dst) {
	dst = *pdst = CLG_(get_eventset_cost)(es);
	CLG_(zero_cost)(es, dst);
    }

    for(i=0; i<es->size; i++) {
	if (new_cost[i] == old[i]) continue;
	dst[i] += new_cost[i] - old[i];
	old[i] = new_cost[i];
	is_nonzero = True;
    }

    return is_nonzero;
}
예제 #29
0
// Called when a translation is removed from the translation cache for
// any reason at all: to free up space, because the guest code was
// unmapped or modified, or for any arbitrary reason.
static
void clg_discard_basic_block_info ( Addr64 orig_addr64, VexGuestExtents vge )
{
    Addr orig_addr = (Addr)orig_addr64;

    tl_assert(vge.n_used > 0);

    if (0)
        VG_(printf)( "discard_basic_block_info: %p, %p, %llu\n",
                     (void*)(Addr)orig_addr,
                     (void*)(Addr)vge.base[0], (ULong)vge.len[0]);

    // Get BB info, remove from table, free BB info.  Simple!  Note that we
    // use orig_addr, not the first instruction address in vge.
    CLG_(delete_bb)(orig_addr);
}
예제 #30
0
파일: bb.c 프로젝트: svn2github/valgrind-3
/* double size of bb table  */
static
void resize_bb_table(void)
{
    Int i, new_size, conflicts1 = 0, conflicts2 = 0;
    BB **new_table, *curr, *next;
    UInt new_idx;

    new_size  = 2* bbs.size +3;
    new_table = (BB**) CLG_MALLOC(new_size * sizeof(BB*));
 
    if (!new_table) return;
 
    for (i = 0; i < new_size; i++)
      new_table[i] = NULL;
 
    for (i = 0; i < bbs.size; i++) {
	if (bbs.table[i] == NULL) continue;
 
	curr = bbs.table[i];
	while (NULL != curr) {
	    next = curr->next;

	    new_idx = bb_hash_idx(curr->obj, curr->offset, new_size);

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

	    curr = next;
	}
    }

    VG_(free)(bbs.table);


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

    bbs.size  = new_size;
    bbs.table = new_table;
    CLG_(stat).bb_hash_resizes++;
}