B
    18\W                 @   s   d Z ddlZddlZddlZddlZddlZeeds>ede Z	e
 add Zdd Zd	d
 Zdd Zdd Zdd ZdddZdS )a  
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)
    NgetdxpzKCan't import analyze_dxp: Python built without -DDYNAMIC_EXECUTION_PROFILE.c             C   s   t | dkot| d tS )z[Returns True if the Python that produced the argument profile
    was built with -DDXPAIRS.r   )len
isinstancelist)profile r   Y/oak/stanford/groups/akundaje/marinovg/programs/Python-3.7.3/Tools/scripts/analyze_dxp.py	has_pairs'   s    r	   c            	   C   s$   t  t  t aW dQ R X dS )z<Forgets any execution profile that has been gathered so far.N)_profile_locksysr   _cumulative_profiler   r   r   r   reset_profile.   s    r   c           	   C   s   t  t } t| rdxvtttD ]:}x4ttt| D ] }t| |  | | | 7  < q:W q$W n*x(tttD ]}t|  | | 7  < qrW W dQ R X dS )zReads sys.getdxp() and merges it into this module's cached copy.

    We need this because sys.getdxp() 0s itself every time it's called.N)r
   r   r   r	   ranger   r   )Znew_profileZ
first_instZsecond_instinstr   r   r   merge_profile6   s    r   c            	   C   s    t  t  ttS Q R X dS )z9Returns the cumulative execution profile until this call.N)r
   r   copydeepcopyr   r   r   r   r   snapshot_profileG   s    r   c             C   sD   t | r| r| d }n| }dd t|D }|jtddd |S )zReturns the most common opcodes in order of descending frequency.

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

    c             S   s(   g | ] \}}|d kr|t j| |fqS )r   )opcodeopname).0opcountr   r   r   
<listcomp>Y   s   z'common_instructions.<locals>.<listcomp>   T)keyreverse)r	   	enumeratesortoperator
itemgetter)r   Z	inst_listresultr   r   r   common_instructionsN   s    
r#   c             C   s>   t | sg S dd t| dd D }|jtddd |S )zReturns 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)

    c             S   sH   g | ]@\}}t |D ].\}}|d kr||ftj| tj| f|fqqS )r   )r   r   r   )r   Zop1Z
op1profileZop2r   r   r   r   r   k   s   z common_pairs.<locals>.<listcomp>Nr   r   T)r   r   )r	   r   r   r    r!   )r   r"   r   r   r   common_pairs`   s    	r$   c                s&    dkrt    fdd}d| S )zRenders 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')

    Nc              3   s*   x$t  D ]\} }}d||f V  q
W d S )Nz%s: %s
)r$   )_opsr   )r   r   r   seq~   s    z render_common_pairs.<locals>.seq )r   join)r   r'   r   )r   r   render_common_pairst   s    r*   )N)__doc__r   r   r    r   	threadinghasattrRuntimeErrorRLockr
   r   r   r	   r   r   r   r#   r$   r*   r   r   r   r   <module>   s    
