[Python-checkins] GH-99554: Pack location tables more effectively (GH-99556)

brandtbucher webhook-mailer at python.org
Wed Dec 21 19:41:24 EST 2022


https://github.com/python/cpython/commit/3c033a2e6fbde56f904aeca138141be6564341cf
commit: 3c033a2e6fbde56f904aeca138141be6564341cf
branch: main
author: Brandt Bucher <brandtbucher at microsoft.com>
committer: brandtbucher <brandtbucher at gmail.com>
date: 2022-12-21T16:41:18-08:00
summary:

GH-99554: Pack location tables more effectively (GH-99556)

files:
A Misc/NEWS.d/next/Core and Builtins/2022-11-16-05-57-24.gh-issue-99554.A_Ywd2.rst
M Programs/test_frozenmain.h
M Python/compile.c

diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-11-16-05-57-24.gh-issue-99554.A_Ywd2.rst b/Misc/NEWS.d/next/Core and Builtins/2022-11-16-05-57-24.gh-issue-99554.A_Ywd2.rst
new file mode 100644
index 000000000000..96ec47db461d
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2022-11-16-05-57-24.gh-issue-99554.A_Ywd2.rst	
@@ -0,0 +1 @@
+Pack debugging location tables more efficiently during bytecode compilation.
diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h
index 96be3ce3c25c..95f78b19e65e 100644
--- a/Programs/test_frozenmain.h
+++ b/Programs/test_frozenmain.h
@@ -28,15 +28,12 @@ unsigned char M_test_frozenmain[] = {
     115,114,3,0,0,0,218,3,107,101,121,169,0,243,0,0,
     0,0,250,18,116,101,115,116,95,102,114,111,122,101,110,109,
     97,105,110,46,112,121,250,8,60,109,111,100,117,108,101,62,
-    114,18,0,0,0,1,0,0,0,115,154,0,0,0,240,3,
-    1,1,1,240,8,0,1,11,128,10,128,10,128,10,216,0,
-    24,208,0,24,208,0,24,208,0,24,224,0,5,128,5,208,
-    6,26,212,0,27,208,0,27,216,0,5,128,5,128,106,144,
-    35,151,40,145,40,212,0,27,208,0,27,216,9,38,208,9,
-    26,215,9,38,209,9,38,212,9,40,168,24,212,9,50,128,
-    6,240,2,6,12,2,240,0,7,1,42,241,0,7,1,42,
-    128,67,240,14,0,5,10,128,69,208,10,40,144,67,208,10,
-    40,208,10,40,152,54,160,35,156,59,208,10,40,208,10,40,
-    212,4,41,208,4,41,208,4,41,240,15,7,1,42,240,0,
-    7,1,42,240,0,7,1,42,114,16,0,0,0,
+    114,18,0,0,0,1,0,0,0,115,100,0,0,0,240,3,
+    1,1,1,243,8,0,1,11,219,0,24,225,0,5,208,6,
+    26,213,0,27,217,0,5,128,106,144,35,151,40,145,40,213,
+    0,27,216,9,38,208,9,26,215,9,38,209,9,38,212,9,
+    40,168,24,212,9,50,128,6,240,2,6,12,2,242,0,7,
+    1,42,128,67,241,14,0,5,10,208,10,40,144,67,209,10,
+    40,152,54,160,35,156,59,209,10,40,214,4,41,242,15,7,
+    1,42,114,16,0,0,0,
 };
diff --git a/Python/compile.c b/Python/compile.c
index 09eb4016940d..023c13507d6a 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -150,6 +150,15 @@ location_is_after(location loc1, location loc2) {
              (loc1.col_offset > loc2.end_col_offset));
 }
 
