mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
GH-93516: Speedup line number checks when tracing. (GH-93763)
* Use a lookup table to reduce overhead of getting line numbers during tracing.
This commit is contained in:
parent
45e62a2bc1
commit
ab0e601016
6 changed files with 101 additions and 8 deletions
|
@ -339,6 +339,8 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
|
|||
co->_co_code = NULL;
|
||||
|
||||
co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE;
|
||||
co->_co_linearray_entry_size = 0;
|
||||
co->_co_linearray = NULL;
|
||||
memcpy(_PyCode_CODE(co), PyBytes_AS_STRING(con->code),
|
||||
PyBytes_GET_SIZE(con->code));
|
||||
int entry_point = 0;
|
||||
|
@ -703,6 +705,50 @@ failed:
|
|||
lnotab_notes.txt for the details of the lnotab representation.
|
||||
*/
|
||||
|
||||
int
|
||||
_PyCode_CreateLineArray(PyCodeObject *co)
|
||||
{
|
||||
assert(co->_co_linearray == NULL);
|
||||
PyCodeAddressRange bounds;
|
||||
int size;
|
||||
int max_line = 0;
|
||||
_PyCode_InitAddressRange(co, &bounds);
|
||||
while(_PyLineTable_NextAddressRange(&bounds)) {
|
||||
if (bounds.ar_line > max_line) {
|
||||
max_line = bounds.ar_line;
|
||||
}
|
||||
}
|
||||
if (max_line < (1 << 15)) {
|
||||
size = 2;
|
||||
}
|
||||
else {
|
||||
size = 4;
|
||||
}
|
||||
co->_co_linearray = PyMem_Malloc(Py_SIZE(co)*size);
|
||||
if (co->_co_linearray == NULL) {
|
||||
PyErr_NoMemory();
|
||||
return -1;
|
||||
}
|
||||
co->_co_linearray_entry_size = size;
|
||||
_PyCode_InitAddressRange(co, &bounds);
|
||||
while(_PyLineTable_NextAddressRange(&bounds)) {
|
||||
int start = bounds.ar_start / sizeof(_Py_CODEUNIT);
|
||||
int end = bounds.ar_end / sizeof(_Py_CODEUNIT);
|
||||
for (int index = start; index < end; index++) {
|
||||
assert(index < (int)Py_SIZE(co));
|
||||
if (size == 2) {
|
||||
assert(((int16_t)bounds.ar_line) == bounds.ar_line);
|
||||
((int16_t *)co->_co_linearray)[index] = bounds.ar_line;
|
||||
}
|
||||
else {
|
||||
assert(size == 4);
|
||||
((int32_t *)co->_co_linearray)[index] = bounds.ar_line;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
PyCode_Addr2Line(PyCodeObject *co, int addrq)
|
||||
{
|
||||
|
@ -710,6 +756,9 @@ PyCode_Addr2Line(PyCodeObject *co, int addrq)
|
|||
return co->co_firstlineno;
|
||||
}
|
||||
assert(addrq >= 0 && addrq < _PyCode_NBYTES(co));
|
||||
if (co->_co_linearray) {
|
||||
return _PyCode_LineNumberFromArray(co, addrq / sizeof(_Py_CODEUNIT));
|
||||
}
|
||||
PyCodeAddressRange bounds;
|
||||
_PyCode_InitAddressRange(co, &bounds);
|
||||
return _PyCode_CheckLineNumber(addrq, &bounds);
|
||||
|
@ -1549,6 +1598,9 @@ code_dealloc(PyCodeObject *co)
|
|||
if (co->co_weakreflist != NULL) {
|
||||
PyObject_ClearWeakRefs((PyObject*)co);
|
||||
}
|
||||
if (co->_co_linearray) {
|
||||
PyMem_Free(co->_co_linearray);
|
||||
}
|
||||
if (co->co_warmup == 0) {
|
||||
_Py_QuickenedCount--;
|
||||
}
|
||||
|
@ -2106,6 +2158,10 @@ _PyStaticCode_Dealloc(PyCodeObject *co)
|
|||
PyObject_ClearWeakRefs((PyObject *)co);
|
||||
co->co_weakreflist = NULL;
|
||||
}
|
||||
if (co->_co_linearray) {
|
||||
PyMem_Free(co->_co_linearray);
|
||||
co->_co_linearray = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue