#!/usr/bin/env python
"""
Some helper functions to analyze the output of sys.getdxp() (which is
only available if Python was built with -DDYNAMIC_EXECUTION_PROFILE).
These will tell you which opcodes have been executed most frequently
in the current process, and, if Python was also built with -DDXPAIRS,
will tell you which instruction _pairs_ were executed most frequently,
which may help in choosing new instructions.

If Python was built without -DDYNAMIC_EXECUTION_PROFILE, importing
this module will raise a RuntimeError.

If you're running a script you want to profile, a simple way to get
the common pairs is:

$ PYTHONPATH=$PYTHONPATH:<python_srcdir>/Tools/scripts \
./python -i -O the_script.py --args
...
> from analyze_dxp import *
> s = render_common_pairs()
> open('/tmp/some_file', 'w').write(s)
"""

import copy
import opcode
import operator
import sys
import threading

if not hasattr(sys, "getdxp"):
    raise RuntimeError("Can't import analyze_dxp: Python built without"
                       " -DDYNAMIC_EXECUTION_PROFILE.")


_profile_lock = threading.RLock()
_cumulative_profile = sys.getdxp()

# If Python was built with -DDXPAIRS, sys.getdxp() returns a list of
# lists of ints.  Otherwise it returns just a list of ints.
def has_pairs(profile):
    """Returns True if the Python that produced the argument profile
    was built with -DDXPAIRS."""

    return len(profile) > 0 and isinstance(profile[0], list)


def reset_profile():
    """Forgets any execution profile that has been gathered so far."""
    with _profile_lock:
        sys.getdxp()  # Resets the internal profile
        global _cumulative_profile
        _cumulative_profile = sys.getdxp()  # 0s out our copy.


def merge_profile():
    """Reads sys.getdxp() and merges it into this module's cached copy.

    We need this because sys.getdxp() 0s itself every time it's called."""

    with _profile_lock:
        new_profile = sys.getdxp()
        if has_pairs(new_profile):
            for first_inst in range(len(_cumulative_profile)):
                for second_inst in range(len(_cumulative_profile[first_inst])):
                    _cumulative_profile[first_inst][second_inst] += (
                        new_profile[first_inst][second_inst])
        else:
            for inst in range(len(_cumulative_profile)):
                _cumulative_profile[inst] += new_profile[inst]


def snapshot_profile():
    """Returns the cumulative execution profile until this call."""
    with _profile_lock:
        merge_profile()
        return copy.deepcopy(_cumulative_profile)


def common_instructions(profile):
    """Returns the most common opcodes in order of descending frequency.

    The result is a list of tuples of the form
      (opcode, opname, # of occurrences)

    """
    if has_pairs(profile) and profile:
        inst_list = profile[-1]
    else:
        inst_list = profile
    result = [(op, opcode.opname[op], count)
              for op, count in enumerate(inst_list)
              if count > 0]
    result.sort(key=operator.itemgetter(2), reverse=True)
    return result


def common_pairs(profile):
    """Returns the most common opcode pairs in order of descending frequency.

    The result is a list of tuples of the form
      ((1st opcode, 2nd opcode),
       (1st opname, 2nd opname),
       # of occurrences of the pair)

    """
    if not has_pairs(profile):
        return []
    result = [((op1, op2), (opcode.opname[op1], opcode.opname[op2]), count)
              # Drop the row of single-op profiles with [:-1]
              for op1, op1profile in enumerate(profile[:-1])
              for op2, count in enumerate(op1profile)
              if count > 0]
    result.sort(key=operator.itemgetter(2), reverse=True)
    return result


def render_common_pairs(profile=None):
    """Renders the most common opcode pairs to a string in order of
    descending frequency.

    The result is a series of lines of the form:
      # of occurrences: ('1st opname', '2nd opname')

    """
    if profile is None:
        profile = snapshot_profile()
    def seq():
        for _, ops, count in common_pairs(profile):
            yield "%s: %s\n" % (count, ops)
    return ''.join(seq())
