summaryrefslogtreecommitdiffstats
path: root/Objects/codeobject.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2022-06-22 15:32:02 (GMT)
committerGitHub <noreply@github.com>2022-06-22 15:32:02 (GMT)
commit3ece6e6feb44b334cd759ead970e877bbd126892 (patch)
tree96846029de1a3123d7fd01f67df0e5597171955a /Objects/codeobject.c
parent8c2af4907133d4a235cce73231fab723653d6429 (diff)
downloadcpython-3ece6e6feb44b334cd759ead970e877bbd126892.zip
cpython-3ece6e6feb44b334cd759ead970e877bbd126892.tar.gz
cpython-3ece6e6feb44b334cd759ead970e877bbd126892.tar.bz2
[3.11] GH-93516: Backport GH-93769: Speedup line number checks when tracing (GH-94127)
Co-authored-by: Pablo Galindo <pablogsal@gmail.com>
Diffstat (limited to 'Objects/codeobject.c')
-rw-r--r--Objects/codeobject.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index dd3f555..0e91456 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -336,6 +336,8 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
co->co_extra = 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));
}
@@ -695,12 +697,59 @@ failed:
*/
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)
{
if (addrq < 0) {
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);
@@ -1539,6 +1588,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--;
}
@@ -2095,6 +2147,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