+static inline bool
+same_location(location a, location b)
+{
+    return a.lineno == b.lineno && 
+           a.end_lineno == b.end_lineno &&
+           a.col_offset == b.col_offset &&
+           a.end_col_offset == b.end_col_offset;
+}
+
 #define LOC(x) SRC_LOCATION_FROM_AST(x)
 
 typedef struct jump_target_label_ {
@@ -7722,15 +7731,15 @@ write_location_info_oneline_form(struct assembler* a, int length, int line_delta
 }
 
 static void
-write_location_info_long_form(struct assembler* a, struct instr* i, int length)
+write_location_info_long_form(struct assembler* a, location loc, int length)
 {
     assert(length > 0 &&  length <= 8);
     write_location_first_byte(a, PY_CODE_LOCATION_INFO_LONG, length);
-    write_location_signed_varint(a, i->i_loc.lineno - a->a_lineno);
-    assert(i->i_loc.end_lineno >= i->i_loc.lineno);
-    write_location_varint(a, i->i_loc.end_lineno - i->i_loc.lineno);
-    write_location_varint(a, i->i_loc.col_offset + 1);
-    write_location_varint(a, i->i_loc.end_col_offset + 1);
+    write_location_signed_varint(a, loc.lineno - a->a_lineno);
+    assert(loc.end_lineno >= loc.lineno);
+    write_location_varint(a, loc.end_lineno - loc.lineno);
+    write_location_varint(a, loc.col_offset + 1);
+    write_location_varint(a, loc.end_col_offset + 1);
 }
 
 static void
@@ -7749,7 +7758,7 @@ write_location_info_no_column(struct assembler* a, int length, int line_delta)
 #define THEORETICAL_MAX_ENTRY_SIZE 25 /* 1 + 6 + 6 + 6 + 6 */
 
 static int
-write_location_info_entry(struct assembler* a, struct instr* i, int isize)
+write_location_info_entry(struct assembler* a, location loc, int isize)
 {
     Py_ssize_t len = PyBytes_GET_SIZE(a->a_linetable);
     if (a->a_location_off + THEORETICAL_MAX_ENTRY_SIZE >= len) {
@@ -7758,49 +7767,51 @@ write_location_info_entry(struct assembler* a, struct instr* i, int isize)
             return -1;
         }
     }
-    if (i->i_loc.lineno < 0) {
+    if (loc.lineno < 0) {
         write_location_info_none(a, isize);
         return 0;
     }
-    int line_delta = i->i_loc.lineno - a->a_lineno;
-    int column = i->i_loc.col_offset;
-    int end_column = i->i_loc.end_col_offset;
+    int line_delta = loc.lineno - a->a_lineno;
+    int column = loc.col_offset;
+    int end_column = loc.end_col_offset;
     assert(column >= -1);
     assert(end_column >= -1);
     if (column < 0 || end_column < 0) {
-        if (i->i_loc.end_lineno == i->i_loc.lineno || i->i_loc.end_lineno == -1) {
+        if (loc.end_lineno == loc.lineno || loc.end_lineno == -1) {
             write_location_info_no_column(a, isize, line_delta);
-            a->a_lineno = i->i_loc.lineno;
+            a->a_lineno = loc.lineno;
             return 0;
         }
     }
-    else if (i->i_loc.end_lineno == i->i_loc.lineno) {
+    else if (loc.end_lineno == loc.lineno) {
         if (line_delta == 0 && column < 80 && end_column - column < 16 && end_column >= column) {
             write_location_info_short_form(a, isize, column, end_column);
             return 0;
         }
         if (line_delta >= 0 && line_delta < 3 && column < 128 && end_column < 128) {
             write_location_info_oneline_form(a, isize, line_delta, column, end_column);
-            a->a_lineno = i->i_loc.lineno;
+            a->a_lineno = loc.lineno;
             return 0;
         }
     }
-    write_location_info_long_form(a, i, isize);
-    a->a_lineno = i->i_loc.lineno;
+    write_location_info_long_form(a, loc, isize);
+    a->a_lineno = loc.lineno;
     return 0;
 }
 
 static int
-assemble_emit_location(struct assembler* a, struct instr* i)
+assemble_emit_location(struct assembler* a, location loc, int isize)
 {
-    int isize = instr_size(i);
+    if (isize == 0) {
+        return 0;
+    }
     while (isize > 8) {
-        if (write_location_info_entry(a, i, 8) < 0) {
+        if (write_location_info_entry(a, loc, 8)) {
             return -1;
         }
         isize -= 8;
     }
-    return write_location_info_entry(a, i, isize);
+    return write_location_info_entry(a, loc, isize);
 }
 
 /* assemble_emit()
@@ -8860,13 +8871,23 @@ assemble(struct compiler *c, int addNone)
 
     /* Emit location info */
     a.a_lineno = c->u->u_firstlineno;
+    location loc = NO_LOCATION;
+    int size = 0;
     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
         for (int j = 0; j < b->b_iused; j++) {
-            if (assemble_emit_location(&a, &b->b_instr[j]) < 0) {
-                goto error;
+            if (!same_location(loc, b->b_instr[j].i_loc)) {
+                if (assemble_emit_location(&a, loc, size)) {
+                    goto error;
+                }
+                loc = b->b_instr[j].i_loc;
+                size = 0;
             }
+            size += instr_size(&b->b_instr[j]);
         }
     }
+    if (assemble_emit_location(&a, loc, size)) {
+        goto error;
+    }
 
     if (assemble_exception_table(&a, g->g_entryblock) < 0) {
         goto error;



More information about the Python-checkins mailing list