#!/usr/bin/env python
#
# Copyright 2012 VMware Inc
# Copyright 2008-2009 Jose Fonseca
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#

"""Perf annotate for JIT code.

Linux `perf annotate` does not work with JIT code.  This script takes the data
produced by `perf script` command, plus the diassemblies outputed by gallivm
into /tmp/perf-XXXXX.map.asm and produces output similar to `perf annotate`.

See docs/llvmpipe.html for usage instructions.

The `perf script` output parser was derived from the gprof2dot.py script.
"""


import sys
import os.path
import re
import optparse
import subprocess


class Parser:
    """Parser interface."""

    def __init__(self):
        pass

    def parse(self):
        raise NotImplementedError


class LineParser(Parser):
    """Base class for parsers that read line-based formats."""

    def __init__(self, file):
        Parser.__init__(self)
        self._file = file
        self.__line = None
        self.__eof = False
        self.line_no = 0

    def readline(self):
        line = self._file.readline()
        if not line:
            self.__line = ''
            self.__eof = True
        else:
            self.line_no += 1
        self.__line = line.rstrip('\r\n')

    def lookahead(self):
        assert self.__line is not None
        return self.__line

    def consume(self):
        assert self.__line is not None
        line = self.__line
        self.readline()
        return line

    def eof(self):
        assert self.__line is not None
        return self.__eof


mapFile = None

def lookupMap(filename, matchSymbol):
    global mapFile
    mapFile = filename
    stream = open(filename, 'rt')
    for line in stream:
        start, length, symbol = line.split()

        start = int(start, 16)
        length = int(length,16)

        if symbol == matchSymbol:
            return start

    return None

def lookupAsm(filename, desiredFunction):
    stream = open(filename + '.asm', 'rt')
    while stream.readline() != desiredFunction + ':\n':
        pass

    asm = []
    line = stream.readline().strip()
    while line:
        addr, instr = line.split(':', 1)
        addr = int(addr)
        asm.append((addr, instr))
        line = stream.readline().strip()

    return asm



samples = {}


class PerfParser(LineParser):
    """Parser for linux perf callgraph output.

    It expects output generated with

        perf record -g
        perf script
    """

    def __init__(self, infile, symbol):
        LineParser.__init__(self, infile)
        self.symbol = symbol

    def readline(self):
        # Override LineParser.readline to ignore comment lines
        while True:
            LineParser.readline(self)
            if self.eof() or not self.lookahead().startswith('#'):
                break

    def parse(self):
        # read lookahead
        self.readline()

        while not self.eof():
            self.parse_event()

        asm = lookupAsm(mapFile, self.symbol)

        addresses = samples.keys()
        addresses.sort()
        total_samples = 0

        sys.stdout.write('%s:\n' % self.symbol)
        for address, instr in asm:
            try:
                sample = samples.pop(address)
            except KeyError:
                sys.stdout.write(6*' ')
            else:
                sys.stdout.write('%6u' % (sample))
                total_samples += sample
            sys.stdout.write('%6u: %s\n' % (address, instr))
        print 'total:', total_samples
        assert len(samples) == 0

        sys.exit(0)

    def parse_event(self):
        if self.eof():
            return

        line = self.consume()
        assert line

        callchain = self.parse_callchain()
        if not callchain:
            return

    def parse_callchain(self):
        callchain = []
        while self.lookahead():
            function = self.parse_call(len(callchain) == 0)
            if function is None:
                break
            callchain.append(function)
        if self.lookahead() == '':
            self.consume()
        return callchain

    call_re = re.compile(r'^\s+(?P<address>[0-9a-fA-F]+)\s+(?P<symbol>.*)\s+\((?P<module>[^)]*)\)$')

    def parse_call(self, first):
        line = self.consume()
        mo = self.call_re.match(line)
        assert mo
        if not mo:
            return None

        if not first:
            return None

        function_name = mo.group('symbol')
        if not function_name:
            function_name = mo.group('address')

        module = mo.group('module')

        function_id = function_name + ':' + module

        address = mo.group('address')
        address = int(address, 16)

        if function_name != self.symbol:
            return None

        start_address = lookupMap(module, function_name)
        address -= start_address

        #print function_name, module, address

        samples[address] = samples.get(address, 0) + 1

        return True


def main():
    """Main program."""

    optparser = optparse.OptionParser(
        usage="\n\t%prog [options] symbol_name")
    (options, args) = optparser.parse_args(sys.argv[1:])
    if len(args) != 1:
        optparser.error('wrong number of arguments')

    symbol = args[0]

    p = subprocess.Popen(['perf', 'script'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    parser = PerfParser(p.stdout, symbol)
    parser.parse()


if __name__ == '__main__':
    main()


# vim: set sw=4 et:
