[squeak-dev] Compiler

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Thu Jun 21 15:55:18 UTC 2012


2012/6/21 Bert Freudenberg <bert at freudenbergs.de>:
> On 2012-06-20, at 20:24, Nicolas Cellier wrote:
>
>> 2012/6/20 Bert Freudenberg <bert at freudenbergs.de>:
>>>
>>>>> in practice a unary method can have at most 56 temps, but that's shared with the stack [...] To overcome this we would need larger context objects.
>>>
>>> - Bert -
>>
>> Oh, but for the number of args, I already have a hack squeak-ready in
>> Smallapack, I just pass a single Array, and for the internal temps, we
>> could use the same trick, maybe I did that too in VW.
>>
>> I was more thinking of the depth of nested message a + (b + (c + (d +
>> ... will be translated as
>> push a; push b; push c; push d; ...; send +; send +; send +
>> Is there a limitation there ?
>
>
> No limit (except for method size). The stack of this context only needs to hold all the arguments for a single of these sends. It's cleared when the control returns to this context so it can be re-used for the next cascaded message send.
>
> That's why, for example, long brace arrays are compiled as
>
>        (Array braceStream: N) nextPut: expr1; nextPut: expr2; nextPut: expr3; ... nextPut: exprN
>
> whereas short ones used to be compiled as
>
>        Array braceWith: expr1 with: expr2 with: expr3
>
> Nowadays the short ones use Eliot's new "pop n into new array" byte code.
>
> - Bert -
>

OK, but with the LargeFrame = 56 limit, I cannot compile a method written

^1+(1+(1+(...  64x times )))

or I get an Error triggered by:

CompiledMethod>>needsFrameSize: newFrameSize
	"Set the largeFrameBit to accomodate the newFrameSize"
	| largeFrameBit header |
	largeFrameBit := 16r20000.
	(self numTemps + newFrameSize) > LargeFrame ifTrue:
		[^ TooDeepStackError signal: 'Cannot compile -- stack including
temps is too deep'].
	header := self objectAt: 1.
	(header bitAnd: largeFrameBit) ~= 0
		ifTrue: [header := header - largeFrameBit].
	self objectAt: 1 put: header
			+ ( ((self numTemps + newFrameSize) > SmallFrame or: [ self
primitive = 84 "perform:withArguments:"])
					ifTrue: [largeFrameBit]
					ifFalse: [0])

To overcome the limitation, I would have to re-arrange the order of
push/sends. Since I can't easily guess absence of side effect in
Smalltalk, I can't reorder.
So I would have to push in a temporary array rather than in a stack
(simulate a stack), then push (array at: i) on demand just before
sending (I think the closure bytecodes also provide some short form).
Phew...

Nicolas


More information about the Squeak-dev mailing list