@@ -328,68 +328,25 @@ intern_strings(PyObject *tuple)
328328#define ABSOLUTE_JUMP (op ) (op==JUMP_ABSOLUTE || op==CONTINUE_LOOP)
329329#define GETJUMPTGT (arr , i ) (GETARG(arr,i) + (ABSOLUTE_JUMP(arr[i]) ? 0 : i+3))
330330#define SETARG (arr , i , val ) arr[i+2] = val>>8; arr[i+1] = val & 255
331- #define CODESIZE (op ) (HAS_ARG(op) ? 3 : 1)
332- #define ISBASICBLOCK (blocks , start , bytes ) (blocks[start]==blocks[start+bytes-1])
333-
334- static unsigned int *
335- markblocks (unsigned char * code , int len )
336- {
337- unsigned int * blocks = PyMem_Malloc (len * sizeof (int ));
338- int i ,j , opcode , oldblock , newblock , blockcnt = 0 ;
339-
340- if (blocks == NULL )
341- return NULL ;
342- memset (blocks , 0 , len * sizeof (int ));
343- for (i = 0 ; i < len ; i += CODESIZE (opcode )) {
344- opcode = code [i ];
345- switch (opcode ) {
346- case FOR_ITER :
347- case JUMP_FORWARD :
348- case JUMP_IF_FALSE :
349- case JUMP_IF_TRUE :
350- case JUMP_ABSOLUTE :
351- case CONTINUE_LOOP :
352- case SETUP_LOOP :
353- case SETUP_EXCEPT :
354- case SETUP_FINALLY :
355- j = GETJUMPTGT (code , i );
356- oldblock = blocks [j ];
357- newblock = ++ blockcnt ;
358- for (; j < len ; j ++ ) {
359- if (blocks [j ] != (unsigned )oldblock )
360- break ;
361- blocks [j ] = newblock ;
362- }
363- break ;
364- }
365- }
366- return blocks ;
367- }
368331
369332static PyObject *
370333optimize_code (PyObject * code , PyObject * consts )
371334{
372335 int i , j , codelen ;
373336 int tgt , tgttgt , opcode ;
374337 unsigned char * codestr ;
375- unsigned int * blocks ;
376338
377339 /* Make a modifiable copy of the code string */
378340 if (!PyString_Check (code ))
379341 goto exitUnchanged ;
380342 codelen = PyString_Size (code );
381343 codestr = PyMem_Malloc (codelen );
382- if (codestr == NULL )
344+ if (codestr == NULL )
383345 goto exitUnchanged ;
384346 codestr = memcpy (codestr , PyString_AS_STRING (code ), codelen );
385- blocks = markblocks (codestr , codelen );
386- if (blocks == NULL ) {
387- PyMem_Free (codestr );
388- goto exitUnchanged ;
389- }
390347 assert (PyTuple_Check (consts ));
391348
392- for (i = 0 ; i < codelen ; i += CODESIZE (codestr [i ])) {
349+ for (i = 0 ; i < codelen - 7 ; i += HAS_ARG (codestr [i ]) ? 3 : 1 ) {
393350 opcode = codestr [i ];
394351 switch (opcode ) {
395352
@@ -406,8 +363,8 @@ optimize_code(PyObject *code, PyObject* consts)
406363 SETARG (codestr , i , 4 );
407364 break ;
408365
409- /* Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2 JMP+2 NOP NOP .
410- Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2 JMP+1 NOP .
366+ /* Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2 JMP+2.
367+ Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2 JMP+1.
411368 Note, these opcodes occur together only in assignment
412369 statements. Accordingly, the unpack opcode is never
413370 a jump target. */
@@ -420,50 +377,20 @@ optimize_code(PyObject *code, PyObject* consts)
420377 codestr [i ] = ROT_TWO ;
421378 codestr [i + 1 ] = JUMP_FORWARD ;
422379 SETARG (codestr , i + 1 , 2 );
423- codestr [i + 4 ] = NOP ;
424- codestr [i + 5 ] = NOP ;
380+ codestr [i + 4 ] = DUP_TOP ; /* Filler codes used as NOPs */
381+ codestr [i + 5 ] = POP_TOP ;
425382 continue ;
426383 }
427384 if (GETARG (codestr , i ) == 3 && \
428385 GETARG (codestr , i + 3 ) == 3 ) {
429386 codestr [i ] = ROT_THREE ;
430387 codestr [i + 1 ] = ROT_TWO ;
431388 codestr [i + 2 ] = JUMP_FORWARD ;
432- SETARG (codestr , i + 2 , 1 );
433- codestr [i + 5 ] = NOP ;
389+ SETARG (codestr , i + 2 , 1 );
390+ codestr [i + 5 ] = DUP_TOP ;
434391 }
435392 break ;
436393
437- /* Simplify inverted tests.
438- Must verify that sequence is a basic block because the jump
439- can itself be a jump target. Also, must verify that *both*
440- jump alternatives go to a POP_TOP. Otherwise, the code will
441- expect the stack value to have been inverted. */
442- case UNARY_NOT :
443- if (codestr [i + 1 ] != JUMP_IF_FALSE || \
444- codestr [i + 4 ] != POP_TOP || \
445- !ISBASICBLOCK (blocks ,i ,5 ))
446- continue ;
447- tgt = GETJUMPTGT (codestr , (i + 1 ));
448- if (codestr [tgt ] != POP_TOP )
449- continue ;
450- codestr [i ] = NOP ;
451- codestr [i + 1 ] = JUMP_IF_TRUE ;
452- break ;
453-
454- /* not a is b --> a is not b
455- not a in b --> a not in b
456- not a is not b --> a is b
457- not a not in b --> a in b */
458- case COMPARE_OP :
459- j = GETARG (codestr , i );
460- if (codestr [i + 3 ] != UNARY_NOT || j < 6 || \
461- j > 9 || !ISBASICBLOCK (blocks ,i ,4 ))
462- continue ;
463- SETARG (codestr , i , (j ^1 ));
464- codestr [i + 3 ] = NOP ;
465- break ;
466-
467394 /* Replace jumps to unconditional jumps */
468395 case FOR_ITER :
469396 case JUMP_FORWARD :
@@ -475,7 +402,7 @@ optimize_code(PyObject *code, PyObject* consts)
475402 case SETUP_EXCEPT :
476403 case SETUP_FINALLY :
477404 tgt = GETJUMPTGT (codestr , i );
478- if (!UNCONDITIONAL_JUMP (codestr [tgt ]))
405+ if (!UNCONDITIONAL_JUMP (codestr [tgt ]))
479406 continue ;
480407 tgttgt = GETJUMPTGT (codestr , tgt );
481408 if (opcode == JUMP_FORWARD ) /* JMP_ABS can go backwards */
@@ -495,7 +422,6 @@ optimize_code(PyObject *code, PyObject* consts)
495422 }
496423 code = PyString_FromStringAndSize (codestr , codelen );
497424 PyMem_Free (codestr );
498- PyMem_Free (blocks );
499425 return code ;
500426
501427exitUnchanged :
0 commit comments