File: jit-profiler.rst

package info (click to toggle)
pypy3 7.0.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 111,848 kB
  • sloc: python: 1,291,746; ansic: 74,281; asm: 5,187; cpp: 3,017; sh: 2,533; makefile: 544; xml: 243; lisp: 45; csh: 21; awk: 4
file content (79 lines) | stat: -rw-r--r-- 2,313 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
A JIT-aware profiler
====================

Goal: have a profiler which is aware of the PyPy JIT and which shows which
percentage of the time have been spent in which loops.

Long term goal: integrate the data collected by the profiler with the
jitviewer.

The idea is record an event in the PYPYLOG everytime we enter and exit a loop
or a bridge.

Expected output
----------------

[100] {jit-profile-enter
loop1      # e.g. an entry bridge
[101] jit-profile-enter}
...
[200] {jit-profile-enter
loop0      # JUMP from loop1 to loop0
[201] jit-profile-enter}
...
[500] {jit-profile-exit
loop0      # e.g. because of a failing guard
[501] jit-profile-exit}

In this example, the exiting from loop1 is implicit because we are entering
loop0.  So, we spent 200-100=100 ticks in the entry bridge, and 500-200=300
ticks in the actual loop.

What to do about "inner" bridges?
----------------------------------

"Inner bridges" are those bridges which jump back to the loop where they
originate from.  There are two possible ways of dealing with them:

  1. we ignore them: we record when we enter the loop, but not when we jump to
     a compiled inner bridge.  The exit event will be recorded only in case of
     a non-compiled guard failure or a JUMP to another loop

  2. we record the enter/exit of each inner bridge

The disadvantage of solution (2) is that there are certain loops which takes
bridges at everty single iteration.  So, in this case we would record a huge
number of events, possibly adding a lot of overhead and thus making the
profiled data useless.


Detecting the enter to/exit from a loop
----------------------------------------

Ways to enter:

    - just after the tracing/compilation

    - from the interpreter, if the loop has already been compiled

    - from another loop, via a JUMP operation

    - from a hot guard failure (which we ignore, in case we choose solution
      (1) above)

    - XXX: am I missing anything?

Ways to exit:

    - guard failure (entering blackhole)

    - guard failure (jumping to a bridge) (ignored in case of solution (1))

    - jump to another loop

    - XXX: am I missing anything?


About call_assembler: I think that at the beginning, we should just ignore
call_assembler: the time spent inside the call will be accounted to the loop
calling it.