fixed address objects (was Calling straight C code)

Jan Bottorff janb at pmatrix.com
Wed Mar 10 05:36:07 UTC 1999


At 12:17 PM 3/9/99 -0800, Tim Rowledge wrote:
>A couple of weeks ago there were some questions about being able to handle
>objects that do not move, for things like bitmap buffers etc. I said I had
some
>code that could do just that and that I would look it out and post it.

((JanB brain) at:#uglyExternalObjects) dumpOn:emailer.

Hmmm. I'm a bit puzzled by how this really would work. The Squeak object
format assumes there is a header in the bytes just before the object data
(correct me if this is wrong). If you want to create say a bitmap that's
actually a real live frame buffer you will not be able to put the header
where Squeak expects it to be. For objects malloced, you can shift things
along in memory, although this may then destroy certain alignment
expectations. For example, if you memory map a file, and want it to show up
as a ByteArray, there is simply no place to put the header.

On possibility is to arrange for object pointers that align on 4 byte
boundries to be treated as "external" objects. You then keep a map that
translates from these aligned addresses to an object header someplace else.
This takes coordination with immediate object representation format (like
SmallInteger). I had worked out the following oop layout at one time:

xx..xxx1	- Small immediate float, 32-bit float with one bit of the exponent
dropped (can you say 3-D)

xx..xx00	- External object, use hash table to figure our object class and
other info, allow direct mixing of Smalltalk and C++ and Microsoft COM
objects (at least from Smalltalk's viewpoint), message sending to external
objects can go thru a central dispatcher that knows how to do a send in the
external format (C++ or COM)

xx..0010	- Normal Smalltalk objects, allways referenced with -2 offset, and
allocate on 16 byte boundry

xx..0110	- SmallInteger space, allows 28 bits of signed magnitude (+/-
134,000,000 or so)

xx..1010	- Other immediate classes, 28 available bits is enough for
immediate Point's with 14 bit precision

xx..001110	- Char's

xx..011110	- whatever...
xx..101110
xx..111110

So this oop format gives, immediate Float's, SmallInteger's, SmallPoint's,
Char's, whatever's, and distinguishable values for most external objects
(class mapped thru a hash table). I believe this is not too painful from an
immediate testing viewpoint, as you often test for an oop being a specific
class and not for exclusion from a group of classes. For example, normal
object testing becomes:

	mov	edx,eax	; make copy for destructive test
	and	edx,0x0F	; mask low 4 bits
	cmp	edx,0x02	; is it a normal non-immediate object?
	jne	notNormal

instead of:

	test	eax,1		; assume only SmallInt is immediate, with low tag bit
	jnz	notNormal

My memory is this oop layout also is ugly from a C syntax viewpoint. To
access an object instance variable, you needed C source like this:

	theIvar = ((INSTANCE *)(((BYTE *)theOop)-2))->interestingIvar;
	theIvar = GetIvar(theOop,INSTANCE,interestingIvar);  // of course C macros
can also hide all this uglyness

All this still doesn't really create exact ByteArray objects that can live
in your video frame buffer. It does make external objects (including
external non-Smalltalk objects) behaive just like a (new class of)
Smalltalk object. It also assumes external objects will allways be 4 byte
aligned, which in almost every case will be true (except for the
exceptions). This idea was part of the VM instruction set research I was
doing a few years ago. Part of the goal was to have Smalltalk and C++/COM
objects coexist. The little detail on how to make C++/COM do it's part
wasn't so well worked out, you would need a vtable in every Smalltalk
object (yuk), not to mention C++ has no understanding about immediate objects.

It seems like other solutions to this are: 1) you need to have an object
table, that stores the headers apart from the actual data 2) you need to
have memory pointer objects, which have an instance variable with the
actual address (these are not really true objects then). I suppose you
could also have a header bit that tells if the object body is following or
if it's indirected thru a pointer.

The problem of doing GC on arbitrary binary structures is sticky too. You
could have some sort of GC map to describe where references in the binary
structure may be. A not insurmountable, but still sticky strategy would be
to just follow everything that might be a pointer, and somehow determine if
its really is a reference. In the past, I've used both exception trapping,
and a sparse address space tree to decide valid references from binary
garbage (things had to work in a sparse memory environment with ROM and
RAM). Lot's of people (some from PARC) have looked into GC in assorted
languages very deeply. I personally think this is all really ugly compared
to the nice clean run-time/memory environment in Smalltalk where you know
where the references are.

- Jan




___________________________________________________________________
            Paradigm Matrix Inc., San Ramon California
   "video products and development services for Win32 platforms"
Internet: Jan Bottorff janb at pmatrix.com
          WWW          http://www.pmatrix.com
Phone: voice  (925) 803-9318
       fax    (925) 803-9397
PGP: public key  <http://www-swiss.ai.mit.edu/~bal/pks-toplev.html>
     fingerprint  52 CB FF 60 91 25 F9 44  6F 87 23 C9 AB 5D 05 F6
___________________________________________________________________





More information about the Squeak-dev mailing list