forked from python/cpython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpycore_instruments.h
More file actions
137 lines (107 loc) · 4.68 KB
/
pycore_instruments.h
File metadata and controls
137 lines (107 loc) · 4.68 KB
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#ifndef Py_INTERNAL_INSTRUMENT_H
#define Py_INTERNAL_INSTRUMENT_H
#ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define"
#endif
#include "pycore_structs.h" // _Py_CODEUNIT
#include "pycore_typedefs.h" // _PyInterpreterFrame
#ifdef __cplusplus
extern "C" {
#endif
typedef uint32_t _PyMonitoringEventSet;
/* Tool IDs */
/* These are defined in PEP 669 for convenience to avoid clashes */
#define PY_MONITORING_DEBUGGER_ID 0
#define PY_MONITORING_COVERAGE_ID 1
#define PY_MONITORING_PROFILER_ID 2
#define PY_MONITORING_OPTIMIZER_ID 5
/* Internal IDs used to support sys.setprofile() and sys.settrace() */
#define PY_MONITORING_SYS_PROFILE_ID 6
#define PY_MONITORING_SYS_TRACE_ID 7
PyObject *_PyMonitoring_RegisterCallback(int tool_id, int event_id, PyObject *obj);
int _PyMonitoring_SetEvents(int tool_id, _PyMonitoringEventSet events);
int _PyMonitoring_SetLocalEvents(PyCodeObject *code, int tool_id, _PyMonitoringEventSet events);
int _PyMonitoring_GetLocalEvents(PyCodeObject *code, int tool_id, _PyMonitoringEventSet *events);
// these are exported only for other re-generated interpreters to call
PyAPI_FUNC(int)
_Py_call_instrumentation(PyThreadState *tstate, int event,
_PyInterpreterFrame *frame, _Py_CODEUNIT *instr);
PyAPI_FUNC(int)
_Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame,
_Py_CODEUNIT *instr, _Py_CODEUNIT *prev);
PyAPI_FUNC(int)
_Py_call_instrumentation_instruction(
PyThreadState *tstate, _PyInterpreterFrame* frame, _Py_CODEUNIT *instr);
PyAPI_FUNC(_Py_CODEUNIT *)
_Py_call_instrumentation_jump(
_Py_CODEUNIT *instr, PyThreadState *tstate, int event,
_PyInterpreterFrame *frame, _Py_CODEUNIT *src, _Py_CODEUNIT *dest);
PyAPI_FUNC(int)
_Py_call_instrumentation_arg(PyThreadState *tstate, int event,
_PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg);
PyAPI_FUNC(int)
_Py_call_instrumentation_2args(PyThreadState *tstate, int event,
_PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg0, PyObject *arg1);
PyAPI_FUNC(void)
_Py_call_instrumentation_exc2(PyThreadState *tstate, int event,
_PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg0, PyObject *arg1);
PyAPI_DATA(PyObject) _PyInstrumentation_MISSING;
PyAPI_DATA(PyObject) _PyInstrumentation_DISABLE;
/* Total tool ids available */
#define PY_MONITORING_TOOL_IDS 8
/* Count of all local monitoring events */
#define _PY_MONITORING_LOCAL_EVENTS 11
/* Count of all "real" monitoring events (not derived from other events) */
#define _PY_MONITORING_UNGROUPED_EVENTS 16
/* Count of all monitoring events */
#define _PY_MONITORING_EVENTS 19
/* Tables of which tools are active for each monitored event. */
typedef struct _Py_LocalMonitors {
uint8_t tools[_PY_MONITORING_LOCAL_EVENTS];
} _Py_LocalMonitors;
typedef struct _Py_GlobalMonitors {
uint8_t tools[_PY_MONITORING_UNGROUPED_EVENTS];
} _Py_GlobalMonitors;
/* Ancillary data structure used for instrumentation.
Line instrumentation creates this with sufficient
space for one entry per code unit. The total size
of the data will be `bytes_per_entry * Py_SIZE(code)` */
typedef struct {
uint8_t bytes_per_entry;
uint8_t data[1];
} _PyCoLineInstrumentationData;
/* Main data structure used for instrumentation.
* This is allocated when needed for instrumentation
*/
typedef struct _PyCoMonitoringData {
/* Monitoring specific to this code object */
_Py_LocalMonitors local_monitors;
/* Monitoring that is active on this code object */
_Py_LocalMonitors active_monitors;
/* The tools that are to be notified for events for the matching code unit */
uint8_t *tools;
/* The version of tools when they instrument the code */
uintptr_t tool_versions[PY_MONITORING_TOOL_IDS];
/* Information to support line events */
_PyCoLineInstrumentationData *lines;
/* The tools that are to be notified for line events for the matching code unit */
uint8_t *line_tools;
/* Information to support instruction events */
/* The underlying instructions, which can themselves be instrumented */
uint8_t *per_instruction_opcodes;
/* The tools that are to be notified for instruction events for the matching code unit */
uint8_t *per_instruction_tools;
} _PyCoMonitoringData;
extern int
_Py_Instrumentation_GetLine(PyCodeObject *code, _PyCoLineInstrumentationData *line_data, int index);
static inline uint8_t
_PyCode_GetOriginalOpcode(_PyCoLineInstrumentationData *line_data, int index)
{
return line_data->data[index*line_data->bytes_per_entry];
}
// Exported for external JIT support
PyAPI_FUNC(uint8_t) _PyCode_Deinstrument(uint8_t opcode);
#ifdef __cplusplus
}
#endif
#endif /* !Py_INTERNAL_INSTRUMENT_H */