Issue 26549: co_stacksize is calculated from unoptimized code (original) (raw)

Created on 2016-03-12 22:45 by ztane, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (7)

msg261668 - (view)

Author: Antti Haapala (ztane) *

Date: 2016-03-12 22:45

When answering a question on StackOverflow, I noticed that a function that only loads a constant tuple to a local variable still has a large co_stacksize as if it was built with BUILD_TUPLE.

e.g.

>>> def foo():
...     a = (1,2,3,4,5,6,7,8,9,10)
...
>>> foo.__code__.co_stacksize
10
>>> dis.dis(foo)
  2           0 LOAD_CONST              11 ((1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
              3 STORE_FAST               0 (a)
              6 LOAD_CONST               0 (None)
              9 RETURN_VALUE

I suspect it is because in the makecode the stack usage is calculated from the unoptimized assembler output instead of the actual optimized bytecode. I do not know if there is any optimization that would increase the stack usage, but perhaps it should be calculated from the resulting output.

msg261700 - (view)

Author: Brett Cannon (brett.cannon) * (Python committer)

Date: 2016-03-13 17:36

I also suspect you're right, Antti, that the stack size is calculated prior to the bytecode being passed to through the peepholer which would have made the built tuple a value in the const array.

Off the top of my head I don't remember where the stack size calculation is made, but my suspicion is it's in the AT -> bytecode step, which would mean making it work from bytecode would mean re-implementing that calculation to work from the bytecode itself (assuming I'm right).

msg264088 - (view)

Author: Jelle Zijlstra (JelleZijlstra) * (Python committer)

Date: 2016-04-24 01:34

This also affects co_consts, which includes constants that are no longer used by the optimized code:

In [8]: def f(): return (1, 2, 3, 4, 5) ...:

In [9]: f.func_code.co_consts Out[9]: (None, 1, 2, 3, 4, 5, (1, 2, 3, 4, 5))

In [12]: dis.dis(f) 2 0 LOAD_CONST 6 ((1, 2, 3, 4, 5)) 3 RETURN_VALUE

msg265217 - (view)

Author: Meador Inge (meador.inge) * (Python committer)

Date: 2016-05-10 02:02

Strictly speaking, the stack size is calculated after the peephole optimizer is run, but the code that computes the stack depth operates on the basic block graph instead of the assembled and optimized byte code.

Anyway, the conclusion is the same as Brett noted -- the stack depth analysis would need to be re-written to operate on the optimized bytecode array.

msg265702 - (view)

Author: Meador Inge (meador.inge) * (Python committer)

Date: 2016-05-16 15:54

See also

msg308281 - (view)

Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer)

Date: 2017-12-14 08:27

Seems moving constant folding to the AST level () have solved this issue.

def foo(): ... a = (1,2,3,4,5,6,7,8,9,10) ... foo.code.co_stacksize 1

msg308298 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2017-12-14 13:30

Seems moving constant folding to the AST level () have solved this issue.

Wow, it's cool to see this bug finally fixed!

History

Date

User

Action

Args

2022-04-11 14:58:28

admin

set

github: 70736

2017-12-14 13:30:36

vstinner

set

messages: +

2017-12-14 08:27:59

serhiy.storchaka

set

status: open -> closed
superseder: AST-level Constant folding
messages: +

resolution: out of date
stage: resolved

2017-07-22 09:33:07

pitrou

set

nosy: + vstinner, serhiy.storchaka

2016-05-18 19:40:37

vstinner

set

type: performance

2016-05-16 15:54:03

meador.inge

set

messages: +

2016-05-10 02:02:02

meador.inge

set

nosy: + meador.inge
messages: +

2016-04-24 01:34:40

JelleZijlstra

set

nosy: + JelleZijlstra
messages: +

2016-03-13 17:36:44

brett.cannon

set

messages: +

2016-03-13 16:02:52

SilentGhost

set

nosy: + brett.cannon, georg.brandl, ncoghlan, benjamin.peterson, yselivanov

2016-03-12 22:45:45

ztane

create