mirror of
https://github.com/python/cpython
synced 2024-09-16 02:40:00 +00:00
bpo-45056: Remove trailing unused constants from co_consts (GH-28109)
This commit is contained in:
parent
19ba2122ac
commit
55c4a92fc1
|
@ -650,6 +650,17 @@ def test_merge_code_attrs(self):
|
|||
self.assertIs(f1.__code__.co_linetable, f2.__code__.co_linetable)
|
||||
self.assertIs(f1.__code__.co_code, f2.__code__.co_code)
|
||||
|
||||
# Stripping unused constants is not a strict requirement for the
|
||||
# Python semantics, it's a more an implementation detail.
|
||||
@support.cpython_only
|
||||
def test_strip_unused_consts(self):
|
||||
# Python 3.10rc1 appended None to co_consts when None is not used
|
||||
# at all. See bpo-45056.
|
||||
def f1():
|
||||
"docstring"
|
||||
return 42
|
||||
self.assertEqual(f1.__code__.co_consts, ("docstring", 42))
|
||||
|
||||
# This is a regression test for a CPython specific peephole optimizer
|
||||
# implementation bug present in a few releases. It's assertion verifies
|
||||
# that peephole optimization was actually done though that isn't an
|
||||
|
|
|
@ -702,10 +702,7 @@ def get_disassembly(self, func, lasti=-1, wrapper=True, **kwargs):
|
|||
if sys.flags.optimize:
|
||||
code_info_consts = "0: None"
|
||||
else:
|
||||
code_info_consts = (
|
||||
"""0: 'Formatted details of methods, functions, or code.'
|
||||
1: None"""
|
||||
)
|
||||
code_info_consts = "0: 'Formatted details of methods, functions, or code.'"
|
||||
|
||||
code_info_code_info = f"""\
|
||||
Name: code_info
|
||||
|
@ -828,7 +825,6 @@ def f(c=c):
|
|||
Constants:
|
||||
0: 0
|
||||
1: 1
|
||||
2: None
|
||||
Names:
|
||||
0: x"""
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Compiler now removes trailing unused constants from co_consts.
|
|
@ -7573,6 +7573,9 @@ normalize_basic_block(basicblock *bb);
|
|||
static int
|
||||
optimize_cfg(struct compiler *c, struct assembler *a, PyObject *consts);
|
||||
|
||||
static int
|
||||
trim_unused_consts(struct compiler *c, struct assembler *a, PyObject *consts);
|
||||
|
||||
/* Duplicates exit BBs, so that line numbers can be propagated to them */
|
||||
static int
|
||||
duplicate_exits_without_lineno(struct compiler *c);
|
||||
|
@ -7870,6 +7873,9 @@ assemble(struct compiler *c, int addNone)
|
|||
if (duplicate_exits_without_lineno(c)) {
|
||||
return NULL;
|
||||
}
|
||||
if (trim_unused_consts(c, &a, consts)) {
|
||||
goto error;
|
||||
}
|
||||
propagate_line_numbers(&a);
|
||||
guarantee_lineno_for_exits(&a, c->u->u_firstlineno);
|
||||
int maxdepth = stackdepth(c);
|
||||
|
@ -8599,6 +8605,33 @@ optimize_cfg(struct compiler *c, struct assembler *a, PyObject *consts)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Remove trailing unused constants.
|
||||
static int
|
||||
trim_unused_consts(struct compiler *c, struct assembler *a, PyObject *consts)
|
||||
{
|
||||
assert(PyList_CheckExact(consts));
|
||||
|
||||
// The first constant may be docstring; keep it always.
|
||||
int max_const_index = 0;
|
||||
for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) {
|
||||
for (int i = 0; i < b->b_iused; i++) {
|
||||
if (b->b_instr[i].i_opcode == LOAD_CONST &&
|
||||
b->b_instr[i].i_oparg > max_const_index) {
|
||||
max_const_index = b->b_instr[i].i_oparg;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (max_const_index+1 < PyList_GET_SIZE(consts)) {
|
||||
//fprintf(stderr, "removing trailing consts: max=%d, size=%d\n",
|
||||
// max_const_index, (int)PyList_GET_SIZE(consts));
|
||||
if (PyList_SetSlice(consts, max_const_index+1,
|
||||
PyList_GET_SIZE(consts), NULL) < 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
is_exit_without_lineno(basicblock *b) {
|
||||
return b->b_exit && b->b_instr[0].i_lineno < 0;
|
||||
|
|
4101
Python/frozen_modules/importlib__bootstrap.h
generated
4101
Python/frozen_modules/importlib__bootstrap.h
generated
File diff suppressed because it is too large
Load diff
6242
Python/frozen_modules/importlib__bootstrap_external.h
generated
6242
Python/frozen_modules/importlib__bootstrap_external.h
generated
File diff suppressed because it is too large
Load diff
2306
Python/frozen_modules/zipimport.h
generated
2306
Python/frozen_modules/zipimport.h
generated
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue