The following method looks complicated for me. Do you know if it is still valid in latest Cog ?<br>Thanks :)<br><br><br>eliotsClosureMeasurementsOn: m over: aFiveArgBlock<br> "<br> See senders.<br> Or try something like:<br>
Smalltalk<br> eliotsClosureMeasurementsOn: FileList >> #defaultContents<br> over: [ :closuresCount :hasCopiedValuesForClosure :hasIndirectTemps :anyClosureHasCopied :anyClosureDoesUAR :anyClosureUsesSelf |<br>
(Array with: closuresCount with: hasCopiedValuesForClosure with: hasIndirectTemps with: anyClosureHasCopied with: anyClosureDoesUAR with: anyClosureUsesSelf)]<br><br> From <a href="http://www.mirandabanda.org/cogblog/2008/11/14/mechanised-modifications-and-miscellaneous-measurements/">http://www.mirandabanda.org/cogblog/2008/11/14/mechanised-modifications-and-miscellaneous-measurements/</a><br>
by Eliot Miranda<br> "<br> | s nextScanStart thisClosureHasCopied closuresCount hasIndirectTemps blkPc blkSz anyClosureHasCopied anyClosureDoesUAR anyClosureUsesSelf analyzedClosures |<br> closuresCount := 0.<br>
hasIndirectTemps := false.<br> anyClosureHasCopied := anyClosureDoesUAR := anyClosureUsesSelf := false.<br> s := InstructionStream on: m.<br> s scanFor: [ :b |<br> b = 16r8F "16r8F = 143 closure creation" ifTrue: [<br>
closuresCount := closuresCount + 1].<br> (b = 16r8A "16r8A = 138indirect temp vector creation" and: [ s followingByte <= 127]) ifTrue: [<br> hasIndirectTemps := true].<br> false].<br>
nextScanStart := m initialPC.<br> analyzedClosures := 0.<br> [ analyzedClosures < closuresCount ] whileTrue: [<br> s pc: nextScanStart; scanFor: [ :b | b = 16r8F ]. "16r8F = 143 Search for first closure"<br>
analyzedClosures := analyzedClosures + 1.<br> thisClosureHasCopied := s followingByte >= 16r10.<br> anyClosureHasCopied := anyClosureHasCopied | thisClosureHasCopied.<br> blkSz := s interpretNextInstructionFor: BlockStartLocator new. "Findout size of first closure"<br>
blkPc := s pc.<br> s scanFor: [ :b |<br> s pc >= (blkPc + blkSz)<br> ifTrue: [<br> nextScanStart := s pc.<br> true]<br> ifFalse: [<br>
b = 16r8F ifTrue: [ <br> thisClosureHasCopied := s followingByte >= 16r10.<br> anyClosureHasCopied := anyClosureHasCopied | thisClosureHasCopied.<br>
analyzedClosures := analyzedClosures + 1 ].<br> anyClosureDoesUAR := anyClosureDoesUAR or: [s willReturn and: [s willBlockReturn not]].<br> anyClosureUsesSelf := anyClosureUsesSelf or: [b = 16r70 "pushSelf"<br>
or: [b < 16r10 "pushInstVar"<br> or: [(b = 16r80 and: [s followingByte <= 16r3F]) "pushInstVar"<br> or: [(b between: 16r60 and: 16r60 + 7) "storePopInstVar"<br>
or: [(b = 16r82 and: [s followingByte <= 63]) "storePopInstVar"<br> or: [(b = 16r81 and: [s followingByte <= 63]) "storeInstVar"<br>
or: [b = 16r84 and: [s followingByte = 160]]]]]]]].<br> false]]].<br> ^aFiveArgBlock valueWithArguments: (Array<br> with: closuresCount<br> with: hasIndirectTemps<br>
with: anyClosureHasCopied<br> with: anyClosureDoesUAR<br> with: anyClosureUsesSelf)<br><br><div class="gmail_quote">On Fri, Dec 2, 2011 at 9:40 PM, Mariano Martinez Peck <span dir="ltr"><<a href="mailto:marianopeck@gmail.com">marianopeck@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><br><br><div class="gmail_quote"><div><div class="h5">On Fri, Dec 2, 2011 at 8:30 PM, Juan Vuletich <span dir="ltr"><<a href="mailto:juan@jvuletich.org" target="_blank">juan@jvuletich.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Eliot Miranda wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>
<br>
<br>
On Fri, Dec 2, 2011 at 10:55 AM, Mariano Martinez Peck <<a href="mailto:marianopeck@gmail.com" target="_blank">marianopeck@gmail.com</a> <mailto:<a href="mailto:marianopeck@gmail.com" target="_blank">marianopeck@gmail.com</a>><u></u>> wrote:<br>
<br>
Thanks both. I am right to assume that if the block refers to temp<br>
vars, parameters, or whatever in another scope, then such solution<br>
won't work. I mean, if I have this example for example:<br>
<br>
| bytes result blah |<br>
blah := 42.<br>
bytes := FLSerializer serializeToByteArray: (SortedCollection<br>
sortBlock: [:a :b | (a + blah) > b ]).<br>
<br>
Then the 'blah' is in a different context. So the mentioned<br>
solution works for "clean" closures, which are "self contained".<br>
In the other cases (such as this example), we should serialize the<br>
whole stack. Is this correct?<br>
<br>
<br>
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.<br></div>
...<br>
</blockquote>
<br>
WRT clean closures, check what I did in Cuis to serialize SortedCollections. See implementors and senders of #isClean.<br>
<br></blockquote></div></div><div><br>Nice. Thanks Juan. I was checking your code, and that's exactly why I asked Eliot. In your method you say:<br><br>isClean<br> "A clean closure is one that doesn't really need the home context because:<br>
- It doesn't send messages to self or super<br> - It doesn't access any instance variable<br> - It doesn't access any outer temp<br> - It doesn't do ^ return"<br>.....<br>
<br>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 ?<br>
<br><br>Thanks a lot in advance!</div></div><span class="HOEnZb"><font color="#888888"><br><br clear="all"><br>-- <br>Mariano<br><a href="http://marianopeck.wordpress.com" target="_blank">http://marianopeck.wordpress.com</a><br>
<br>
</font></span></blockquote></div><br><br clear="all"><br>-- <br>Mariano<br><a href="http://marianopeck.wordpress.com" target="_blank">http://marianopeck.wordpress.com</a><br><br>