[squeak-dev] Questions about FullBlock closures

Jaromir Matas mail at jaromir.net
Sun Feb 19 12:09:07 UTC 2023


Hi Eliot, tim, all,

>> On Feb 12, 2023, at 10:23 AM, tim Rowledge <tim at rowledge.org> wrote:
>>
>> The actual primitives for Cog are *much* more complex. Whilst I wouldn't normally advise looking at the C code for the VM, in this case it might be instructive to peek at the generated gcc3x-cointerp.c file and find the primitiveTerminateTo() routine.

> No, no and thrice times no!! :-) There is a story I'll tell you at the end if the email, but first...
>
> The only times to look at this code are probably
>  - when one is checking that Slang has generated the correct code from the VMMaker.oscog package’s Smalltalk code
>  - when debugging the VM at the C level instead of the Smalltalk level

I agree. I compared both the C and Slang code, both have (unsurprisingly) similar structure just the C code is way scarier :)

> If you do want to look at the code and make sense of it look at the VMMaker.oscog code in an image.  There is a script, image/buildspurtrunkvmmaker64image.sh that will build such an image.

Brilliant, thanks! I assume the script is unix based; evaluating BuildSqueakSpurTrunkVMMakerImage.st in a fresh image's workspace seems to do the job too, at least allows me to browse the system. Except: you need to replace 'sic reorganizeAsISeeFit' with 'sic perform: #reorganizeAsISeeFit' to be able to run it in one piece (enclosing).

Best,
Jaromir


--

From: Eliot Miranda<mailto:eliot.miranda at gmail.com>
Sent: Sunday, February 12, 2023 21:48
To: The general-purpose Squeak developers list<mailto:squeak-dev at lists.squeakfoundation.org>
Subject: Re: [squeak-dev] Questions about FullBlock closures

Hi Tim, hi All,



On Feb 12, 2023, at 10:23 AM, tim Rowledge <tim at rowledge.org<mailto:tim at rowledge.org>> wrote:
[snip]

The actual primitives for Cog are *much* more complex. Whilst I wouldn't normally advise looking at the C code for the VM, in this case it might be instructive to peek at the generated gcc3x-cointerp.c file and find the primitiveTerminateTo() routine.

No, no and thrice times no!! :-) There is a story I'll tell you at the end if the email, but first...

The only times to look at this code are probably
- when one is checking that Slang has generated the correct code from the VMMaker.oscog package’s Smalltalk code
- when debugging the VM at the C level instead of the Smalltalk level

If you do want to look at the code and make sense of it look at the VMMaker.oscog code in an image.  There is a script, image/buildspurtrunkvmmaker64image.sh https://github.com/OpenSmalltalk/opensmalltalk-vm/blob/Cog/image/buildspurtrunkvmmaker64image.sh, that will build such an image.

The VM’s interpreter code is the hierarchy of StackInterpreter.
The VM’s JIT code is the hierarchies of
   Cogit
   CogAbstractInstruction
    CogObjectRepresentation
The VM's memory managers are
    SpurMemoryManager
    NewObjectMemory

But on the "do..." menu you'll find
    openCogSpurMultiWindowBrowser
    openCogitMultiWindowBrowser
    openSpurMultiWindowBrowser
et al which make it much easier to browse this admittedly rather complex system. And in finding methods MessageNames is your friend. It understands patterns separated by semicolons.  So a MessageNames on *terminateTo* will find the code you;re looking for.

You'll also find workspaces to help you run the VM simulator, generate VM sources, JIOT a method, etc.


Now that story. Once upon a time Alan Kay's team were working at Hewlett-Packard. HP were trying to sell 64-bit machines based on the 64-bit HPPA RISC chip. One of the customers used Squeak.  So a team of HP engineers tried to port Squeak to 64-bits by starting with interp.c, the generated code for the 32-bit BackToTheFuture interpreter VM. They spent at least 6 months, and failed.  Alan was alerted and Dan Ingalls, Ian Piumarta and others did a very quick port, 3 months, IIRC, and this is why the original 64-bit Squeak stull only had 31-bit SmallIntegers, etc, [and is why I don't consider this a "real" 64-bit implementation.  It's merely a widening of the 32-bit implementation so that one can have 64-bit oops, but otherwise wastes lots of opportunities (64-bit Spur has 3 tagged (immediate) types, SmallInteger, Character, and SmallFloat64; it also supports 8-bit, 16-bit, 32-bit and 64-bit integer arrays, etc)].

