comparison gcc/libgcov.c @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents a06113de4d67
children f6334be47118
comparison
equal deleted inserted replaced
52:c156f1bd5cd9 55:77e2b8dfacca
86 86
87 /* Size of the longest file name. */ 87 /* Size of the longest file name. */
88 static size_t gcov_max_filename = 0; 88 static size_t gcov_max_filename = 0;
89 89
90 #ifdef TARGET_POSIX_IO 90 #ifdef TARGET_POSIX_IO
91 /* Make sure path component of the given FILENAME exists, create 91 /* Make sure path component of the given FILENAME exists, create
92 missing directories. FILENAME must be writable. 92 missing directories. FILENAME must be writable.
93 Returns zero on success, or -1 if an error occurred. */ 93 Returns zero on success, or -1 if an error occurred. */
94 94
95 static int 95 static int
96 create_file_directory (char *filename) 96 create_file_directory (char *filename)
97 { 97 {
112 fprintf (stderr, "profiling:%s:Cannot create directory\n", 112 fprintf (stderr, "profiling:%s:Cannot create directory\n",
113 filename); 113 filename);
114 *s = sep; 114 *s = sep;
115 return -1; 115 return -1;
116 }; 116 };
117 117
118 *s = sep; 118 *s = sep;
119 }; 119 };
120 return 0; 120 return 0;
121 } 121 }
122 #endif 122 #endif
123 123
124 /* Check if VERSION of the info block PTR matches libgcov one. 124 /* Check if VERSION of the info block PTR matches libgcov one.
125 Return 1 on success, or zero in case of versions mismatch. 125 Return 1 on success, or zero in case of versions mismatch.
126 If FILENAME is not NULL, its value used for reporting purposes 126 If FILENAME is not NULL, its value used for reporting purposes
127 instead of value from the info block. */ 127 instead of value from the info block. */
128 128
129 static int 129 static int
130 gcov_version (struct gcov_info *ptr, gcov_unsigned_t version, 130 gcov_version (struct gcov_info *ptr, gcov_unsigned_t version,
131 const char *filename) 131 const char *filename)
132 { 132 {
133 if (version != GCOV_VERSION) 133 if (version != GCOV_VERSION)
134 { 134 {
135 char v[4], e[4]; 135 char v[4], e[4];
136 136
137 GCOV_UNSIGNED2STRING (v, version); 137 GCOV_UNSIGNED2STRING (v, version);
138 GCOV_UNSIGNED2STRING (e, GCOV_VERSION); 138 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
139 139
140 fprintf (stderr, 140 fprintf (stderr,
141 "profiling:%s:Version mismatch - expected %.4s got %.4s\n", 141 "profiling:%s:Version mismatch - expected %.4s got %.4s\n",
142 filename? filename : ptr->filename, e, v); 142 filename? filename : ptr->filename, e, v);
143 return 0; 143 return 0;
144 } 144 }
201 gcov_prefix_strip = atoi (tmp); 201 gcov_prefix_strip = atoi (tmp);
202 /* Do not consider negative values. */ 202 /* Do not consider negative values. */
203 if (gcov_prefix_strip < 0) 203 if (gcov_prefix_strip < 0)
204 gcov_prefix_strip = 0; 204 gcov_prefix_strip = 0;
205 } 205 }
206 206
207 prefix_length = strlen(gcov_prefix); 207 prefix_length = strlen(gcov_prefix);
208 208
209 /* Remove an unnecessary trailing '/' */ 209 /* Remove an unnecessary trailing '/' */
210 if (IS_DIR_SEPARATOR (gcov_prefix[prefix_length - 1])) 210 if (IS_DIR_SEPARATOR (gcov_prefix[prefix_length - 1]))
211 prefix_length--; 211 prefix_length--;
212 } 212 }
213 else 213 else
214 prefix_length = 0; 214 prefix_length = 0;
215 215
216 /* Allocate and initialize the filename scratch space. */ 216 /* Allocate and initialize the filename scratch space. */
217 gi_filename = (char *) alloca (prefix_length + gcov_max_filename + 1); 217 gi_filename = (char *) alloca (prefix_length + gcov_max_filename + 1);
218 if (prefix_length) 218 if (prefix_length)
219 memcpy (gi_filename, gcov_prefix, prefix_length); 219 memcpy (gi_filename, gcov_prefix, prefix_length);
220 gi_filename_up = gi_filename + prefix_length; 220 gi_filename_up = gi_filename + prefix_length;
221 221
222 /* Now merge each file. */ 222 /* Now merge each file. */
223 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next) 223 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
224 { 224 {
225 struct gcov_summary this_object; 225 struct gcov_summary this_object;
226 struct gcov_summary object, program; 226 struct gcov_summary object, program;
234 gcov_position_t summary_pos = 0; 234 gcov_position_t summary_pos = 0;
235 gcov_position_t eof_pos = 0; 235 gcov_position_t eof_pos = 0;
236 236
237 memset (&this_object, 0, sizeof (this_object)); 237 memset (&this_object, 0, sizeof (this_object));
238 memset (&object, 0, sizeof (object)); 238 memset (&object, 0, sizeof (object));
239 239
240 /* Build relocated filename, stripping off leading 240 /* Build relocated filename, stripping off leading
241 directories from the initial filename if requested. */ 241 directories from the initial filename if requested. */
242 if (gcov_prefix_strip > 0) 242 if (gcov_prefix_strip > 0)
243 { 243 {
244 int level = 0; 244 int level = 0;
245 const char *fname = gi_ptr->filename; 245 const char *fname = gi_ptr->filename;
292 if (__alignof__ (struct gcov_fn_info) > sizeof (unsigned)) 292 if (__alignof__ (struct gcov_fn_info) > sizeof (unsigned))
293 { 293 {
294 fi_stride += __alignof__ (struct gcov_fn_info) - 1; 294 fi_stride += __alignof__ (struct gcov_fn_info) - 1;
295 fi_stride &= ~(__alignof__ (struct gcov_fn_info) - 1); 295 fi_stride &= ~(__alignof__ (struct gcov_fn_info) - 1);
296 } 296 }
297 297
298 if (!gcov_open (gi_filename)) 298 if (!gcov_open (gi_filename))
299 { 299 {
300 #ifdef TARGET_POSIX_IO 300 #ifdef TARGET_POSIX_IO
301 /* Open failed likely due to missed directory. 301 /* Open failed likely due to missed directory.
302 Create directory and retry to open file. */ 302 Create directory and retry to open file. */
329 329
330 length = gcov_read_unsigned (); 330 length = gcov_read_unsigned ();
331 if (length != gi_ptr->stamp) 331 if (length != gi_ptr->stamp)
332 /* Read from a different compilation. Overwrite the file. */ 332 /* Read from a different compilation. Overwrite the file. */
333 goto rewrite; 333 goto rewrite;
334 334
335 /* Merge execution counts for each function. */ 335 /* Merge execution counts for each function. */
336 for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++) 336 for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
337 { 337 {
338 fi_ptr = (const struct gcov_fn_info *) 338 fi_ptr = (const struct gcov_fn_info *)
339 ((const char *) gi_ptr->functions + f_ix * fi_stride); 339 ((const char *) gi_ptr->functions + f_ix * fi_stride);
358 { 358 {
359 gcov_merge_fn merge; 359 gcov_merge_fn merge;
360 360
361 if (!((1 << t_ix) & gi_ptr->ctr_mask)) 361 if (!((1 << t_ix) & gi_ptr->ctr_mask))
362 continue; 362 continue;
363 363
364 n_counts = fi_ptr->n_ctrs[c_ix]; 364 n_counts = fi_ptr->n_ctrs[c_ix];
365 merge = gi_ptr->counts[c_ix].merge; 365 merge = gi_ptr->counts[c_ix].merge;
366 366
367 tag = gcov_read_unsigned (); 367 tag = gcov_read_unsigned ();
368 length = gcov_read_unsigned (); 368 length = gcov_read_unsigned ();
369 if (tag != GCOV_TAG_FOR_COUNTER (t_ix) 369 if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
370 || length != GCOV_TAG_COUNTER_LENGTH (n_counts)) 370 || length != GCOV_TAG_COUNTER_LENGTH (n_counts))
371 goto read_mismatch; 371 goto read_mismatch;
380 f_ix = ~0u; 380 f_ix = ~0u;
381 /* Check program & object summary */ 381 /* Check program & object summary */
382 while (1) 382 while (1)
383 { 383 {
384 int is_program; 384 int is_program;
385 385
386 eof_pos = gcov_position (); 386 eof_pos = gcov_position ();
387 tag = gcov_read_unsigned (); 387 tag = gcov_read_unsigned ();
388 if (!tag) 388 if (!tag)
389 break; 389 break;
390 390
402 goto rewrite; 402 goto rewrite;
403 } 403 }
404 } 404 }
405 } 405 }
406 goto rewrite; 406 goto rewrite;
407 407
408 read_error:; 408 read_error:;
409 fprintf (stderr, error < 0 ? "profiling:%s:Overflow merging\n" 409 fprintf (stderr, error < 0 ? "profiling:%s:Overflow merging\n"
410 : "profiling:%s:Error merging\n", gi_filename); 410 : "profiling:%s:Error merging\n", gi_filename);
411 411
412 read_fatal:; 412 read_fatal:;
413 gcov_close (); 413 gcov_close ();
414 continue; 414 continue;
415 415
416 rewrite:; 416 rewrite:;
436 goto read_mismatch; 436 goto read_mismatch;
437 cs_obj->sum_all += cs_tobj->sum_all; 437 cs_obj->sum_all += cs_tobj->sum_all;
438 if (cs_obj->run_max < cs_tobj->run_max) 438 if (cs_obj->run_max < cs_tobj->run_max)
439 cs_obj->run_max = cs_tobj->run_max; 439 cs_obj->run_max = cs_tobj->run_max;
440 cs_obj->sum_max += cs_tobj->run_max; 440 cs_obj->sum_max += cs_tobj->run_max;
441 441
442 if (!cs_prg->runs++) 442 if (!cs_prg->runs++)
443 cs_prg->num = cs_tprg->num; 443 cs_prg->num = cs_tprg->num;
444 else if (cs_prg->num != cs_tprg->num) 444 else if (cs_prg->num != cs_tprg->num)
445 goto read_mismatch; 445 goto read_mismatch;
446 cs_prg->sum_all += cs_tprg->sum_all; 446 cs_prg->sum_all += cs_tprg->sum_all;
448 cs_prg->run_max = cs_tprg->run_max; 448 cs_prg->run_max = cs_tprg->run_max;
449 cs_prg->sum_max += cs_tprg->run_max; 449 cs_prg->sum_max += cs_tprg->run_max;
450 } 450 }
451 else if (cs_obj->num || cs_prg->num) 451 else if (cs_obj->num || cs_prg->num)
452 goto read_mismatch; 452 goto read_mismatch;
453 453
454 if (!cs_all->runs && cs_prg->runs) 454 if (!cs_all->runs && cs_prg->runs)
455 memcpy (cs_all, cs_prg, sizeof (*cs_all)); 455 memcpy (cs_all, cs_prg, sizeof (*cs_all));
456 else if (!all.checksum 456 else if (!all.checksum
457 && (!GCOV_LOCKED || cs_all->runs == cs_prg->runs) 457 && (!GCOV_LOCKED || cs_all->runs == cs_prg->runs)
458 && memcmp (cs_all, cs_prg, sizeof (*cs_all))) 458 && memcmp (cs_all, cs_prg, sizeof (*cs_all)))
461 gi_filename, GCOV_LOCKED 461 gi_filename, GCOV_LOCKED
462 ? "" : " or concurrent update without locking support"); 462 ? "" : " or concurrent update without locking support");
463 all.checksum = ~0u; 463 all.checksum = ~0u;
464 } 464 }
465 } 465 }
466 466
467 c_ix = 0; 467 c_ix = 0;
468 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++) 468 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
469 if ((1 << t_ix) & gi_ptr->ctr_mask) 469 if ((1 << t_ix) & gi_ptr->ctr_mask)
470 { 470 {
471 values[c_ix] = gi_ptr->counts[c_ix].values; 471 values[c_ix] = gi_ptr->counts[c_ix].values;
472 c_ix++; 472 c_ix++;
473 } 473 }
474 474
475 program.checksum = gcov_crc32; 475 program.checksum = gcov_crc32;
476 476
477 /* Write out the data. */ 477 /* Write out the data. */
478 gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION); 478 gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
479 gcov_write_unsigned (gi_ptr->stamp); 479 gcov_write_unsigned (gi_ptr->stamp);
480 480
481 /* Write execution counts for each function. */ 481 /* Write execution counts for each function. */
482 for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++) 482 for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
483 { 483 {
484 fi_ptr = (const struct gcov_fn_info *) 484 fi_ptr = (const struct gcov_fn_info *)
485 ((const char *) gi_ptr->functions + f_ix * fi_stride); 485 ((const char *) gi_ptr->functions + f_ix * fi_stride);
496 496
497 if (!((1 << t_ix) & gi_ptr->ctr_mask)) 497 if (!((1 << t_ix) & gi_ptr->ctr_mask))
498 continue; 498 continue;
499 499
500 n_counts = fi_ptr->n_ctrs[c_ix]; 500 n_counts = fi_ptr->n_ctrs[c_ix];
501 501
502 gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix), 502 gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
503 GCOV_TAG_COUNTER_LENGTH (n_counts)); 503 GCOV_TAG_COUNTER_LENGTH (n_counts));
504 c_ptr = values[c_ix]; 504 c_ptr = values[c_ix];
505 while (n_counts--) 505 while (n_counts--)
506 gcov_write_counter (*c_ptr++); 506 gcov_write_counter (*c_ptr++);
542 size_t filename_length = strlen(info->filename); 542 size_t filename_length = strlen(info->filename);
543 543
544 /* Refresh the longest file name information */ 544 /* Refresh the longest file name information */
545 if (filename_length > gcov_max_filename) 545 if (filename_length > gcov_max_filename)
546 gcov_max_filename = filename_length; 546 gcov_max_filename = filename_length;
547 547
548 do 548 do
549 { 549 {
550 unsigned ix; 550 unsigned ix;
551 gcov_unsigned_t value = *ptr << 24; 551 gcov_unsigned_t value = *ptr << 24;
552 552
558 crc32 <<= 1; 558 crc32 <<= 1;
559 crc32 ^= feedback; 559 crc32 ^= feedback;
560 } 560 }
561 } 561 }
562 while (*ptr++); 562 while (*ptr++);
563 563
564 gcov_crc32 = crc32; 564 gcov_crc32 = crc32;
565 565
566 if (!gcov_list) 566 if (!gcov_list)
567 atexit (gcov_exit); 567 atexit (gcov_exit);
568 568
569 info->next = gcov_list; 569 info->next = gcov_list;
570 gcov_list = info; 570 gcov_list = info;
571 } 571 }
572 info->version = 0; 572 info->version = 0;
573 } 573 }
584 gcov_exit (); 584 gcov_exit ();
585 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next) 585 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
586 { 586 {
587 unsigned t_ix; 587 unsigned t_ix;
588 const struct gcov_ctr_info *ci_ptr; 588 const struct gcov_ctr_info *ci_ptr;
589 589
590 for (t_ix = 0, ci_ptr = gi_ptr->counts; t_ix != GCOV_COUNTERS; t_ix++) 590 for (t_ix = 0, ci_ptr = gi_ptr->counts; t_ix != GCOV_COUNTERS; t_ix++)
591 if ((1 << t_ix) & gi_ptr->ctr_mask) 591 if ((1 << t_ix) & gi_ptr->ctr_mask)
592 { 592 {
593 memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num); 593 memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
594 ci_ptr++; 594 ci_ptr++;
626 /* The profile merging function for choosing the most common value. 626 /* The profile merging function for choosing the most common value.
627 It is given an array COUNTERS of N_COUNTERS old counters and it 627 It is given an array COUNTERS of N_COUNTERS old counters and it
628 reads the same number of counters from the gcov file. The counters 628 reads the same number of counters from the gcov file. The counters
629 are split into 3-tuples where the members of the tuple have 629 are split into 3-tuples where the members of the tuple have
630 meanings: 630 meanings:
631 631
632 -- the stored candidate on the most common value of the measured entity 632 -- the stored candidate on the most common value of the measured entity
633 -- counter 633 -- counter
634 -- total number of evaluations of the value */ 634 -- total number of evaluations of the value */
635 void 635 void
636 __gcov_merge_single (gcov_type *counters, unsigned n_counters) 636 __gcov_merge_single (gcov_type *counters, unsigned n_counters)
664 /* The profile merging function for choosing the most common 664 /* The profile merging function for choosing the most common
665 difference between two consecutive evaluations of the value. It is 665 difference between two consecutive evaluations of the value. It is
666 given an array COUNTERS of N_COUNTERS old counters and it reads the 666 given an array COUNTERS of N_COUNTERS old counters and it reads the
667 same number of counters from the gcov file. The counters are split 667 same number of counters from the gcov file. The counters are split
668 into 4-tuples where the members of the tuple have meanings: 668 into 4-tuples where the members of the tuple have meanings:
669 669
670 -- the last value of the measured entity 670 -- the last value of the measured entity
671 -- the stored candidate on the most common difference 671 -- the stored candidate on the most common difference
672 -- counter 672 -- counter
673 -- total number of evaluations of the value */ 673 -- total number of evaluations of the value */
674 void 674 void
675 __gcov_merge_delta (gcov_type *counters, unsigned n_counters) 675 __gcov_merge_delta (gcov_type *counters, unsigned n_counters)
676 { 676 {
677 unsigned i, n_measures; 677 unsigned i, n_measures;
678 gcov_type last, value, counter, all; 678 gcov_type value, counter, all;
679 679
680 gcc_assert (!(n_counters % 4)); 680 gcc_assert (!(n_counters % 4));
681 n_measures = n_counters / 4; 681 n_measures = n_counters / 4;
682 for (i = 0; i < n_measures; i++, counters += 4) 682 for (i = 0; i < n_measures; i++, counters += 4)
683 { 683 {
684 last = gcov_read_counter (); 684 /* last = */ gcov_read_counter ();
685 value = gcov_read_counter (); 685 value = gcov_read_counter ();
686 counter = gcov_read_counter (); 686 counter = gcov_read_counter ();
687 all = gcov_read_counter (); 687 all = gcov_read_counter ();
688 688
689 if (counters[1] == value) 689 if (counters[1] == value)
768 #endif 768 #endif
769 769
770 #ifdef L_gcov_indirect_call_profiler 770 #ifdef L_gcov_indirect_call_profiler
771 /* Tries to determine the most common value among its inputs. */ 771 /* Tries to determine the most common value among its inputs. */
772 void 772 void
773 __gcov_indirect_call_profiler (gcov_type* counter, gcov_type value, 773 __gcov_indirect_call_profiler (gcov_type* counter, gcov_type value,
774 void* cur_func, void* callee_func) 774 void* cur_func, void* callee_func)
775 { 775 {
776 /* If the C++ virtual tables contain function descriptors then one 776 /* If the C++ virtual tables contain function descriptors then one
777 function may have multiple descriptors and we need to dereference 777 function may have multiple descriptors and we need to dereference
778 the descriptors to see if they point to the same function. */ 778 the descriptors to see if they point to the same function. */