[Vm-dev] Sometimes it's too easy, part II

Andres Valloud avalloud at smalltalk.comcastbiz.net
Sat Jan 28 07:54:28 UTC 2017

I recently tackled this problem with the scheme below:

1.  qOop is a pointer sized unsigned integer.

2.  oop is typedef'ed as a pointer to a qOop.

3.  sqOop is a pointer sized signed integer.

4.  If *oop is tagged as a small integer, one has the right to cast *oop 
as an sqOop.  This new sqOop is the small integer value encoded in the oop.

5.  If *oop is not tagged, one has the right to cast *oop as an oop, and 
dereference this new oop.

This naming scheme subsumes the "int" part within the "q".  In practice, 
qOop makes a lot of sense because it reads as "q the size of an oop", 
just like qN reads as "q of N bits" --- although I'd explore letting N's 
unit be bytes instead.  Overall, the meaning is very close to the 
underlying assembly / compiler output / jitted code.

The sqOop type for small integers is close enough, I doubt we will have 
so many tag bits as to justify a small integer value type significantly 
smaller than that of a signed integer the size of a pointer.

I'd rather not key in uintptr_t and friends every time, so:

	typedef uintptr_t qOop;

I replaced the previously existing type scheme with the above, and 1000 
LOC went away in the process.  New code feels easy to write, too.  I'd 
say this approach turned out very well.

Nothing prevents the following, if needed:

#if PRE_C99


On 1/26/17 8:52 , Eliot Miranda wrote:
> Hi Bert,
> On Jan 26, 2017, at 2:42 AM, Bert Freudenberg <bert at freudenbergs.de
> <mailto:bert at freudenbergs.de>> wrote:
>> Awesome! However ...
>> On Wed, Jan 25, 2017 at 6:22 PM, Eliot Miranda
>> <eliot.miranda at gmail.com <mailto:eliot.miranda at gmail.com>> wrote:
>>     The default type for oops in the VM is sqInt (*), which is signed.
>> ... since this keeps biting us time and time again, how hard would it
>> be to change? Defaulting to unsigned seems much more reasonable, no?
>> Unless we're dealing with SmallIntegers, which have to be
>> special-cased anyways, we never want unsigned behavior, right?
> well, I've wanted to change this for some time but potentially it's a
> lot of work, as it affects the plugin and platform support code as much
> as the VM source.  But let's at least discuss it.
> First, what exactly do we do?  Right now we have sqInt & usqInt as
> oop-sized signed and unsigned types.  My list of pros and cons below is
> off the top of my head, preliminary.  Most of the below share the issue
> that we have to identify places where signed SmallInteger arithmetic is
> done and re-type them appropriately.  Do we
> - a) change the code generator to use usqInt as the default type in
> place of sqInt?
>    pros presumably minimal changes except to code generator and removing
> pragmas that specify usqInt?
>    cons rewriting platform support code to use usqInt for at least
> parameters
> - b) add a new default type, e.g. oop_t, which is the same as usqInt?
>   pros, see above
>   cons figuring out which usqInt types apply to oops and which to
> unsigned values
> - c) change sqInt to be unsigned and add e.g. ssqInt as a signed type
>    pros don't have to change platform source
> - d) add a new default type, e.g. oop_t, which is the same as char *?
>    pros oops are pointers
>     cons C allows arithmetic on char *, so this won't fix inappropriate
> arithmetic on oops
>          It's undefined in C whether pointers to different structures
> can be compared (but I do not know if an implement ration that refuses
> to compare pointers as simply addresses)
> - e) use void * instead of char * (too horrible bow to contemplate cuz
> one can't compare void *)
> - f..z) ?
> Bert, is there a similar analysis for SqueakJS or are the C types
> irrelevant and ignored?
> Anyway, looks to me like a) or c) are the main contenders.  What d'all
> think?
>> - Bert -
>> (*) fixed the typo

More information about the Vm-dev mailing list