From 42fa384f7f1d12e02987b17d2650e2136b38fa00 Mon Sep 17 00:00:00 2001
From: nathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Sun, 6 Jul 2003 14:51:48 +0000
Subject: [PATCH] 	* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@69006 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog   | 16 ++++++++++++++++
 gcc/coverage.c  | 22 +++++++++++++++-------
 gcc/gcov-dump.c |  7 +++++++
 gcc/gcov-io.h   | 20 +++++++++++++++++---
 gcc/gcov.c      | 13 ++++++++++++-
 gcc/libgcov.c   | 16 +++++++++++++---
 6 files changed, 80 insertions(+), 14 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index da3621f5076..5fa2546a82b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,19 @@
+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.
diff --git a/gcc/coverage.c b/gcc/coverage.c
index 7f0aa8da012..4a0033247ad 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -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);
     }
 }
diff --git a/gcc/gcov-dump.c b/gcc/gcov-dump.c
index 86834e25b7b..67a34dcfff7 100644
--- a/gcc/gcov-dump.c
+++ b/gcc/gcov-dump.c
@@ -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 ();
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index 5d0b716c7f1..999d07eea08 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -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 */
diff --git a/gcc/gcov.c b/gcc/gcov.c
index c671599c886..c8fc6ad5d31 100644
--- a/gcc/gcov.c
+++ b/gcc/gcov.c
@@ -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 ()))
     {
diff --git a/gcc/libgcov.c b/gcc/libgcov.c
index 74d830dc1b0..72126466f66 100644
--- a/gcc/libgcov.c
+++ b/gcc/libgcov.c
@@ -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--;
-- 
GitLab