Skip to content

Commit 3c033a2

Browse files
authored
GH-99554: Pack location tables more effectively (GH-99556)
1 parent bbf4a66 commit 3c033a2

File tree

3 files changed

+53
-34
lines changed

3 files changed

+53
-34
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Pack debugging location tables more efficiently during bytecode compilation.

Programs/test_frozenmain.h

+8-11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/compile.c

+44-23
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,15 @@ location_is_after(location loc1, location loc2) {
150150
(loc1.col_offset > loc2.end_col_offset));
151151
}
152152

153+
static inline bool
154+
same_location(location a, location b)
155+
{
156+
return a.lineno == b.lineno &&
157+
a.end_lineno == b.end_lineno &&
158+
a.col_offset == b.col_offset &&
159+
a.end_col_offset == b.end_col_offset;
160+
}
161+
153162
#define LOC(x) SRC_LOCATION_FROM_AST(x)
154163

155164
typedef struct jump_target_label_ {
@@ -7722,15 +7731,15 @@ write_location_info_oneline_form(struct assembler* a, int length, int line_delta
77227731
}
77237732

77247733
static void
7725-
write_location_info_long_form(struct assembler* a, struct instr* i, int length)
7734+
write_location_info_long_form(struct assembler* a, location loc, int length)
77267735
{
77277736
assert(length > 0 && length <= 8);
77287737
write_location_first_byte(a, PY_CODE_LOCATION_INFO_LONG, length);
7729-
write_location_signed_varint(a, i->i_loc.lineno - a->a_lineno);
7730-
assert(i->i_loc.end_lineno >= i->i_loc.lineno);
7731-
write_location_varint(a, i->i_loc.end_lineno - i->i_loc.lineno);
7732-
write_location_varint(a, i->i_loc.col_offset + 1);
7733-
write_location_varint(a, i->i_loc.end_col_offset + 1);
7738+
write_location_signed_varint(a, loc.lineno - a->a_lineno);
7739+
assert(loc.end_lineno >= loc.lineno);
7740+
write_location_varint(a, loc.end_lineno - loc.lineno);
7741+
write_location_varint(a, loc.col_offset + 1);
7742+
write_location_varint(a, loc.end_col_offset + 1);
77347743
}
77357744

77367745
static void
@@ -7749,7 +7758,7 @@ write_location_info_no_column(struct assembler* a, int length, int line_delta)
77497758
#define THEORETICAL_MAX_ENTRY_SIZE 25 /* 1 + 6 + 6 + 6 + 6 */
77507759

77517760
static int
7752-
write_location_info_entry(struct assembler* a, struct instr* i, int isize)
7761+
write_location_info_entry(struct assembler* a, location loc, int isize)
77537762
{
77547763
Py_ssize_t len = PyBytes_GET_SIZE(a->a_linetable);
77557764
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)
77587767
return -1;
77597768
}
77607769
}
7761-
if (i->i_loc.lineno < 0) {
7770+
if (loc.lineno < 0) {
77627771
write_location_info_none(a, isize);
77637772
return 0;
77647773
}
7765-
int line_delta = i->i_loc.lineno - a->a_lineno;
7766-
int column = i->i_loc.col_offset;
7767-
int end_column = i->i_loc.end_col_offset;
7774+
int line_delta = loc.lineno - a->a_lineno;
7775+
int column = loc.col_offset;
7776+
int end_column = loc.end_col_offset;
77687777
assert(column >= -1);
77697778
assert(end_column >= -1);
77707779
if (column < 0 || end_column < 0) {
7771-
if (i->i_loc.end_lineno == i->i_loc.lineno || i->i_loc.end_lineno == -1) {
7780+
if (loc.end_lineno == loc.lineno || loc.end_lineno == -1) {
77727781
write_location_info_no_column(a, isize, line_delta);
7773-
a->a_lineno = i->i_loc.lineno;
7782+
a->a_lineno = loc.lineno;
77747783
return 0;
77757784
}
77767785
}
7777-
else if (i->i_loc.end_lineno == i->i_loc.lineno) {
7786+
else if (loc.end_lineno == loc.lineno) {
77787787
if (line_delta == 0 && column < 80 && end_column - column < 16 && end_column >= column) {
77797788
write_location_info_short_form(a, isize, column, end_column);
77807789
return 0;
77817790
}
77827791
if (line_delta >= 0 && line_delta < 3 && column < 128 && end_column < 128) {
77837792
write_location_info_oneline_form(a, isize, line_delta, column, end_column);
7784-
a->a_lineno = i->i_loc.lineno;
7793+
a->a_lineno = loc.lineno;
77857794
return 0;
77867795
}
77877796
}
7788-
write_location_info_long_form(a, i, isize);
7789-
a->a_lineno = i->i_loc.lineno;
7797+
write_location_info_long_form(a, loc, isize);
7798+
a->a_lineno = loc.lineno;
77907799
return 0;
77917800
}
77927801

77937802
static int
7794-
assemble_emit_location(struct assembler* a, struct instr* i)
7803+
assemble_emit_location(struct assembler* a, location loc, int isize)
77957804
{
7796-
int isize = instr_size(i);
7805+
if (isize == 0) {
7806+
return 0;
7807+
}
77977808
while (isize > 8) {
7798-
if (write_location_info_entry(a, i, 8) < 0) {
7809+
if (write_location_info_entry(a, loc, 8)) {
77997810
return -1;
78007811
}
78017812
isize -= 8;
78027813
}
7803-
return write_location_info_entry(a, i, isize);
7814+
return write_location_info_entry(a, loc, isize);
78047815
}
78057816

78067817
/* assemble_emit()
@@ -8860,13 +8871,23 @@ assemble(struct compiler *c, int addNone)
88608871

88618872
/* Emit location info */
88628873
a.a_lineno = c->u->u_firstlineno;
8874+
location loc = NO_LOCATION;
8875+
int size = 0;
88638876
for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
88648877
for (int j = 0; j < b->b_iused; j++) {
8865-
if (assemble_emit_location(&a, &b->b_instr[j]) < 0) {
8866-
goto error;
8878+
if (!same_location(loc, b->b_instr[j].i_loc)) {
8879+
if (assemble_emit_location(&a, loc, size)) {
8880+
goto error;
8881+
}
8882+
loc = b->b_instr[j].i_loc;
8883+
size = 0;
88678884
}
8885+
size += instr_size(&b->b_instr[j]);
88688886
}
88698887
}
8888+
if (assemble_emit_location(&a, loc, size)) {
8889+
goto error;
8890+
}
88708891

88718892
if (assemble_exception_table(&a, g->g_entryblock) < 0) {
88728893
goto error;

0 commit comments

Comments
 (0)