[Vm-dev] Direct pointer vs pointerForOop()

Eliot Miranda eliot.miranda at gmail.com
Sun Apr 8 11:21:02 UTC 2018


Hi Subbu, Hi David,


> On Apr 8, 2018, at 3:30 AM, K K Subbu <kksubbu.ml at gmail.com> wrote:
> 
>> On Sunday 08 April 2018 02:34 AM, David T. Lewis wrote:
>> 
>> I was unclear in my meaning when I said "data type" for object pointers.
>> I really only meant something like "#typedef usqInt sqObjectPointer" such
>> that "sqObjectPointer" could be used when the intent is an object pointer,
>> and "usqInt" could be used when the intent is an unsigned integer. Nothing
>> would actually change, but it might make the VM code a bit easier to read
>> and understand.

I disagree. That isn't useful since sqInt doesn't mean "machine word", it means "integer containing an oop" and so adding sqObjectPointer is simply noise.

> 
> Your mail was very clear. But the new type is insufficient to handle all platform variations or suppress compiler warnings. An object pointer implementation could use direct address (void *), address offset (size_t) or table index (unsigned int). Compilers warn if we mix these in the same expression.

Duh. Come on, we know this.  It isn't the issue.  The interface files in platforms/Cross/plugins/XXXPlugin/XXXPlugin.h are free to specify one or the other (but should clearly not mix both).  If they specify integers then the cast to pointer has to happen in the platform implementations, leading to more casts.  If they specify pointers then the cast must happen in the generated plugin code.  I know which I prefer but fixing the warning means fixing the interface file and the plugin code in VMMaker and VMMaker.oscog since we've made zero progress on merging these two packages.

> 
>> With respect to defining data types, I think that Nicolas has already
>> handled the most important case with the introduction of sqIntptr and
>> usqIntptr. This clarifies the usage a lot, and cleans up a lot of problems
>> across different compilers and platforms.

Right.  But (pedantry) FYI it is sqIntptr_t.

> 
> This is a really good fix, but it won't stop compilers warning about mixing ints/pointers :-(. sqMemoryAccess.h has many comments like:
> -----
> sqInt is a signed integer with size adequate for holding an Object Oriented Pointer (or immediate value) ....
> ---
> 
> Such intents can be captured in directly in a single union. Arch-independent code could use oop or oop.asOop while different implementations could choose different representations (oop.asAddr, oop.asOffset, oop.asInt, etc) without having to use casts. I have tried using both casts and unions in my other projects, and the ones with unions proved to be compact, readable and compiled without type warnings.

No.  Using a union requires a huge rewrite of all of the platform code and VMMaker.

A feasible change is to replace sqInt globally with e.g. sqOop where sqOop is an anonymous pointer:

typedef sqOop struct _opaque_object *;

and then rewrite all arithmetic in VMMaker to cast from sqOop to sqInt, where sqInt is defined as "machine word", and discard the 64/32 and 32/64 configurations of VMMaker  as unsupportable.  But I don't the no David is happy about doing that.

In any case using the union is a red herring.  The issue is deciding whether an interface takes an integral argument or a pointer one and sticking to it, casting as appropriate on either side.  The secondary issue is that Slang chose the B route of calling everything an integer, which has costs and benefits, just like the alternative choices.

> 
>> You are right that "object pointer" is a confusing term for people who may
>> be thinking in terms of C pointers. We also have a fair amount of confusion
>> in the use of term "word". But in a very real sense, an object pointer
>> really is a pointer (not just an identifier), even if that does mean
>> something different from the term "pointer" in C. I don't know, maybe
>> "object reference" instead of "object pointer"?

An object pointer is only a pointer if we're prepared to drop support for 64/32 32/64 VMMaker configurations.  This is sane, David, but you'll have to sacrifice it.  Spur was architected on this notion. If I were free to make the decision I would 

- introduce
    typedef sqOop struct _opaque_object *;
- rewrite sqMemoryAccess.h appropriately
- make sqOop the default argument and parameter type in VMMaker (but not the default return type; that must remain sqInt because primitives don't return results; they put them in the stack explicitly (a different mess))
- make sqInt & usqInt synonymous with sqIntptr_t (i.e. always a machine word), & hence eliminate sqIntptr_t in favour of usqInt

And hang any platform that has different pointer and register sizes.  The DEC 10 and its ilk have died long ago and the MIPS in the PlayStation 2 has too.  Nowadays wide registers are CI fined to special instruction sets (SSE et al) and the general purpose registers are always pointer-sized.

But even this simple rational proposal, which simply says that an oop is a tagged pointer and if you're going to do arithmetic on it you're going to have to cast, is a /lot/ of work in VMMaker.

> Excellent suggestion! sqObjectRef fits neatly into object graph model.
> 
> Members like word, byte etc. are only used within platform implementation code where their meaning would be clear. Higher layers would only use oop.
> 
> Regards .. Subbu


More information about the Vm-dev mailing list