summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoroetting <jacob@oettinger.dk>2008-04-23 07:43:33 +0000
committeroetting <jacob@oettinger.dk>2008-04-23 07:43:33 +0000
commitd24dba24bd911b63234fa66e491471b79ac9d9d3 (patch)
treee51e11b7c6f99a506d0ccdac67f5c9eefecb7bf7
parent7b5eb58718604441c7652295eba1a569c38bed0d (diff)
downloadwebgrind-d24dba24bd911b63234fa66e491471b79ac9d9d3.zip
webgrind-d24dba24bd911b63234fa66e491471b79ac9d9d3.tar.gz
webgrind-d24dba24bd911b63234fa66e491471b79ac9d9d3.tar.bz2
Now showing both called from and sub calls in detailed information
-rw-r--r--index.php16
-rw-r--r--js/jquery.pack.js (renamed from js/jquery-1.2.3.pack.js)0
-rw-r--r--library/Preprocessor.php36
-rw-r--r--library/Reader.php44
-rw-r--r--templates/index.phtml70
5 files changed, 110 insertions, 56 deletions
diff --git a/index.php b/index.php
index 2ffa766..895e87d 100644
--- a/index.php
+++ b/index.php
@@ -68,17 +68,25 @@ switch(get('op')){
$functionNr = get('functionNr');
$function = $reader->getFunctionInfo($functionNr);
- $result = array('invocations'=>array());
+ $result = array('calledFrom'=>array(), 'subCalls'=>array());
$foundInvocations = 0;
- for($i=0;$i<$function['callInfoCount'];$i++){
- $invo = $reader->getCallInfo($functionNr, $i, get('costFormat', 'absolute'));
+ for($i=0;$i<$function['calledFromInfoCount'];$i++){
+ $invo = $reader->getCalledFromInfo($functionNr, $i, get('costFormat', 'absolute'));
$foundInvocations += $invo['callCount'];
$callerInfo = $reader->getFunctionInfo($invo['functionNr'], get('costFormat', 'absolute'));
$invo['callerFile'] = $callerInfo['file'];
$invo['callerFunctionName'] = $callerInfo['functionName'];
- $result['invocations'][] = $invo;
+ $result['calledFrom'][] = $invo;
}
$result['calledByHost'] = ($foundInvocations<$function['invocationCount']);
+
+ for($i=0;$i<$function['subCallInfoCount'];$i++){
+ $invo = $reader->getSubCallInfo($functionNr, $i, get('costFormat', 'absolute'));
+ $callInfo = $reader->getFunctionInfo($invo['functionNr'], get('costFormat', 'absolute'));
+ $invo['callerFile'] = $callInfo['file'];
+ $invo['callerFunctionName'] = $callInfo['functionName'];
+ $result['subCalls'][] = $invo;
+ }
echo json_encode($result);
break;
diff --git a/js/jquery-1.2.3.pack.js b/js/jquery.pack.js
index 74cdfee..74cdfee 100644
--- a/js/jquery-1.2.3.pack.js
+++ b/js/jquery.pack.js
diff --git a/library/Preprocessor.php b/library/Preprocessor.php
index 39ea943..5022431 100644
--- a/library/Preprocessor.php
+++ b/library/Preprocessor.php
@@ -16,11 +16,11 @@ class Webgrind_Preprocessor
/**
* Fileformat version. Embedded in the output for parsers to use.
*/
- const FILE_FORMAT_VERSION = 5;
+ const FILE_FORMAT_VERSION = 6;
/**
* Binary number format used.
- * @see http://dk2.php.net/pack
+ * @see http://php.net/pack
*/
const NR_FORMAT = 'V';
@@ -54,6 +54,7 @@ class Webgrind_Preprocessor
$nextFuncNr = 0;
$functions = array();
$headers = array();
+ $calls = array();
// Read information into memory
@@ -62,7 +63,7 @@ class Webgrind_Preprocessor
// Found invocation of function. Read functionname
list($function) = fscanf($in,"fn=%s");
if(!isset($functions[$function])){
- $functions[$function] = array('filename'=>substr(trim($line),3), 'invocationCount'=>0,'nr'=>$nextFuncNr++,'count'=>0,'summedSelfCost'=>0,'summedInclusiveCost'=>0,'callInformation'=>array());
+ $functions[$function] = array('filename'=>substr(trim($line),3), 'invocationCount'=>0,'nr'=>$nextFuncNr++,'count'=>0,'summedSelfCost'=>0,'summedInclusiveCost'=>0,'calledFromInformation'=>array(),'subCallInformation'=>array());
}
$functions[$function]['invocationCount']++;
// Special case for ENTRY_POINT - it contains summary header
@@ -85,11 +86,18 @@ class Webgrind_Preprocessor
$functions[$function]['summedInclusiveCost'] += $cost;
- if(!isset($functions[$calledFunctionName]['callInformation'][$function.':'.$lnr]))
- $functions[$calledFunctionName]['callInformation'][$function.':'.$lnr] = array('functionNr'=>$functions[$function]['nr'],'line'=>$lnr,'callCount'=>0,'summedCallCost'=>0);
+ if(!isset($functions[$calledFunctionName]['calledFromInformation'][$function.':'.$lnr]))
+ $functions[$calledFunctionName]['calledFromInformation'][$function.':'.$lnr] = array('functionNr'=>$functions[$function]['nr'],'line'=>$lnr,'callCount'=>0,'summedCallCost'=>0);
+
+ $functions[$calledFunctionName]['calledFromInformation'][$function.':'.$lnr]['callCount']++;
+ $functions[$calledFunctionName]['calledFromInformation'][$function.':'.$lnr]['summedCallCost'] += $cost;
+
+ if(!isset($functions[$function]['subCallInformation'][$calledFunctionName.':'.$lnr]))
+ $functions[$function]['subCallInformation'][$calledFunctionName.':'.$lnr] = array('functionNr'=>$functions[$calledFunctionName]['nr'],'line'=>$lnr,'callCount'=>0,'summedCallCost'=>0);
+
+ $functions[$function]['subCallInformation'][$calledFunctionName.':'.$lnr]['callCount']++;
+ $functions[$function]['subCallInformation'][$calledFunctionName.':'.$lnr]['summedCallCost'] += $cost;
- $functions[$calledFunctionName]['callInformation'][$function.':'.$lnr]['callCount']++;
- $functions[$calledFunctionName]['callInformation'][$function.':'.$lnr]['summedCallCost'] += $cost;
} else if(strpos($line,': ')!==false){
// Found header
@@ -106,12 +114,18 @@ class Webgrind_Preprocessor
$functionAddresses = array();
foreach($functions as $functionName => $function){
$functionAddresses[] = ftell($out);
- $calledFromCount = sizeof($function['callInformation']);
- fwrite($out, pack(self::NR_FORMAT.'*', $function['summedSelfCost'], $function['summedInclusiveCost'], $function['invocationCount'], $calledFromCount));
- // Write call information
- foreach($function['callInformation'] as $call){
+ $calledFromCount = sizeof($function['calledFromInformation']);
+ $subCallCount = sizeof($function['subCallInformation']);
+ fwrite($out, pack(self::NR_FORMAT.'*', $function['summedSelfCost'], $function['summedInclusiveCost'], $function['invocationCount'], $calledFromCount, $subCallCount));
+ // Write called from information
+ foreach($function['calledFromInformation'] as $call){
fwrite($out, pack(self::NR_FORMAT.'*', $call['functionNr'], $call['line'], $call['callCount'], $call['summedCallCost']));
}
+ // Write sub call information
+ foreach($function['subCallInformation'] as $call){
+ fwrite($out, pack(self::NR_FORMAT.'*', $call['functionNr'], $call['line'], $call['callCount'], $call['summedCallCost']));
+ }
+
fwrite($out, $function['filename']."\n".$functionName."\n");
}
$headersPos = ftell($out);
diff --git a/library/Reader.php b/library/Reader.php
index dbd348c..f4a3232 100644
--- a/library/Reader.php
+++ b/library/Reader.php
@@ -10,7 +10,7 @@ class Webgrind_Reader
/**
* File format version that this reader understands
*/
- const FILE_FORMAT_VERSION = 5;
+ const FILE_FORMAT_VERSION = 6;
/**
* Binary number format used.
@@ -94,9 +94,9 @@ class Webgrind_Reader
function getFunctionInfo($nr, $costFormat = 'absolute'){
$this->seek($this->functionPos[$nr]);
- list($summedSelfCost, $summedInclusiveCost, $invocationCount, $calledFromCount) = $this->read(4);
+ list($summedSelfCost, $summedInclusiveCost, $invocationCount, $calledFromCount, $subCallCount) = $this->read(5);
- $this->seek(self::NR_SIZE*self::CALLINFORMATION_LENGTH*$calledFromCount, SEEK_CUR);
+ $this->seek(self::NR_SIZE*self::CALLINFORMATION_LENGTH*($calledFromCount+$subCallCount), SEEK_CUR);
$file = $this->readLine();
$function = $this->readLine();
@@ -106,7 +106,8 @@ class Webgrind_Reader
'summedSelfCost'=>$summedSelfCost,
'summedInclusiveCost'=>$summedInclusiveCost,
'invocationCount'=>$invocationCount,
- 'callInfoCount'=>$calledFromCount
+ 'calledFromInfoCount'=>$calledFromCount,
+ 'subCallInfoCount'=>$subCallCount
);
if ($costFormat == 'percentual') {
$result['summedSelfCost'] = $this->percentCost($result['summedSelfCost']);
@@ -124,9 +125,38 @@ class Webgrind_Reader
* @param $costFormat Format to return costs in. 'absolute' (default) or 'percentual'
* @return array Called from information
*/
- function getCallInfo($functionNr, $calledFromNr, $costFormat = 'absolute'){
- // 4 = number of numbers before a call information
- $this->seek($this->functionPos[$functionNr]+self::NR_SIZE*(self::CALLINFORMATION_LENGTH*$calledFromNr+4));
+ function getCalledFromInfo($functionNr, $calledFromNr, $costFormat = 'absolute'){
+ // 5 = number of numbers before called from information
+ $this->seek($this->functionPos[$functionNr]+self::NR_SIZE*(self::CALLINFORMATION_LENGTH*$calledFromNr+5));
+ $data = $this->read(self::CALLINFORMATION_LENGTH);
+
+ $result = array(
+ 'functionNr'=>$data[0],
+ 'line'=>$data[1],
+ 'callCount'=>$data[2],
+ 'summedCallCost'=>$data[3]
+ );
+
+ if ($costFormat == 'percentual') {
+ $result['summedCallCost'] = $this->percentCost($result['summedCallCost']);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns information about functions called by a function
+ *
+ * @param $functionNr int Function number
+ * @param $subCallNr int Sub call position nr
+ * @param $costFormat Format to return costs in. 'absolute' (default) or 'percentual'
+ * @return array Sub call information
+ */
+ function getSubCallInfo($functionNr, $subCallNr, $costFormat = 'absolute'){
+ // 4 = number of numbers before sub call count
+ $this->seek($this->functionPos[$functionNr]+self::NR_SIZE*3);
+ $calledFromInfoCount = $this->read();
+ $this->seek( ( ($calledFromInfoCount+$subCallNr) * self::CALLINFORMATION_LENGTH + 1 ) * self::NR_SIZE,SEEK_CUR);
$data = $this->read(self::CALLINFORMATION_LENGTH);
$result = array(
diff --git a/templates/index.phtml b/templates/index.phtml
index 60f4e71..345a2fd 100644
--- a/templates/index.phtml
+++ b/templates/index.phtml
@@ -5,7 +5,7 @@
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>webgrind</title>
<link rel="stylesheet" type="text/css" href="styles/style.css" />
- <script src="js/jquery-1.2.3.pack.js" type="text/javascript" charset="utf-8"></script>
+ <script src="js/jquery.pack.js" type="text/javascript" charset="utf-8"></script>
<script src="js/jquery.blockUI.js" type="text/javascript" charset="utf-8"></script>
<script src="js/jquery.tablesorter.js" type="text/javascript" charset="utf-8"></script>
<script src="js/jquery.selectboxes.js" type="text/javascript" charset="utf-8"></script>
@@ -71,50 +71,52 @@
{'op':'callinfo_list', 'file':currentDataFile, 'functionNr':functionNr, 'costFormat':$("#costFormat").val()},
function(data){
- if(!callInfoLoaded[functionNr]){
- if(data.invocations.length>0)
- $("#callinfo_area_"+functionNr).append(callInfoTable(functionNr));
- if(data.calledByHost){
- $("#callinfo_area_"+functionNr).append('Called by script host');
- }
-
- }
-
- for(i=0;i<data.invocations.length;i++){
- $("#callinfo_table_"+functionNr+" tbody").append(callInfoTableRow(i, data.invocations[i]));
- }
-
- if(data.invocations.length>0){
- $("#callinfo_table_"+functionNr).tablesorter({
- widgets: ['zebra'],
- headers: {
- 3: {
- sorter: false
- }
- }
- });
- $("#callinfo_table_"+functionNr).bind("sortStart",sortBlock).bind("sortEnd",$.unblockUI);
- $("#callinfo_table_"+functionNr).trigger("sorton",[[[2,1]]]);
-
-
- }
-
+ insertCallInfo(functionNr, 'sub_calls_table_', 'Calls', data.subCalls);
+ insertCallInfo(functionNr, 'called_from_table_', 'Called From', data.calledFrom);
+
+ if(data.calledByHost)
+ $("#callinfo_area_"+functionNr).append('Called by script host');
+
callInfoLoaded[functionNr] = true;
}
);
}
- function callInfoTable(functionNr){
- return '<table class="tablesorter" id="callinfo_table_'+functionNr+'" cellspacing="0"> \
- <thead><tr><th>Called from</th><th>Count</th><th>Total Call Cost</th><th> </th></tr></thead> \
+ function insertCallInfo(functionNr, idPrefix, title, data){
+ if(data.length==0)
+ return;
+
+ $("#callinfo_area_"+functionNr).append(callTable(functionNr,idPrefix, title));
+
+ for(i=0;i<data.length;i++){
+ $("#"+idPrefix+functionNr+" tbody").append(callTableRow(i, data[i]));
+ }
+
+ $("#"+idPrefix+functionNr).tablesorter({
+ widgets: ['zebra'],
+ headers: {
+ 3: {
+ sorter: false
+ }
+ }
+ });
+ $("#"+idPrefix+functionNr).bind("sortStart",sortBlock).bind("sortEnd",$.unblockUI);
+ $("#"+idPrefix+functionNr).trigger("sorton",[[[2,1]]]);
+
+
+ }
+
+ function callTable(functionNr, idPrefix, title){
+ return '<table class="tablesorter" id="'+idPrefix+functionNr+'" cellspacing="0"> \
+ <thead><tr><th>'+title+'</th><th>Count</th><th>Total Call Cost</th><th> </th></tr></thead> \
<tbody> \
</tbody> \
</table> \
';
}
- function callInfoTableRow(nr,data){
+ function callTableRow(nr,data){
return '<tr> \
<td>'+data.callerFunctionName+' @ '+data.line+'</td> \
<td class="nr">'+data.callCount+'</td> \
@@ -123,7 +125,7 @@
</tr>';
}
-
+
function toggleCallInfo(functionNr){
if(!callInfoLoaded[functionNr]){
loadCallInfo(functionNr);