On Wed, Aug 20, 2014 at 10:15 PM, Nicolai Hess <[email protected]> wrote:
> > 2014-08-19 19:02 GMT+02:00 Eliot Miranda <[email protected]>: > > Hi Nicolai, >> >> >> On Aug 19, 2014, at 11:58 AM, Nicolai Hess <[email protected]> wrote: >> >> Thank you eliot, >> >> >> 2014-08-19 7:29 GMT+02:00 Eliot Miranda <[email protected]>: >> >>> Hi Nicolai, >>> >>> the stack starts as deep as the method's number of temporaries, >> >> >> ok, >> >> >>> which is the sum of the number of arguments >> >> >> ok, >> >> >>> plus the number of temporary variables that can exist in the stack >> >> >> ok (what does "can exist in the stack" mean? They always do?) >> >> >> Not necessarily. The closure implementation moves temps that need it >> into an indirect temp vector. See eg my blog on the closure compiler. >> >> http://www.mirandabanda.org/cogblog/2008/06/07/closures-part-i/ >> >> 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? >> >> >> >> No. What about this: >> >> ^Point x: 1 y: (self a: 1 b: 2 c: 3) >> >> >> Before sending a:b:c: the stack is >> >> Point >> 1 >> self >> 1 >> 2 >> 3 >> >> >> 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 :) >> >> >> May be a bug in the old compiler. The stack size is the max of the >> separate sizes in the method and each block. >> >> >> >> >>> >>> 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"? >> >> >> No, it is how many things it pushes in the stack at the deepest point. >> See my example above. >> >> >> >>> 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 + t7 >> >> >> >> They 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 -> 56 >> >> >> >> the opal compiler computes the opposite sizes >> fooSmall frameSize -> 56 >> fooLarge frameSize -> 16 >> >> >> >> Looks like a bug in the Opal compiler :-). Well found. >> >> >> >> I am confused. >> >> >> No you're not. You've found a bug. Now find its cause.... >> > > > No, I am still confused :) > > Maybe you can help me with, how the old compiler computes the stack frame > in this examples: > > I changed CompiledMethod>>#needsFrameSize: > to write the value for self numTemps and newFrameSize to the Transcript > and compiled some simple functions: > > foo > |a b| > a:=1. > b:=1. > ^ a+b > > numTemps:2 > frameSize: 2 > > ok, two temps and two pushes on the stack > > > foo > ^ [ 1+1 ] > > numTemps:0 > frameSize: 2 > > ok, no temps and two pushs (push constant:1/push constant:1) on the stack > > > > > > foo > ^ [|a b| a:=1. b:=1. a+b ] > > numTemps:0 > frameSize: 4 > > ok, no (method) temps, why is the stackframe 4? Two block local temps and > two pushs. > > > |x y| > x:=1. > y:=1. > ^ [|a b| a:=1. b:=1. a+b ] > > numTemps:2 > frameSize: 2 > > Now what? Adding method temps enlarges the number of temps, ok. But the > stackframe decreases? > Looks like a bug. The stack size needed in |x y| x:=1. y:=1. ^ [|a b| a:=1. b:=1. a+b ] is 4, unless the compiler is optimizing away the a+b and is replacing the block with [1] ? The stack size of the outer method is 3 (2 temps + 1 for the push of either 1 or the block). > Nicolai > > > >> >> >> >> >>> >>> On Aug 18, 2014, at 11:32 PM, Nicolai Hess <[email protected]> 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" >>> > >>> >> >> >> Eliot (phone) >> > > -- best, Eliot
