]> granicus.if.org Git - python/commitdiff
Issue #1754094: Improve the stack depth calculation in the compiler.
authorNeil Schemenauer <nascheme@enme.ucalgary.ca>
Wed, 14 Oct 2009 17:17:14 +0000 (17:17 +0000)
committerNeil Schemenauer <nascheme@enme.ucalgary.ca>
Wed, 14 Oct 2009 17:17:14 +0000 (17:17 +0000)
There should be no other effect than a small decrease in memory use.
Patch by Christopher Tur Lesniewski-Laas.

Misc/NEWS
Python/compile.c

index 2fdbd6dfa1281eba232b07448a997386b2e53144..5c5acd7a8a6336ef1251ba43f0ba31eec26655eb 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,10 @@ What's New in Python 2.7 alpha 1
 Core and Builtins
 -----------------
 
+- Issue #1754094: Improve the stack depth calculation in the compiler.
+  There should be no other effect than a small decrease in memory use.
+  Patch by Christopher Tur Lesniewski-Laas.
+
 - Issue #7084: Fix a (very unlikely) crash when printing a list from one
   thread, and mutating it from another one.  Patch by Scott Dial.
 
index 3b5f5ef0a77ff15d62c63d105680c9784390c21f..844aca6be909aeb2fb8c8658aefe9e34e3d52f21 100644 (file)
@@ -692,13 +692,13 @@ opcode_stack_effect(int opcode, int oparg)
                        return -1;
 
                case SLICE+0:
-                       return 1;
-               case SLICE+1:
                        return 0;
+               case SLICE+1:
+                       return -1;
                case SLICE+2:
-                       return 0;
-               case SLICE+3:
                        return -1;
+               case SLICE+3:
+                       return -2;
 
                case STORE_SLICE+0:
                        return -2;
@@ -778,7 +778,8 @@ opcode_stack_effect(int opcode, int oparg)
                case POP_BLOCK:
                        return 0;
                case END_FINALLY:
-                       return -1; /* or -2 or -3 if exception occurred */
+                       return -3; /* or -1 or -2 if no exception occurred or
+                                     return/break/continue */
                case BUILD_CLASS:
                        return -2;
 
@@ -789,7 +790,7 @@ opcode_stack_effect(int opcode, int oparg)
                case UNPACK_SEQUENCE:
                        return oparg-1;
                case FOR_ITER:
-                       return 1;
+                       return 1; /* or -1, at end of iterator */
 
                case STORE_ATTR:
                        return -2;
@@ -815,7 +816,7 @@ opcode_stack_effect(int opcode, int oparg)
                case COMPARE_OP:
                        return -1;
                case IMPORT_NAME:
-                       return 0;
+                       return -1;
                case IMPORT_FROM:
                        return 1;
 
@@ -835,10 +836,9 @@ opcode_stack_effect(int opcode, int oparg)
                case CONTINUE_LOOP:
                        return 0;
                case SETUP_LOOP:
-                       return 0;
                case SETUP_EXCEPT:
                case SETUP_FINALLY:
-                       return 3; /* actually pushed by an exception */
+                       return 0;
 
                case LOAD_FAST:
                        return 1;
@@ -867,7 +867,7 @@ opcode_stack_effect(int opcode, int oparg)
                                return -1;
 
                case MAKE_CLOSURE:
-                       return -oparg;
+                       return -oparg-1;
                case LOAD_CLOSURE:
                        return 1;
                case LOAD_DEREF:
@@ -3328,7 +3328,7 @@ dfs(struct compiler *c, basicblock *b, struct assembler *a)
 static int
 stackdepth_walk(struct compiler *c, basicblock *b, int depth, int maxdepth)
 {
-       int i;
+       int i, target_depth;
        struct instr *instr;
        if (b->b_seen || b->b_startdepth >= depth)
                return maxdepth;
@@ -3341,8 +3341,17 @@ stackdepth_walk(struct compiler *c, basicblock *b, int depth, int maxdepth)
                        maxdepth = depth;
                assert(depth >= 0); /* invalid code or bug in stackdepth() */
                if (instr->i_jrel || instr->i_jabs) {
+                       target_depth = depth;
+                       if (instr->i_opcode == FOR_ITER) {
+                               target_depth = depth-2;
+                       } else if (instr->i_opcode == SETUP_FINALLY ||
+                                  instr->i_opcode == SETUP_EXCEPT) {
+                               target_depth = depth+3;
+                               if (target_depth > maxdepth)
+                                       maxdepth = target_depth;
+                       }
                        maxdepth = stackdepth_walk(c, instr->i_target,
-                                                  depth, maxdepth);
+                                                  target_depth, maxdepth);
                        if (instr->i_opcode == JUMP_ABSOLUTE ||
                            instr->i_opcode == JUMP_FORWARD) {
                                goto out; /* remaining code is dead */