gcov-io.h: Add a local time stamp.
authorNathan Sidwell <nathan@codesourcery.com>
Sun, 6 Jul 2003 14:51:48 +0000 (14:51 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Sun, 6 Jul 2003 14:51:48 +0000 (14:51 +0000)
* gcov-io.h: Add a local time stamp.
(struct gcov_info): Add stamp field.
(gcov_truncate): New.
* coverage.c (read_counts_file): Skip the stamp.
(coverage_begin_output): Write the stamp.
(build_gcov_info): Declare and init the stamp.
(coverage_finish): Only unlink data file, if stamp is zero.
* gcov-dump.c (dump_file): Dump the stamp.
* gcov.c (bbg_stamp): New.
(release_structures): Clear bbg_stamp.
(read_graph_file): Read stamp.
(read_count_file): Check stamp.
* libgcov.c (gcov_exit): Check stamp and truncate if needed.

From-SVN: r69006

gcc/ChangeLog
gcc/coverage.c
gcc/gcov-dump.c
gcc/gcov-io.h
gcc/gcov.c
gcc/libgcov.c

index da3621f..5fa2546 100644 (file)
@@ -1,5 +1,21 @@
 2003-07-06  Nathan Sidwell  <nathan@codesourcery.com>
 
+       * gcov-io.h: Add a local time stamp.
+       (struct gcov_info): Add stamp field.
+       (gcov_truncate): New.
+       * coverage.c (read_counts_file): Skip the stamp.
+       (coverage_begin_output): Write the stamp.
+       (build_gcov_info): Declare and init the stamp.
+       (coverage_finish): Only unlink data file, if stamp is zero.
+       * gcov-dump.c (dump_file): Dump the stamp.
+       * gcov.c (bbg_stamp): New.
+       (release_structures): Clear bbg_stamp.
+       (read_graph_file): Read stamp.
+       (read_count_file): Check stamp.
+       * libgcov.c (gcov_exit): Check stamp and truncate if needed.
+
+2003-07-06  Nathan Sidwell  <nathan@codesourcery.com>
+
        * tree.h (default_flag_random_seed): Remove.
        * toplev.h (local_tick): Declare.
        * tree.c (flag_random_seed, default_flag_random_seed): Move to
index 7f0aa8d..4a00332 100644 (file)
@@ -182,6 +182,9 @@ read_counts_file (void)
       return;
     }
 
+  /* Read and discard the stamp. */
+  gcov_read_unsigned ();
+  
   counts_hash = htab_create (10,
                             htab_counts_entry_hash, htab_counts_entry_eq,
                             htab_counts_entry_del);
@@ -445,6 +448,7 @@ coverage_begin_output (void)
            {
              gcov_write_unsigned (GCOV_GRAPH_MAGIC);
              gcov_write_unsigned (GCOV_VERSION);
+             gcov_write_unsigned (local_tick);
            }
          bbg_file_opened = 1;
        }
@@ -708,6 +712,14 @@ build_gcov_info (void)
   fields = field;
   value = tree_cons (field, null_pointer_node, value);
 
+  /* stamp */
+  field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
+  TREE_CHAIN (field) = fields;
+  fields = field;
+  value = tree_cons (field, convert (unsigned_intSI_type_node,
+                                    build_int_2 (local_tick, 0)),
+                    value);
+
   /* Filename */
   string_type = build_pointer_type (build_qualified_type (char_type_node,
                                                    TYPE_QUAL_CONST));
@@ -905,13 +917,9 @@ coverage_finish (void)
 
       if (error)
        unlink (bbg_file_name);
-#if SELF_COVERAGE
-      /* If the compiler is instrumented, we should not
-         unconditionally remove the counts file, because we might be
-         recompiling ourselves. The .da files are all removed during
-         copying the stage1 files.  */
-      if (error)
-#endif
+      if (!local_tick)
+       /* Only remove the da file, if we cannot stamp it. If we can
+          stamp it, libgcov will DTRT.  */
        unlink (da_file_name);
     }
 }
index 86834e2..67a34dc 100644 (file)
@@ -184,6 +184,13 @@ dump_file (const char *filename)
       printf ("%s:warning:current version is `%.4s'\n", filename, e);
   }
 
