[PATCH 1/3] gcov: Cache source files
Jørgen Kvalsvik
j@lambda.is
Sun Sep 8 20:25:12 GMT 2024
On 8/23/24 09:39, Jan Hubicka wrote:
> 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.
Thanks, pushed.
>> 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
>>
More information about the Gcc-patches
mailing list