1#! /bin/bash -u
2# Copyright 2015 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6# This script first collects the addresses of the instructions being tracked by
7# the profile. After that, it calculates the offset of the addresses compared
8# to the base address and then gets the number of execution times for each
9# address. After that, it draws the heat map and the time map. A heap map shows
10# the overall hotness of instructions being executed while the time map shows the
11# hotness of instruction at different time.
12
13# binary : the name of the binary
14# profile : output of 'perf report -D'
15# loading_address  : the loading address of the binary
16# page_size : the size to be displayed, usually 4096(byte).
17
18if [[ $# -ne 4 ]]; then
19     echo 'Illegal number of parameters' exit 1
20fi
21
22binary=$1
23profile=$2
24loading_address=$3
25page_size=$4
26
27# size of binary supported.
28binary_maximum=1000000000
29
30if ! [[ -e $profile ]] ; then
31     echo "error: profile does not exist" >&2; exit 1
32fi
33
34re='^[0-9]+$'
35if ! [[ $page_size =~ $re ]] ; then
36     echo "error: page_size is not a number" >&2; exit 1
37fi
38
39function test {
40    "$@"
41    local status=$?
42    if [ $status -ne 0 ]; then
43        echo "error with $1" >&2
44    fi
45    return $status
46}
47
48HEAT_PNG="heat_map.png"
49TIMELINE_PNG="timeline.png"
50
51test  grep -A 2 PERF_RECORD_SAMPLE $profile | grep -A 1 -B 1 "thread: $binary" | \
52grep -B 2 "dso.*$binary$" | awk -v base=$loading_address \
53     "BEGIN { count=0; } /PERF_RECORD_SAMPLE/ {addr = strtonum(\$8) - strtonum(base); \
54     if (addr < $binary_maximum) count++; \
55     if (addr < $binary_maximum) print \$7,count,int(addr/$page_size)*$page_size}" >  out.txt
56
57
58test  awk '{print $3}' out.txt | sort -n | uniq -c > inst-histo.txt
59
60# generate inst heat map
61echo "
62set terminal png size 600,450
63set xlabel \"Instruction Virtual Address (MB)\"
64set ylabel \"Sample Occurance\"
65set grid
66
67set output \"${HEAT_PNG}\"
68set title \"Instruction Heat Map\"
69
70plot 'inst-histo.txt' using (\$2/1024/1024):1 with impulses notitle
71" | test gnuplot
72
73# generate instruction page access timeline
74num=$(awk 'END {print NR+1}' out.txt)
75
76echo "
77set terminal png size 600,450
78set xlabel \"time (sec)\"
79set ylabel \"Instruction Virtual Address (MB)\"
80
81set output \"${TIMELINE_PNG}\"
82set title \"instruction page accessd timeline\"
83
84plot 'out.txt' using (\$0/$num*10):(\$3/1024/1024) with dots notitle
85" | test gnuplot
86