#! /usr/bin/python2
#
# Copyright 2016 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#

import argparse
import collections
import re
import subprocess
import sys


__DESCRIPTION = """
Processes a perf.data sample file and reports the hottest Ignition bytecodes,
or write an input file for flamegraph.pl.
"""


__HELP_EPILOGUE = """
examples:
  # Get a flamegraph for Ignition bytecode handlers on Octane benchmark,
  # without considering the time spent compiling JS code, entry trampoline
  # samples and other non-Ignition samples.
  #
  $ tools/run-perf.sh out/x64.release/d8 --noopt run.js
  $ tools/ignition/linux_perf_report.py --flamegraph -o out.collapsed
  $ flamegraph.pl --colors js out.collapsed > out.svg

  # Same as above, but show all samples, including time spent compiling JS code,
  # entry trampoline samples and other samples.
  $ # ...
  $ tools/ignition/linux_perf_report.py \\
      --flamegraph --show-all -o out.collapsed
  $ # ...

  # Same as above, but show full function signatures in the flamegraph.
  $ # ...
  $ tools/ignition/linux_perf_report.py \\
      --flamegraph --show-full-signatures -o out.collapsed
  $ # ...

  # See the hottest bytecodes on Octane benchmark, by number of samples.
  #
  $ tools/run-perf.sh out/x64.release/d8 --noopt octane/run.js
  $ tools/ignition/linux_perf_report.py
"""


COMPILER_SYMBOLS_RE = re.compile(
  r"v8::internal::(?:\(anonymous namespace\)::)?Compile|v8::internal::Parser")
JIT_CODE_SYMBOLS_RE = re.compile(
  r"(LazyCompile|Compile|Eval|Script):(\*|~)")
GC_SYMBOLS_RE = re.compile(
  r"v8::internal::Heap::CollectGarbage")


def strip_function_parameters(symbol):
  if symbol[-1] != ')': return symbol
  pos = 1
  parenthesis_count = 0
  for c in reversed(symbol):
    if c == ')':
      parenthesis_count += 1
    elif c == '(':
      parenthesis_count -= 1
    if parenthesis_count == 0:
      break
    else:
      pos += 1
  return symbol[:-pos]


def collapsed_callchains_generator(perf_stream, hide_other=False,
                                   hide_compiler=False, hide_jit=False,
                                   hide_gc=False, show_full_signatures=False):
  current_chain = []
  skip_until_end_of_chain = False
  compiler_symbol_in_chain = False

  for line in perf_stream:
    # Lines starting with a "#" are comments, skip them.
    if line[0] == "#":
      continue

    line = line.strip()

    # Empty line signals the end of the callchain.
    if not line:
      if (not skip_until_end_of_chain and current_chain
          and not hide_other):
        current_chain.append("[other]")
        yield current_chain
      # Reset parser status.
      current_chain = []
      skip_until_end_of_chain = False
      compiler_symbol_in_chain = False
      continue

    if skip_until_end_of_chain:
      continue

    # Trim the leading address and the trailing +offset, if present.
    symbol = line.split(" ", 1)[1].split("+", 1)[0]
    if not show_full_signatures:
      symbol = strip_function_parameters(symbol)

    # Avoid chains of [unknown]
    if (symbol == "[unknown]" and current_chain and
        current_chain[-1] == "[unknown]"):
      continue

    current_chain.append(symbol)

    if symbol.startswith("BytecodeHandler:"):
      current_chain.append("[interpreter]")
      yield current_chain
      skip_until_end_of_chain = True
    elif JIT_CODE_SYMBOLS_RE.match(symbol):
      if not hide_jit:
        current_chain.append("[jit]")
        yield current_chain
        skip_until_end_of_chain = True
    elif GC_SYMBOLS_RE.match(symbol):
      if not hide_gc:
        current_chain.append("[gc]")
        yield current_chain
        skip_until_end_of_chain = True
    elif symbol == "Stub:CEntryStub" and compiler_symbol_in_chain:
      if not hide_compiler:
        current_chain.append("[compiler]")
        yield current_chain
      skip_until_end_of_chain = True
    elif COMPILER_SYMBOLS_RE.match(symbol):
      compiler_symbol_in_chain = True
    elif symbol == "Builtin:InterpreterEntryTrampoline":
      if len(current_chain) == 1:
        yield ["[entry trampoline]"]
      else:
        # If we see an InterpreterEntryTrampoline which is not at the top of the
        # chain and doesn't have a BytecodeHandler above it, then we have
        # skipped the top BytecodeHandler due to the top-level stub not building
        # a frame. File the chain in the [misattributed] bucket.
        current_chain[-1] = "[misattributed]"
        yield current_chain
      skip_until_end_of_chain = True


