mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Add the stack_usage.tcl script for analyzing the output of objdump on the
amalgamation and estimating the sizes of stack frames on each function. FossilOrigin-Name: 030013ff0c7af5f146a64f9ede31297ff003e0c4
This commit is contained in:
98
tool/stack_usage.tcl
Normal file
98
tool/stack_usage.tcl
Normal file
@ -0,0 +1,98 @@
|
||||
#!/usr/bin/tclsh
|
||||
#
|
||||
# Parse the output of
|
||||
#
|
||||
# objdump -d sqlite3.o
|
||||
#
|
||||
# for x64 and generate a report showing:
|
||||
#
|
||||
# (1) Stack used by each function
|
||||
# (2) Recursion paths and their aggregate stack depth
|
||||
#
|
||||
set getStack 0
|
||||
while {![eof stdin]} {
|
||||
set line [gets stdin]
|
||||
if {[regexp {^[0-9a-f]+ <([^>]+)>:\s*$} $line all procname]} {
|
||||
set curfunc $procname
|
||||
set root($curfunc) 1
|
||||
set calls($curfunc) {}
|
||||
set calledby($curfunc) {}
|
||||
set recursive($curfunc) {}
|
||||
set stkdepth($curfunc) 0
|
||||
set getStack 1
|
||||
continue
|
||||
}
|
||||
if {[regexp {callq? +[0-9a-z]+ <([^>]+)>} $line all other]} {
|
||||
set key [list $curfunc $other]
|
||||
set callpair($key) 1
|
||||
unset -nocomplain root($curfunc)
|
||||
continue
|
||||
}
|
||||
if {[regexp {sub +\$(0x[0-9a-z]+),%[er]sp} $line all xdepth]} {
|
||||
if {$getStack} {
|
||||
scan $xdepth %x depth
|
||||
set stkdepth($curfunc) $depth
|
||||
set getStack 0
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
puts "****************** Stack Usage By Function ********************"
|
||||
set sdlist {}
|
||||
foreach f [array names stkdepth] {
|
||||
lappend sdlist [list $stkdepth($f) $f]
|
||||
}
|
||||
foreach sd [lsort -integer -decr -index 0 $sdlist] {
|
||||
foreach {depth fname} $sd break
|
||||
puts [format {%6d %s} $depth $fname]
|
||||
}
|
||||
|
||||
puts "****************** Stack Usage By Recursion *******************"
|
||||
foreach key [array names callpair] {
|
||||
foreach {from to} $key break
|
||||
lappend calls($from) $to
|
||||
# lappend calledby($to) $from
|
||||
}
|
||||
proc all_descendents {root} {
|
||||
global calls recursive
|
||||
set todo($root) $root
|
||||
set go 1
|
||||
while {$go} {
|
||||
set go 0
|
||||
foreach f [array names todo] {
|
||||
set path $todo($f)
|
||||
unset todo($f)
|
||||
if {![info exists calls($f)]} continue
|
||||
foreach x $calls($f) {
|
||||
if {$x==$root} {
|
||||
lappend recursive($root) [concat $path $root]
|
||||
} elseif {![info exists d($x)]} {
|
||||
set go 1
|
||||
set todo($x) [concat $path $x]
|
||||
set d($x) 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return [array names d]
|
||||
}
|
||||
set pathlist {}
|
||||
foreach f [array names recursive] {
|
||||
all_descendents $f
|
||||
foreach m $recursive($f) {
|
||||
set depth 0
|
||||
foreach b [lrange $m 0 end-1] {
|
||||
set depth [expr {$depth+$stkdepth($b)}]
|
||||
}
|
||||
lappend pathlist [list $depth $m]
|
||||
}
|
||||
}
|
||||
foreach path [lsort -integer -decr -index 0 $pathlist] {
|
||||
foreach {depth m} $path break
|
||||
set first [lindex $m 0]
|
||||
puts [format {%6d %s %d} $depth $first $stkdepth($first)]
|
||||
foreach b [lrange $m 1 end] {
|
||||
puts " $b $stkdepth($b)"
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user