2323 (blocks[start]==blocks[end])
2424
2525
26- #define CONST_STACK_CREATE () { \
27- const_stack_size = 256; \
28- const_stack = PyMem_New(PyObject *, const_stack_size); \
29- if (!const_stack) { \
30- PyErr_NoMemory(); \
31- goto exitError; \
32- } \
33- }
34-
35- #define CONST_STACK_DELETE () do { \
36- if (const_stack) \
37- PyMem_Free(const_stack); \
38- } while(0)
39-
40- #define CONST_STACK_LEN () ((unsigned)(const_stack_top + 1))
41-
42- #define CONST_STACK_PUSH_OP (i ) do { \
43- PyObject *_x; \
44- assert(_Py_OPCODE(codestr[i]) == LOAD_CONST); \
45- assert(PyList_GET_SIZE(consts) > (Py_ssize_t)get_arg(codestr, i)); \
46- _x = PyList_GET_ITEM(consts, get_arg(codestr, i)); \
47- if (++const_stack_top >= const_stack_size) { \
48- const_stack_size *= 2; \
49- PyMem_Resize(const_stack, PyObject *, const_stack_size); \
50- if (!const_stack) { \
51- PyErr_NoMemory(); \
52- goto exitError; \
53- } \
54- } \
55- const_stack[const_stack_top] = _x; \
56- in_consts = 1; \
57- } while(0)
58-
59- #define CONST_STACK_RESET () do { \
60- const_stack_top = -1; \
61- } while(0)
62-
63- #define CONST_STACK_LASTN (i ) \
64- &const_stack[CONST_STACK_LEN() - i]
65-
66- #define CONST_STACK_POP (i ) do { \
67- assert(CONST_STACK_LEN() >= i); \
68- const_stack_top -= i; \
69- } while(0)
70-
7126/* Scans back N consecutive LOAD_CONST instructions, skipping NOPs,
7227 returns index of the Nth last's LOAD_CONST's EXTENDED_ARG prefix.
7328 Callers are responsible to check CONST_STACK_LEN beforehand.
@@ -88,8 +43,7 @@ lastn_const_start(const _Py_CODEUNIT *codestr, Py_ssize_t i, Py_ssize_t n)
8843 }
8944 }
9045 else {
91- assert (_Py_OPCODE (codestr [i ]) == NOP ||
92- _Py_OPCODE (codestr [i ]) == EXTENDED_ARG );
46+ assert (_Py_OPCODE (codestr [i ]) == EXTENDED_ARG );
9347 }
9448 }
9549}
@@ -172,39 +126,40 @@ copy_op_arg(_Py_CODEUNIT *codestr, Py_ssize_t i, unsigned char op,
172126 The consts table must still be in list form so that the
173127 new constant (c1, c2, ... cn) can be appended.
174128 Called with codestr pointing to the first LOAD_CONST.
175- Bails out with no change if one or more of the LOAD_CONSTs is missing.
176129*/
177130static Py_ssize_t
178131fold_tuple_on_constants (_Py_CODEUNIT * codestr , Py_ssize_t c_start ,
179- Py_ssize_t opcode_end , unsigned char opcode ,
180- PyObject * consts , PyObject * * objs , int n )
132+ Py_ssize_t opcode_end , PyObject * consts , int n )
181133{
182- PyObject * newconst , * constant ;
183- Py_ssize_t i , len_consts ;
184-
185134 /* Pre-conditions */
186135 assert (PyList_CheckExact (consts ));
187136
188137 /* Buildup new tuple of constants */
189- newconst = PyTuple_New (n );
138+ PyObject * newconst = PyTuple_New (n );
190139 if (newconst == NULL ) {
191140 return -1 ;
192141 }
193- for (i = 0 ; i < n ; i ++ ) {
194- constant = objs [i ];
142+
143+ for (Py_ssize_t i = 0 , pos = c_start ; i < n ; i ++ , pos ++ ) {
144+ assert (pos < opcode_end );
145+ pos = find_op (codestr , pos );
146+ assert (_Py_OPCODE (codestr [pos ]) == LOAD_CONST );
147+
148+ unsigned int arg = get_arg (codestr , pos );
149+ PyObject * constant = PyList_GET_ITEM (consts , arg );
195150 Py_INCREF (constant );
196151 PyTuple_SET_ITEM (newconst , i , constant );
197152 }
198153
199154 /* Append folded constant onto consts */
200- len_consts = PyList_GET_SIZE (consts );
201155 if (PyList_Append (consts , newconst )) {
202156 Py_DECREF (newconst );
203157 return -1 ;
204158 }
205159 Py_DECREF (newconst );
206160
207- return copy_op_arg (codestr , c_start , LOAD_CONST , len_consts , opcode_end );
161+ return copy_op_arg (codestr , c_start , LOAD_CONST ,
162+ PyList_GET_SIZE (consts )- 1 , opcode_end );
208163}
209164
210165static unsigned int *
@@ -274,10 +229,8 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
274229 unsigned char * lnotab ;
275230 unsigned int cum_orig_offset , last_offset ;
276231 Py_ssize_t tabsiz ;
277- PyObject * * const_stack = NULL ;
278- Py_ssize_t const_stack_top = -1 ;
279- Py_ssize_t const_stack_size = 0 ;
280- int in_consts = 0 ; /* whether we are in a LOAD_CONST sequence */
232+ // Count runs of consecutive LOAD_CONSTs
233+ unsigned int cumlc = 0 , lastlc = 0 ;
281234 unsigned int * blocks = NULL ;
282235
283236 /* Bail out if an exception is set */
@@ -314,8 +267,6 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
314267 goto exitError ;
315268 assert (PyList_Check (consts ));
316269
317- CONST_STACK_CREATE ();
318-
319270 for (i = find_op (codestr , 0 ) ; i < codelen ; i = nexti ) {
320271 opcode = _Py_OPCODE (codestr [i ]);
321272 op_start = i ;
@@ -328,23 +279,21 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
328279 nexti ++ ;
329280 nextop = nexti < codelen ? _Py_OPCODE (codestr [nexti ]) : 0 ;
330281
331- if (!in_consts ) {
332- CONST_STACK_RESET ();
333- }
334- in_consts = 0 ;
282+ lastlc = cumlc ;
283+ cumlc = 0 ;
335284
336285 switch (opcode ) {
337286 /* Skip over LOAD_CONST trueconst
338287 POP_JUMP_IF_FALSE xx. This improves
339288 "while 1" performance. */
340289 case LOAD_CONST :
341- CONST_STACK_PUSH_OP ( i ) ;
290+ cumlc = lastlc + 1 ;
342291 if (nextop != POP_JUMP_IF_FALSE ||
343292 !ISBASICBLOCK (blocks , op_start , i + 1 ) ||
344293 !PyObject_IsTrue (PyList_GET_ITEM (consts , get_arg (codestr , i ))))
345294 break ;
346295 fill_nops (codestr , op_start , nexti + 1 );
347- CONST_STACK_POP ( 1 ) ;
296+ cumlc = 0 ;
348297 break ;
349298
350299 /* Try to fold tuples of constants.
@@ -353,15 +302,10 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
353302 Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */
354303 case BUILD_TUPLE :
355304 j = get_arg (codestr , i );
356- if (j > 0 && CONST_STACK_LEN () >= j ) {
305+ if (j > 0 && lastlc >= j ) {
357306 h = lastn_const_start (codestr , op_start , j );
358307 if (ISBASICBLOCK (blocks , h , op_start )) {
359- h = fold_tuple_on_constants (codestr , h , i + 1 , opcode ,
360- consts , CONST_STACK_LASTN (j ), j );
361- if (h >= 0 ) {
362- CONST_STACK_POP (j );
363- CONST_STACK_PUSH_OP (h );
364- }
308+ h = fold_tuple_on_constants (codestr , h , i + 1 , consts , j );
365309 break ;
366310 }
367311 }
@@ -374,12 +318,10 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
374318 } else if (j == 2 ) {
375319 codestr [op_start ] = PACKOPARG (ROT_TWO , 0 );
376320 fill_nops (codestr , op_start + 1 , nexti + 1 );
377- CONST_STACK_RESET ();
378321 } else if (j == 3 ) {
379322 codestr [op_start ] = PACKOPARG (ROT_THREE , 0 );
380323 codestr [op_start + 1 ] = PACKOPARG (ROT_TWO , 0 );
381324 fill_nops (codestr , op_start + 2 , nexti + 1 );
382- CONST_STACK_RESET ();
383325 }
384326 break ;
385327
@@ -538,7 +480,6 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
538480 }
539481 assert (h + (Py_ssize_t )nops == codelen );
540482
541- CONST_STACK_DELETE ();
542483 PyMem_Free (blocks );
543484 code = PyBytes_FromStringAndSize ((char * )codestr , h * sizeof (_Py_CODEUNIT ));
544485 PyMem_Free (codestr );
@@ -549,7 +490,6 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
549490
550491 exitUnchanged :
551492 Py_XINCREF (code );
552- CONST_STACK_DELETE ();
553493 PyMem_Free (blocks );
554494 PyMem_Free (codestr );
555495 return code ;
0 commit comments