[Vm-dev] Probably pointless endianness question re: Float changes circa 4.6

Eliot Miranda eliot.miranda at gmail.com
Sun Jul 5 22:00:23 UTC 2020


Hi Tim,

> On Jul 5, 2020, at 12:52 PM, Tim Johnson <digit at sonic.net> wrote:
> 
> Hi all,
> 
> I finally achieved something I have wanted to do for ten years, though its relevance has steadily declined over that time:  build the Carbon and Cocoa VMs on a PowerPC Mac.
> 
> - Carbon VM (4.2.5b1, from VMMaker 4.2.4 on Squeak 4.1)
> - iOS/ObjC/Cocoa VM (5.7b2, from VMMaker 4.2.6 on Squeak 4.1)
> 
> After building a successful product, I took the Carbon VM and began incrementing the non-oscog VMMaker's version in a Squeak 4.5 image.  I was able to build products along the way from 4.3.21 past 4.4.12 and beyond.  (I had to stop when [as could be expected] some plugins wouldn't export and some support code was missing.)
> 
> Eventually I had a Mac Carbon VM which could load 4.6's format 6505 image, and it began displaying the world, but it also had a few drawing errors and didn't respond to events.  A snip from SqueakDebug.log is at the end of this message, but probably isn't worth anyone's time to evaluate!
> 
> Where I think my efforts hit a dead end is with the Float changes [2] in the 6505 image format used by Squeak 4.6 [1].
> 
> But I'm just hoping to verify here that the Float changes in image format 6505 could have fatal implications for a big-endian platform like PowerPC (the formerly-native format for the Floats ;) ) on a "vintage" stack/interpreter VM, and that perhaps that would have been /expected/ to be the last straw for it.  (A further question might be:  how big would the lift have been to keep it going?  Or was that work done and just would require some extra attention?)

I designed the scheme so that it would *not* have fatal implications on any platform :-)

First let’s understand the representation.  A Float is a double-precision 64-bit ieee float represented as a two element word array. 

Before the changes floats were always stored in the heap in big-endian format which meant:

- aFloat at: 1 accessed the most significant word of the float on both big & little median platforms 
- on little endian platforms the vm therefore has to word reverse Float objects, perform arithmetic to obtain a new 64-big float, and word reverse it to store it back into a new Float

This unfairly penalizes little endian platforms.

My simple change was three-fold:
1. A bit in the image header specifies whether floats in the image are in big-endian format (bit unset) or in platform format (eg big endian on PPC, little endian on x86).

2. on load if required all Floats would be word reversed to ensure they are in platform order

3. Float at: was modified so that on little endian platforms Float at: 1 answered the most significant word, just as it does on big endian platforms, hence hiding from the image the change in layout on little endian platforms and avoiding having to do any word reversal in arithmetic on any platforms


So what I did leveled the playing field.  How does this have fatal consequences for big endian platforms?

Note that the word reversal on Float at: is for free because the primitive only takes 1&2 as valid indices, so the implementation is really cheap.  So in fact what I did was ensure that fp was as fast as possible on both platforms and (consciously) didn’t penalize either platform.

Does this explanation make the scheme seem more sensible now?

> 
> I'm sure none of this is relevant or worth time.  I guess my main question is whether this was supposed to have "kept working" but didn't — and whether that could have lingering implications on Squeak's effort (thanks David T Lewis!) to continue supporting the stack/interpreter VMMaker (though specifically only affecting big-endian platforms, which admittedly is a very small population).  I suppose there could hypothetically be some big-endian platform out there which gets some Linux package of the 4.10.2 VM and fails to launch any image past 4.5 for similar reasons...?
> 
> FWIW, I did try the old Darwin/PPC port of 4.10.2 [3]  with both 4.6 and David T Lewis's "Squeak 5.2-in-V3 format" image (which is no longer available on the 'net!) and it exhibited similar behavior:  couldn't display the world, ate 100% CPU, had to be forced to quit.
> 
> Thanks,
> a Tim
> 
> [1] http://wiki.squeak.org/squeak/6290
> [2] http://forum.world.st/float-word-order-td106936.html
> [3] http://squeakvm.org/unix/
> 
> Error: Cannot truncate this number
> 3 July 2020 8:11:03.001 am
> 
> VM: unix - Smalltalk
> Image: Squeak4.6 [latest update: #13700]
> 
> SecurityManager state:
> Restricted: false
> FileAccess: true
> SocketAccess: true
> Working Dir /Users/ADMIN/Downloads/Squeak4.6-13700
> Trusted Dir /Users/ADMIN/Downloads/Squeak4.6-13700/secure
> Untrusted Dir /Users/ADMIN/Downloads/Squeak4.6-13700/My Squeak
> 
> Float(Object)>>error:
>    Receiver: NaN
>    Arguments and temporary variables:
>        aString:    'Cannot truncate this number'
>    Receiver's instance variables:
> NaN
> Float>>truncated
>    Receiver: NaN
>    Arguments and temporary variables:
>        di:    nil
>        df:    nil
>        q:    nil
>        r:    nil
>    Receiver's instance variables:
> NaN
> Float>>rounded
>    Receiver: NaN
>    Arguments and temporary variables:
> 
>    Receiver's instance variables:
> NaN
> Color>>setRed:green:blue:
>    Receiver: <<error during printing>>
>    Arguments and temporary variables:
>        r:    NaN
>        g:    NaN
>        b:    NaN
>    Receiver's instance variables:
>        rgb:    nil
>        cachedDepth:    nil
>        cachedBitPattern:    nil
> 
> Color class>>r:g:b:
>    Receiver: Color
>    Arguments and temporary variables:
>        r:    NaN
>        g:    NaN
>        b:    NaN
>    Receiver's instance variables:
>        superclass:    Object
>        methodDict:    a MethodDictionary(size 107)
>        format:    136
>        instanceVariables:    #('rgb' 'cachedDepth' 'cachedBitPattern')
>        organization:    ('access' alpha blue brightness green hue luminance red saturatio...etc...
>        subclasses:    {TranslucentColor}
>        name:    #Color
>        classPool:    a Dictionary(#Black->Color black #Blue->Color blue #BlueShift->0 #Br...etc...
>        sharedPools:    nil
>        environment:    Smalltalk
>        category:    #'Graphics-Primitives'
> 
> Color class>>r:g:b:alpha:
>    Receiver: Color
>    Arguments and temporary variables:
>        r:    NaN
>        g:    NaN
>        b:    NaN
>        alpha:    0.0
>    Receiver's instance variables:
>        superclass:    Object
>        methodDict:    a MethodDictionary(size 107)
>        format:    136
>        instanceVariables:    #('rgb' 'cachedDepth' 'cachedBitPattern')
>        organization:    ('access' alpha blue brightness green hue luminance red saturatio...etc...
>        subclasses:    {TranslucentColor}
>        name:    #Color
>        classPool:    a Dictionary(#Black->Color black #Blue->Color blue #BlueShift->0 #Br...etc...
>        sharedPools:    nil
>        environment:    Smalltalk
>        category:    #'Graphics-Primitives'
> 
> Color>>alphaMixed:with:
>    Receiver: Color veryDarkGray
>    Arguments and temporary variables:
> 


More information about the Vm-dev mailing list