1 2 /*--------------------------------------------------------------------*/ 3 /*--- For printing superblock profiles m_sbprofile.c ---*/ 4 /*--------------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2012-2013 Mozilla Foundation 11 12 This program is free software; you can redistribute it and/or 13 modify it under the terms of the GNU General Public License as 14 published by the Free Software Foundation; either version 2 of the 15 License, or (at your option) any later version. 16 17 This program is distributed in the hope that it will be useful, but 18 WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 General Public License for more details. 21 22 You should have received a copy of the GNU General Public License 23 along with this program; if not, write to the Free Software 24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 25 02111-1307, USA. 26 27 The GNU General Public License is contained in the file COPYING. 28 */ 29 30 /* Contributed by Julian Seward <jseward (at) acm.org> */ 31 32 #include "pub_core_basics.h" 33 #include "pub_core_transtab.h" 34 #include "pub_core_libcbase.h" 35 #include "pub_core_libcprint.h" 36 #include "pub_core_libcassert.h" 37 #include "pub_core_debuginfo.h" 38 #include "pub_core_translate.h" 39 #include "pub_core_options.h" 40 #include "pub_core_sbprofile.h" // self 41 42 /*====================================================================*/ 43 /*=== SB profiling ===*/ 44 /*====================================================================*/ 45 46 static UInt n_profiles = 0; 47 48 static 49 void show_SB_profile ( SBProfEntry tops[], UInt n_tops, 50 ULong score_total, ULong ecs_done ) 51 { 52 ULong score_cumul, score_cumul_saved, score_here; 53 HChar buf_cumul[10], buf_here[10]; 54 HChar name[64]; 55 Int r; /* must be signed */ 56 57 HChar ecs_txt[50]; 58 if (ecs_done > 0) { 59 VG_(sprintf)(ecs_txt, "%'llu ecs done", ecs_done); 60 } else { 61 VG_(strcpy)(ecs_txt, "for the entire run"); 62 } 63 64 vg_assert(VG_(clo_profyle_sbs)); 65 66 VG_(printf)("\n"); 67 VG_(printf)("<<<---<<<---<<<---<<<---<<<---<<<---<<<---" 68 "<<<---<<<---<<<---<<<---<<<---<<<\n"); 69 VG_(printf)("<<<---<<<---<<<---<<<---<<<---<<<---<<<---" 70 "<<<---<<<---<<<---<<<---<<<---<<<\n"); 71 VG_(printf)("\n"); 72 VG_(printf)("<<< BEGIN SB Profile #%u (%s)\n", 73 ++n_profiles, ecs_txt); 74 VG_(printf)("<<<\n"); 75 VG_(printf)("\n"); 76 77 VG_(printf)("Total score = %'lld\n\n", score_total); 78 79 /* Print an initial per-block summary. */ 80 VG_(printf)("rank ---cumulative--- -----self-----\n"); 81 score_cumul = 0; 82 for (r = 0; r < n_tops; r++) { 83 if (tops[r].addr == 0) 84 continue; 85 if (tops[r].score == 0) 86 continue; 87 name[0] = 0; 88 VG_(get_fnname_w_offset)(tops[r].addr, name, 64); 89 name[63] = 0; 90 score_here = tops[r].score; 91 score_cumul += score_here; 92 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul); 93 VG_(percentify)(score_here, score_total, 2, 6, buf_here); 94 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n", 95 r, 96 score_cumul, buf_cumul, 97 score_here, buf_here, tops[r].addr, name ); 98 } 99 score_cumul_saved = score_cumul; 100 101 if (VG_(clo_profyle_flags) > 0) { 102 103 /* Show the details, if requested. */ 104 VG_(printf)("\n"); 105 VG_(printf)("-----------------------------" 106 "------------------------------\n"); 107 VG_(printf)("--- SB Profile (SB details) " 108 " ---\n"); 109 VG_(printf)("-----------------------------" 110 "------------------------------\n"); 111 VG_(printf)("\n"); 112 113 score_cumul = 0; 114 for (r = 0; r < n_tops; r++) { 115 if (tops[r].addr == 0) 116 continue; 117 if (tops[r].score == 0) 118 continue; 119 name[0] = 0; 120 VG_(get_fnname_w_offset)(tops[r].addr, name, 64); 121 name[63] = 0; 122 score_here = tops[r].score; 123 score_cumul += score_here; 124 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul); 125 VG_(percentify)(score_here, score_total, 2, 6, buf_here); 126 VG_(printf)("\n"); 127 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= begin SB rank %d " 128 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r); 129 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n", 130 r, 131 score_cumul, buf_cumul, 132 score_here, buf_here, tops[r].addr, name ); 133 VG_(printf)("\n"); 134 VG_(discard_translations)(tops[r].addr, 1, "bb profile"); 135 VG_(translate)(0, tops[r].addr, True, VG_(clo_profyle_flags), 0, True); 136 VG_(printf)("=-=-=-=-=-=-=-=-=-=-=-=-=-= end SB rank %d " 137 "=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n", r); 138 } 139 140 /* Print a final per-block summary, in reverse order, for the 141 convenience of people reading up from the end. */ 142 score_cumul = score_cumul_saved; 143 for (r = n_tops-1; r >= 0; r--) { 144 if (tops[r].addr == 0) 145 continue; 146 if (tops[r].score == 0) 147 continue; 148 name[0] = 0; 149 VG_(get_fnname_w_offset)(tops[r].addr, name, 64); 150 name[63] = 0; 151 score_here = tops[r].score; 152 VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul); 153 VG_(percentify)(score_here, score_total, 2, 6, buf_here); 154 VG_(printf)("%3d: (%9lld %s) %9lld %s 0x%llx %s\n", 155 r, 156 score_cumul, buf_cumul, 157 score_here, buf_here, tops[r].addr, name ); 158 score_cumul -= score_here; 159 } 160 VG_(printf)("rank ---cumulative--- -----self-----\n"); 161 162 } 163 164 VG_(printf)("\n"); 165 VG_(printf)(">>>\n"); 166 VG_(printf)(">>> END SB Profile #%u (%s)\n", 167 n_profiles, ecs_txt); 168 VG_(printf)(">>>\n"); 169 VG_(printf)(">>>--->>>--->>>--->>>--->>>--->>>--->>>---" 170 ">>>--->>>--->>>--->>>--->>>--->>>\n"); 171 VG_(printf)(">>>--->>>--->>>--->>>--->>>--->>>--->>>---" 172 ">>>--->>>--->>>--->>>--->>>--->>>\n"); 173 VG_(printf)("\n"); 174 } 175 176 177 /* Get and print a profile. Also, zero out the counters so that if we 178 call it again later, the second call will only show new work done 179 since the first call. ecs_done == 0 is taken to mean this is a 180 run-end profile. */ 181 void VG_(get_and_show_SB_profile) ( ULong ecs_done ) 182 { 183 /* The number of blocks to show for a end-of-run profile */ 184 # define N_MAX_END 200 185 /* The number of blocks to show for a mid-run profile. */ 186 # define N_MAX_INTERVAL 20 187 vg_assert(N_MAX_INTERVAL <= N_MAX_END); 188 SBProfEntry tops[N_MAX_END]; 189 Int nToShow = ecs_done == 0 ? N_MAX_END : N_MAX_INTERVAL; 190 ULong score_total = VG_(get_SB_profile)(tops, nToShow); 191 show_SB_profile(tops, nToShow, score_total, ecs_done); 192 # undef N_MAX_END 193 # undef N_MAX_INTERVAL 194 } 195 196 197 /*--------------------------------------------------------------------*/ 198 /*--- end m_sbprofile.c ---*/ 199 /*--------------------------------------------------------------------*/ 200