@@ -339,6 +339,8 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
339
339
co -> _co_code = NULL ;
340
340
341
341
co -> co_warmup = QUICKENING_INITIAL_WARMUP_VALUE ;
342
+ co -> _co_linearray_entry_size = 0 ;
343
+ co -> _co_linearray = NULL ;
342
344
memcpy (_PyCode_CODE (co ), PyBytes_AS_STRING (con -> code ),
343
345
PyBytes_GET_SIZE (con -> code ));
344
346
int entry_point = 0 ;
@@ -703,13 +705,60 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
703
705
lnotab_notes.txt for the details of the lnotab representation.
704
706
*/
705
707
708
+ int
709
+ _PyCode_CreateLineArray (PyCodeObject * co )
710
+ {
711
+ assert (co -> _co_linearray == NULL );
712
+ PyCodeAddressRange bounds ;
713
+ int size ;
714
+ int max_line = 0 ;
715
+ _PyCode_InitAddressRange (co , & bounds );
716
+ while (_PyLineTable_NextAddressRange (& bounds )) {
717
+ if (bounds .ar_line > max_line ) {
718
+ max_line = bounds .ar_line ;
719
+ }
720
+ }
721
+ if (max_line < (1 << 15 )) {
722
+ size = 2 ;
723
+ }
724
+ else {
725
+ size = 4 ;
726
+ }
727
+ co -> _co_linearray = PyMem_Malloc (Py_SIZE (co )* size );
728
+ if (co -> _co_linearray == NULL ) {
729
+ PyErr_NoMemory ();
730
+ return -1 ;
731
+ }
732
+ co -> _co_linearray_entry_size = size ;
733
+ _PyCode_InitAddressRange (co , & bounds );
734
+ while (_PyLineTable_NextAddressRange (& bounds )) {
735
+ int start = bounds .ar_start / sizeof (_Py_CODEUNIT );
736
+ int end = bounds .ar_end / sizeof (_Py_CODEUNIT );
737
+ for (int index = start ; index < end ; index ++ ) {
738
+ assert (index < (int )Py_SIZE (co ));
739
+ if (size == 2 ) {
740
+ assert (((int16_t )bounds .ar_line ) == bounds .ar_line );
741
+ ((int16_t * )co -> _co_linearray )[index ] = bounds .ar_line ;
742
+ }
743
+ else {
744
+ assert (size == 4 );
745
+ ((int32_t * )co -> _co_linearray )[index ] = bounds .ar_line ;
746
+ }
747
+ }
748
+ }
749
+ return 0 ;
750
+ }
751
+
706
752
int
707
753
PyCode_Addr2Line (PyCodeObject * co , int addrq )
708
754
{
709
755
if (addrq < 0 ) {
710
756
return co -> co_firstlineno ;
711
757
}
712
758
assert (addrq >= 0 && addrq < _PyCode_NBYTES (co ));
759
+ if (co -> _co_linearray ) {
760
+ return _PyCode_LineNumberFromArray (co , addrq / sizeof (_Py_CODEUNIT ));
761
+ }
713
762
PyCodeAddressRange bounds ;
714
763
_PyCode_InitAddressRange (co , & bounds );
715
764
return _PyCode_CheckLineNumber (addrq , & bounds );
@@ -1549,6 +1598,9 @@ code_dealloc(PyCodeObject *co)
1549
1598
if (co -> co_weakreflist != NULL ) {
1550
1599
PyObject_ClearWeakRefs ((PyObject * )co );
1551
1600
}
1601
+ if (co -> _co_linearray ) {
1602
+ PyMem_Free (co -> _co_linearray );
1603
+ }
1552
1604
if (co -> co_warmup == 0 ) {
1553
1605
_Py_QuickenedCount -- ;
1554
1606
}
@@ -2106,6 +2158,10 @@ _PyStaticCode_Dealloc(PyCodeObject *co)
2106
2158
PyObject_ClearWeakRefs ((PyObject * )co );
2107
2159
co -> co_weakreflist = NULL ;
2108
2160
}
2161
+ if (co -> _co_linearray ) {
2162
+ PyMem_Free (co -> _co_linearray );
2163
+ co -> _co_linearray = NULL ;
2164
+ }
2109
2165
}
2110
2166
2111
2167
int
0 commit comments