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

Mariano Martinez Peck marianopeck at gmail.com
Fri Dec 2 20:42:30 UTC 2011


The following method looks complicated for me. Do you know if it is still
valid in latest Cog ?
Thanks :)


eliotsClosureMeasurementsOn: m over: aFiveArgBlock
    "
    See senders.
    Or try something like:
        Smalltalk
            eliotsClosureMeasurementsOn: FileList >> #defaultContents
            over: [ :closuresCount :hasCopiedValuesForClosure
:hasIndirectTemps :anyClosureHasCopied :anyClosureDoesUAR
:anyClosureUsesSelf |
                (Array with: closuresCount with: hasCopiedValuesForClosure
with: hasIndirectTemps with: anyClosureHasCopied with: anyClosureDoesUAR
with: anyClosureUsesSelf)]

    From
http://www.mirandabanda.org/cogblog/2008/11/14/mechanised-modifications-and-miscellaneous-measurements/
    by Eliot Miranda
    "
    | s nextScanStart thisClosureHasCopied closuresCount hasIndirectTemps
blkPc blkSz anyClosureHasCopied anyClosureDoesUAR anyClosureUsesSelf
analyzedClosures |
    closuresCount := 0.
    hasIndirectTemps := false.
    anyClosureHasCopied :=  anyClosureDoesUAR := anyClosureUsesSelf :=
false.
    s := InstructionStream on: m.
    s scanFor: [ :b |
        b = 16r8F "16r8F = 143 closure creation" ifTrue: [
            closuresCount := closuresCount + 1].
        (b = 16r8A "16r8A = 138indirect temp vector creation" and: [ s
followingByte <= 127]) ifTrue: [
                hasIndirectTemps := true].
        false].
    nextScanStart := m initialPC.
    analyzedClosures := 0.
    [ analyzedClosures < closuresCount ] whileTrue: [
        s pc: nextScanStart; scanFor: [ :b | b = 16r8F ].    "16r8F = 143
Search for first closure"
        analyzedClosures := analyzedClosures + 1.
        thisClosureHasCopied := s followingByte >= 16r10.
        anyClosureHasCopied := anyClosureHasCopied | thisClosureHasCopied.
        blkSz := s interpretNextInstructionFor: BlockStartLocator new.
    "Findout size of first closure"
        blkPc := s pc.
        s scanFor: [ :b |
            s pc >= (blkPc + blkSz)
                ifTrue: [
                    nextScanStart := s pc.
                    true]
                ifFalse: [
                    b = 16r8F ifTrue: [
                        thisClosureHasCopied := s followingByte >= 16r10.
                        anyClosureHasCopied := anyClosureHasCopied |
thisClosureHasCopied.
                        analyzedClosures := analyzedClosures + 1 ].
                    anyClosureDoesUAR := anyClosureDoesUAR or: [s
willReturn and: [s willBlockReturn not]].
                    anyClosureUsesSelf := anyClosureUsesSelf or: [b = 16r70
"pushSelf"
                                        or: [b < 16r10 "pushInstVar"
                                        or: [(b = 16r80 and: [s
followingByte <= 16r3F]) "pushInstVar"
                                        or: [(b between: 16r60 and: 16r60 +
7) "storePopInstVar"
                                        or: [(b = 16r82 and: [s
followingByte <= 63]) "storePopInstVar"
                                        or: [(b = 16r81 and: [s
followingByte <= 63]) "storeInstVar"
                                        or: [b = 16r84 and: [s
followingByte = 160]]]]]]]].
                    false]]].
    ^aFiveArgBlock valueWithArguments: (Array
            with: closuresCount
            with: hasIndirectTemps
            with: anyClosureHasCopied
            with: anyClosureDoesUAR
            with: anyClosureUsesSelf)

On Fri, Dec 2, 2011 at 9:40 PM, Mariano Martinez Peck <marianopeck at gmail.com
> wrote:

>
>
> On Fri, Dec 2, 2011 at 8:30 PM, Juan Vuletich <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>**> 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". 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
>
>


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


More information about the Squeak-dev mailing list