10000 GH-127953: Make line number lookup O(1) regardless of the size of the… · python/cpython@7239da7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7239da7

Browse files
authored
GH-127953: Make line number lookup O(1) regardless of the size of the code object (GH-128350)
1 parent f7cc7d2 commit 7239da7

File tree

6 files changed

+214
-163
lines changed

6 files changed

+214
-163
lines changed

Include/cpython/code.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,12 @@ typedef struct {
3535
} _PyCoCached;
3636

3737
/* Ancillary data structure used for instrumentation.
38-
Line instrumentation creates an array of
39-
these. One entry per code unit.*/
38+
Line instrumentation creates this with sufficient
39 8000 +
space for one entry per code unit. The total size
40+
of the data will be `bytes_per_entry * Py_SIZE(code)` */
4041
typedef struct {
41-
uint8_t original_opcode;
42-
int8_t line_delta;
42+
uint8_t bytes_per_entry;
43+
uint8_t data[1];
4344
} _PyCoLineInstrumentationData;
4445

4546

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The time to handle a ``LINE`` event in sys.monitoring (and sys.settrace) is
2+
now independent of the number of lines in the code object.

Objects/codeobject.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,9 @@ PyCode_Addr2Line(PyCodeObject *co 8000 , int addrq)
979979
if (addrq < 0) {
980980
return co->co_firstlineno;
981981
}
982+
if (co->_co_monitoring && co->_co_monitoring->lines) {
983+
return _Py_Instrumentation_GetLine(co, addrq/sizeof(_Py_CODEUNIT));
984+
}
982985
assert(addrq >= 0 && addrq < _PyCode_NBYTES(co));
983986
PyCodeAddressRange bounds;
984987
_PyCode_InitAddressRange(co, &bounds);

Python/bytecodes.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4816,7 +4816,8 @@ dummy_func(
48164816
int original_opcode = 0;
48174817
if (tstate->tracing) {
48184818
PyCodeObject *code = _PyFrame_GetCode(frame);
4819-
original_opcode = code->_co_monitoring->lines[(int)(this_instr - _PyFrame_GetBytecode(frame))].original_opcode;
4819+
int index = (int)(this_instr - _PyFrame_GetBytecode(frame));
4820+
original_opcode = code->_co_monitoring->lines->data[index*code->_co_monitoring->lines->bytes_per_entry];
48204821
next_instr = this_instr;
48214822
} else {
48224823
original_opcode = _Py_call_instrumentation_line(

Python/generated_cases.c.h

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
0