+  /* stamp */
+  {
+    unsigned stamp = gcov_read_unsigned ();
+
+    printf ("%s:stamp %lu\n", filename, (unsigned long)stamp);
+  }
+  
   while (1)
     {
       gcov_position_t base, position = gcov_position ();
index 5d0b716..999d07e 100644 (file)
@@ -52,11 +52,17 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
    The basic format of the files is
 
-       file : int32:magic int32:version record*
+       file : int32:magic int32:version int32:stamp record*
 
    The magic ident is different for the bbg and the counter files.
    The version is the same for both files and is derived from gcc's
-   version number.  Although the ident and version are formally 32 bit
+   version number. The stamp value is used to synchronize bbg and
+   counter files and to synchronize merging within a counter file. It
+   need not be an absolute time stamp, merely a ticker that increments
+   fast enough and cycles slow enough to distinguish different
+   compile/run/compile cycles.
+   
+   Although the ident and version are formally 32 bit
    numbers, they are derived from 4 character ASCII strings.  The
    version number consists of the single character major version
    number, a two character minor version number (leading zero for
@@ -370,8 +376,9 @@ struct gcov_info
   gcov_unsigned_t version;     /* expected version number */
   struct gcov_info *next;      /* link to next, used by libgcc */
 
+  gcov_unsigned_t stamp;       /* uniquifying time stamp */
   const char *filename;                /* output file name */
-
+  
   unsigned n_functions;                /* number of functions */
   const struct gcov_fn_info *functions; /* table of functions */
 
@@ -453,6 +460,7 @@ GCOV_LINKAGE void gcov_write_counter (gcov_type);
 GCOV_LINKAGE void gcov_write_tag_length (gcov_unsigned_t, gcov_unsigned_t);
 GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
                                      const struct gcov_summary *);
+static void gcov_truncate (void);
 static void gcov_rewrite (void);
 GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/);
 #else
@@ -525,6 +533,12 @@ gcov_rewrite (void)
   gcov_var.offset = 0;
   fseek (gcov_var.file, 0L, SEEK_SET);
 }
+
+static inline void
+gcov_truncate (void)
+{
+  ftruncate (fileno (gcov_var.file), 0L);
+}
 #endif
 
 #endif /* IN_LIBGCOV >= 0 */
index c671599..c8fc6ad 100644 (file)
@@ -269,6 +269,9 @@ static time_t bbg_file_time;
 
 static char *bbg_file_name;
 
+/* Stamp of the bbg file */
+static unsigned bbg_stamp;
+
 /* Name and file pointer of the input file for the arc count data.  */
 
 static char *da_file_name;
@@ -583,6 +586,7 @@ release_structures ()
   free (da_file_name);
   da_file_name = bbg_file_name = NULL;
   bbg_file_time = 0;
+  bbg_stamp = 0;
   
   while ((src = sources))
     {
@@ -740,7 +744,8 @@ read_graph_file ()
       fnotice (stderr, "%s:version `%.4s', prefer `%.4s'\n",
               bbg_file_name, v, e);
     }
-  
+  bbg_stamp = gcov_read_unsigned ();
+
   while ((tag = gcov_read_unsigned ()))
     {
       unsigned length = gcov_read_unsigned ();
@@ -1008,6 +1013,12 @@ read_count_file ()
       fnotice (stderr, "%s:version `%.4s', prefer version `%.4s'\n",
               da_file_name, v, e);
     }
+  tag = gcov_read_unsigned ();
+  if (tag != bbg_stamp)
+    {
+      fnotice (stderr, "%s:stamp mismatch with graph file\n", da_file_name);
+      goto cleanup;
+    }
   
   while ((tag = gcov_read_unsigned ()))
     {
index 74d830d..7212646 100644 (file)
@@ -167,8 +167,10 @@ gcov_exit (void)
       gcov_unsigned_t tag, length;
       gcov_position_t summary_pos = 0;
 
-      /* Totals for this object file.  */
       memset (&this_object, 0, sizeof (this_object));
+      memset (&object, 0, sizeof (object));
+      
+      /* Totals for this object file.  */
       for (t_ix = c_ix = 0,
             ci_ptr = gi_ptr->counts, cs_ptr = this_object.ctrs;
           t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++, cs_ptr++)
@@ -223,6 +225,15 @@ gcov_exit (void)
              gcov_version_mismatch (gi_ptr, length);
              goto read_fatal;
            }
+
+         length = gcov_read_unsigned ();
+         if (length != gi_ptr->stamp)
+           {
+             /* Read from a different compilation. Overwrite the
+                file.  */
+             gcov_truncate ();
+             goto rewrite;
+           }
          
          /* Merge execution counts for each function.  */
          for (f_ix = gi_ptr->n_functions, fi_ptr = gi_ptr->functions;
@@ -298,8 +309,6 @@ gcov_exit (void)
        rewrite:;
          gcov_rewrite ();
        }
-      else
-       memset (&object, 0, sizeof (object));
       if (!summary_pos)
        memset (&program, 0, sizeof (program));
 
@@ -355,6 +364,7 @@ gcov_exit (void)
       
       /* Write out the data.  */
       gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
+      gcov_write_unsigned (gi_ptr->stamp);
       
       /* Write execution counts for each function.  */
       for (f_ix = gi_ptr->n_functions, fi_ptr = gi_ptr->functions; f_ix--;