[Vm-dev] Direct pointer vs pointerForOop()

David T. Lewis lewis at mail.msen.com
Sat Apr 7 14:32:23 UTC 2018


On Sat, Apr 07, 2018 at 02:25:18PM +0200, Nicolas Cellier wrote:
>  
> Hi all,
> I was about fixing
> https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/240
> some implementations use int to pass a pointer, that clearly does not work
> in 64bits...
> 
> What we need is to pass a buffer which is a Smalltalk ByteArray (or
> WordArray or something), in other word an oop, (stored into a sqInt/usqInt).
> 
> In Cog/Spur, an oop is a direct machine pointer, so we can avoid a
> translation and that's why some implementation directly declare a void*
> parameter.
> 
> In legacy interpreter VM, an oop is always an sqInt, but not always a
> pointer. For example a 32bits image can run on a VM compiled for 64bits,
> and in this case, sqInt is 32-bit wide, while the pointer is 64bits. So we
> used to pass thru pointerForOop. Some implementations do that.
> 
> So what we have now is a big mix of partly compatible/uncompatible code. We
> have to fix the int buf, but what should we better use, pointerForOop(sqInt
> buf) or direct void *buf?
> 
> Nicolas

It is good to maintain a clear distinction between object pointers
and "C" pointers.

There were (and still are) a number of plugins that never got updated
to be 32/64 bit clean. These still have problems such as pointers stored
in int fields. For these cases, it is best to explicitly declare data types
for things like pointers and structs. Once that is done properly, the
rest of the problems go away.

I have long thought that it would be a good idea for purposes of clarity
to have a separate "sqObjectPointer" data type distinct from sqInt and
usqInt. This would make the intentions clear, and I think it would make
the VM code easier to read and understand. But it would probably be a
lot of work to do this throughout the VM.

One thing that I did do was write MemoryAccess as a replacement for the
C macros. One reason for this was to document the functions, because I
always have a hard time remembering what the various macros actually do.
For example, in the case of the pointerForOop() macro, it looks like this:

pointerForOop: oop
	"Answer the machine address of the object to which oop refers. This method maps
	object memory locations to their underlying machine addresses (C pointers).

	char *pointerForOop(usqInt oop) { return sqMemoryBase + oop; }"

	<inline: true>
	<returnTypeC: 'char *'>
	<var: #oop type: 'usqInt'>
	^ self sqMemoryBaseAddress + oop


Dave



More information about the Vm-dev mailing list