[Openmcl-devel] something is not quite right in cocoa land

Gary Byers gb at clozure.com
Fri Jun 10 16:15:38 PDT 2005

On Fri, 10 Jun 2005, alex crain wrote:

> On Jun 8, 2005, at 11:13 PM, Gary Byers wrote:
>> If the class involved is declared, the current mechanism is about the
>> same as the old mechanism: we have search trees which contain all
>> known (declared) ObjC classes and metaclasses; for a given pointer:
>>   1) if the pointer is found in the metaclass tree, it's that metaclass
>>   2) if the pointer is found in the class tree, it's that class
>>   3) if we think that it's safe to indirect through the first word in
>>      the pointer (the "isa" field) and that first word is found in the
>>      class tree, the pointer is an instance of that class.
>> This mostly happens in the function RECOGNIZE-OBJC-OBJECT.
>> When we start up/restart a saved images, we enumerate all foreign
>> classes. (We should also ensure that this happens whenever someone
>> loads an auxiliary ObjC library.)
>> If the class is declared, it gets added to the search trees; this is
>> how things have worked for a long time.
>> If the class is undeclared, it gets added to another search tree
>> (one used to track "private ObjC classes"; I don't remember its name
>> offhand.)  The datum associated with each class in the private class
>> tree is a little structure that's supposed to contain information
>> about the nearest declared superclass.  That information isn't
>> filled out yet; the code that enumerates all classes should make
>> a pass over the private class tree and fill in that information.
>> Once that information's available, case 3 above gets extended;
>>   3b) if the pointer's "isa" field is found in the private class
>>       tree, the pointer is an instance of the public class associated
>>       with that private class.  We may or may not want to define some
>>       extra pointer type bits so that we can recognize that the instance
>>       isn't a "true" or "direct" instance, but I think that we can
>>       almost always ignore this distinction.
> So if I'm tracking this right, an undeclared objc class is not an instance of 
> a class
> but rather and instance of PRIVATE-OBJC-CLASS-INFO. This isn't a problem
> because the only thing that need to understand undeclared classes would be
> SEND, %SEND, PRINT-OBJECT and a few assorted things that call OBJC-CLASS-OF.
> CLASS-OF and TYPE-OF are going to need to return the nearest declared 
> superclass
> in order to be consistent but that seems reasonable enough since any 
> slots/methods in
> an undeclared type are effectively private.

Note that CLASS-OF uses information returned by RECOGNIZE-OBJC-OBJECT,
and (once it gets by a few built-in types) TYPE-OF is basically

> There are several places in the code where we can safely assume that a macptr 
> is
> a objc instance or class: methods that return :ID and ALLOCATE-INSTANCE come 
> to mind.
> If we insert code in the method returns that will register objects on the fly 
> then we should
> catch all the cases.

The most expensive part of recognizing an ObjC object is (probably) the
part that tries to determine whether or not a pointer was allocated by
malloc or is in some library section that may contain static strings. I
think that there's code that tries to skip the heuristics for SELF, and
we could apply it to other things known to be of type :ID.

I'd have to think about it a bit more, but my first reaction is that
knowing that it's safe to skip the heuristic ("safe pointer") check
is a good thing, but only if we have some reason to want to know the
(CLOS) class of something.  RECOGNIZE-OBJC-OBJECT has to do a few
tree searches; those should usually be < log2 n (splay-trees reorganize
themselves so that "popular" search keys bubble up near the root), but
we only need to do any of this if we need to do a (CLOS) CLASS-OF (or
similar operation.)

> Did I miss anything?

I don't think so.  I -think- that the short-term change (case 3B in
RECOGNIZE-OBJC-OBJECT, support for it in the "private ObjC class"
tree) will likely either get you to the point where you can make
progress on Hemlock or we'll see problems that aren't apparent to
either of us yet.

One tip (if it's not obvious): multiple MACPTRs can point to the same
address; such pointers are EQL but distinct MACPTRs aren't EQ to
each other.  The CLOS implementation assumes that classes (whether
"standard" or "foreign") can be compared with EQ, so it's important
that ObjC class (and metaclass) pointers be canonicalized (that
things like CLASS-OF return the exact (EQ) MACPTR to a class that
CLOS knows about.)  E.g.:

   ;;; Assume that INSTANCE is known to be an ObjC instance of some
   ;;; class; return that class.

    #+wrong (pref instance :objc_object.isa)
    #-wrong (let* ((raw-class-pointer (pref instance :objc_object.isa)))
              (canonicalize-objc-class raw-class-pointer))

More information about the Openmcl-devel mailing list