]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Do not fold a constant if a large sequence will result.
authorRaymond Hettinger <python@rcn.com>
Wed, 26 Jan 2005 12:50:05 +0000 (12:50 +0000)
committerRaymond Hettinger <python@rcn.com>
Wed, 26 Jan 2005 12:50:05 +0000 (12:50 +0000)
Saves space in the presence of code like: (None,)*10000

Lib/test/test_peepholer.py
Python/compile.c

index 42224244ef205a36ade45cc427726dc135ef08d0..34bd99f2a402cca3c52a63b8796240f6a495d216 100644 (file)
@@ -129,6 +129,10 @@ class TestTranforms(unittest.TestCase):
         self.assert_('(2)' in asm)
         self.assert_("('b')" in asm)
 
+        # Verify that large sequences do not result from folding
+        asm = dis_single('a="x"*1000')
+        self.assert_('(1000)' in asm)
+
     def test_elim_extra_return(self):
         # RETURN LOAD_CONST None RETURN  -->  RETURN
         def f(x):
index 545042f87c0ab22ae9d74dfe67b223e6e1dd677c..acfbfe112a10220f5b8974535e2b0d6619912ee2 100644 (file)
@@ -444,12 +444,16 @@ tuple_of_constants(unsigned char *codestr, int n, PyObject *consts)
    The consts table must still be in list form so that the
        new constant can be appended.
    Called with codestr pointing to the first LOAD_CONST. 
-   Abandons the transformation if the folding fails (i.e.  1+'a').  */
+   Abandons the transformation if the folding fails (i.e.  1+'a').  
+   If the new constant is a sequence, only folds when the size
+       is below a threshold value.  That keeps pyc files from
+       becoming large in the presence of code like:  (None,)*1000.
+*/
 static int
 fold_binops_on_constants(unsigned char *codestr, PyObject *consts)
 {
        PyObject *newconst, *v, *w;
-       int len_consts, opcode;
+       int len_consts, opcode, size;
 
        /* Pre-conditions */
        assert(PyList_CheckExact(consts));
@@ -468,8 +472,8 @@ fold_binops_on_constants(unsigned char *codestr, PyObject *consts)
                newconst = PyNumber_Multiply(v, w);
                break;
        case BINARY_DIVIDE:
-               /* XXX care is needed to fold this operation statically:
-               the result might depend on the run-time presence of the -Qnew flag */
+               /* Cannot fold this operation statically since
+               the result can depend on the run-time presence of the -Qnew flag */
                return 0;
        case BINARY_TRUE_DIVIDE:
                newconst = PyNumber_TrueDivide(v, w);
@@ -513,6 +517,13 @@ fold_binops_on_constants(unsigned char *codestr, PyObject *consts)
                PyErr_Clear();
                return 0;
        }
+       size = PyObject_Size(newconst);
+       if (size == -1)
+               PyErr_Clear();
+       else if (size > 20) {
+               Py_DECREF(newconst);
+               return 0;
+       }
 
        /* Append folded constant into consts table */
        len_consts = PyList_GET_SIZE(consts);
@@ -733,7 +744,6 @@ optimize_code(PyObject *code, PyObject* consts, PyObject *names, PyObject *linen
                   LOAD_CONST c1 LOAD_CONST c2 BINOP -->  LOAD_CONST binop(c1,c2) */
                case BINARY_POWER:
                case BINARY_MULTIPLY:
-               case BINARY_DIVIDE:
                case BINARY_TRUE_DIVIDE:
                case BINARY_FLOOR_DIVIDE:
                case BINARY_MODULO: