Hi, > 1: 4:int notmain(const char *entity) > -: == inlined from hello.h == > 1: 6: if (s) > branch 0 taken 0 (fallthrough) > branch 1 taken 1 > #####: 7: printf ("hello, %s!\n", s); > %%%%%: 7-block 3 > call 0 never executed > -: 8: else > 1: 9: printf ("hello, world!\n"); > 1: 9-block 4 > call 0 returned 1 > 1: 10: return 0; > 1: 10-block 5 > -: == inlined from hello.h (end) == > -: 5:{ > 1: 6: return hello (entity); > 1: 6-block 7 > -: 7:}
This indeed looks like a reasonable goal. > gcc/ChangeLog: > > * gcov.cc (release_structures): Release source_lines. > (slurp): New function. > (output_lines): Read sources with slurp. > --- > gcc/gcov.cc | 70 ++++++++++++++++++++++++++++++++++++++++------------- > 1 file changed, 53 insertions(+), 17 deletions(-) > > diff --git a/gcc/gcov.cc b/gcc/gcov.cc > index e76a314041c..19019f404ee 100644 > --- a/gcc/gcov.cc > +++ b/gcc/gcov.cc > @@ -550,6 +550,11 @@ static vector<name_map> names; > a file being read multiple times. */ > static vector<char *> processed_files; > > +/* The contents of a source file. The nth SOURCE_LINES entry is the > + contents of the nth SOURCES, or empty if it has not or could not be > + read. */ > +static vector<vector<const char *>*> source_lines; > + > /* This holds data summary information. */ > > static unsigned object_runs; > @@ -762,6 +767,8 @@ static string make_gcov_file_name (const char *, const > char *); > static char *mangle_name (const char *); > static void release_structures (void); > extern int main (int, char **); > +static const vector<const char *>& > +slurp (const source_info &src, FILE *gcov_file, const char *line_start); > > function_info::function_info (): m_name (NULL), m_demangled_name (NULL), > ident (0), lineno_checksum (0), cfg_checksum (0), has_catch (0), > @@ -1804,6 +1811,15 @@ release_structures (void) > it != functions.end (); it++) > delete (*it); > > + for (vector<const char *> *lines : source_lines) > + { > + if (lines) > + for (const char *line : *lines) > + free (const_cast <char*> (line)); > + delete (lines); > + } > + source_lines.resize (0); > + > for (fnfilter &filter : filters) > regfree (&filter.regex); > > @@ -3246,6 +3262,41 @@ read_line (FILE *file) > return pos ? string : NULL; > } > > +/* Get the vector with the contents SRC, possibly from a cache. If > + the reading fails, a message prefixed with LINE_START is written to > + GCOV_FILE. */ > +static const vector<const char *>& > +slurp (const source_info &src, FILE *gcov_file, > + const char *line_start) > +{ > + if (source_lines.size () <= src.index) > + source_lines.resize (src.index + 1); > + > + /* Store vector pointers so that the returned references remain > + stable and won't be broken by successive calls to slurp. */ > + if (!source_lines[src.index]) > + source_lines[src.index] = new vector<const char *> (); > + > + if (!source_lines[src.index]->empty ()) > + return *source_lines[src.index]; > + > + FILE *source_file = fopen (src.name, "r"); > + if (!source_file) > + fnotice (stderr, "Cannot open source file %s\n", src.name); > + else if (src.file_time == 0) > + fprintf (gcov_file, "%sSource is newer than graph\n", line_start); > + > + const char *retval; > + vector<const char *> &lines = *source_lines[src.index]; > + if (source_file) > + while ((retval = read_line (source_file))) > + lines.push_back (xstrdup (retval)); > + > + if (source_file) > + fclose (source_file); > + return lines; So this is basically going to read all sources needed for single compilation unit (.cc file) into memory at once. I guess that is OK. I wonder if we don't want to do something like mmap the source and then set up source_lines array instead of reading every like into spearate xstrduped chunk? But that could be done incrementally, so th epatch is OK. Honza > +} > + > /* Pad string S with spaces from left to have total width equal to 9. */ > > static void > @@ -3435,9 +3486,6 @@ output_lines (FILE *gcov_file, const source_info *src) > #define DEFAULT_LINE_START " -: 0:" > #define FN_SEPARATOR "------------------\n" > > - FILE *source_file; > - const char *retval; > - > /* Print colorization legend. */ > if (flag_use_colors) > fprintf (gcov_file, "%s", > @@ -3464,17 +3512,8 @@ output_lines (FILE *gcov_file, const source_info *src) > fprintf (gcov_file, DEFAULT_LINE_START "Runs:%u\n", object_runs); > } > > - source_file = fopen (src->name, "r"); > - if (!source_file) > - fnotice (stderr, "Cannot open source file %s\n", src->name); > - else if (src->file_time == 0) > - fprintf (gcov_file, DEFAULT_LINE_START "Source is newer than graph\n"); > - > - vector<const char *> source_lines; > - if (source_file) > - while ((retval = read_line (source_file)) != NULL) > - source_lines.push_back (xstrdup (retval)); > - > + const vector<const char *> &source_lines = slurp (*src, gcov_file, > + DEFAULT_LINE_START); > unsigned line_start_group = 0; > vector<function_info *> *fns; > unsigned filtered_line_end = !filters.empty () ? 0 : source_lines.size (); > @@ -3596,7 +3635,4 @@ output_lines (FILE *gcov_file, const source_info *src) > line_start_group = 0; > } > } > - > - if (source_file) > - fclose (source_file); > } > -- > 2.39.2 >