def calculate_samples_count_per_callchain(callchains):
  chain_counters = collections.defaultdict(int)
  for callchain in callchains:
    key = ";".join(reversed(callchain))
    chain_counters[key] += 1
  return chain_counters.items()


def calculate_samples_count_per_handler(callchains):
  def strip_handler_prefix_if_any(handler):
    return handler if handler[0] == "[" else handler.split(":", 1)[1]

  handler_counters = collections.defaultdict(int)
  for callchain in callchains:
    handler = strip_handler_prefix_if_any(callchain[-1])
    handler_counters[handler] += 1
  return handler_counters.items()


def write_flamegraph_input_file(output_stream, callchains):
  for callchain, count in calculate_samples_count_per_callchain(callchains):
    output_stream.write("{}; {}\n".format(callchain, count))


def write_handlers_report(output_stream, callchains):
  handler_counters = calculate_samples_count_per_handler(callchains)
  samples_num = sum(counter for _, counter in handler_counters)
  # Sort by decreasing number of samples
  handler_counters.sort(key=lambda entry: entry[1], reverse=True)
  for bytecode_name, count in handler_counters:
    output_stream.write(
      "{}\t{}\t{:.3f}%\n".format(bytecode_name, count,
                                 100. * count / samples_num))


def parse_command_line():
  command_line_parser = argparse.ArgumentParser(
    formatter_class=argparse.RawDescriptionHelpFormatter,
    description=__DESCRIPTION,
    epilog=__HELP_EPILOGUE)

  command_line_parser.add_argument(
    "perf_filename",
    help="perf sample file to process (default: perf.data)",
    nargs="?",
    default="perf.data",
    metavar="<perf filename>"
  )
  command_line_parser.add_argument(
    "--flamegraph", "-f",
    help="output an input file for flamegraph.pl, not a report",
    action="store_true",
    dest="output_flamegraph"
  )
  command_line_parser.add_argument(
    "--hide-other",
    help="Hide other samples",
    action="store_true"
  )
  command_line_parser.add_argument(
    "--hide-compiler",
    help="Hide samples during compilation",
    action="store_true"
  )
  command_line_parser.add_argument(
    "--hide-jit",
    help="Hide samples from JIT code execution",
    action="store_true"
  )
  command_line_parser.add_argument(
    "--hide-gc",
    help="Hide samples from garbage collection",
    action="store_true"
  )
  command_line_parser.add_argument(
    "--show-full-signatures", "-s",
    help="show full signatures instead of function names",
    action="store_true"
  )
  command_line_parser.add_argument(
    "--output", "-o",
    help="output file name (stdout if omitted)",
    type=argparse.FileType('wt'),
    default=sys.stdout,
    metavar="<output filename>",
    dest="output_stream"
  )

  return command_line_parser.parse_args()


def main():
  program_options = parse_command_line()

  perf = subprocess.Popen(["perf", "script", "--fields", "ip,sym",
                           "-i", program_options.perf_filename],
                          stdout=subprocess.PIPE)

  callchains = collapsed_callchains_generator(
    perf.stdout, program_options.hide_other, program_options.hide_compiler,
    program_options.hide_jit, program_options.hide_gc,
    program_options.show_full_signatures)

  if program_options.output_flamegraph:
    write_flamegraph_input_file(program_options.output_stream, callchains)
  else:
    write_handlers_report(program_options.output_stream, callchains)


if __name__ == "__main__":
  main()