The moral of this tale is that, no matter how good you are, you won't make head nor tail of the overall VM architecture and functionality looking at Slang's output. The only proper place to try and make sense of the VM is the level at which it is written and debugged, which is in Smalltalk.


  1.  Daniel Ingalls, Eliot Miranda, Clément Béra, and Elisa Gonzalez Boix. “Two Decades of Live Coding and Debugging of Virtual Machines through Simulation.”Software: Practice and Experience 50, no. 9 (2020): 1629–50. https://onlinelibrary.wiley.com/doi/abs/10.1002/spe.2841.
  2.  Eliot Miranda, Clément Béra, Elisa Gonzalez Boix, and Dan Ingalls. “Two Decades of Smalltalk VM Development: Live VM Development Through Simulation Tools.”In Proceedings of the 10th ACM SIGPLAN International Workshop on Virtual Machines and Intermediate Languages, 57–66. VMIL 2018. New York, NY, USA: ACM, 2018.https://doi.acm.org/10.1145/3281287.3281295.
  3.  Available on request.

_,,,^..^,,,_ (phone)




On 2023-02-12, at 7:53 AM, Eliot Miranda <eliot.miranda at gmail.com<mailto:eliot.miranda at gmail.com>> wrote:

Hi Jaromir,

On Feb 12, 2023, at 5:13 AM, Jaromir Matas <mail at jaromir.net<mailto:mail at jaromir.net>> wrote:


Hi,



What is the purpose of the primitive 196 Context>>#terminateTo:?



Strongly related to prim 195 & 197. You have to check each context up the chain to see what exceptions might be dealt with & by which context.



My understanding is prim 195 (#findNextUnwindContextUpTo:) searches for unwind contexts and prim 197 (#findNextHandlerContextStarting) searches for handler context. But prim 195 (#terminateTo:) is unclear to me. #terminateTo comment says:



"Terminate all the Contexts between me and previousContext, if previousContext is on my Context stack. Make previousContext my sender."



Which doesn't say much except it's nilling all context's pc and sender between self and the argument. I wonder what else it does behind the scenes and why :)



In a paper from 2009 Eliot wrote:

"[...] there’s a primitive terminateTo: that does something similar to the context nilling in non-local return. It is a little simpler than non-local return (although not much) but it is just a variation on the same theme so I’ll spare you."



I wish Eliot didn't spare us :) Other than that I haven't found any further info.



Because the primitive 196 dates back to 2001 I'm unable to judge whether it's still essential to nil the intermediate contexts (to free stack pages or something).



In particular I'm trying to understand whether the use of #terminateTo *primitive* in #resumeEvaluating: and #resume:through: is essential or not.


There are three things that primitive 296, Context>>terminateTo: does, or rather there are two things it does, and it does them in a particular way. It sets senders and pcs of intervening contexts to nil. It sets the sender of the receiver to the argument. If does this atomically.

I can’t say whether the last of these is necessary. If it is, then the primitive is needed, essential. But the primitive merely optimized the former two operations.

In the StackInterpreter & CoInterpreter it provides a significant optimization because

- the primitive avoids creating any contexts; if if were not implemented primitively then  contexts would have to be created for all intervening frames, merely to throw unreferenced ones away

- intervening stack pages can be freed without looking at their contents

So the primitive is an important optimization for Stack/CoInterpreter.

But I suspect that atomicity is not crucial and that therefore the terminateTo: primitive is only an optimization.

Any additional info greatly appreciated.


HTH

Thanks,

Jaromir



--

Jaromír Matas

mail at jaromir.net<mailto:mail at jaromir.net>





From: tim Rowledge
Sent: Sunday, February 12, 2023 5:18
To: The general-purpose Squeak developers list
Subject: Re: [squeak-dev] Questions about FullBlock closures





On 2023-02-11, at 4:04 PM, Jaromir Matas <mail at jaromir.net<mailto:mail at jaromir.net>> wrote:

If I may, I have a question here: What is the purpose of the primitive 196 Context>>#terminateTo:? Why primitive and why terminating each context along the way? Naively, I'd think checking the two contexts are in the same sender chain and patching them via privSender should do but I'm sure I'm missing something here :)


Exception handling stuff. Strongly related to prim 195 & 197. You have to check each context up the chain to see what exceptions might be dealt with & by which context. Look at e.g. Process>>#terminate for some context.


tim
--
tim Rowledge; tim at rowledge.org<mailto:tim at rowledge.org>; http://www.rowledge.org/tim
When flying inverted, remember that down is up and up is expensive




tim
--
tim Rowledge; tim at rowledge.org<mailto:tim at rowledge.org>; http://www.rowledge.org/tim
Useful random insult:- Life by Norman Rockwell, but screenplay by Stephen King.



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20230219/99a72c99/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: BuildSqueakSpurTrunkVMMakerImageWin.st
Type: application/octet-stream
Size: 3605 bytes
Desc: BuildSqueakSpurTrunkVMMakerImageWin.st
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20230219/99a72c99/attachment.obj>


More information about the Squeak-dev mailing list