/* hist.c - Histogram related operations.
- Copyright 1999, 2000, 2001, 2002, 2004, 2005
+ Copyright 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2009
Free Software Foundation, Inc.
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 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
\f
-#include "libiberty.h"
#include "gprof.h"
+#include "libiberty.h"
#include "search_list.h"
#include "source.h"
#include "symtab.h"
static histogram *find_histogram (bfd_vma lowpc, bfd_vma highpc);
static histogram *find_histogram_for_pc (bfd_vma pc);
+histogram * histograms;
+unsigned num_histograms;
double hist_scale;
static char hist_dimension[16] = "seconds";
static char hist_dimension_abbrev = 's';
/* This is new record. Add it to global array and allocate space for
the samples. */
- histograms = xrealloc (histograms,
- sizeof (histogram) * (num_histograms + 1));
+ histograms = (struct histogram *)
+ xrealloc (histograms, sizeof (histogram) * (num_histograms + 1));
memcpy (histograms + num_histograms,
&n_record, sizeof (histogram));
record = &histograms[num_histograms];
for (sym = symtab.base; sym < symtab.limit; sym++)
{
- sym->hist.scaled_addr = sym->addr / sizeof (UNIT);
-
histogram *r = find_histogram_for_pc (sym->addr);
+ sym->hist.scaled_addr = sym->addr / sizeof (UNIT);
+
if (r)
{
bin_of_entry = (sym->hist.scaled_addr - r->lowpc) / hist_scale;
bfd_vma sym_low_pc, sym_high_pc;
bfd_vma overlap, addr;
unsigned int bin_count;
- unsigned int i, j;
- double time, credit;
+ unsigned int i, j, k;
+ double count_time, credit;
bfd_vma lowpc = r->lowpc / sizeof (UNIT);
/* Iterate over all sample bins. */
- for (i = 0, j = 1; i < r->num_bins; ++i)
+ for (i = 0, k = 1; i < r->num_bins; ++i)
{
bin_count = r->sample[i];
if (! bin_count)
bin_low_pc = lowpc + (bfd_vma) (hist_scale * i);
bin_high_pc = lowpc + (bfd_vma) (hist_scale * (i + 1));
- time = bin_count;
+ count_time = bin_count;
DBG (SAMPLEDEBUG,
printf (
(unsigned long) (sizeof (UNIT) * bin_low_pc),
(unsigned long) (sizeof (UNIT) * bin_high_pc),
bin_count));
- total_time += time;
+ total_time += count_time;
- /* Credit all symbols that are covered by bin I. */
- for (j = j - 1; j < symtab.len; ++j)
+ /* Credit all symbols that are covered by bin I.
+
+ PR gprof/13325: Make sure that K does not get decremented
+ and J will never be less than 0. */
+ for (j = k - 1; j < symtab.len; k = ++j)
{
sym_low_pc = symtab.base[j].hist.scaled_addr;
sym_high_pc = symtab.base[j + 1].hist.scaled_addr;
"[assign_samples] [0x%lx,0x%lx) %s gets %f ticks %ld overlap\n",
(unsigned long) symtab.base[j].addr,
(unsigned long) (sizeof (UNIT) * sym_high_pc),
- symtab.base[j].name, overlap * time / hist_scale,
+ symtab.base[j].name, overlap * count_time / hist_scale,
(long) overlap));
addr = symtab.base[j].addr;
- credit = overlap * time / hist_scale;
+ credit = overlap * count_time / hist_scale;
/* Credit symbol if it appears in INCL_FLAT or that
table is empty and it does not appear it in
if (bsd_style_output)
{
printf (_("\ngranularity: each sample hit covers %ld byte(s)"),
- (long) hist_scale * sizeof (UNIT));
+ (long) hist_scale * (long) sizeof (UNIT));
if (total_time > 0.0)
{
printf (_(" for %.2f%% of %.2f %s\n\n"),
hist_print ()
{
Sym **time_sorted_syms, *top_dog, *sym;
- unsigned int index;
+ unsigned int sym_index;
unsigned log_scale;
- double top_time, time;
+ double top_time;
bfd_vma addr;
if (first_output)
and tertiary keys). */
time_sorted_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
- for (index = 0; index < symtab.len; ++index)
- time_sorted_syms[index] = &symtab.base[index];
+ for (sym_index = 0; sym_index < symtab.len; ++sym_index)
+ time_sorted_syms[sym_index] = &symtab.base[sym_index];
qsort (time_sorted_syms, symtab.len, sizeof (Sym *), cmp_time);
top_dog = 0;
top_time = 0.0;
- for (index = 0; index < symtab.len; ++index)
+ for (sym_index = 0; sym_index < symtab.len; ++sym_index)
{
- sym = time_sorted_syms[index];
+ sym = time_sorted_syms[sym_index];
if (sym->ncalls != 0)
{
- time = (sym->hist.time + sym->cg.child_time) / sym->ncalls;
+ double call_time;
+
+ call_time = (sym->hist.time + sym->cg.child_time) / sym->ncalls;
- if (time > top_time)
+ if (call_time > top_time)
{
top_dog = sym;
- top_time = time;
+ top_time = call_time;
}
}
}
I-cache misses etc.). */
print_header (SItab[log_scale].prefix);
- for (index = 0; index < symtab.len; ++index)
+ for (sym_index = 0; sym_index < symtab.len; ++sym_index)
{
- addr = time_sorted_syms[index]->addr;
+ addr = time_sorted_syms[sym_index]->addr;
/* Print symbol if its in INCL_FLAT table or that table
is empty and the symbol is not in EXCL_FLAT. */
if (sym_lookup (&syms[INCL_FLAT], addr)
|| (syms[INCL_FLAT].len == 0
&& !sym_lookup (&syms[EXCL_FLAT], addr)))
- print_line (time_sorted_syms[index], SItab[log_scale].scale);
+ print_line (time_sorted_syms[sym_index], SItab[log_scale].scale);
}
free (time_sorted_syms);