#!/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.rst 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:
