| 1 | efrain | 1 | <?php
 | 
        
           |  |  | 2 | //  Copyright (c) 2009 Facebook
 | 
        
           |  |  | 3 | //
 | 
        
           |  |  | 4 | //  Licensed under the Apache License, Version 2.0 (the "License");
 | 
        
           |  |  | 5 | //  you may not use this file except in compliance with the License.
 | 
        
           |  |  | 6 | //  You may obtain a copy of the License at
 | 
        
           |  |  | 7 | //
 | 
        
           |  |  | 8 | //      http://www.apache.org/licenses/LICENSE-2.0
 | 
        
           |  |  | 9 | //
 | 
        
           |  |  | 10 | //  Unless required by applicable law or agreed to in writing, software
 | 
        
           |  |  | 11 | //  distributed under the License is distributed on an "AS IS" BASIS,
 | 
        
           |  |  | 12 | //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
        
           |  |  | 13 | //  See the License for the specific language governing permissions and
 | 
        
           |  |  | 14 | //  limitations under the License.
 | 
        
           |  |  | 15 | //
 | 
        
           |  |  | 16 |   | 
        
           |  |  | 17 | //
 | 
        
           |  |  | 18 | // XHProf: A Hierarchical Profiler for PHP
 | 
        
           |  |  | 19 | //
 | 
        
           |  |  | 20 | // XHProf has two components:
 | 
        
           |  |  | 21 | //
 | 
        
           |  |  | 22 | //  * This module is the UI/reporting component, used
 | 
        
           |  |  | 23 | //    for viewing results of XHProf runs from a browser.
 | 
        
           |  |  | 24 | //
 | 
        
           |  |  | 25 | //  * Data collection component: This is implemented
 | 
        
           |  |  | 26 | //    as a PHP extension (XHProf).
 | 
        
           |  |  | 27 | //
 | 
        
           |  |  | 28 | // @author Kannan Muthukkaruppan
 | 
        
           |  |  | 29 | //
 | 
        
           |  |  | 30 |   | 
        
           |  |  | 31 | if (!isset($GLOBALS['XHPROF_LIB_ROOT'])) {
 | 
        
           |  |  | 32 |   // by default, the parent directory is XHPROF lib root
 | 
        
           |  |  | 33 |   $GLOBALS['XHPROF_LIB_ROOT'] = realpath(dirname(__FILE__) . '/..');
 | 
        
           |  |  | 34 | }
 | 
        
           |  |  | 35 |   | 
        
           |  |  | 36 | require_once $GLOBALS['XHPROF_LIB_ROOT'].'/utils/xhprof_lib.php';
 | 
        
           |  |  | 37 | require_once $GLOBALS['XHPROF_LIB_ROOT'].'/utils/callgraph_utils.php';
 | 
        
           |  |  | 38 | require_once $GLOBALS['XHPROF_LIB_ROOT'].'/utils/xhprof_runs.php';
 | 
        
           |  |  | 39 |   | 
        
           |  |  | 40 |   | 
        
           |  |  | 41 | /**
 | 
        
           |  |  | 42 |  * Our coding convention disallows relative paths in hrefs.
 | 
        
           |  |  | 43 |  * Get the base URL path from the SCRIPT_NAME.
 | 
        
           |  |  | 44 |  */
 | 
        
           |  |  | 45 | $base_path = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/\\');
 | 
        
           |  |  | 46 | $base_url = htmlentities($_SERVER['SCRIPT_NAME']);
 | 
        
           |  |  | 47 |   | 
        
           |  |  | 48 | /**
 | 
        
           |  |  | 49 |  * Generate references to required stylesheets & javascript.
 | 
        
           |  |  | 50 |  *
 | 
        
           |  |  | 51 |  * If the calling script (such as index.php) resides in
 | 
        
           |  |  | 52 |  * a different location that than 'xhprof_html' directory the
 | 
        
           |  |  | 53 |  * caller must provide the URL path to 'xhprof_html' directory
 | 
        
           |  |  | 54 |  * so that the correct location of the style sheets/javascript
 | 
        
           |  |  | 55 |  * can be specified in the generated HTML.
 | 
        
           |  |  | 56 |  *
 | 
        
           |  |  | 57 |  */
 | 
        
           |  |  | 58 | function xhprof_include_js_css($ui_dir_url_path = null) {
 | 
        
           |  |  | 59 |   global $base_path;
 | 
        
           |  |  | 60 |   | 
        
           |  |  | 61 |   if (empty($ui_dir_url_path)) {
 | 
        
           |  |  | 62 |     $ui_dir_url_path = $base_path;
 | 
        
           |  |  | 63 |   }
 | 
        
           |  |  | 64 |   | 
        
           |  |  | 65 |   // style sheets
 | 
        
           |  |  | 66 |   echo "<link href='$ui_dir_url_path/css/xhprof.css' rel='stylesheet' ".
 | 
        
           |  |  | 67 |     " type='text/css' />";
 | 
        
           |  |  | 68 |   echo "<link href='$ui_dir_url_path/jquery/jquery.tooltip.css' ".
 | 
        
           |  |  | 69 |     " rel='stylesheet' type='text/css' />";
 | 
        
           |  |  | 70 |   echo "<link href='$ui_dir_url_path/jquery/jquery.autocomplete.css' ".
 | 
        
           |  |  | 71 |     " rel='stylesheet' type='text/css' />";
 | 
        
           |  |  | 72 |   | 
        
           |  |  | 73 |   // javascript
 | 
        
           |  |  | 74 |   echo "<script src='$ui_dir_url_path/jquery/jquery-1.2.6.js'>".
 | 
        
           |  |  | 75 |        "</script>";
 | 
        
           |  |  | 76 |   echo "<script src='$ui_dir_url_path/jquery/jquery.tooltip.js'>".
 | 
        
           |  |  | 77 |        "</script>";
 | 
        
           |  |  | 78 |   echo "<script src='$ui_dir_url_path/jquery/jquery.autocomplete.js'>"
 | 
        
           |  |  | 79 |        ."</script>";
 | 
        
           |  |  | 80 |   echo "<script src='$ui_dir_url_path/js/xhprof_report.js'></script>";
 | 
        
           |  |  | 81 | }
 | 
        
           |  |  | 82 |   | 
        
           |  |  | 83 |   | 
        
           |  |  | 84 | /*
 | 
        
           |  |  | 85 |  * Formats call counts for XHProf reports.
 | 
        
           |  |  | 86 |  *
 | 
        
           |  |  | 87 |  * Description:
 | 
        
           |  |  | 88 |  * Call counts in single-run reports are integer values.
 | 
        
           |  |  | 89 |  * However, call counts for aggregated reports can be
 | 
        
           |  |  | 90 |  * fractional. This function will print integer values
 | 
        
           |  |  | 91 |  * without decimal point, but with commas etc.
 | 
        
           |  |  | 92 |  *
 | 
        
           |  |  | 93 |  *   4000 ==> 4,000
 | 
        
           |  |  | 94 |  *
 | 
        
           |  |  | 95 |  * It'll round fractional values to decimal precision of 3
 | 
        
           |  |  | 96 |  *   4000.1212 ==> 4,000.121
 | 
        
           |  |  | 97 |  *   4000.0001 ==> 4,000
 | 
        
           |  |  | 98 |  *
 | 
        
           |  |  | 99 |  */
 | 
        
           |  |  | 100 | function xhprof_count_format($num) {
 | 
        
           |  |  | 101 |   $num = round($num, 3);
 | 
        
           |  |  | 102 |   if (round($num) == $num) {
 | 
        
           |  |  | 103 |     return number_format($num);
 | 
        
           |  |  | 104 |   } else {
 | 
        
           |  |  | 105 |     return number_format($num, 3);
 | 
        
           |  |  | 106 |   }
 | 
        
           |  |  | 107 | }
 | 
        
           |  |  | 108 |   | 
        
           |  |  | 109 | function xhprof_percent_format($s, $precision = 1) {
 | 
        
           |  |  | 110 |   return sprintf('%.'.$precision.'f%%', 100 * $s);
 | 
        
           |  |  | 111 | }
 | 
        
           |  |  | 112 |   | 
        
           |  |  | 113 | /**
 | 
        
           |  |  | 114 |  * Implodes the text for a bunch of actions (such as links, forms,
 | 
        
           |  |  | 115 |  * into a HTML list and returns the text.
 | 
        
           |  |  | 116 |  */
 | 
        
           |  |  | 117 | function xhprof_render_actions($actions) {
 | 
        
           |  |  | 118 |   $out = array();
 | 
        
           |  |  | 119 |   | 
        
           |  |  | 120 |   if (count($actions)) {
 | 
        
           |  |  | 121 |     $out[] = '<ul class="xhprof_actions">';
 | 
        
           |  |  | 122 |     foreach ($actions as $action) {
 | 
        
           |  |  | 123 |       $out[] = '<li>'.$action.'</li>';
 | 
        
           |  |  | 124 |     }
 | 
        
           |  |  | 125 |     $out[] = '</ul>';
 | 
        
           |  |  | 126 |   }
 | 
        
           |  |  | 127 |   | 
        
           |  |  | 128 |   return implode('', $out);
 | 
        
           |  |  | 129 | }
 | 
        
           |  |  | 130 |   | 
        
           |  |  | 131 |   | 
        
           |  |  | 132 | /**
 | 
        
           |  |  | 133 |  * @param html-str $content  the text/image/innerhtml/whatever for the link
 | 
        
           |  |  | 134 |  * @param raw-str  $href
 | 
        
           |  |  | 135 |  * @param raw-str  $class
 | 
        
           |  |  | 136 |  * @param raw-str  $id
 | 
        
           |  |  | 137 |  * @param raw-str  $title
 | 
        
           |  |  | 138 |  * @param raw-str  $target
 | 
        
           |  |  | 139 |  * @param raw-str  $onclick
 | 
        
           |  |  | 140 |  * @param raw-str  $style
 | 
        
           |  |  | 141 |  * @param raw-str  $access
 | 
        
           |  |  | 142 |  * @param raw-str  $onmouseover
 | 
        
           |  |  | 143 |  * @param raw-str  $onmouseout
 | 
        
           |  |  | 144 |  * @param raw-str  $onmousedown
 | 
        
           |  |  | 145 |  * @param raw-str  $dir
 | 
        
           |  |  | 146 |  * @param raw-str  $rel
 | 
        
           |  |  | 147 |  */
 | 
        
           |  |  | 148 | function xhprof_render_link($content, $href, $class='', $id='', $title='',
 | 
        
           |  |  | 149 |                             $target='',
 | 
        
           |  |  | 150 |                             $onclick='', $style='', $access='', $onmouseover='',
 | 
        
           |  |  | 151 |                             $onmouseout='', $onmousedown='') {
 | 
        
           |  |  | 152 |   | 
        
           |  |  | 153 |   if (!$content) {
 | 
        
           |  |  | 154 |     return '';
 | 
        
           |  |  | 155 |   }
 | 
        
           |  |  | 156 |   | 
        
           |  |  | 157 |   if ($href) {
 | 
        
           |  |  | 158 |     $link = '<a href="' . ($href) . '"';
 | 
        
           |  |  | 159 |   } else {
 | 
        
           |  |  | 160 |     $link = '<span';
 | 
        
           |  |  | 161 |   }
 | 
        
           |  |  | 162 |   | 
        
           |  |  | 163 |   if ($class) {
 | 
        
           |  |  | 164 |     $link .= ' class="' . ($class) . '"';
 | 
        
           |  |  | 165 |   }
 | 
        
           |  |  | 166 |   if ($id) {
 | 
        
           |  |  | 167 |     $link .= ' id="' . ($id) . '"';
 | 
        
           |  |  | 168 |   }
 | 
        
           |  |  | 169 |   if ($title) {
 | 
        
           |  |  | 170 |     $link .= ' title="' . ($title) . '"';
 | 
        
           |  |  | 171 |   }
 | 
        
           |  |  | 172 |   if ($target) {
 | 
        
           |  |  | 173 |     $link .= ' target="' . ($target) . '"';
 | 
        
           |  |  | 174 |   }
 | 
        
           |  |  | 175 |   if ($onclick && $href) {
 | 
        
           |  |  | 176 |     $link .= ' onclick="' . ($onclick) . '"';
 | 
        
           |  |  | 177 |   }
 | 
        
           |  |  | 178 |   if ($style && $href) {
 | 
        
           |  |  | 179 |     $link .= ' style="' . ($style) . '"';
 | 
        
           |  |  | 180 |   }
 | 
        
           |  |  | 181 |   if ($access && $href) {
 | 
        
           |  |  | 182 |     $link .= ' accesskey="' . ($access) . '"';
 | 
        
           |  |  | 183 |   }
 | 
        
           |  |  | 184 |   if ($onmouseover) {
 | 
        
           |  |  | 185 |     $link .= ' onmouseover="' . ($onmouseover) . '"';
 | 
        
           |  |  | 186 |   }
 | 
        
           |  |  | 187 |   if ($onmouseout) {
 | 
        
           |  |  | 188 |     $link .= ' onmouseout="' . ($onmouseout) . '"';
 | 
        
           |  |  | 189 |   }
 | 
        
           |  |  | 190 |   if ($onmousedown) {
 | 
        
           |  |  | 191 |     $link .= ' onmousedown="' . ($onmousedown) . '"';
 | 
        
           |  |  | 192 |   }
 | 
        
           |  |  | 193 |   | 
        
           |  |  | 194 |   $link .= '>';
 | 
        
           |  |  | 195 |   $link .= $content;
 | 
        
           |  |  | 196 |   if ($href) {
 | 
        
           |  |  | 197 |     $link .= '</a>';
 | 
        
           |  |  | 198 |   } else {
 | 
        
           |  |  | 199 |     $link .= '</span>';
 | 
        
           |  |  | 200 |   }
 | 
        
           |  |  | 201 |   | 
        
           |  |  | 202 |   return $link;
 | 
        
           |  |  | 203 | }
 | 
        
           |  |  | 204 |   | 
        
           |  |  | 205 |   | 
        
           |  |  | 206 | // default column to sort on -- wall time
 | 
        
           |  |  | 207 | $sort_col = "wt";
 | 
        
           |  |  | 208 |   | 
        
           |  |  | 209 | // default is "single run" report
 | 
        
           |  |  | 210 | $diff_mode = false;
 | 
        
           |  |  | 211 |   | 
        
           |  |  | 212 | // call count data present?
 | 
        
           |  |  | 213 | $display_calls = true;
 | 
        
           |  |  | 214 |   | 
        
           |  |  | 215 | // The following column headers are sortable
 | 
        
           |  |  | 216 | $sortable_columns = array("fn" => 1,
 | 
        
           |  |  | 217 |                           "ct" => 1,
 | 
        
           |  |  | 218 |                           "wt" => 1,
 | 
        
           |  |  | 219 |                           "excl_wt" => 1,
 | 
        
           |  |  | 220 |                           "ut" => 1,
 | 
        
           |  |  | 221 |                           "excl_ut" => 1,
 | 
        
           |  |  | 222 |                           "st" => 1,
 | 
        
           |  |  | 223 |                           "excl_st" => 1,
 | 
        
           |  |  | 224 |                           "mu" => 1,
 | 
        
           |  |  | 225 |                           "excl_mu" => 1,
 | 
        
           |  |  | 226 |                           "pmu" => 1,
 | 
        
           |  |  | 227 |                           "excl_pmu" => 1,
 | 
        
           |  |  | 228 |                           "cpu" => 1,
 | 
        
           |  |  | 229 |                           "excl_cpu" => 1,
 | 
        
           |  |  | 230 |                           "samples" => 1,
 | 
        
           |  |  | 231 |                           "excl_samples" => 1
 | 
        
           |  |  | 232 |                           );
 | 
        
           |  |  | 233 |   | 
        
           |  |  | 234 | // Textual descriptions for column headers in "single run" mode
 | 
        
           |  |  | 235 | $descriptions = array(
 | 
        
           |  |  | 236 |                       "fn" => "Function Name",
 | 
        
           |  |  | 237 |                       "ct" =>  "Calls",
 | 
        
           |  |  | 238 |                       "Calls%" => "Calls%",
 | 
        
           |  |  | 239 |   | 
        
           |  |  | 240 |                       "wt" => "Incl. Wall Time<br>(microsec)",
 | 
        
           |  |  | 241 |                       "IWall%" => "IWall%",
 | 
        
           |  |  | 242 |                       "excl_wt" => "Excl. Wall Time<br>(microsec)",
 | 
        
           |  |  | 243 |                       "EWall%" => "EWall%",
 | 
        
           |  |  | 244 |   | 
        
           |  |  | 245 |                       "ut" => "Incl. User<br>(microsecs)",
 | 
        
           |  |  | 246 |                       "IUser%" => "IUser%",
 | 
        
           |  |  | 247 |                       "excl_ut" => "Excl. User<br>(microsec)",
 | 
        
           |  |  | 248 |                       "EUser%" => "EUser%",
 | 
        
           |  |  | 249 |   | 
        
           |  |  | 250 |                       "st" => "Incl. Sys <br>(microsec)",
 | 
        
           |  |  | 251 |                       "ISys%" => "ISys%",
 | 
        
           |  |  | 252 |                       "excl_st" => "Excl. Sys <br>(microsec)",
 | 
        
           |  |  | 253 |                       "ESys%" => "ESys%",
 | 
        
           |  |  | 254 |   | 
        
           |  |  | 255 |                       "cpu" => "Incl. CPU<br>(microsecs)",
 | 
        
           |  |  | 256 |                       "ICpu%" => "ICpu%",
 | 
        
           |  |  | 257 |                       "excl_cpu" => "Excl. CPU<br>(microsec)",
 | 
        
           |  |  | 258 |                       "ECpu%" => "ECPU%",
 | 
        
           |  |  | 259 |   | 
        
           |  |  | 260 |                       "mu" => "Incl.<br>MemUse<br>(bytes)",
 | 
        
           |  |  | 261 |                       "IMUse%" => "IMemUse%",
 | 
        
           |  |  | 262 |                       "excl_mu" => "Excl.<br>MemUse<br>(bytes)",
 | 
        
           |  |  | 263 |                       "EMUse%" => "EMemUse%",
 | 
        
           |  |  | 264 |   | 
        
           |  |  | 265 |                       "pmu" => "Incl.<br> PeakMemUse<br>(bytes)",
 | 
        
           |  |  | 266 |                       "IPMUse%" => "IPeakMemUse%",
 | 
        
           |  |  | 267 |                       "excl_pmu" => "Excl.<br>PeakMemUse<br>(bytes)",
 | 
        
           |  |  | 268 |                       "EPMUse%" => "EPeakMemUse%",
 | 
        
           |  |  | 269 |   | 
        
           |  |  | 270 |                       "samples" => "Incl. Samples",
 | 
        
           |  |  | 271 |                       "ISamples%" => "ISamples%",
 | 
        
           |  |  | 272 |                       "excl_samples" => "Excl. Samples",
 | 
        
           |  |  | 273 |                       "ESamples%" => "ESamples%",
 | 
        
           |  |  | 274 |                       );
 | 
        
           |  |  | 275 |   | 
        
           |  |  | 276 | // Formatting Callback Functions...
 | 
        
           |  |  | 277 | $format_cbk = array(
 | 
        
           |  |  | 278 |                       "fn" => "",
 | 
        
           |  |  | 279 |                       "ct" => "xhprof_count_format",
 | 
        
           |  |  | 280 |                       "Calls%" => "xhprof_percent_format",
 | 
        
           |  |  | 281 |   | 
        
           |  |  | 282 |                       "wt" => "number_format",
 | 
        
           |  |  | 283 |                       "IWall%" => "xhprof_percent_format",
 | 
        
           |  |  | 284 |                       "excl_wt" => "number_format",
 | 
        
           |  |  | 285 |                       "EWall%" => "xhprof_percent_format",
 | 
        
           |  |  | 286 |   | 
        
           |  |  | 287 |                       "ut" => "number_format",
 | 
        
           |  |  | 288 |                       "IUser%" => "xhprof_percent_format",
 | 
        
           |  |  | 289 |                       "excl_ut" => "number_format",
 | 
        
           |  |  | 290 |                       "EUser%" => "xhprof_percent_format",
 | 
        
           |  |  | 291 |   | 
        
           |  |  | 292 |                       "st" => "number_format",
 | 
        
           |  |  | 293 |                       "ISys%" => "xhprof_percent_format",
 | 
        
           |  |  | 294 |                       "excl_st" => "number_format",
 | 
        
           |  |  | 295 |                       "ESys%" => "xhprof_percent_format",
 | 
        
           |  |  | 296 |   | 
        
           |  |  | 297 |                       "cpu" => "number_format",
 | 
        
           |  |  | 298 |                       "ICpu%" => "xhprof_percent_format",
 | 
        
           |  |  | 299 |                       "excl_cpu" => "number_format",
 | 
        
           |  |  | 300 |                       "ECpu%" => "xhprof_percent_format",
 | 
        
           |  |  | 301 |   | 
        
           |  |  | 302 |                       "mu" => "number_format",
 | 
        
           |  |  | 303 |                       "IMUse%" => "xhprof_percent_format",
 | 
        
           |  |  | 304 |                       "excl_mu" => "number_format",
 | 
        
           |  |  | 305 |                       "EMUse%" => "xhprof_percent_format",
 | 
        
           |  |  | 306 |   | 
        
           |  |  | 307 |                       "pmu" => "number_format",
 | 
        
           |  |  | 308 |                       "IPMUse%" => "xhprof_percent_format",
 | 
        
           |  |  | 309 |                       "excl_pmu" => "number_format",
 | 
        
           |  |  | 310 |                       "EPMUse%" => "xhprof_percent_format",
 | 
        
           |  |  | 311 |   | 
        
           |  |  | 312 |                       "samples" => "number_format",
 | 
        
           |  |  | 313 |                       "ISamples%" => "xhprof_percent_format",
 | 
        
           |  |  | 314 |                       "excl_samples" => "number_format",
 | 
        
           |  |  | 315 |                       "ESamples%" => "xhprof_percent_format",
 | 
        
           |  |  | 316 |                       );
 | 
        
           |  |  | 317 |   | 
        
           |  |  | 318 |   | 
        
           |  |  | 319 | // Textual descriptions for column headers in "diff" mode
 | 
        
           |  |  | 320 | $diff_descriptions = array(
 | 
        
           |  |  | 321 |                       "fn" => "Function Name",
 | 
        
           |  |  | 322 |                       "ct" =>  "Calls Diff",
 | 
        
           |  |  | 323 |                       "Calls%" => "Calls<br>Diff%",
 | 
        
           |  |  | 324 |   | 
        
           |  |  | 325 |                       "wt" => "Incl. Wall<br>Diff<br>(microsec)",
 | 
        
           |  |  | 326 |                       "IWall%" => "IWall<br> Diff%",
 | 
        
           |  |  | 327 |                       "excl_wt" => "Excl. Wall<br>Diff<br>(microsec)",
 | 
        
           |  |  | 328 |                       "EWall%" => "EWall<br>Diff%",
 | 
        
           |  |  | 329 |   | 
        
           |  |  | 330 |                       "ut" => "Incl. User Diff<br>(microsec)",
 | 
        
           |  |  | 331 |                       "IUser%" => "IUser<br>Diff%",
 | 
        
           |  |  | 332 |                       "excl_ut" => "Excl. User<br>Diff<br>(microsec)",
 | 
        
           |  |  | 333 |                       "EUser%" => "EUser<br>Diff%",
 | 
        
           |  |  | 334 |   | 
        
           |  |  | 335 |                       "cpu" => "Incl. CPU Diff<br>(microsec)",
 | 
        
           |  |  | 336 |                       "ICpu%" => "ICpu<br>Diff%",
 | 
        
           |  |  | 337 |                       "excl_cpu" => "Excl. CPU<br>Diff<br>(microsec)",
 | 
        
           |  |  | 338 |                       "ECpu%" => "ECpu<br>Diff%",
 | 
        
           |  |  | 339 |   | 
        
           |  |  | 340 |                       "st" => "Incl. Sys Diff<br>(microsec)",
 | 
        
           |  |  | 341 |                       "ISys%" => "ISys<br>Diff%",
 | 
        
           |  |  | 342 |                       "excl_st" => "Excl. Sys Diff<br>(microsec)",
 | 
        
           |  |  | 343 |                       "ESys%" => "ESys<br>Diff%",
 | 
        
           |  |  | 344 |   | 
        
           |  |  | 345 |                       "mu" => "Incl.<br>MemUse<br>Diff<br>(bytes)",
 | 
        
           |  |  | 346 |                       "IMUse%" => "IMemUse<br>Diff%",
 | 
        
           |  |  | 347 |                       "excl_mu" => "Excl.<br>MemUse<br>Diff<br>(bytes)",
 | 
        
           |  |  | 348 |                       "EMUse%" => "EMemUse<br>Diff%",
 | 
        
           |  |  | 349 |   | 
        
           |  |  | 350 |                       "pmu" => "Incl.<br> PeakMemUse<br>Diff<br>(bytes)",
 | 
        
           |  |  | 351 |                       "IPMUse%" => "IPeakMemUse<br>Diff%",
 | 
        
           |  |  | 352 |                       "excl_pmu" => "Excl.<br>PeakMemUse<br>Diff<br>(bytes)",
 | 
        
           |  |  | 353 |                       "EPMUse%" => "EPeakMemUse<br>Diff%",
 | 
        
           |  |  | 354 |   | 
        
           |  |  | 355 |                       "samples" => "Incl. Samples Diff",
 | 
        
           |  |  | 356 |                       "ISamples%" => "ISamples Diff%",
 | 
        
           |  |  | 357 |                       "excl_samples" => "Excl. Samples Diff",
 | 
        
           |  |  | 358 |                       "ESamples%" => "ESamples Diff%",
 | 
        
           |  |  | 359 |                       );
 | 
        
           |  |  | 360 |   | 
        
           |  |  | 361 | // columns that'll be displayed in a top-level report
 | 
        
           |  |  | 362 | $stats = array();
 | 
        
           |  |  | 363 |   | 
        
           |  |  | 364 | // columns that'll be displayed in a function's parent/child report
 | 
        
           |  |  | 365 | $pc_stats = array();
 | 
        
           |  |  | 366 |   | 
        
           |  |  | 367 | // Various total counts
 | 
        
           |  |  | 368 | $totals = 0;
 | 
        
           |  |  | 369 | $totals_1 = 0;
 | 
        
           |  |  | 370 | $totals_2 = 0;
 | 
        
           |  |  | 371 |   | 
        
           |  |  | 372 | /*
 | 
        
           |  |  | 373 |  * The subset of $possible_metrics that is present in the raw profile data.
 | 
        
           |  |  | 374 |  */
 | 
        
           |  |  | 375 | $metrics = null;
 | 
        
           |  |  | 376 |   | 
        
           |  |  | 377 | /**
 | 
        
           |  |  | 378 |  * Callback comparison operator (passed to usort() for sorting array of
 | 
        
           |  |  | 379 |  * tuples) that compares array elements based on the sort column
 | 
        
           |  |  | 380 |  * specified in $sort_col (global parameter).
 | 
        
           |  |  | 381 |  *
 | 
        
           |  |  | 382 |  * @author Kannan
 | 
        
           |  |  | 383 |  */
 | 
        
           |  |  | 384 | function sort_cbk($a, $b) {
 | 
        
           |  |  | 385 |   global $sort_col;
 | 
        
           |  |  | 386 |   global $diff_mode;
 | 
        
           |  |  | 387 |   | 
        
           |  |  | 388 |   if ($sort_col == "fn") {
 | 
        
           |  |  | 389 |   | 
        
           |  |  | 390 |     // case insensitive ascending sort for function names
 | 
        
           |  |  | 391 |     $left = strtoupper($a["fn"]);
 | 
        
           |  |  | 392 |     $right = strtoupper($b["fn"]);
 | 
        
           |  |  | 393 |   | 
        
           |  |  | 394 |     if ($left == $right)
 | 
        
           |  |  | 395 |       return 0;
 | 
        
           |  |  | 396 |     return ($left < $right) ? -1 : 1;
 | 
        
           |  |  | 397 |   | 
        
           |  |  | 398 |   } else {
 | 
        
           |  |  | 399 |   | 
        
           |  |  | 400 |     // descending sort for all others
 | 
        
           |  |  | 401 |     $left = $a[$sort_col];
 | 
        
           |  |  | 402 |     $right = $b[$sort_col];
 | 
        
           |  |  | 403 |   | 
        
           |  |  | 404 |     // if diff mode, sort by absolute value of regression/improvement
 | 
        
           |  |  | 405 |     if ($diff_mode) {
 | 
        
           |  |  | 406 |       $left = abs($left);
 | 
        
           |  |  | 407 |       $right = abs($right);
 | 
        
           |  |  | 408 |     }
 | 
        
           |  |  | 409 |   | 
        
           |  |  | 410 |     if ($left == $right)
 | 
        
           |  |  | 411 |       return 0;
 | 
        
           |  |  | 412 |     return ($left > $right) ? -1 : 1;
 | 
        
           |  |  | 413 |   }
 | 
        
           |  |  | 414 | }
 | 
        
           |  |  | 415 |   | 
        
           |  |  | 416 | /**
 | 
        
           |  |  | 417 |  * Get the appropriate description for a statistic
 | 
        
           |  |  | 418 |  * (depending upon whether we are in diff report mode
 | 
        
           |  |  | 419 |  * or single run report mode).
 | 
        
           |  |  | 420 |  *
 | 
        
           |  |  | 421 |  * @author Kannan
 | 
        
           |  |  | 422 |  */
 | 
        
           |  |  | 423 | function stat_description($stat) {
 | 
        
           |  |  | 424 |   global $descriptions;
 | 
        
           |  |  | 425 |   global $diff_descriptions;
 | 
        
           |  |  | 426 |   global $diff_mode;
 | 
        
           |  |  | 427 |   | 
        
           |  |  | 428 |   if ($diff_mode) {
 | 
        
           |  |  | 429 |     return $diff_descriptions[$stat];
 | 
        
           |  |  | 430 |   } else {
 | 
        
           |  |  | 431 |     return $descriptions[$stat];
 | 
        
           |  |  | 432 |   }
 | 
        
           |  |  | 433 | }
 | 
        
           |  |  | 434 |   | 
        
           |  |  | 435 |   | 
        
           |  |  | 436 | /**
 | 
        
           |  |  | 437 |  * Analyze raw data & generate the profiler report
 | 
        
           |  |  | 438 |  * (common for both single run mode and diff mode).
 | 
        
           |  |  | 439 |  *
 | 
        
           |  |  | 440 |  * @author: Kannan
 | 
        
           |  |  | 441 |  */
 | 
        
           |  |  | 442 | function profiler_report ($url_params,
 | 
        
           |  |  | 443 |                           $rep_symbol,
 | 
        
           |  |  | 444 |                           $sort,
 | 
        
           |  |  | 445 |                           $run1,
 | 
        
           |  |  | 446 |                           $run1_desc,
 | 
        
           |  |  | 447 |                           $run1_data,
 | 
        
           |  |  | 448 |                           $run2 = 0,
 | 
        
           |  |  | 449 |                           $run2_desc = "",
 | 
        
           |  |  | 450 |                           $run2_data = array()) {
 | 
        
           |  |  | 451 |   global $totals;
 | 
        
           |  |  | 452 |   global $totals_1;
 | 
        
           |  |  | 453 |   global $totals_2;
 | 
        
           |  |  | 454 |   global $stats;
 | 
        
           |  |  | 455 |   global $pc_stats;
 | 
        
           |  |  | 456 |   global $diff_mode;
 | 
        
           |  |  | 457 |   global $base_url;
 | 
        
           |  |  | 458 |   | 
        
           |  |  | 459 |   // if we are reporting on a specific function, we can trim down
 | 
        
           |  |  | 460 |   // the report(s) to just stuff that is relevant to this function.
 | 
        
           |  |  | 461 |   // That way compute_flat_info()/compute_diff() etc. do not have
 | 
        
           |  |  | 462 |   // to needlessly work hard on churning irrelevant data.
 | 
        
           |  |  | 463 |   if (!empty($rep_symbol)) {
 | 
        
           |  |  | 464 |     $run1_data = xhprof_trim_run($run1_data, array($rep_symbol));
 | 
        
           |  |  | 465 |     if ($diff_mode) {
 | 
        
           |  |  | 466 |       $run2_data = xhprof_trim_run($run2_data, array($rep_symbol));
 | 
        
           |  |  | 467 |     }
 | 
        
           |  |  | 468 |   }
 | 
        
           |  |  | 469 |   | 
        
           |  |  | 470 |   if ($diff_mode) {
 | 
        
           |  |  | 471 |     $run_delta = xhprof_compute_diff($run1_data, $run2_data);
 | 
        
           |  |  | 472 |     $symbol_tab  = xhprof_compute_flat_info($run_delta, $totals);
 | 
        
           |  |  | 473 |     $symbol_tab1 = xhprof_compute_flat_info($run1_data, $totals_1);
 | 
        
           |  |  | 474 |     $symbol_tab2 = xhprof_compute_flat_info($run2_data, $totals_2);
 | 
        
           |  |  | 475 |   } else {
 | 
        
           |  |  | 476 |     $symbol_tab = xhprof_compute_flat_info($run1_data, $totals);
 | 
        
           |  |  | 477 |   }
 | 
        
           |  |  | 478 |   | 
        
           |  |  | 479 |   $run1_txt = sprintf("<b>Run #%s:</b> %s",
 | 
        
           |  |  | 480 |                       $run1, $run1_desc);
 | 
        
           |  |  | 481 |   | 
        
           |  |  | 482 |   $base_url_params = xhprof_array_unset(xhprof_array_unset($url_params,
 | 
        
           |  |  | 483 |                                                            'symbol'),
 | 
        
           |  |  | 484 |                                         'all');
 | 
        
           |  |  | 485 |   | 
        
           |  |  | 486 |   $top_link_query_string = "$base_url?" . http_build_query($base_url_params);
 | 
        
           |  |  | 487 |   | 
        
           |  |  | 488 |   if ($diff_mode) {
 | 
        
           |  |  | 489 |     $diff_text = "Diff";
 | 
        
           |  |  | 490 |     $base_url_params = xhprof_array_unset($base_url_params, 'run1');
 | 
        
           |  |  | 491 |     $base_url_params = xhprof_array_unset($base_url_params, 'run2');
 | 
        
           |  |  | 492 |     $run1_link = xhprof_render_link('View Run #' . $run1,
 | 
        
           |  |  | 493 |                            "$base_url?" .
 | 
        
           |  |  | 494 |                            http_build_query(xhprof_array_set($base_url_params,
 | 
        
           |  |  | 495 |                                                       'run',
 | 
        
           |  |  | 496 |                                                       $run1)));
 | 
        
           |  |  | 497 |     $run2_txt = sprintf("<b>Run #%s:</b> %s",
 | 
        
           |  |  | 498 |                         $run2, $run2_desc);
 | 
        
           |  |  | 499 |   | 
        
           |  |  | 500 |     $run2_link = xhprof_render_link('View Run #' . $run2,
 | 
        
           |  |  | 501 |                                     "$base_url?" .
 | 
        
           |  |  | 502 |                         http_build_query(xhprof_array_set($base_url_params,
 | 
        
           |  |  | 503 |                                                           'run',
 | 
        
           |  |  | 504 |                                                           $run2)));
 | 
        
           |  |  | 505 |   } else {
 | 
        
           |  |  | 506 |     $diff_text = "Run";
 | 
        
           |  |  | 507 |   }
 | 
        
           |  |  | 508 |   | 
        
           |  |  | 509 |   // set up the action links for operations that can be done on this report
 | 
        
           |  |  | 510 |   $links = array();
 | 
        
           |  |  | 511 |   $links [] =  xhprof_render_link("View Top Level $diff_text Report",
 | 
        
           |  |  | 512 |                                  $top_link_query_string);
 | 
        
           |  |  | 513 |   | 
        
           |  |  | 514 |   if ($diff_mode) {
 | 
        
           |  |  | 515 |     $inverted_params = $url_params;
 | 
        
           |  |  | 516 |     $inverted_params['run1'] = $url_params['run2'];
 | 
        
           |  |  | 517 |     $inverted_params['run2'] = $url_params['run1'];
 | 
        
           |  |  | 518 |   | 
        
           |  |  | 519 |     // view the different runs or invert the current diff
 | 
        
           |  |  | 520 |     $links [] = $run1_link;
 | 
        
           |  |  | 521 |     $links [] = $run2_link;
 | 
        
           |  |  | 522 |     $links [] = xhprof_render_link('Invert ' . $diff_text . ' Report',
 | 
        
           |  |  | 523 |                            "$base_url?".
 | 
        
           |  |  | 524 |                            http_build_query($inverted_params));
 | 
        
           |  |  | 525 |   }
 | 
        
           |  |  | 526 |   | 
        
           |  |  | 527 |   // lookup function typeahead form
 | 
        
           |  |  | 528 |   $links [] = '<input class="function_typeahead" ' .
 | 
        
           |  |  | 529 |               ' type="input" size="40" maxlength="100" />';
 | 
        
           |  |  | 530 |   | 
        
           |  |  | 531 |   echo xhprof_render_actions($links);
 | 
        
           |  |  | 532 |   | 
        
           |  |  | 533 |   | 
        
           |  |  | 534 |   echo
 | 
        
           |  |  | 535 |     '<dl class=phprof_report_info>' .
 | 
        
           |  |  | 536 |     '  <dt>' . $diff_text . ' Report</dt>' .
 | 
        
           |  |  | 537 |     '  <dd>' . ($diff_mode ?
 | 
        
           |  |  | 538 |                 $run1_txt . '<br><b>vs.</b><br>' . $run2_txt :
 | 
        
           |  |  | 539 |                 $run1_txt) .
 | 
        
           |  |  | 540 |     '  </dd>' .
 | 
        
           |  |  | 541 |     '  <dt>Tip</dt>' .
 | 
        
           |  |  | 542 |     '  <dd>Click a function name below to drill down.</dd>' .
 | 
        
           |  |  | 543 |     '</dl>' .
 | 
        
           |  |  | 544 |     '<div style="clear: both; margin: 3em 0em;"></div>';
 | 
        
           |  |  | 545 |   | 
        
           |  |  | 546 |   // data tables
 | 
        
           |  |  | 547 |   if (!empty($rep_symbol)) {
 | 
        
           |  |  | 548 |     if (!isset($symbol_tab[$rep_symbol])) {
 | 
        
           |  |  | 549 |       echo "<hr>Symbol <b>$rep_symbol</b> not found in XHProf run</b><hr>";
 | 
        
           |  |  | 550 |       return;
 | 
        
           |  |  | 551 |     }
 | 
        
           |  |  | 552 |   | 
        
           |  |  | 553 |     /* single function report with parent/child information */
 | 
        
           |  |  | 554 |     if ($diff_mode) {
 | 
        
           |  |  | 555 |       $info1 = isset($symbol_tab1[$rep_symbol]) ?
 | 
        
           |  |  | 556 |                        $symbol_tab1[$rep_symbol] : null;
 | 
        
           |  |  | 557 |       $info2 = isset($symbol_tab2[$rep_symbol]) ?
 | 
        
           |  |  | 558 |                        $symbol_tab2[$rep_symbol] : null;
 | 
        
           |  |  | 559 |       symbol_report($url_params, $run_delta, $symbol_tab[$rep_symbol],
 | 
        
           |  |  | 560 |                     $sort, $rep_symbol,
 | 
        
           |  |  | 561 |                     $run1, $info1,
 | 
        
           |  |  | 562 |                     $run2, $info2);
 | 
        
           |  |  | 563 |     } else {
 | 
        
           |  |  | 564 |       symbol_report($url_params, $run1_data, $symbol_tab[$rep_symbol],
 | 
        
           |  |  | 565 |                     $sort, $rep_symbol, $run1);
 | 
        
           |  |  | 566 |     }
 | 
        
           |  |  | 567 |   } else {
 | 
        
           |  |  | 568 |     /* flat top-level report of all functions */
 | 
        
           |  |  | 569 |     full_report($url_params, $symbol_tab, $sort, $run1, $run2);
 | 
        
           |  |  | 570 |   }
 | 
        
           |  |  | 571 | }
 | 
        
           |  |  | 572 |   | 
        
           |  |  | 573 | /**
 | 
        
           |  |  | 574 |  * Computes percentage for a pair of values, and returns it
 | 
        
           |  |  | 575 |  * in string format.
 | 
        
           |  |  | 576 |  */
 | 
        
           |  |  | 577 | function pct($a, $b) {
 | 
        
           |  |  | 578 |   if ($b == 0) {
 | 
        
           |  |  | 579 |     return "N/A";
 | 
        
           |  |  | 580 |   } else {
 | 
        
           |  |  | 581 |     $res = (round(($a * 1000 / $b)) / 10);
 | 
        
           |  |  | 582 |     return $res;
 | 
        
           |  |  | 583 |   }
 | 
        
           |  |  | 584 | }
 | 
        
           |  |  | 585 |   | 
        
           |  |  | 586 | /**
 | 
        
           |  |  | 587 |  * Given a number, returns the td class to use for display.
 | 
        
           |  |  | 588 |  *
 | 
        
           |  |  | 589 |  * For instance, negative numbers in diff reports comparing two runs (run1 & run2)
 | 
        
           |  |  | 590 |  * represent improvement from run1 to run2. We use green to display those deltas,
 | 
        
           |  |  | 591 |  * and red for regression deltas.
 | 
        
           |  |  | 592 |  */
 | 
        
           |  |  | 593 | function get_print_class($num, $bold) {
 | 
        
           |  |  | 594 |   global $vbar;
 | 
        
           |  |  | 595 |   global $vbbar;
 | 
        
           |  |  | 596 |   global $vrbar;
 | 
        
           |  |  | 597 |   global $vgbar;
 | 
        
           |  |  | 598 |   global $diff_mode;
 | 
        
           |  |  | 599 |   | 
        
           |  |  | 600 |   if ($bold) {
 | 
        
           |  |  | 601 |     if ($diff_mode) {
 | 
        
           |  |  | 602 |       if ($num <= 0) {
 | 
        
           |  |  | 603 |         $class = $vgbar; // green (improvement)
 | 
        
           |  |  | 604 |       } else {
 | 
        
           |  |  | 605 |         $class = $vrbar; // red (regression)
 | 
        
           |  |  | 606 |       }
 | 
        
           |  |  | 607 |     } else {
 | 
        
           |  |  | 608 |       $class = $vbbar; // blue
 | 
        
           |  |  | 609 |     }
 | 
        
           |  |  | 610 |   }
 | 
        
           |  |  | 611 |   else {
 | 
        
           |  |  | 612 |     $class = $vbar;  // default (black)
 | 
        
           |  |  | 613 |   }
 | 
        
           |  |  | 614 |   | 
        
           |  |  | 615 |   return $class;
 | 
        
           |  |  | 616 | }
 | 
        
           |  |  | 617 |   | 
        
           |  |  | 618 | /**
 | 
        
           |  |  | 619 |  * Prints a <td> element with a numeric value.
 | 
        
           |  |  | 620 |  */
 | 
        
           |  |  | 621 | function print_td_num($num, $fmt_func, $bold=false, $attributes=null) {
 | 
        
           |  |  | 622 |   | 
        
           |  |  | 623 |   $class = get_print_class($num, $bold);
 | 
        
           |  |  | 624 |   | 
        
           |  |  | 625 |   if (!empty($fmt_func) && is_numeric($num) ) {
 | 
        
           |  |  | 626 |     $num = call_user_func($fmt_func, $num);
 | 
        
           |  |  | 627 |   }
 | 
        
           |  |  | 628 |   | 
        
           |  |  | 629 |   print("<td $attributes $class>$num</td>\n");
 | 
        
           |  |  | 630 | }
 | 
        
           |  |  | 631 |   | 
        
           |  |  | 632 | /**
 | 
        
           |  |  | 633 |  * Prints a <td> element with a pecentage.
 | 
        
           |  |  | 634 |  */
 | 
        
           |  |  | 635 | function print_td_pct($numer, $denom, $bold=false, $attributes=null) {
 | 
        
           |  |  | 636 |   global $vbar;
 | 
        
           |  |  | 637 |   global $vbbar;
 | 
        
           |  |  | 638 |   global $diff_mode;
 | 
        
           |  |  | 639 |   | 
        
           |  |  | 640 |   $class = get_print_class($numer, $bold);
 | 
        
           |  |  | 641 |   | 
        
           |  |  | 642 |   if ($denom == 0) {
 | 
        
           |  |  | 643 |     $pct = "N/A%";
 | 
        
           |  |  | 644 |   } else {
 | 
        
           |  |  | 645 |     $pct = xhprof_percent_format($numer / abs($denom));
 | 
        
           |  |  | 646 |   }
 | 
        
           |  |  | 647 |   | 
        
           |  |  | 648 |   print("<td $attributes $class>$pct</td>\n");
 | 
        
           |  |  | 649 | }
 | 
        
           |  |  | 650 |   | 
        
           |  |  | 651 | /**
 | 
        
           |  |  | 652 |  * Print "flat" data corresponding to one function.
 | 
        
           |  |  | 653 |  *
 | 
        
           |  |  | 654 |  * @author Kannan
 | 
        
           |  |  | 655 |  */
 | 
        
           |  |  | 656 | function print_function_info($url_params, $info, $sort, $run1, $run2) {
 | 
        
           |  |  | 657 |   static $odd_even = 0;
 | 
        
           |  |  | 658 |   | 
        
           |  |  | 659 |   global $totals;
 | 
        
           |  |  | 660 |   global $sort_col;
 | 
        
           |  |  | 661 |   global $metrics;
 | 
        
           |  |  | 662 |   global $format_cbk;
 | 
        
           |  |  | 663 |   global $display_calls;
 | 
        
           |  |  | 664 |   global $base_url;
 | 
        
           |  |  | 665 |   | 
        
           |  |  | 666 |   // Toggle $odd_or_even
 | 
        
           |  |  | 667 |   $odd_even = 1 - $odd_even;
 | 
        
           |  |  | 668 |   | 
        
           |  |  | 669 |   if ($odd_even) {
 | 
        
           |  |  | 670 |     print("<tr>");
 | 
        
           |  |  | 671 |   }
 | 
        
           |  |  | 672 |   else {
 | 
        
           |  |  | 673 |     print('<tr bgcolor="#e5e5e5">');
 | 
        
           |  |  | 674 |   }
 | 
        
           |  |  | 675 |   | 
        
           |  |  | 676 |   $href = "$base_url?" .
 | 
        
           |  |  | 677 |            http_build_query(xhprof_array_set($url_params,
 | 
        
           |  |  | 678 |                                              'symbol', $info["fn"]));
 | 
        
           |  |  | 679 |   | 
        
           |  |  | 680 |   print('<td>');
 | 
        
           |  |  | 681 |   print(xhprof_render_link($info["fn"], $href));
 | 
        
           |  |  | 682 |   print_source_link($info);
 | 
        
           |  |  | 683 |   print("</td>\n");
 | 
        
           |  |  | 684 |   | 
        
           |  |  | 685 |   if ($display_calls) {
 | 
        
           |  |  | 686 |     // Call Count..
 | 
        
           |  |  | 687 |     print_td_num($info["ct"], $format_cbk["ct"], ($sort_col == "ct"));
 | 
        
           |  |  | 688 |     print_td_pct($info["ct"], $totals["ct"], ($sort_col == "ct"));
 | 
        
           |  |  | 689 |   }
 | 
        
           |  |  | 690 |   | 
        
           |  |  | 691 |   // Other metrics..
 | 
        
           |  |  | 692 |   foreach ($metrics as $metric) {
 | 
        
           |  |  | 693 |     // Inclusive metric
 | 
        
           |  |  | 694 |     print_td_num($info[$metric], $format_cbk[$metric],
 | 
        
           |  |  | 695 |                  ($sort_col == $metric));
 | 
        
           |  |  | 696 |     print_td_pct($info[$metric], $totals[$metric],
 | 
        
           |  |  | 697 |                  ($sort_col == $metric));
 | 
        
           |  |  | 698 |   | 
        
           |  |  | 699 |     // Exclusive Metric
 | 
        
           |  |  | 700 |     print_td_num($info["excl_" . $metric],
 | 
        
           |  |  | 701 |                  $format_cbk["excl_" . $metric],
 | 
        
           |  |  | 702 |                  ($sort_col == "excl_" . $metric));
 | 
        
           |  |  | 703 |     print_td_pct($info["excl_" . $metric],
 | 
        
           |  |  | 704 |                  $totals[$metric],
 | 
        
           |  |  | 705 |                  ($sort_col == "excl_" . $metric));
 | 
        
           |  |  | 706 |   }
 | 
        
           |  |  | 707 |   | 
        
           |  |  | 708 |   print("</tr>\n");
 | 
        
           |  |  | 709 | }
 | 
        
           |  |  | 710 |   | 
        
           |  |  | 711 | /**
 | 
        
           |  |  | 712 |  * Print non-hierarchical (flat-view) of profiler data.
 | 
        
           |  |  | 713 |  *
 | 
        
           |  |  | 714 |  * @author Kannan
 | 
        
           |  |  | 715 |  */
 | 
        
           |  |  | 716 | function print_flat_data($url_params, $title, $flat_data, $sort, $run1, $run2, $limit) {
 | 
        
           |  |  | 717 |   | 
        
           |  |  | 718 |   global $stats;
 | 
        
           |  |  | 719 |   global $sortable_columns;
 | 
        
           |  |  | 720 |   global $vwbar;
 | 
        
           |  |  | 721 |   global $base_url;
 | 
        
           |  |  | 722 |   | 
        
           |  |  | 723 |   $size  = count($flat_data);
 | 
        
           |  |  | 724 |   if (!$limit) {              // no limit
 | 
        
           |  |  | 725 |     $limit = $size;
 | 
        
           |  |  | 726 |     $display_link = "";
 | 
        
           |  |  | 727 |   } else {
 | 
        
           |  |  | 728 |     $display_link = xhprof_render_link(" [ <b class=bubble>display all </b>]",
 | 
        
           |  |  | 729 |                                        "$base_url?" .
 | 
        
           |  |  | 730 |                                        http_build_query(xhprof_array_set($url_params,
 | 
        
           |  |  | 731 |                                                                          'all', 1)));
 | 
        
           |  |  | 732 |   }
 | 
        
           |  |  | 733 |   | 
        
           |  |  | 734 |   print("<h3 align=center>$title $display_link</h3><br>");
 | 
        
           |  |  | 735 |   | 
        
           |  |  | 736 |   print('<table border=1 cellpadding=2 cellspacing=1 width="90%" '
 | 
        
           |  |  | 737 |         .'rules=rows bordercolor="#bdc7d8" align=center>');
 | 
        
           |  |  | 738 |   print('<tr bgcolor="#bdc7d8" align=right>');
 | 
        
           |  |  | 739 |   | 
        
           |  |  | 740 |   foreach ($stats as $stat) {
 | 
        
           |  |  | 741 |     $desc = stat_description($stat);
 | 
        
           |  |  | 742 |     if (array_key_exists($stat, $sortable_columns)) {
 | 
        
           |  |  | 743 |       $href = "$base_url?"
 | 
        
           |  |  | 744 |               . http_build_query(xhprof_array_set($url_params, 'sort', $stat));
 | 
        
           |  |  | 745 |       $header = xhprof_render_link($desc, $href);
 | 
        
           |  |  | 746 |     } else {
 | 
        
           |  |  | 747 |       $header = $desc;
 | 
        
           |  |  | 748 |     }
 | 
        
           |  |  | 749 |   | 
        
           |  |  | 750 |     if ($stat == "fn")
 | 
        
           |  |  | 751 |       print("<th align=left><nobr>$header</th>");
 | 
        
           |  |  | 752 |     else print("<th " . $vwbar . "><nobr>$header</th>");
 | 
        
           |  |  | 753 |   }
 | 
        
           |  |  | 754 |   print("</tr>\n");
 | 
        
           |  |  | 755 |   | 
        
           |  |  | 756 |   if ($limit >= 0) {
 | 
        
           |  |  | 757 |     $limit = min($size, $limit);
 | 
        
           |  |  | 758 |     for ($i = 0; $i < $limit; $i++) {
 | 
        
           |  |  | 759 |       print_function_info($url_params, $flat_data[$i], $sort, $run1, $run2);
 | 
        
           |  |  | 760 |     }
 | 
        
           |  |  | 761 |   } else {
 | 
        
           |  |  | 762 |     // if $limit is negative, print abs($limit) items starting from the end
 | 
        
           |  |  | 763 |     $limit = min($size, abs($limit));
 | 
        
           |  |  | 764 |     for ($i = 0; $i < $limit; $i++) {
 | 
        
           |  |  | 765 |       print_function_info($url_params, $flat_data[$size - $i - 1], $sort, $run1, $run2);
 | 
        
           |  |  | 766 |     }
 | 
        
           |  |  | 767 |   }
 | 
        
           |  |  | 768 |   print("</table>");
 | 
        
           |  |  | 769 |   | 
        
           |  |  | 770 |   // let's print the display all link at the bottom as well...
 | 
        
           |  |  | 771 |   if ($display_link) {
 | 
        
           |  |  | 772 |     echo '<div style="text-align: left; padding: 2em">' . $display_link . '</div>';
 | 
        
           |  |  | 773 |   }
 | 
        
           |  |  | 774 |   | 
        
           |  |  | 775 | }
 | 
        
           |  |  | 776 |   | 
        
           |  |  | 777 | /**
 | 
        
           |  |  | 778 |  * Generates a tabular report for all functions. This is the top-level report.
 | 
        
           |  |  | 779 |  *
 | 
        
           |  |  | 780 |  * @author Kannan
 | 
        
           |  |  | 781 |  */
 | 
        
           |  |  | 782 | function full_report($url_params, $symbol_tab, $sort, $run1, $run2) {
 | 
        
           |  |  | 783 |   global $vwbar;
 | 
        
           |  |  | 784 |   global $vbar;
 | 
        
           |  |  | 785 |   global $totals;
 | 
        
           |  |  | 786 |   global $totals_1;
 | 
        
           |  |  | 787 |   global $totals_2;
 | 
        
           |  |  | 788 |   global $metrics;
 | 
        
           |  |  | 789 |   global $diff_mode;
 | 
        
           |  |  | 790 |   global $descriptions;
 | 
        
           |  |  | 791 |   global $sort_col;
 | 
        
           |  |  | 792 |   global $format_cbk;
 | 
        
           |  |  | 793 |   global $display_calls;
 | 
        
           |  |  | 794 |   global $base_path;
 | 
        
           |  |  | 795 |   global $base_url;
 | 
        
           |  |  | 796 |   | 
        
           |  |  | 797 |   $possible_metrics = xhprof_get_possible_metrics();
 | 
        
           |  |  | 798 |   | 
        
           |  |  | 799 |   if ($diff_mode) {
 | 
        
           |  |  | 800 |   | 
        
           |  |  | 801 |     $base_url_params = xhprof_array_unset(xhprof_array_unset($url_params,
 | 
        
           |  |  | 802 |                                                              'run1'),
 | 
        
           |  |  | 803 |                                           'run2');
 | 
        
           |  |  | 804 |     $href1 = "$base_url?" .
 | 
        
           |  |  | 805 |       http_build_query(xhprof_array_set($base_url_params,
 | 
        
           |  |  | 806 |                                         'run', $run1));
 | 
        
           |  |  | 807 |     $href2 = "$base_url?" .
 | 
        
           |  |  | 808 |       http_build_query(xhprof_array_set($base_url_params,
 | 
        
           |  |  | 809 |                                         'run', $run2));
 | 
        
           |  |  | 810 |   | 
        
           |  |  | 811 |     print("<h3><center>Overall Diff Summary</center></h3>");
 | 
        
           |  |  | 812 |     print('<table border=1 cellpadding=2 cellspacing=1 width="30%" '
 | 
        
           |  |  | 813 |           .'rules=rows bordercolor="#bdc7d8" align=center>' . "\n");
 | 
        
           |  |  | 814 |     print('<tr bgcolor="#bdc7d8" align=right>');
 | 
        
           |  |  | 815 |     print("<th></th>");
 | 
        
           |  |  | 816 |     print("<th $vwbar>" . xhprof_render_link("Run #$run1", $href1) . "</th>");
 | 
        
           |  |  | 817 |     print("<th $vwbar>" . xhprof_render_link("Run #$run2", $href2) . "</th>");
 | 
        
           |  |  | 818 |     print("<th $vwbar>Diff</th>");
 | 
        
           |  |  | 819 |     print("<th $vwbar>Diff%</th>");
 | 
        
           |  |  | 820 |     print('</tr>');
 | 
        
           |  |  | 821 |   | 
        
           |  |  | 822 |     if ($display_calls) {
 | 
        
           |  |  | 823 |       print('<tr>');
 | 
        
           |  |  | 824 |       print("<td>Number of Function Calls</td>");
 | 
        
           |  |  | 825 |       print_td_num($totals_1["ct"], $format_cbk["ct"]);
 | 
        
           |  |  | 826 |       print_td_num($totals_2["ct"], $format_cbk["ct"]);
 | 
        
           |  |  | 827 |       print_td_num($totals_2["ct"] - $totals_1["ct"], $format_cbk["ct"], true);
 | 
        
           |  |  | 828 |       print_td_pct($totals_2["ct"] - $totals_1["ct"], $totals_1["ct"], true);
 | 
        
           |  |  | 829 |       print('</tr>');
 | 
        
           |  |  | 830 |     }
 | 
        
           |  |  | 831 |   | 
        
           |  |  | 832 |     foreach ($metrics as $metric) {
 | 
        
           |  |  | 833 |       $m = $metric;
 | 
        
           |  |  | 834 |       print('<tr>');
 | 
        
           |  |  | 835 |       print("<td>" . str_replace("<br>", " ", $descriptions[$m]) . "</td>");
 | 
        
           |  |  | 836 |       print_td_num($totals_1[$m], $format_cbk[$m]);
 | 
        
           |  |  | 837 |       print_td_num($totals_2[$m], $format_cbk[$m]);
 | 
        
           |  |  | 838 |       print_td_num($totals_2[$m] - $totals_1[$m], $format_cbk[$m], true);
 | 
        
           |  |  | 839 |       print_td_pct($totals_2[$m] - $totals_1[$m], $totals_1[$m], true);
 | 
        
           |  |  | 840 |       print('<tr>');
 | 
        
           |  |  | 841 |     }
 | 
        
           |  |  | 842 |     print('</table>');
 | 
        
           |  |  | 843 |   | 
        
           |  |  | 844 |     $callgraph_report_title = '[View Regressions/Improvements using Callgraph Diff]';
 | 
        
           |  |  | 845 |   | 
        
           |  |  | 846 |   } else {
 | 
        
           |  |  | 847 |     print("<p><center>\n");
 | 
        
           |  |  | 848 |   | 
        
           |  |  | 849 |     print('<table cellpadding=2 cellspacing=1 width="30%" '
 | 
        
           |  |  | 850 |           .'bgcolor="#bdc7d8" align=center>' . "\n");
 | 
        
           |  |  | 851 |     echo "<tr>";
 | 
        
           |  |  | 852 |     echo "<th style='text-align:right'>Overall Summary</th>";
 | 
        
           |  |  | 853 |     echo "<th></th>";
 | 
        
           |  |  | 854 |     echo "</tr>";
 | 
        
           |  |  | 855 |   | 
        
           |  |  | 856 |     foreach ($metrics as $metric) {
 | 
        
           |  |  | 857 |       echo "<tr>";
 | 
        
           |  |  | 858 |       echo "<td style='text-align:right; font-weight:bold'>Total "
 | 
        
           |  |  | 859 |             . str_replace("<br>", " ", stat_description($metric)) . ":</td>";
 | 
        
           |  |  | 860 |       echo "<td>" . number_format($totals[$metric]) .  " "
 | 
        
           |  |  | 861 |            . $possible_metrics[$metric][1] . "</td>";
 | 
        
           |  |  | 862 |       echo "</tr>";
 | 
        
           |  |  | 863 |     }
 | 
        
           |  |  | 864 |   | 
        
           |  |  | 865 |     if ($display_calls) {
 | 
        
           |  |  | 866 |       echo "<tr>";
 | 
        
           |  |  | 867 |       echo "<td style='text-align:right; font-weight:bold'>Number of Function Calls:</td>";
 | 
        
           |  |  | 868 |       echo "<td>" . number_format($totals['ct']) . "</td>";
 | 
        
           |  |  | 869 |       echo "</tr>";
 | 
        
           |  |  | 870 |     }
 | 
        
           |  |  | 871 |   | 
        
           |  |  | 872 |     echo "</table>";
 | 
        
           |  |  | 873 |     print("</center></p>\n");
 | 
        
           |  |  | 874 |   | 
        
           |  |  | 875 |     $callgraph_report_title = '[View Full Callgraph]';
 | 
        
           |  |  | 876 |   }
 | 
        
           |  |  | 877 |   | 
        
           |  |  | 878 |   print("<center><br><h3>" .
 | 
        
           |  |  | 879 |         xhprof_render_link($callgraph_report_title,
 | 
        
           |  |  | 880 |                     "$base_path/callgraph.php" . "?" . http_build_query($url_params))
 | 
        
           |  |  | 881 |         . "</h3></center>");
 | 
        
           |  |  | 882 |   | 
        
           |  |  | 883 |   | 
        
           |  |  | 884 |   $flat_data = array();
 | 
        
           |  |  | 885 |   foreach ($symbol_tab as $symbol => $info) {
 | 
        
           |  |  | 886 |     $tmp = $info;
 | 
        
           |  |  | 887 |     $tmp["fn"] = $symbol;
 | 
        
           |  |  | 888 |     $flat_data[] = $tmp;
 | 
        
           |  |  | 889 |   }
 | 
        
           |  |  | 890 |   usort($flat_data, 'sort_cbk');
 | 
        
           |  |  | 891 |   | 
        
           |  |  | 892 |   print("<br>");
 | 
        
           |  |  | 893 |   | 
        
           |  |  | 894 |   if (!empty($url_params['all'])) {
 | 
        
           |  |  | 895 |     $all = true;
 | 
        
           |  |  | 896 |     $limit = 0;    // display all rows
 | 
        
           |  |  | 897 |   } else {
 | 
        
           |  |  | 898 |     $all = false;
 | 
        
           |  |  | 899 |     $limit = 100;  // display only limited number of rows
 | 
        
           |  |  | 900 |   }
 | 
        
           |  |  | 901 |   | 
        
           |  |  | 902 |   $desc = str_replace("<br>", " ", $descriptions[$sort_col]);
 | 
        
           |  |  | 903 |   | 
        
           |  |  | 904 |   if ($diff_mode) {
 | 
        
           |  |  | 905 |     if ($all) {
 | 
        
           |  |  | 906 |       $title = "Total Diff Report: '
 | 
        
           |  |  | 907 |                .'Sorted by absolute value of regression/improvement in $desc";
 | 
        
           |  |  | 908 |     } else {
 | 
        
           |  |  | 909 |       $title = "Top 100 <i style='color:red'>Regressions</i>/"
 | 
        
           |  |  | 910 |                . "<i style='color:green'>Improvements</i>: "
 | 
        
           |  |  | 911 |                . "Sorted by $desc Diff";
 | 
        
           |  |  | 912 |     }
 | 
        
           |  |  | 913 |   } else {
 | 
        
           |  |  | 914 |     if ($all) {
 | 
        
           |  |  | 915 |       $title = "Sorted by $desc";
 | 
        
           |  |  | 916 |     } else {
 | 
        
           |  |  | 917 |       $title = "Displaying top $limit functions: Sorted by $desc";
 | 
        
           |  |  | 918 |     }
 | 
        
           |  |  | 919 |   }
 | 
        
           |  |  | 920 |   print_flat_data($url_params, $title, $flat_data, $sort, $run1, $run2, $limit);
 | 
        
           |  |  | 921 | }
 | 
        
           |  |  | 922 |   | 
        
           |  |  | 923 |   | 
        
           |  |  | 924 | /**
 | 
        
           |  |  | 925 |  * Return attribute names and values to be used by javascript tooltip.
 | 
        
           |  |  | 926 |  */
 | 
        
           |  |  | 927 | function get_tooltip_attributes($type, $metric) {
 | 
        
           |  |  | 928 |   return "type='$type' metric='$metric'";
 | 
        
           |  |  | 929 | }
 | 
        
           |  |  | 930 |   | 
        
           |  |  | 931 | /**
 | 
        
           |  |  | 932 |  * Print info for a parent or child function in the
 | 
        
           |  |  | 933 |  * parent & children report.
 | 
        
           |  |  | 934 |  *
 | 
        
           |  |  | 935 |  * @author Kannan
 | 
        
           |  |  | 936 |  */
 | 
        
           |  |  | 937 | function pc_info($info, $base_ct, $base_info, $parent) {
 | 
        
           |  |  | 938 |   global $sort_col;
 | 
        
           |  |  | 939 |   global $metrics;
 | 
        
           |  |  | 940 |   global $format_cbk;
 | 
        
           |  |  | 941 |   global $display_calls;
 | 
        
           |  |  | 942 |   | 
        
           |  |  | 943 |   if ($parent)
 | 
        
           |  |  | 944 |     $type = "Parent";
 | 
        
           |  |  | 945 |   else $type = "Child";
 | 
        
           |  |  | 946 |   | 
        
           |  |  | 947 |   if ($display_calls) {
 | 
        
           |  |  | 948 |     $mouseoverct = get_tooltip_attributes($type, "ct");
 | 
        
           |  |  | 949 |     /* call count */
 | 
        
           |  |  | 950 |     print_td_num($info["ct"], $format_cbk["ct"], ($sort_col == "ct"), $mouseoverct);
 | 
        
           |  |  | 951 |     print_td_pct($info["ct"], $base_ct, ($sort_col == "ct"), $mouseoverct);
 | 
        
           |  |  | 952 |   }
 | 
        
           |  |  | 953 |   | 
        
           |  |  | 954 |   /* Inclusive metric values  */
 | 
        
           |  |  | 955 |   foreach ($metrics as $metric) {
 | 
        
           |  |  | 956 |     print_td_num($info[$metric], $format_cbk[$metric],
 | 
        
           |  |  | 957 |                  ($sort_col == $metric),
 | 
        
           |  |  | 958 |                  get_tooltip_attributes($type, $metric));
 | 
        
           |  |  | 959 |     print_td_pct($info[$metric], $base_info[$metric], ($sort_col == $metric),
 | 
        
           |  |  | 960 |                  get_tooltip_attributes($type, $metric));
 | 
        
           |  |  | 961 |   }
 | 
        
           |  |  | 962 | }
 | 
        
           |  |  | 963 |   | 
        
           |  |  | 964 | function print_pc_array($url_params, $results, $base_ct, $base_info, $parent,
 | 
        
           |  |  | 965 |                         $run1, $run2) {
 | 
        
           |  |  | 966 |   global $base_url;
 | 
        
           |  |  | 967 |   | 
        
           |  |  | 968 |   // Construct section title
 | 
        
           |  |  | 969 |   if ($parent) {
 | 
        
           |  |  | 970 |     $title = 'Parent function';
 | 
        
           |  |  | 971 |   }
 | 
        
           |  |  | 972 |   else {
 | 
        
           |  |  | 973 |     $title = 'Child function';
 | 
        
           |  |  | 974 |   }
 | 
        
           |  |  | 975 |   if (count($results) > 1) {
 | 
        
           |  |  | 976 |     $title .= 's';
 | 
        
           |  |  | 977 |   }
 | 
        
           |  |  | 978 |   | 
        
           |  |  | 979 |   print("<tr bgcolor='#e0e0ff'><td>");
 | 
        
           |  |  | 980 |   print("<b><i><center>" . $title . "</center></i></b>");
 | 
        
           |  |  | 981 |   print("</td></tr>");
 | 
        
           |  |  | 982 |   | 
        
           |  |  | 983 |   $odd_even = 0;
 | 
        
           |  |  | 984 |   foreach ($results as $info) {
 | 
        
           |  |  | 985 |     $href = "$base_url?" .
 | 
        
           |  |  | 986 |       http_build_query(xhprof_array_set($url_params,
 | 
        
           |  |  | 987 |                                         'symbol', $info["fn"]));
 | 
        
           |  |  | 988 |   | 
        
           |  |  | 989 |     $odd_even = 1 - $odd_even;
 | 
        
           |  |  | 990 |   | 
        
           |  |  | 991 |     if ($odd_even) {
 | 
        
           |  |  | 992 |       print('<tr>');
 | 
        
           |  |  | 993 |     }
 | 
        
           |  |  | 994 |     else {
 | 
        
           |  |  | 995 |       print('<tr bgcolor="#e5e5e5">');
 | 
        
           |  |  | 996 |     }
 | 
        
           |  |  | 997 |   | 
        
           |  |  | 998 |     print("<td>" . xhprof_render_link($info["fn"], $href));
 | 
        
           |  |  | 999 |     print_source_link($info);
 | 
        
           |  |  | 1000 |     print("</td>");
 | 
        
           |  |  | 1001 |     pc_info($info, $base_ct, $base_info, $parent);
 | 
        
           |  |  | 1002 |     print("</tr>");
 | 
        
           |  |  | 1003 |   }
 | 
        
           |  |  | 1004 | }
 | 
        
           |  |  | 1005 |   | 
        
           |  |  | 1006 | function print_source_link($info) {
 | 
        
           |  |  | 1007 |   if (strncmp($info['fn'], 'run_init', 8) && $info['fn'] !== 'main()') {
 | 
        
           |  |  | 1008 |     if (defined('XHPROF_SYMBOL_LOOKUP_URL')) {
 | 
        
           |  |  | 1009 |       $link = xhprof_render_link(
 | 
        
           |  |  | 1010 |         'source',
 | 
        
           |  |  | 1011 |         XHPROF_SYMBOL_LOOKUP_URL . '?symbol='.rawurlencode($info["fn"]));
 | 
        
           |  |  | 1012 |       print(' ('.$link.')');
 | 
        
           |  |  | 1013 |     }
 | 
        
           |  |  | 1014 |   }
 | 
        
           |  |  | 1015 | }
 | 
        
           |  |  | 1016 |   | 
        
           |  |  | 1017 |   | 
        
           |  |  | 1018 | function print_symbol_summary($symbol_info, $stat, $base) {
 | 
        
           |  |  | 1019 |   | 
        
           |  |  | 1020 |   $val = $symbol_info[$stat];
 | 
        
           |  |  | 1021 |   $desc = str_replace("<br>", " ", stat_description($stat));
 | 
        
           |  |  | 1022 |   | 
        
           |  |  | 1023 |   print("$desc: </td>");
 | 
        
           |  |  | 1024 |   print(number_format($val));
 | 
        
           |  |  | 1025 |   print(" (" . pct($val, $base) . "% of overall)");
 | 
        
           |  |  | 1026 |   if (substr($stat, 0, 4) == "excl") {
 | 
        
           |  |  | 1027 |     $func_base = $symbol_info[str_replace("excl_", "", $stat)];
 | 
        
           |  |  | 1028 |     print(" (" . pct($val, $func_base) . "% of this function)");
 | 
        
           |  |  | 1029 |   }
 | 
        
           |  |  | 1030 |   print("<br>");
 | 
        
           |  |  | 1031 | }
 | 
        
           |  |  | 1032 |   | 
        
           |  |  | 1033 | /**
 | 
        
           |  |  | 1034 |  * Generates a report for a single function/symbol.
 | 
        
           |  |  | 1035 |  *
 | 
        
           |  |  | 1036 |  * @author Kannan
 | 
        
           |  |  | 1037 |  */
 | 
        
           |  |  | 1038 | function symbol_report($url_params,
 | 
        
           |  |  | 1039 |                        $run_data, $symbol_info, $sort, $rep_symbol,
 | 
        
           |  |  | 1040 |                        $run1,
 | 
        
           |  |  | 1041 |                        $symbol_info1 = null,
 | 
        
           |  |  | 1042 |                        $run2 = 0,
 | 
        
           |  |  | 1043 |                        $symbol_info2 = null) {
 | 
        
           |  |  | 1044 |   global $vwbar;
 | 
        
           |  |  | 1045 |   global $vbar;
 | 
        
           |  |  | 1046 |   global $totals;
 | 
        
           |  |  | 1047 |   global $pc_stats;
 | 
        
           |  |  | 1048 |   global $sortable_columns;
 | 
        
           |  |  | 1049 |   global $metrics;
 | 
        
           |  |  | 1050 |   global $diff_mode;
 | 
        
           |  |  | 1051 |   global $descriptions;
 | 
        
           |  |  | 1052 |   global $format_cbk;
 | 
        
           |  |  | 1053 |   global $sort_col;
 | 
        
           |  |  | 1054 |   global $display_calls;
 | 
        
           |  |  | 1055 |   global $base_path;
 | 
        
           |  |  | 1056 |   global $base_url;
 | 
        
           |  |  | 1057 |   | 
        
           |  |  | 1058 |   $possible_metrics = xhprof_get_possible_metrics();
 | 
        
           |  |  | 1059 |   | 
        
           |  |  | 1060 |   if ($diff_mode) {
 | 
        
           |  |  | 1061 |     $diff_text = "<b>Diff</b>";
 | 
        
           |  |  | 1062 |     $regr_impr = "<i style='color:red'>Regression</i>/<i style='color:green'>Improvement</i>";
 | 
        
           |  |  | 1063 |   } else {
 | 
        
           |  |  | 1064 |     $diff_text = "";
 | 
        
           |  |  | 1065 |     $regr_impr = "";
 | 
        
           |  |  | 1066 |   }
 | 
        
           |  |  | 1067 |   | 
        
           |  |  | 1068 |   if ($diff_mode) {
 | 
        
           |  |  | 1069 |   | 
        
           |  |  | 1070 |     $base_url_params = xhprof_array_unset(xhprof_array_unset($url_params,
 | 
        
           |  |  | 1071 |                                                              'run1'),
 | 
        
           |  |  | 1072 |                                           'run2');
 | 
        
           |  |  | 1073 |     $href1 = "$base_url?"
 | 
        
           |  |  | 1074 |       . http_build_query(xhprof_array_set($base_url_params, 'run', $run1));
 | 
        
           |  |  | 1075 |     $href2 = "$base_url?"
 | 
        
           |  |  | 1076 |       . http_build_query(xhprof_array_set($base_url_params, 'run', $run2));
 | 
        
           |  |  | 1077 |   | 
        
           |  |  | 1078 |     print("<h3 align=center>$regr_impr summary for $rep_symbol<br><br></h3>");
 | 
        
           |  |  | 1079 |     print('<table border=1 cellpadding=2 cellspacing=1 width="30%" '
 | 
        
           |  |  | 1080 |           .'rules=rows bordercolor="#bdc7d8" align=center>' . "\n");
 | 
        
           |  |  | 1081 |     print('<tr bgcolor="#bdc7d8" align=right>');
 | 
        
           |  |  | 1082 |     print("<th align=left>$rep_symbol</th>");
 | 
        
           |  |  | 1083 |     print("<th $vwbar><a href=" . $href1 . ">Run #$run1</a></th>");
 | 
        
           |  |  | 1084 |     print("<th $vwbar><a href=" . $href2 . ">Run #$run2</a></th>");
 | 
        
           |  |  | 1085 |     print("<th $vwbar>Diff</th>");
 | 
        
           |  |  | 1086 |     print("<th $vwbar>Diff%</th>");
 | 
        
           |  |  | 1087 |     print('</tr>');
 | 
        
           |  |  | 1088 |     print('<tr>');
 | 
        
           |  |  | 1089 |   | 
        
           |  |  | 1090 |     if ($display_calls) {
 | 
        
           |  |  | 1091 |       print("<td>Number of Function Calls</td>");
 | 
        
           |  |  | 1092 |       print_td_num($symbol_info1["ct"], $format_cbk["ct"]);
 | 
        
           |  |  | 1093 |       print_td_num($symbol_info2["ct"], $format_cbk["ct"]);
 | 
        
           |  |  | 1094 |       print_td_num($symbol_info2["ct"] - $symbol_info1["ct"],
 | 
        
           |  |  | 1095 |                    $format_cbk["ct"], true);
 | 
        
           |  |  | 1096 |       print_td_pct($symbol_info2["ct"] - $symbol_info1["ct"],
 | 
        
           |  |  | 1097 |                    $symbol_info1["ct"], true);
 | 
        
           |  |  | 1098 |       print('</tr>');
 | 
        
           |  |  | 1099 |     }
 | 
        
           |  |  | 1100 |   | 
        
           |  |  | 1101 |   | 
        
           |  |  | 1102 |     foreach ($metrics as $metric) {
 | 
        
           |  |  | 1103 |       $m = $metric;
 | 
        
           |  |  | 1104 |   | 
        
           |  |  | 1105 |       // Inclusive stat for metric
 | 
        
           |  |  | 1106 |       print('<tr>');
 | 
        
           |  |  | 1107 |       print("<td>" . str_replace("<br>", " ", $descriptions[$m]) . "</td>");
 | 
        
           |  |  | 1108 |       print_td_num($symbol_info1[$m], $format_cbk[$m]);
 | 
        
           |  |  | 1109 |       print_td_num($symbol_info2[$m], $format_cbk[$m]);
 | 
        
           |  |  | 1110 |       print_td_num($symbol_info2[$m] - $symbol_info1[$m], $format_cbk[$m], true);
 | 
        
           |  |  | 1111 |       print_td_pct($symbol_info2[$m] - $symbol_info1[$m], $symbol_info1[$m], true);
 | 
        
           |  |  | 1112 |       print('</tr>');
 | 
        
           |  |  | 1113 |   | 
        
           |  |  | 1114 |       // AVG (per call) Inclusive stat for metric
 | 
        
           |  |  | 1115 |       print('<tr>');
 | 
        
           |  |  | 1116 |       print("<td>" . str_replace("<br>", " ", $descriptions[$m]) . " per call </td>");
 | 
        
           |  |  | 1117 |       $avg_info1 = 'N/A';
 | 
        
           |  |  | 1118 |       $avg_info2 = 'N/A';
 | 
        
           |  |  | 1119 |       if ($symbol_info1['ct'] > 0) {
 | 
        
           |  |  | 1120 |         $avg_info1 = ($symbol_info1[$m] / $symbol_info1['ct']);
 | 
        
           |  |  | 1121 |       }
 | 
        
           |  |  | 1122 |       if ($symbol_info2['ct'] > 0) {
 | 
        
           |  |  | 1123 |         $avg_info2 = ($symbol_info2[$m] / $symbol_info2['ct']);
 | 
        
           |  |  | 1124 |       }
 | 
        
           |  |  | 1125 |       print_td_num($avg_info1, $format_cbk[$m]);
 | 
        
           |  |  | 1126 |       print_td_num($avg_info2, $format_cbk[$m]);
 | 
        
           |  |  | 1127 |       print_td_num($avg_info2 - $avg_info1, $format_cbk[$m], true);
 | 
        
           |  |  | 1128 |       print_td_pct($avg_info2 - $avg_info1, $avg_info1, true);
 | 
        
           |  |  | 1129 |       print('</tr>');
 | 
        
           |  |  | 1130 |   | 
        
           |  |  | 1131 |       // Exclusive stat for metric
 | 
        
           |  |  | 1132 |       $m = "excl_" . $metric;
 | 
        
           |  |  | 1133 |       print('<tr style="border-bottom: 1px solid black;">');
 | 
        
           |  |  | 1134 |       print("<td>" . str_replace("<br>", " ", $descriptions[$m]) . "</td>");
 | 
        
           |  |  | 1135 |       print_td_num($symbol_info1[$m], $format_cbk[$m]);
 | 
        
           |  |  | 1136 |       print_td_num($symbol_info2[$m], $format_cbk[$m]);
 | 
        
           |  |  | 1137 |       print_td_num($symbol_info2[$m] - $symbol_info1[$m], $format_cbk[$m], true);
 | 
        
           |  |  | 1138 |       print_td_pct($symbol_info2[$m] - $symbol_info1[$m], $symbol_info1[$m], true);
 | 
        
           |  |  | 1139 |       print('</tr>');
 | 
        
           |  |  | 1140 |     }
 | 
        
           |  |  | 1141 |   | 
        
           |  |  | 1142 |     print('</table>');
 | 
        
           |  |  | 1143 |   }
 | 
        
           |  |  | 1144 |   | 
        
           |  |  | 1145 |   print("<br><h4><center>");
 | 
        
           |  |  | 1146 |   print("Parent/Child $regr_impr report for <b>$rep_symbol</b>");
 | 
        
           |  |  | 1147 |   | 
        
           |  |  | 1148 |   $callgraph_href = "$base_path/callgraph.php?"
 | 
        
           |  |  | 1149 |     . http_build_query(xhprof_array_set($url_params, 'func', $rep_symbol));
 | 
        
           |  |  | 1150 |   | 
        
           |  |  | 1151 |   print(" <a href='$callgraph_href'>[View Callgraph $diff_text]</a><br>");
 | 
        
           |  |  | 1152 |   | 
        
           |  |  | 1153 |   print("</center></h4><br>");
 | 
        
           |  |  | 1154 |   | 
        
           |  |  | 1155 |   print('<table border=1 cellpadding=2 cellspacing=1 width="90%" '
 | 
        
           |  |  | 1156 |         .'rules=rows bordercolor="#bdc7d8" align=center>' . "\n");
 | 
        
           |  |  | 1157 |   print('<tr bgcolor="#bdc7d8" align=right>');
 | 
        
           |  |  | 1158 |   | 
        
           |  |  | 1159 |   foreach ($pc_stats as $stat) {
 | 
        
           |  |  | 1160 |     $desc = stat_description($stat);
 | 
        
           |  |  | 1161 |     if (array_key_exists($stat, $sortable_columns)) {
 | 
        
           |  |  | 1162 |   | 
        
           |  |  | 1163 |       $href = "$base_url?" .
 | 
        
           |  |  | 1164 |         http_build_query(xhprof_array_set($url_params,
 | 
        
           |  |  | 1165 |                                           'sort', $stat));
 | 
        
           |  |  | 1166 |       $header = xhprof_render_link($desc, $href);
 | 
        
           |  |  | 1167 |     } else {
 | 
        
           |  |  | 1168 |       $header = $desc;
 | 
        
           |  |  | 1169 |     }
 | 
        
           |  |  | 1170 |   | 
        
           |  |  | 1171 |     if ($stat == "fn")
 | 
        
           |  |  | 1172 |       print("<th align=left><nobr>$header</th>");
 | 
        
           |  |  | 1173 |     else print("<th " . $vwbar . "><nobr>$header</th>");
 | 
        
           |  |  | 1174 |   }
 | 
        
           |  |  | 1175 |   print("</tr>");
 | 
        
           |  |  | 1176 |   | 
        
           |  |  | 1177 |   print("<tr bgcolor='#e0e0ff'><td>");
 | 
        
           |  |  | 1178 |   print("<b><i><center>Current Function</center></i></b>");
 | 
        
           |  |  | 1179 |   print("</td></tr>");
 | 
        
           |  |  | 1180 |   | 
        
           |  |  | 1181 |   print("<tr>");
 | 
        
           |  |  | 1182 |   // make this a self-reference to facilitate copy-pasting snippets to e-mails
 | 
        
           |  |  | 1183 |   print("<td><a href=''>$rep_symbol</a>");
 | 
        
           |  |  | 1184 |   print_source_link(array('fn' => $rep_symbol));
 | 
        
           |  |  | 1185 |   print("</td>");
 | 
        
           |  |  | 1186 |   | 
        
           |  |  | 1187 |   if ($display_calls) {
 | 
        
           |  |  | 1188 |     // Call Count
 | 
        
           |  |  | 1189 |     print_td_num($symbol_info["ct"], $format_cbk["ct"]);
 | 
        
           |  |  | 1190 |     print_td_pct($symbol_info["ct"], $totals["ct"]);
 | 
        
           |  |  | 1191 |   }
 | 
        
           |  |  | 1192 |   | 
        
           |  |  | 1193 |   // Inclusive Metrics for current function
 | 
        
           |  |  | 1194 |   foreach ($metrics as $metric) {
 | 
        
           |  |  | 1195 |     print_td_num($symbol_info[$metric], $format_cbk[$metric], ($sort_col == $metric));
 | 
        
           |  |  | 1196 |     print_td_pct($symbol_info[$metric], $totals[$metric], ($sort_col == $metric));
 | 
        
           |  |  | 1197 |   }
 | 
        
           |  |  | 1198 |   print("</tr>");
 | 
        
           |  |  | 1199 |   | 
        
           |  |  | 1200 |   print("<tr bgcolor='#ffffff'>");
 | 
        
           |  |  | 1201 |   print("<td style='text-align:right;color:blue'>"
 | 
        
           |  |  | 1202 |         ."Exclusive Metrics $diff_text for Current Function</td>");
 | 
        
           |  |  | 1203 |   | 
        
           |  |  | 1204 |   if ($display_calls) {
 | 
        
           |  |  | 1205 |     // Call Count
 | 
        
           |  |  | 1206 |     print("<td $vbar></td>");
 | 
        
           |  |  | 1207 |     print("<td $vbar></td>");
 | 
        
           |  |  | 1208 |   }
 | 
        
           |  |  | 1209 |   | 
        
           |  |  | 1210 |   // Exclusive Metrics for current function
 | 
        
           |  |  | 1211 |   foreach ($metrics as $metric) {
 | 
        
           |  |  | 1212 |     print_td_num($symbol_info["excl_" . $metric], $format_cbk["excl_" . $metric],
 | 
        
           |  |  | 1213 |                  ($sort_col == $metric),
 | 
        
           |  |  | 1214 |                  get_tooltip_attributes("Child", $metric));
 | 
        
           |  |  | 1215 |     print_td_pct($symbol_info["excl_" . $metric], $symbol_info[$metric],
 | 
        
           |  |  | 1216 |                  ($sort_col == $metric),
 | 
        
           |  |  | 1217 |                  get_tooltip_attributes("Child", $metric));
 | 
        
           |  |  | 1218 |   }
 | 
        
           |  |  | 1219 |   print("</tr>");
 | 
        
           |  |  | 1220 |   | 
        
           |  |  | 1221 |   // list of callers/parent functions
 | 
        
           |  |  | 1222 |   $results = array();
 | 
        
           |  |  | 1223 |   if ($display_calls) {
 | 
        
           |  |  | 1224 |     $base_ct = $symbol_info["ct"];
 | 
        
           |  |  | 1225 |   } else {
 | 
        
           |  |  | 1226 |     $base_ct = 0;
 | 
        
           |  |  | 1227 |   }
 | 
        
           |  |  | 1228 |   foreach ($metrics as $metric) {
 | 
        
           |  |  | 1229 |     $base_info[$metric] = $symbol_info[$metric];
 | 
        
           |  |  | 1230 |   }
 | 
        
           |  |  | 1231 |   foreach ($run_data as $parent_child => $info) {
 | 
        
           |  |  | 1232 |     list($parent, $child) = xhprof_parse_parent_child($parent_child);
 | 
        
           |  |  | 1233 |     if (($child == $rep_symbol) && ($parent)) {
 | 
        
           |  |  | 1234 |       $info_tmp = $info;
 | 
        
           |  |  | 1235 |       $info_tmp["fn"] = $parent;
 | 
        
           |  |  | 1236 |       $results[] = $info_tmp;
 | 
        
           |  |  | 1237 |     }
 | 
        
           |  |  | 1238 |   }
 | 
        
           |  |  | 1239 |   usort($results, 'sort_cbk');
 | 
        
           |  |  | 1240 |   | 
        
           |  |  | 1241 |   if (count($results) > 0) {
 | 
        
           |  |  | 1242 |     print_pc_array($url_params, $results, $base_ct, $base_info, true,
 | 
        
           |  |  | 1243 |                    $run1, $run2);
 | 
        
           |  |  | 1244 |   }
 | 
        
           |  |  | 1245 |   | 
        
           |  |  | 1246 |   // list of callees/child functions
 | 
        
           |  |  | 1247 |   $results = array();
 | 
        
           |  |  | 1248 |   $base_ct = 0;
 | 
        
           |  |  | 1249 |   foreach ($run_data as $parent_child => $info) {
 | 
        
           |  |  | 1250 |     list($parent, $child) = xhprof_parse_parent_child($parent_child);
 | 
        
           |  |  | 1251 |     if ($parent == $rep_symbol) {
 | 
        
           |  |  | 1252 |       $info_tmp = $info;
 | 
        
           |  |  | 1253 |       $info_tmp["fn"] = $child;
 | 
        
           |  |  | 1254 |       $results[] = $info_tmp;
 | 
        
           |  |  | 1255 |       if ($display_calls) {
 | 
        
           |  |  | 1256 |         $base_ct += $info["ct"];
 | 
        
           |  |  | 1257 |       }
 | 
        
           |  |  | 1258 |     }
 | 
        
           |  |  | 1259 |   }
 | 
        
           |  |  | 1260 |   usort($results, 'sort_cbk');
 | 
        
           |  |  | 1261 |   | 
        
           |  |  | 1262 |   if (count($results)) {
 | 
        
           |  |  | 1263 |     print_pc_array($url_params, $results, $base_ct, $base_info, false,
 | 
        
           |  |  | 1264 |                    $run1, $run2);
 | 
        
           |  |  | 1265 |   }
 | 
        
           |  |  | 1266 |   | 
        
           |  |  | 1267 |   print("</table>");
 | 
        
           |  |  | 1268 |   | 
        
           |  |  | 1269 |   // These will be used for pop-up tips/help.
 | 
        
           |  |  | 1270 |   // Related javascript code is in: xhprof_report.js
 | 
        
           |  |  | 1271 |   print("\n");
 | 
        
           |  |  | 1272 |   print('<script language="javascript">' . "\n");
 | 
        
           |  |  | 1273 |   print("var func_name = '\"" . $rep_symbol . "\"';\n");
 | 
        
           |  |  | 1274 |   print("var total_child_ct  = " . $base_ct . ";\n");
 | 
        
           |  |  | 1275 |   if ($display_calls) {
 | 
        
           |  |  | 1276 |     print("var func_ct   = " . $symbol_info["ct"] . ";\n");
 | 
        
           |  |  | 1277 |   }
 | 
        
           |  |  | 1278 |   print("var func_metrics = new Array();\n");
 | 
        
           |  |  | 1279 |   print("var metrics_col  = new Array();\n");
 | 
        
           |  |  | 1280 |   print("var metrics_desc  = new Array();\n");
 | 
        
           |  |  | 1281 |   if ($diff_mode) {
 | 
        
           |  |  | 1282 |     print("var diff_mode = true;\n");
 | 
        
           |  |  | 1283 |   } else {
 | 
        
           |  |  | 1284 |     print("var diff_mode = false;\n");
 | 
        
           |  |  | 1285 |   }
 | 
        
           |  |  | 1286 |   $column_index = 3; // First three columns are Func Name, Calls, Calls%
 | 
        
           |  |  | 1287 |   foreach ($metrics as $metric) {
 | 
        
           |  |  | 1288 |     print("func_metrics[\"" . $metric . "\"] = " . round($symbol_info[$metric]) . ";\n");
 | 
        
           |  |  | 1289 |     print("metrics_col[\"". $metric . "\"] = " . $column_index . ";\n");
 | 
        
           |  |  | 1290 |     print("metrics_desc[\"". $metric . "\"] = \"" . $possible_metrics[$metric][2] . "\";\n");
 | 
        
           |  |  | 1291 |   | 
        
           |  |  | 1292 |     // each metric has two columns..
 | 
        
           |  |  | 1293 |     $column_index += 2;
 | 
        
           |  |  | 1294 |   }
 | 
        
           |  |  | 1295 |   print('</script>');
 | 
        
           |  |  | 1296 |   print("\n");
 | 
        
           |  |  | 1297 |   | 
        
           |  |  | 1298 | }
 | 
        
           |  |  | 1299 |   | 
        
           |  |  | 1300 | /**
 | 
        
           |  |  | 1301 |  * Generate the profiler report for a single run.
 | 
        
           |  |  | 1302 |  *
 | 
        
           |  |  | 1303 |  * @author Kannan
 | 
        
           |  |  | 1304 |  */
 | 
        
           |  |  | 1305 | function profiler_single_run_report ($url_params,
 | 
        
           |  |  | 1306 |                                      $xhprof_data,
 | 
        
           |  |  | 1307 |                                      $run_desc,
 | 
        
           |  |  | 1308 |                                      $rep_symbol,
 | 
        
           |  |  | 1309 |                                      $sort,
 | 
        
           |  |  | 1310 |                                      $run) {
 | 
        
           |  |  | 1311 |   | 
        
           |  |  | 1312 |   init_metrics($xhprof_data, $rep_symbol, $sort, false);
 | 
        
           |  |  | 1313 |   | 
        
           |  |  | 1314 |   profiler_report($url_params, $rep_symbol, $sort, $run, $run_desc,
 | 
        
           |  |  | 1315 |                   $xhprof_data);
 | 
        
           |  |  | 1316 | }
 | 
        
           |  |  | 1317 |   | 
        
           |  |  | 1318 |   | 
        
           |  |  | 1319 |   | 
        
           |  |  | 1320 | /**
 | 
        
           |  |  | 1321 |  * Generate the profiler report for diff mode (delta between two runs).
 | 
        
           |  |  | 1322 |  *
 | 
        
           |  |  | 1323 |  * @author Kannan
 | 
        
           |  |  | 1324 |  */
 | 
        
           |  |  | 1325 | function profiler_diff_report($url_params,
 | 
        
           |  |  | 1326 |                               $xhprof_data1,
 | 
        
           |  |  | 1327 |                               $run1_desc,
 | 
        
           |  |  | 1328 |                               $xhprof_data2,
 | 
        
           |  |  | 1329 |                               $run2_desc,
 | 
        
           |  |  | 1330 |                               $rep_symbol,
 | 
        
           |  |  | 1331 |                               $sort,
 | 
        
           |  |  | 1332 |                               $run1,
 | 
        
           |  |  | 1333 |                               $run2) {
 | 
        
           |  |  | 1334 |   | 
        
           |  |  | 1335 |   | 
        
           |  |  | 1336 |   // Initialize what metrics we'll display based on data in Run2
 | 
        
           |  |  | 1337 |   init_metrics($xhprof_data2, $rep_symbol, $sort, true);
 | 
        
           |  |  | 1338 |   | 
        
           |  |  | 1339 |   profiler_report($url_params,
 | 
        
           |  |  | 1340 |                   $rep_symbol,
 | 
        
           |  |  | 1341 |                   $sort,
 | 
        
           |  |  | 1342 |                   $run1,
 | 
        
           |  |  | 1343 |                   $run1_desc,
 | 
        
           |  |  | 1344 |                   $xhprof_data1,
 | 
        
           |  |  | 1345 |                   $run2,
 | 
        
           |  |  | 1346 |                   $run2_desc,
 | 
        
           |  |  | 1347 |                   $xhprof_data2);
 | 
        
           |  |  | 1348 | }
 | 
        
           |  |  | 1349 |   | 
        
           |  |  | 1350 |   | 
        
           |  |  | 1351 | /**
 | 
        
           |  |  | 1352 |  * Generate a XHProf Display View given the various URL parameters
 | 
        
           |  |  | 1353 |  * as arguments. The first argument is an object that implements
 | 
        
           |  |  | 1354 |  * the iXHProfRuns interface.
 | 
        
           |  |  | 1355 |  *
 | 
        
           |  |  | 1356 |  * @param object  $xhprof_runs_impl  An object that implements
 | 
        
           |  |  | 1357 |  *                                   the iXHProfRuns interface
 | 
        
           |  |  | 1358 |  *.
 | 
        
           |  |  | 1359 |  * @param array   $url_params   Array of non-default URL params.
 | 
        
           |  |  | 1360 |  *
 | 
        
           |  |  | 1361 |  * @param string  $source       Category/type of the run. The source in
 | 
        
           |  |  | 1362 |  *                              combination with the run id uniquely
 | 
        
           |  |  | 1363 |  *                              determines a profiler run.
 | 
        
           |  |  | 1364 |  *
 | 
        
           |  |  | 1365 |  * @param string  $run          run id, or comma separated sequence of
 | 
        
           |  |  | 1366 |  *                              run ids. The latter is used if an aggregate
 | 
        
           |  |  | 1367 |  *                              report of the runs is desired.
 | 
        
           |  |  | 1368 |  *
 | 
        
           |  |  | 1369 |  * @param string  $wts          Comma separate list of integers.
 | 
        
           |  |  | 1370 |  *                              Represents the weighted ratio in
 | 
        
           |  |  | 1371 |  *                              which which a set of runs will be
 | 
        
           |  |  | 1372 |  *                              aggregated. [Used only for aggregate
 | 
        
           |  |  | 1373 |  *                              reports.]
 | 
        
           |  |  | 1374 |  *
 | 
        
           |  |  | 1375 |  * @param string  $symbol       Function symbol. If non-empty then the
 | 
        
           |  |  | 1376 |  *                              parent/child view of this function is
 | 
        
           |  |  | 1377 |  *                              displayed. If empty, a flat-profile view
 | 
        
           |  |  | 1378 |  *                              of the functions is displayed.
 | 
        
           |  |  | 1379 |  *
 | 
        
           |  |  | 1380 |  * @param string  $run1         Base run id (for diff reports)
 | 
        
           |  |  | 1381 |  *
 | 
        
           |  |  | 1382 |  * @param string  $run2         New run id (for diff reports)
 | 
        
           |  |  | 1383 |  *
 | 
        
           |  |  | 1384 |  */
 | 
        
           |  |  | 1385 | function displayXHProfReport($xhprof_runs_impl, $url_params, $source,
 | 
        
           |  |  | 1386 |                              $run, $wts, $symbol, $sort, $run1, $run2) {
 | 
        
           |  |  | 1387 |   | 
        
           |  |  | 1388 |   if ($run) {                              // specific run to display?
 | 
        
           |  |  | 1389 |   | 
        
           |  |  | 1390 |     // run may be a single run or a comma separate list of runs
 | 
        
           |  |  | 1391 |     // that'll be aggregated. If "wts" (a comma separated list
 | 
        
           |  |  | 1392 |     // of integral weights is specified), the runs will be
 | 
        
           |  |  | 1393 |     // aggregated in that ratio.
 | 
        
           |  |  | 1394 |     //
 | 
        
           |  |  | 1395 |     $runs_array = explode(",", $run);
 | 
        
           |  |  | 1396 |   | 
        
           |  |  | 1397 |     if (count($runs_array) == 1) {
 | 
        
           |  |  | 1398 |       $xhprof_data = $xhprof_runs_impl->get_run($runs_array[0],
 | 
        
           |  |  | 1399 |                                                 $source,
 | 
        
           |  |  | 1400 |                                                 $description);
 | 
        
           |  |  | 1401 |     } else {
 | 
        
           |  |  | 1402 |       if (!empty($wts)) {
 | 
        
           |  |  | 1403 |         $wts_array  = explode(",", $wts);
 | 
        
           |  |  | 1404 |       } else {
 | 
        
           |  |  | 1405 |         $wts_array = null;
 | 
        
           |  |  | 1406 |       }
 | 
        
           |  |  | 1407 |       $data = xhprof_aggregate_runs($xhprof_runs_impl,
 | 
        
           |  |  | 1408 |                                     $runs_array, $wts_array, $source, false);
 | 
        
           |  |  | 1409 |       $xhprof_data = $data['raw'];
 | 
        
           |  |  | 1410 |       $description = $data['description'];
 | 
        
           |  |  | 1411 |     }
 | 
        
           |  |  | 1412 |   | 
        
           |  |  | 1413 |   | 
        
           |  |  | 1414 |     profiler_single_run_report($url_params,
 | 
        
           |  |  | 1415 |                                $xhprof_data,
 | 
        
           |  |  | 1416 |                                $description,
 | 
        
           |  |  | 1417 |                                $symbol,
 | 
        
           |  |  | 1418 |                                $sort,
 | 
        
           |  |  | 1419 |                                $run);
 | 
        
           |  |  | 1420 |   | 
        
           |  |  | 1421 |   } else if ($run1 && $run2) {                  // diff report for two runs
 | 
        
           |  |  | 1422 |   | 
        
           |  |  | 1423 |     $xhprof_data1 = $xhprof_runs_impl->get_run($run1, $source, $description1);
 | 
        
           |  |  | 1424 |     $xhprof_data2 = $xhprof_runs_impl->get_run($run2, $source, $description2);
 | 
        
           |  |  | 1425 |   | 
        
           |  |  | 1426 |     profiler_diff_report($url_params,
 | 
        
           |  |  | 1427 |                          $xhprof_data1,
 | 
        
           |  |  | 1428 |                          $description1,
 | 
        
           |  |  | 1429 |                          $xhprof_data2,
 | 
        
           |  |  | 1430 |                          $description2,
 | 
        
           |  |  | 1431 |                          $symbol,
 | 
        
           |  |  | 1432 |                          $sort,
 | 
        
           |  |  | 1433 |                          $run1,
 | 
        
           |  |  | 1434 |                          $run2);
 | 
        
           |  |  | 1435 |   | 
        
           |  |  | 1436 |   } else {
 | 
        
           |  |  | 1437 |     echo "No XHProf runs specified in the URL.";
 | 
        
           |  |  | 1438 |     if (method_exists($xhprof_runs_impl, 'list_runs')) {
 | 
        
           |  |  | 1439 |       $xhprof_runs_impl->list_runs();
 | 
        
           |  |  | 1440 |     }
 | 
        
           |  |  | 1441 |   }
 | 
        
           |  |  | 1442 | }
 |