[squeak-dev] Re: [Pharo-project] Prune stack serialization

Mariano Martinez Peck marianopeck at gmail.com
Sat Dec 3 00:25:53 UTC 2011


Thank you very much Eliot and Juan for this nice discussion. I have just
commit this new functionality and it seems to work fine. I ended up using
Eliot's #abstractBytecodes since the one from Juan didn't work out of the
box in Pharo.


On Fri, Dec 2, 2011 at 10:38 PM, Eliot Miranda <eliot.miranda at gmail.com>wrote:

> Hi Juan,
>
> On Fri, Dec 2, 2011 at 11:59 AM, Juan Vuletich <juan at jvuletich.org> wrote:
>
>> Mariano Martinez Peck wrote:
>>
>>>
>>>
>>> On Fri, Dec 2, 2011 at 9:46 PM, Eliot Miranda <eliot.miranda at gmail.com<mailto:
>>> eliot.miranda at gmail.**com <eliot.miranda at gmail.com>>> wrote:
>>>
>>>
>>>
>>>    On Fri, Dec 2, 2011 at 12:40 PM, Mariano Martinez Peck
>>>    <marianopeck at gmail.com <mailto:marianopeck at gmail.com>**> wrote:
>>>
>>>
>>>
>>>        On Fri, Dec 2, 2011 at 8:30 PM, Juan Vuletich
>>>        <juan at jvuletich.org <mailto:juan at jvuletich.org>> wrote:
>>>
>>>            Eliot Miranda wrote:
>>>
>>>
>>>
>>>                On Fri, Dec 2, 2011 at 10:55 AM, Mariano Martinez Peck
>>>                <marianopeck at gmail.com <mailto:marianopeck at gmail.com>
>>>                <mailto:marianopeck at gmail.com
>>>
>>>                <mailto:marianopeck at gmail.com>**>> wrote:
>>>
>>>                   Thanks both. I am right to assume that if the block
>>>                refers to temp
>>>                   vars, parameters, or whatever in another scope,
>>>                then such solution
>>>                   won't work. I mean, if I have this example for example:
>>>
>>>                   | bytes result blah |
>>>                   blah := 42.
>>>                   bytes := FLSerializer serializeToByteArray:
>>>                (SortedCollection
>>>                   sortBlock: [:a :b | (a + blah) > b ]).
>>>
>>>                   Then the 'blah' is in a different context. So the
>>>                mentioned
>>>                   solution works for "clean" closures, which are
>>>                "self contained".
>>>                   In the other cases (such as this example), we
>>>                should serialize the
>>>                   whole stack. Is this correct?
>>>
>>>
>>>                No.  The closure implementation arranges that any and
>>>                all temporary variables accessed by the closure are
>>>                directly accessible from the closure without accessing
>>>                the outer contexts.
>>>                 ...
>>>
>>>
>>>            WRT clean closures, check what I did in Cuis to serialize
>>>            SortedCollections. See implementors and senders of #isClean.
>>>
>>>
>>>        Nice. Thanks Juan. I was checking your code, and that's
>>>        exactly why I asked Eliot. In your method you say:
>>>
>>>        isClean
>>>            "A clean closure is one that doesn't really need the home
>>>        context because:
>>>                - It doesn't send messages to self or super
>>>                - It doesn't access any instance variable
>>>                - It doesn't access any outer temp
>>>                - It doesn't do ^ return"
>>>        .....
>>>
>>>        So... my question is, WHAT do I need to serialize if I want to
>>>        be able to serialize also "non clean".
>>>
>>>
>>>    IMO, dy default, everything reachable from the closure, including
>>>    the outerContext chain and their senders.  But that's only a
>>>    default.  What makes sense in any given context is up to the
>>>    application, e.g. see Seaside.  One size won't fit all.  You
>>>    should handle the common cases (e.g. clean blocks and everything
>>>    else) and leave it up to the user to figure out what they need to
>>>    do in complex situations, making sure you provide them with the
>>>    hooks they'll need, such as the ability to substitute objects when
>>>    serializing etc, and perhaps some useful examples.
>>>
>>>
>>> +1   Then we will do the following: we will check whether the closure is
>>> clean. If it is, then we serialize just the closure plus its outerContext
>>> but only with receiver and method. If it is not clean, then we serialize
>>> the whole stack. That's all by default. If then someone needs something
>>> different, then to use the hooks :)
>>> So the final question is whether what Juan is using in Cuis is up to
>>> date. If it is, then I have all I need :)
>>> Thank you guys.
>>>
>>
>> I can say that it does indeed work. But I'd be really grateful if Eliot
>> took a good look at that code!
>>
>
> There is a much better way, using
> InstructionStream>>interpreetNextInstructionFor: which abstracts away from
> the bytecode encoding and allows one to simply use messages.  e.g. look at
>
> BlockClosure methods for private
> abstractBytecodes
> "Answer an OrderedCollection of the abstract bytecodes sent in the
> receiver."
>  | scanner blockCreationMessage end abstractBytecodes |
> scanner := InstructionStream new.
>  "find the creation message to find the extent of the block."
> scanner  method: self method pc: self method initialPC.
>  [scanner pc < startpc] whileTrue:
> [[scanner interpretNextInstructionFor: nil]
>  on: MessageNotUnderstood
> do: [:ex| blockCreationMessage := ex message]].
>  end := blockCreationMessage arguments last + startpc - 1.
> "now collect all the bytecode messages in the block."
>  abstractBytecodes := OrderedCollection new.
> scanner method: self method pc: startpc.
>  [scanner pc < end] whileTrue:
> [[scanner interpretNextInstructionFor: nil]
>  on: MessageNotUnderstood
> do: [:ex| abstractBytecodes add: ex message selector]].
>  ^abstractBytecodes
>
> and (SortedCollection sortBlock: [:a :b| a compare: b caseSensitive:
> false]) sortBlock abstractBytecodes evaluates to
>
> an OrderedCollection(#pushTemporaryVariable: #pushTemporaryVariable:
> #pushConstant: #send:super:numArgs:)
>
> So a check for clean blocks would check for a block's abstractBytecodes
> not including some particular set of banned messages (which I *think* is
> pushReceiver pushReceiverVariable: popIntoReceiverVariable:
> storeIntoReceiverVariable: methodReturnConstant: methodReturnReceiver
> methodReturnTop).
>
> e.g.
>
> isClean
>       ^(self abstractBytecodes intersection: #(pushReceiver
> pushReceiverVariable: popIntoReceiverVariable: storeIntoReceiverVariable:
> methodReturnConstant: methodReturnReceiver methodReturnTop)) isEmpty
>
>
>> Cheers,
>> Juan Vuletich
>>
>>
>>>
>>>
>>>        I mean, for each item on that list, what do I need apart from
>>>        the closure instance and the receiver and method from the
>>>        outerContext ?  the whole stack of contexts ?
>>>
>>>
>>>        Thanks a lot in advance!
>>>
>>>
>>>
>>>        --         Mariano
>>>        http://marianopeck.wordpress.**com<http://marianopeck.wordpress.com>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>    --     best,
>>>    Eliot
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> --
>>> Mariano
>>> http://marianopeck.wordpress.**com <http://marianopeck.wordpress.com>
>>>
>>> ------------------------------**------------------------------**
>>> ------------
>>>
>>>
>>>
>>> ------------------------------**------------------------------**
>>> ------------
>>>
>>> No virus found in this message.
>>> Checked by AVG - www.avg.com <http://www.avg.com>
>>> Version: 10.0.1411 / Virus Database: 2102/4052 - Release Date: 12/02/11
>>>
>>>
>>
>>
>
>
> --
> best,
> Eliot
>
>
>
>
>


-- 
Mariano
http://marianopeck.wordpress.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20111203/ae89c604/attachment.htm


More information about the Squeak-dev mailing list