From ada7f44e62ae7919b2f17caa1d463ea7c256a129 Mon Sep 17 00:00:00 2001 From: Daniel Beardsley Date: Fri, 3 Nov 2023 00:50:02 -0700 Subject: [PATCH 1/6] Preprocessor.php: break up some long lines Easier to read / maintian this way. --- library/Preprocessor.php | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/library/Preprocessor.php b/library/Preprocessor.php index 8535910..55b89bf 100644 --- a/library/Preprocessor.php +++ b/library/Preprocessor.php @@ -139,7 +139,12 @@ static function parse($inFile, $outFile) $key = $index.$lnr; if (!isset($functions[$calledIndex]['calledFromInformation'][$key])) { - $functions[$calledIndex]['calledFromInformation'][$key] = array('functionNr'=>$index,'line'=>$lnr,'callCount'=>0,'summedCallCost'=>0); + $functions[$calledIndex]['calledFromInformation'][$key] = array( + 'functionNr'=>$index, + 'line'=>$lnr, + 'callCount'=>0, + 'summedCallCost'=>0, + ); } $functions[$calledIndex]['calledFromInformation'][$key]['callCount']++; @@ -147,7 +152,12 @@ static function parse($inFile, $outFile) $calledKey = $calledIndex.$lnr; if (!isset($functions[$index]['subCallInformation'][$calledKey])) { - $functions[$index]['subCallInformation'][$calledKey] = array('functionNr'=>$calledIndex,'line'=>$lnr,'callCount'=>0,'summedCallCost'=>0); + $functions[$index]['subCallInformation'][$calledKey] = array( + 'functionNr'=>$calledIndex, + 'line'=>$lnr, + 'callCount'=>0, + 'summedCallCost'=>0, + ); } $functions[$index]['subCallInformation'][$calledKey]['callCount']++; @@ -171,14 +181,27 @@ static function parse($inFile, $outFile) $functionAddresses[] = ftell($out); $calledFromCount = sizeof($function['calledFromInformation']); $subCallCount = sizeof($function['subCallInformation']); - fwrite($out, pack(self::NR_FORMAT.'*', $function['line'], $function['summedSelfCost'], $function['summedInclusiveCost'], $function['invocationCount'], $calledFromCount, $subCallCount)); + fwrite($out, pack(self::NR_FORMAT.'*', + $function['line'], + $function['summedSelfCost'], + $function['summedInclusiveCost'], + $function['invocationCount'], + $calledFromCount, $subCallCount)); // Write called from information foreach ((array)$function['calledFromInformation'] as $call) { - fwrite($out, pack(self::NR_FORMAT.'*', $call['functionNr'], $call['line'], $call['callCount'], $call['summedCallCost'])); + fwrite($out, pack(self::NR_FORMAT.'*', + $call['functionNr'], + $call['line'], + $call['callCount'], + $call['summedCallCost'])); } // Write sub call information foreach ((array)$function['subCallInformation'] as $call) { - fwrite($out, pack(self::NR_FORMAT.'*', $call['functionNr'], $call['line'], $call['callCount'], $call['summedCallCost'])); + fwrite($out, pack(self::NR_FORMAT.'*', + $call['functionNr'], + $call['line'], + $call['callCount'], + $call['summedCallCost'])); } fwrite($out, $function['filename']."\n".$functionNames[$index]."\n"); From 648de4c3884dcaf4f4781ff5c2185d4a2523d4da Mon Sep 17 00:00:00 2001 From: Daniel Beardsley Date: Fri, 3 Nov 2023 02:53:00 -0700 Subject: [PATCH 2/6] PHP 8 fixes (no undefined properties). --- library/FileHandler.php | 2 +- library/Reader.php | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/library/FileHandler.php b/library/FileHandler.php index d09ac9f..ee9d4a9 100644 --- a/library/FileHandler.php +++ b/library/FileHandler.php @@ -11,7 +11,7 @@ class Webgrind_FileHandler { private static $singleton = null; - + private $files; /** * @return Singleton instance of the filehandler diff --git a/library/Reader.php b/library/Reader.php index 3742131..f4f4e17 100644 --- a/library/Reader.php +++ b/library/Reader.php @@ -61,6 +61,8 @@ class Webgrind_Reader */ private $costFormat; + private $fp; + /** * Constructor From b638910ae157cf815441a57f4ebff985d69eec57 Mon Sep 17 00:00:00 2001 From: Daniel Beardsley Date: Fri, 3 Nov 2023 02:54:30 -0700 Subject: [PATCH 3/6] Support Memory in cachegrind files. Xdebug has supported memory for a while, but this tool hadn't been updated to use it. Here we add a new "costFormat" option of "bytes of memory". We pass this through to the pre-processor to have it read the memory cost field instead of the time cost field. --- library/FileHandler.php | 6 ++++-- library/Preprocessor.php | 11 ++++++----- library/Reader.php | 4 ++++ templates/index.phtml | 1 + 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/library/FileHandler.php b/library/FileHandler.php index ee9d4a9..103001a 100644 --- a/library/FileHandler.php +++ b/library/FileHandler.php @@ -160,12 +160,14 @@ public function getTraceList() { * @return Webgrind_Reader Reader for $file */ public function getTraceReader($file, $costFormat) { - $prepFile = Webgrind_Config::storageDir().$file.Webgrind_Config::$preprocessedSuffix; + $readMemory = $costFormat === 'bytes'; + $memorySuffix = $readMemory ? ".memory" : ""; + $prepFile = Webgrind_Config::storageDir().$file.$memorySuffix.Webgrind_Config::$preprocessedSuffix; try { $r = new Webgrind_Reader($prepFile, $costFormat); } catch (Exception $e) { // Preprocessed file does not exist or other error - Webgrind_Preprocessor::parse(Webgrind_Config::xdebugOutputDir().$file, $prepFile); + Webgrind_Preprocessor::parse(Webgrind_Config::xdebugOutputDir().$file, $prepFile, $readMemory); $r = new Webgrind_Reader($prepFile, $costFormat); } return $r; diff --git a/library/Preprocessor.php b/library/Preprocessor.php index 55b89bf..e3d5ccc 100644 --- a/library/Preprocessor.php +++ b/library/Preprocessor.php @@ -42,8 +42,9 @@ class Webgrind_Preprocessor * @param string $outFile File to write preprocessed data to * @return void */ - static function parse($inFile, $outFile) + static function parse($inFile, $outFile, $readMemory = false) { + $costPattern = $readMemory ? "%*d %d" : "%d"; // If possible, use the binary preprocessor if (self::binaryParse($inFile, $outFile)) { return; @@ -74,17 +75,17 @@ static function parse($inFile, $outFile) $buffer = fgets($in); if(strlen($buffer) > 0 && ctype_digit($buffer[0])) { // Cost line - sscanf($buffer, "%d %d", $lnr, $cost); + sscanf($buffer, "%d $costPattern", $lnr, $cost); } else { // Special case for ENTRY_POINT - it contains summary header $headers[] = fgets($in); fgets($in); // Cost line - fscanf($in, "%d %d", $lnr, $cost); + fscanf($in, "%d $costPattern", $lnr, $cost); } } else { // Cost line - fscanf($in, "%d %d", $lnr, $cost); + fscanf($in, "%d $costPattern", $lnr, $cost); } if (!isset($functionNames[$function])) { @@ -114,7 +115,7 @@ static function parse($inFile, $outFile) // Skip call line fgets($in); // Cost line - fscanf($in, "%d %d", $lnr, $cost); + fscanf($in, "%d $costPattern", $lnr, $cost); // Current function is a proxy -> skip if (isset($proxyQueue[$index])) { diff --git a/library/Reader.php b/library/Reader.php index f4f4e17..e3129e4 100644 --- a/library/Reader.php +++ b/library/Reader.php @@ -231,6 +231,10 @@ function formatCost($cost, $format=null) { if ($format==null) $format = $this->costFormat; + if ($format == 'bytes') { + return number_format($cost, 0, '.', ','); + } + if ($format == 'percent') { $total = $this->getHeader('summary'); $result = ($total==0) ? 0 : ($cost*100)/$total; diff --git a/templates/index.phtml b/templates/index.phtml index f4e8a0b..c88494d 100644 --- a/templates/index.phtml +++ b/templates/index.phtml @@ -386,6 +386,7 @@ +
From b5aa9f673e9741605b40c516b551496eb40e0f30 Mon Sep 17 00:00:00 2001 From: Daniel Beardsley Date: Fri, 3 Nov 2023 09:31:14 -0700 Subject: [PATCH 4/6] Preprocessor.cpp: read memory usage if asked Just like the PHP pre-processor, we read the memory if costFormat == 'bytes'. --- library/Preprocessor.php | 6 +++--- library/preprocessor.cpp | 12 +++++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/library/Preprocessor.php b/library/Preprocessor.php index e3d5ccc..5a7fbd6 100644 --- a/library/Preprocessor.php +++ b/library/Preprocessor.php @@ -46,7 +46,7 @@ static function parse($inFile, $outFile, $readMemory = false) { $costPattern = $readMemory ? "%*d %d" : "%d"; // If possible, use the binary preprocessor - if (self::binaryParse($inFile, $outFile)) { + if (self::binaryParse($inFile, $outFile, $readMemory)) { return; } @@ -257,14 +257,14 @@ static function getCompressedName($name, $isFile) * @param string $outFile File to write preprocessed data to * @return bool True if binary preprocessor was executed */ - static function binaryParse($inFile, $outFile) + static function binaryParse($inFile, $outFile, $readMemory) { $preprocessor = Webgrind_Config::getBinaryPreprocessor(); if (!is_executable($preprocessor)) { return false; } - $cmd = escapeshellarg($preprocessor).' '.escapeshellarg($inFile).' '.escapeshellarg($outFile); + $cmd = escapeshellarg($preprocessor).' '.escapeshellarg($inFile).' '.escapeshellarg($outFile).' '.($readMemory ? '1' : '0'); foreach (Webgrind_Config::$proxyFunctions as $function) { $cmd .= ' '.escapeshellarg($function); } diff --git a/library/preprocessor.cpp b/library/preprocessor.cpp index cc8494c..d2f0008 100644 --- a/library/preprocessor.cpp +++ b/library/preprocessor.cpp @@ -125,7 +125,7 @@ class Webgrind_Preprocessor * @param outFile File to write preprocessed data to * @param proxyFunctions Functions to skip, treated as proxies */ - void parse(const char* inFile, const char* outFile, std::vector& proxyFunctions) + void parse(const char* inFile, const char* outFile, bool readMemory, std::vector& proxyFunctions) { #ifdef WITH_ZLIB igzstream in(inFile); @@ -160,6 +160,7 @@ class Webgrind_Preprocessor // Cost line std::istringstream bufferReader(buffer); bufferReader >> lnr >> cost; + if (readMemory) bufferReader >> cost; } else { // Special case for ENTRY_POINT - it contains summary header std::getline(in, buffer); @@ -167,11 +168,13 @@ class Webgrind_Preprocessor std::getline(in, buffer); // Cost line in >> lnr >> cost; + if (readMemory) in >> cost; std::getline(in, buffer); } } else { // Cost line in >> lnr >> cost; + if (readMemory) in >> cost; std::getline(in, buffer); } @@ -200,6 +203,7 @@ class Webgrind_Preprocessor std::getline(in, buffer); // Cost line in >> lnr >> cost; + if (readMemory) in >> cost; std::getline(in, buffer); int calledIndex = funcIndexes[funcCompressedId]; @@ -372,7 +376,7 @@ class Webgrind_Preprocessor int main(int argc, char* argv[]) { - if (argc < 3) { + if (argc < 4) { return 1; } std::vector proxyFunctions; @@ -381,6 +385,8 @@ int main(int argc, char* argv[]) } std::sort(proxyFunctions.begin(), proxyFunctions.end()); Webgrind_Preprocessor processor; - processor.parse(argv[1], argv[2], proxyFunctions); + + bool useMemory = argv[3] == std::string("1"); + processor.parse(argv[1], argv[2], useMemory, proxyFunctions); return 0; } From 0cfb031d033e2d9748005265f5154994c1f200cd Mon Sep 17 00:00:00 2001 From: Daniel Beardsley Date: Mon, 6 Nov 2023 11:57:35 -0800 Subject: [PATCH 5/6] blockUI: handle jQuery upgrade Some other pull upgraded jQuery and that caused this jQuery plugin to crash. Stubbing this "browser" object will allow expressions like "$.browser.ie" to return undefined instead of throwing. --- js/jquery.blockUI.js | 1 + 1 file changed, 1 insertion(+) diff --git a/js/jquery.blockUI.js b/js/jquery.blockUI.js index 2b0a360..b444071 100644 --- a/js/jquery.blockUI.js +++ b/js/jquery.blockUI.js @@ -12,6 +12,7 @@ * http://www.gnu.org/licenses/gpl.html */ (function($) { + $.browser = {}; /** * blockUI provides a mechanism for blocking user interaction with a page (or parts of a page). * This can be an effective way to simulate synchronous behavior during ajax operations without From 30066e67d9653ae2db6ad484dd1cb9a902d6f2a6 Mon Sep 17 00:00:00 2001 From: Daniel Beardsley Date: Mon, 6 Nov 2023 11:59:55 -0800 Subject: [PATCH 6/6] Table sorting: be explicit with column types Previously, the tablesorter was detecting numeric values with thousands separators as "text" and sorting them incorrectly. I added thousands separators for bytes values, so they are easier to read at a glance as the numbers get long but the sorter hadn't been parsing them well. Note: I'm not sure why the "Cost" column was set to "sorter: false" on the subtables, it had still been sorting but it had been falling back to auto-detecting the sort type. --- templates/index.phtml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/templates/index.phtml b/templates/index.phtml index c88494d..3bde416 100644 --- a/templates/index.phtml +++ b/templates/index.phtml @@ -161,8 +161,9 @@ $("#"+idPrefix+functionNr).tablesorter({ widgets: ['zebra'], headers: { + 2: { sorter: "floating" }, 3: { - sorter: false + sorter: "floating" } } }); @@ -330,7 +331,10 @@ }, 2: { sorter: false - } + }, + 3: { sorter: "floating" }, + 4: { sorter: "floating" }, + 5: { sorter: "floating" }, } }); $("#function_table").bind("sortStart",sortBlock).bind("sortEnd",$.unblockUI);