[3.11] GH-93516: Backport GH-93769: Speedup line number checks when t… · python/cpython@3ece6e6

GitHub

@@ -336,6 +336,8 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)

336336co->co_extra=NULL;

337337338338co->co_warmup=QUICKENING_INITIAL_WARMUP_VALUE;

339+co->_co_linearray_entry_size=0;

340+co->_co_linearray=NULL;

339341memcpy(_PyCode_CODE(co), PyBytes_AS_STRING(con->code),

340342PyBytes_GET_SIZE(con->code));

341343}

@@ -694,13 +696,60 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)

694696 lnotab_notes.txt for the details of the lnotab representation.

695697*/

696698699+int

700+_PyCode_CreateLineArray(PyCodeObject*co)

701+{

702+assert(co->_co_linearray==NULL);

703+PyCodeAddressRangebounds;

704+intsize;

705+intmax_line=0;

706+_PyCode_InitAddressRange(co, &bounds);

707+while(_PyLineTable_NextAddressRange(&bounds)) {

708+if (bounds.ar_line>max_line) {

709+max_line=bounds.ar_line;

710+ }

711+ }

712+if (max_line< (1 << 15)) {

713+size=2;

714+ }

715+else {

716+size=4;

717+ }

718+co->_co_linearray=PyMem_Malloc(Py_SIZE(co)*size);

719+if (co->_co_linearray==NULL) {

720+PyErr_NoMemory();

721+return-1;

722+ }

723+co->_co_linearray_entry_size=size;

724+_PyCode_InitAddressRange(co, &bounds);

725+while(_PyLineTable_NextAddressRange(&bounds)) {

726+intstart=bounds.ar_start / sizeof(_Py_CODEUNIT);

727+intend=bounds.ar_end / sizeof(_Py_CODEUNIT);

728+for (intindex=start; index<end; index++) {

729+assert(index< (int)Py_SIZE(co));

730+if (size==2) {

731+assert(((int16_t)bounds.ar_line) ==bounds.ar_line);

732+ ((int16_t*)co->_co_linearray)[index] =bounds.ar_line;

733+ }

734+else {

735+assert(size==4);

736+ ((int32_t*)co->_co_linearray)[index] =bounds.ar_line;

737+ }

738+ }

739+ }

740+return0;

741+}

742+697743int

698744PyCode_Addr2Line(PyCodeObject*co, intaddrq)

699745{

700746if (addrq<0) {

701747returnco->co_firstlineno;

702748 }

703749assert(addrq >= 0&&addrq<_PyCode_NBYTES(co));

750+if (co->_co_linearray) {

751+return_PyCode_LineNumberFromArray(co, addrq / sizeof(_Py_CODEUNIT));

752+ }

704753PyCodeAddressRangebounds;

705754_PyCode_InitAddressRange(co, &bounds);

706755return_PyCode_CheckLineNumber(addrq, &bounds);

@@ -1539,6 +1588,9 @@ code_dealloc(PyCodeObject *co)

15391588if (co->co_weakreflist!=NULL) {

15401589PyObject_ClearWeakRefs((PyObject*)co);

15411590 }

1591+if (co->_co_linearray) {

1592+PyMem_Free(co->_co_linearray);

1593+ }

15421594if (co->co_warmup==0) {

15431595_Py_QuickenedCount--;

15441596 }

@@ -2095,6 +2147,10 @@ _PyStaticCode_Dealloc(PyCodeObject *co)

20952147PyObject_ClearWeakRefs((PyObject*)co);

20962148co->co_weakreflist=NULL;

20972149 }

2150+if (co->_co_linearray) {

2151+PyMem_Free(co->_co_linearray);

2152+co->_co_linearray=NULL;

2153+ }

20982154}

2099215521002156int