@@ -336,6 +336,8 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
336
336
co -> co_extra = NULL ;
337
337
338
338
co -> co_warmup = QUICKENING_INITIAL_WARMUP_VALUE ;
339
+ co -> _co_linearray_entry_size = 0 ;
340
+ co -> _co_linearray = NULL ;
339
341
memcpy (_PyCode_CODE (co ), PyBytes_AS_STRING (con -> code ),
340
342
PyBytes_GET_SIZE (con -> code ));
341
343
}
@@ -694,13 +696,60 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
694
696
lnotab_notes.txt for the details of the lnotab representation.
695
697
*/
696
698
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
+
697
743
int
698
744
PyCode_Addr2Line (PyCodeObject * co , int addrq )
699
745
{
700
746
if (addrq < 0 ) {
701
747
return co -> co_firstlineno ;
702
748
}
703
749
assert (addrq >= 0 && addrq < _PyCode_NBYTES (co ));
750
+ if (co -> _co_linearray ) {
751
+ return _PyCode_LineNumberFromArray (co , addrq / sizeof (_Py_CODEUNIT ));
752
+ }
704
753
PyCodeAddressRange bounds ;
705
754
_PyCode_InitAddressRange (co , & bounds );
706
755
return _PyCode_CheckLineNumber (addrq , & bounds );
@@ -1534,6 +1583,9 @@ code_dealloc(PyCodeObject *co)
1534
1583
if (co -> co_weakreflist != NULL ) {
1535
1584
PyObject_ClearWeakRefs ((PyObject * )co );
1536
1585
}
1586
+ if (co -> _co_linearray ) {
1587
+ PyMem_Free (co -> _co_linearray );
1588
+ }
1537
1589
if (co -> co_warmup == 0 ) {
1538
1590
_Py_QuickenedCount -- ;
1539
1591
}
@@ -2090,6 +2142,10 @@ _PyStaticCode_Dealloc(PyCodeObject *co)
2090
2142
PyObject_ClearWeakRefs ((PyObject * )co );
2091
2143
co -> co_weakreflist = NULL ;
2092
2144
}
2145
+ if (co -> _co_linearray ) {
2146
+ PyMem_Free (co -> _co_linearray );
2147
+ co -> _co_linearray = NULL ;
2148
+ }
2093
2149
}
2094
2150
2095
2151
int
0 commit comments