@@ -336,6 +336,8 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
336336 co -> co_extra = NULL ;
337337
338338 co -> co_warmup = QUICKENING_INITIAL_WARMUP_VALUE ;
339+ co -> _co_linearray_entry_size = 0 ;
340+ co -> _co_linearray = NULL ;
339341 memcpy (_PyCode_CODE (co ), PyBytes_AS_STRING (con -> code ),
340342 PyBytes_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*/
696698
699+ int
700+ _PyCode_CreateLineArray (PyCodeObject * co )
701+ {
702+ assert (co -> _co_linearray == NULL );
703+ PyCodeAddressRange bounds ;
704+ int size ;
705+ int max_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+ int start = bounds .ar_start / sizeof (_Py_CODEUNIT );
727+ int end = bounds .ar_end / sizeof (_Py_CODEUNIT );
728+ for (int index = 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+ return 0 ;
741+ }
742+
697743int
698744PyCode_Addr2Line (PyCodeObject * co , int addrq )
699745{
700746 if (addrq < 0 ) {
701747 return co -> co_firstlineno ;
702748 }
703749 assert (addrq >= 0 && addrq < _PyCode_NBYTES (co ));
750+ if (co -> _co_linearray ) {
751+ return _PyCode_LineNumberFromArray (co , addrq / sizeof (_Py_CODEUNIT ));
752+ }
704753 PyCodeAddressRange bounds ;
705754 _PyCode_InitAddressRange (co , & bounds );
706755 return _PyCode_CheckLineNumber (addrq , & bounds );
@@ -1534,6 +1583,9 @@ code_dealloc(PyCodeObject *co)
15341583 if (co -> co_weakreflist != NULL ) {
15351584 PyObject_ClearWeakRefs ((PyObject * )co );
15361585 }
1586+ if (co -> _co_linearray ) {
1587+ PyMem_Free (co -> _co_linearray );
1588+ }
15371589 if (co -> co_warmup == 0 ) {
15381590 _Py_QuickenedCount -- ;
15391591 }
@@ -2090,6 +2142,10 @@ _PyStaticCode_Dealloc(PyCodeObject *co)
20902142 PyObject_ClearWeakRefs ((PyObject * )co );
20912143 co -> co_weakreflist = NULL ;
20922144 }
2145+ if (co -> _co_linearray ) {
2146+ PyMem_Free (co -> _co_linearray );
2147+ co -> _co_linearray = NULL ;
2148+ }
20932149}
20942150
20952151int
0 commit comments