Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9feb267

Browse files
committed
Do not fold a constant if a large sequence will result.
Saves space in the presence of code like: (None,)*10000
1 parent c560a00 commit 9feb267

2 files changed

Lines changed: 19 additions & 5 deletions

File tree

Lib/test/test_peepholer.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ def test_folding_of_binops_on_constants(self):
129129
self.assert_('(2)' in asm)
130130
self.assert_("('b')" in asm)
131131

132+
# Verify that large sequences do not result from folding
133+
asm = dis_single('a="x"*1000')
134+
self.assert_('(1000)' in asm)
135+
132136
def test_elim_extra_return(self):
133137
# RETURN LOAD_CONST None RETURN --> RETURN
134138
def f(x):

Python/compile.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -444,12 +444,16 @@ tuple_of_constants(unsigned char *codestr, int n, PyObject *consts)
444444
The consts table must still be in list form so that the
445445
new constant can be appended.
446446
Called with codestr pointing to the first LOAD_CONST.
447-
Abandons the transformation if the folding fails (i.e. 1+'a'). */
447+
Abandons the transformation if the folding fails (i.e. 1+'a').
448+
If the new constant is a sequence, only folds when the size
449+
is below a threshold value. That keeps pyc files from
450+
becoming large in the presence of code like: (None,)*1000.
451+
*/
448452
static int
449453
fold_binops_on_constants(unsigned char *codestr, PyObject *consts)
450454
{
451455
PyObject *newconst, *v, *w;
452-
int len_consts, opcode;
456+
int len_consts, opcode, size;
453457

454458
/* Pre-conditions */
455459
assert(PyList_CheckExact(consts));
@@ -468,8 +472,8 @@ fold_binops_on_constants(unsigned char *codestr, PyObject *consts)
468472
newconst = PyNumber_Multiply(v, w);
469473
break;
470474
case BINARY_DIVIDE:
471-
/* XXX care is needed to fold this operation statically:
472-
the result might depend on the run-time presence of the -Qnew flag */
475+
/* Cannot fold this operation statically since
476+
the result can depend on the run-time presence of the -Qnew flag */
473477
return 0;
474478
case BINARY_TRUE_DIVIDE:
475479
newconst = PyNumber_TrueDivide(v, w);
@@ -513,6 +517,13 @@ fold_binops_on_constants(unsigned char *codestr, PyObject *consts)
513517
PyErr_Clear();
514518
return 0;
515519
}
520+
size = PyObject_Size(newconst);
521+
if (size == -1)
522+
PyErr_Clear();
523+
else if (size > 20) {
524+
Py_DECREF(newconst);
525+
return 0;
526+
}
516527

517528
/* Append folded constant into consts table */
518529
len_consts = PyList_GET_SIZE(consts);
@@ -733,7 +744,6 @@ optimize_code(PyObject *code, PyObject* consts, PyObject *names, PyObject *linen
733744
LOAD_CONST c1 LOAD_CONST c2 BINOP --> LOAD_CONST binop(c1,c2) */
734745
case BINARY_POWER:
735746
case BINARY_MULTIPLY:
736-
case BINARY_DIVIDE:
737747
case BINARY_TRUE_DIVIDE:
738748
case BINARY_FLOOR_DIVIDE:
739749
case BINARY_MODULO:

0 commit comments

Comments
 (0)