[squeak-dev] inlining repeat and the decompiler (Compiler-nice.186)

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Sat Apr 2 12:49:36 UTC 2011


That can happen only if
    self generateAsClosure
answer false in BlockNode.

That can happen if (blockExtent == nil)

Only #analyseTempsWithin:rootNode:assignmentPools: does fill this ivar.
But it never do it if optimized.

So probably, the block is deOptimize-d too late after the analyseTemps
is performed...

Nicolas

2011/4/2 Levente Uzonyi <leves at elte.hu>:
> On Thu, 31 Mar 2011, Eliot Miranda wrote:
>
>> Hi All,
>>
>>   just a note that once Compiler-nice.186 is installed, which inlines
>> #repeat, one needs to recompile all senders of repeat to avoid having the
>> decompiler crap out on you, e.g. in the debugger.  For example the
>
> IMHO it's simply a decompiler bug. It should be able to decompile
> non-inlined #repeat sends, because it's possible in the current system to
> write code which yields such bytecodes. For example:
>
> [ ] repeat; yourself.
>
> Just tried the following which raises an interesting error:
>
> [ [ ] repeat; yourself ] decompile
>
> The error is:
>
> 'DecompilerConstructorForClosures(Object)>>error:
> DecompilerConstructorForClosures(Object)>>primitiveFailed:
> DecompilerConstructorForClosures(Object)>>primitiveFailed
> DecompilerConstructorForClosures(Object)>>primitiveChangeClassTo:
> Decompiler>>sawBlueBookBlock
> Decompiler>>checkForBlockCopy:
> Decompiler>>checkForBlock:selector:arguments:
> Decompiler>>send:super:numArgs:
> Decompiler(InstructionStream)>>interpretNextInstructionFor:
> Decompiler>>interpretNextInstructionFor:
> Decompiler>>statementsTo:
> Decompiler>>blockTo:
> Decompiler>>doClosureCopyCopiedValues:numArgs:blockSize:
> Decompiler>>pushClosureCopyNumCopiedValues:numArgs:blockSize:
> Decompiler(InstructionStream)>>interpretExtension:in:for:
> Decompiler(InstructionStream)>>interpretNextInstructionFor:
> Decompiler>>interpretNextInstructionFor:
> Decompiler>>statementsTo:
> Decompiler>>blockTo:
> Decompiler>>decompile:in:method:using:
> Decompiler>>decompile:in:method:
> CompiledMethod>>getSourceFor:in:
> CompiledMethod>>methodNode
> CompiledMethod>>decompileWithTemps
> Decompiler>>decompileBlock:
> BlockClosure>>decompile
> UndefinedObject>>DoIt
> ...
>
> The source of the error is:
>
> Decompiler >> sawBlueBookBlock
>        constructor isForClosures ifTrue:
>                [constructor primitiveChangeClassTo: DecompilerConstructor
> new]
>
> I guess the decompiler should never see a blue book block, so it seems to be
> a compiler bug. The bytecodes for the CompiledMethod are:
>
> 25 <8F 00 00 0C> closureNumCopied: 0 numArgs: 0 bytes 29 to 40
> 29      <89> pushThisContext:
> 30      <75> pushConstant: 0
> 31      <C8> send: blockCopy:
> 32      <A4 02> jumpTo: 36
> 34              <73> pushConstant: nil
> 35              <7D> blockReturn
> 36      <88> dup
> 37      <D1> send: repeat
> 38      <87> pop
> 39      <D2> send: yourself
> 40      <7D> blockReturn
> 41 <D0> send: decompile
> 42 <7C> returnTop
>
> Evaluating the following is also funny, it brings you back to the world of
> BlockContexts:
>
> [ self halt ] repeat; yourself
>
>
> Levente
>
>> compilation of
>>
>> GeneratorTest methods for generators
>> fibonacciSequence
>> "Yields an infinite sequence of fibonacci numbers."
>> ^ Generator on: [ :generator |
>> | a b |
>> a := 0. b := 1.
>> [ a := b + (b := a).
>>  generator yield: a ]
>> repeat ]
>>
>> with non-inlined repeat:
>> pushLit: Generator
>> closureNumCopied: 0 numArgs: 1 bytes 34 to 72
>> pushConstant: nil
>> push: (Array new: 2)
>> popIntoTemp: 1
>> pushConstant: 0
>> popIntoTemp: 0 inVectorAt: 1
>> pushConstant: 1
>> popIntoTemp: 1 inVectorAt: 1
>> pushTemp: 0
>> pushTemp: 1
>> closureNumCopied: 2 numArgs: 0 bytes 52 to 70
>> pushTemp: 1 inVectorAt: 1
>> pushTemp: 0 inVectorAt: 1
>> storeIntoTemp: 1 inVectorAt: 1
>> send: #+ (1 arg)
>> popIntoTemp: 0 inVectorAt: 1
>> pushTemp: 0
>> pushTemp: 0 inVectorAt: 1
>> send: #yield: (1 arg)
>> blockReturn
>> send: #repeat (0 args)
>> blockReturn
>> send: #on: (1 arg)
>> returnTop
>>
>> with inlined repeat:
>> pushLit: Generator
>> closureNumCopied: 0 numArgs: 1 bytes 34 to 53
>> pushConstant: nil
>> pushConstant: nil
>> pushConstant: 0
>> popIntoTemp: 1
>> pushConstant: 1
>> popIntoTemp: 2
>> L1:
>> pushTemp: 2
>> pushTemp: 1
>> storeIntoTemp: 2
>> send: #+ (1 arg)
>> popIntoTemp: 1
>> pushTemp: 0
>> pushTemp: 1
>> send: #yield: (1 arg)
>> pop
>> jumpTo: L1
>> pushConstant: nil
>> blockReturn
>> send: #on: (1 arg)
>> returnTop
>>
>>
>> will cause the decompiler to fail horribly if the non-inlined result is
>> decompiled with Compiler-nice.186 installed.  The fix is merely to
>> recompile
>> it (and other senders of #repeat).  The underlying problem is that if the
>> is
>> given temp names via a schematicTempNamesString then that string must
>> match
>> the temps in the method, and in the above if repeat is not inlined a and b
>> are remote, and hence the schematicTempNamesString is [generator (a b)]
>> but
>> if repeat is inlined then they are local and the schematicTempNamesString
>> is
>> [generator a b].
>>
>> BTW, kudos to Nicholas for the newParser/newCompiler changes!
>>
>> best
>> Eliot
>>
>
>



More information about the Squeak-dev mailing list