Thank you eliot,2014-08-19 7:29 GMT+02:00 Eliot Miranda <eliot.miranda@gmail.com>:
Hi Nicolai,
the stack starts as deep as the method's number of temporaries,ok,which is the sum of the number of argumentsok,plus the number of temporary variables that can exist in the stackok (what does "can exist in the stack" mean? They always do?)
plus one if there are any closed-over temporary variables that need to be in an indirection vector. Then as execution proceeds the receiver and arguments are pushed on the stack, and are replaced by intermediate results by sends it by the create array bytecode.So, for a method with no blocks, the stack is just the number of temporaries plus the number of args for the message send with the maximum number of args?
Any blocks within the method start with the sum of their number of arguments, their number of copied values (temp values they access read-only) plus their local temporaries.But this is not just added to the stack size, right?
I have a method with 9 local temporaris and a block in this method with 8 local temporaries and the frameSize is still 16, (with the old compiler/ 56 with the new compiler).So, method and block local temporaries not just sum up?
I tried different variations
- numberOfMethod temps smaller/equal/greater numberOfBlockTemp- no/some/all method temporaries are accessed in the block closure.But I can not see a pattern :)
In the method and each block scope stack depth is the hence the sum of the number of temporaries plus the max execution depth. And the method's depth is the max of the method and that of any blocks within it.What is the execution depth of a method ? The number of "nested blocks"?
Then if that depth is 17 or greater it gets the LargeFrame flag set which means the VM allocates a 56 slot context, the compiler raising an error if the depth is greater than 56.
HTH
Eliot (phone)Here are two carefully handcrafted methods :)
fooSmall
|t1 t2 t3 t4 t5 t6 t7 t8|
t1:=1.
t2:=2.
t3:=3.
t4:=4.
t5:=5.
t6:=6.
t7:=7.
t8:= 8.
t1:=[:i | |b1 b2 b3 b4 c1 c2 c3 c4 x|
b1:=1. b2:=2. b3:=3. b4:=4.
c1:=1. c2:=2. c3:=3. c4:=4.
x:=1.
x+t1 + b1+b2+b3+b4 + c1 + c2 + c3 + c4] value:1.
^ t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8
fooLarge
|t1 t2 t3 t4 t5 t6 t7|
t1:=1.
t2:=2.
t3:=3.
t4:=4.
t5:=5.
t6:=6.
t7:=7.
t1:=[:i | |b1 b2 b3 b4 c1 c2 c3 c4 x|
b1:=1. b2:=2. b3:=3. b4:=4.
c1:=1. c2:=2. c3:=3. c4:=4.
x:=1.
x+t1 +t2 + t3 + t4 + t5+ b1+b2+b3+b4 + c1 + c2 + c3 + c4] value:1.
^ t1 + t2 + t3 + t4 + t5 + t6 + t7They differ only in the number of tempraries (t1-t8 / t1-t7) and the number of copied values for the block closure (1 / 5).
with the old compiler:fooSmall frameSize -> 16
fooLarge frameSize -> 56the opal compiler computes the opposite sizes
fooSmall frameSize -> 56
fooLarge frameSize -> 16
I am confused.
On Aug 18, 2014, at 11:32 PM, Nicolai Hess <nicolaihess@web.de> wrote:
> Hi,
>
> on what depends the stack size for a compiled method?
> I try to figure out, why the old compiler and the opal compile generate different
> compiled method headers.
> I think this comes from a wrong stack size computed by opal, but I can not figure
> out how the stack size is computed.
>
> Old Compiler
> PolygonMorph>>#lineSegmentsDo:
> header -> "primitive: 0
> numArgs: 1
> numTemps: 3
> numLiterals: 23
> frameSize: 56"
>
> Opal compiler:
> PolygonMorph>>#lineSegmentsDo:
> header -> "primitive: 0
> numArgs: 1
> numTemps: 3
> numLiterals: 23
> frameSize: 16"
>