Changeset 14198

Aug 18, 2010, 7:34:47 AM (9 years ago)

Revive some old code which tries to ensure that lisp slot-vectors
are removed when NSObjects are deallocated.

This approach may have problems (because of the way that tls cleanup
works on OSX, or at least the way that it used to) and is suboptimal;
the comments near the change discuss some other approaches.

It'd be interesting to see whether this change causes the symptoms
describe in ticket:706 to disappear. (If so, we know what the problem
is and may need to think of a better way to fix it.)

1 edited


  • trunk/source/objc-bridge/objc-runtime.lisp

    r13907 r14198  
    30833083  #+gnu-objc (#_method_get_number_of_arguments m))
    3085 #+(and apple-objc (not apple-objc-2.0) ppc-target)
     3085#+(or apple-objc cocotron-objc)
    3087 (defloadvar *original-deallocate-hook*
    3088         #&_dealloc)
    3090 (defcallback deallocate-nsobject (:address obj :int)
     3087(defloadvar *original-deallocate-hook* nil)
     3089;;; At one point in the past, an earlier version of
     3090;;; this code caused problems.  When a thread exits
     3091;;; and runs tls deallocation code, Mach used to remove
     3092;;; the message port that enabled it to respond to
     3093;;; asynchonous signals.  Some of that deallocation
     3094;;; code involved running this callback, and that meant
     3095;;; that callbacks were run on a thread that couldn't
     3096;;; be interrupted (and that could cause GC and other
     3097;;; problems.)
     3098;;; I don't know if that's still a problem; if it is,
     3099;;; we probably have to give up on this idea.
     3100;;; It's silly (and somewhat expensive) to call REMHASH
     3101;;; every time an NSObject gets freed; it's only necessary
     3102;;; to do this for instances of lisp-defined ObjC classes
     3103;;; that implement lisp slots.
     3104;;; One somewhat fascist approach would be:
     3105;;; - the user is prohibited from defining a dealloc method
     3106;;;   on their classes.
     3107;;; - for classes whose instances need lisp slot vectors,
     3108;;;   we automatically define a dealloc method which does
     3109;;;   the remhash and calls the next method.
     3111;;; ticket:706 suggests that people and libraries are using the
     3112;;; lisp-slot-on-foreign-object mechanism enough that it's
     3113;;; not acceptable to leave slot-vectors associated with (possibly
     3114;;; deallocated) NSObjects.  (Another, unrelated object gets created
     3115;;; at the same address as the deallocated object and winds up
     3116;;; getting the deallocated object's slot-vector.)
     3117(defcallback deallocate-nsobject (:address obj :void)
     3118  (declare (dynamic-extent obj))
    30913119  (unless (%null-ptr-p obj)
    30923120    (remhash obj *objc-object-slot-vectors*))
    3093   (ff-call *original-deallocate-hook* :address obj :int))
     3121  (ff-call *original-deallocate-hook* :address obj :void))
    30953123(defun install-lisp-deallocate-hook ()
    3096   (setf #&_dealloc deallocate-nsobject))
    3098 #+later
     3124  (let* ((class (@class "NSObject"))
     3125         (sel (@selector "dealloc")))
     3126    (setq *original-deallocate-hook* (#_class_getMethodImplementation class sel))
     3127    (with-cstrs ((types (encode-objc-method-arglist '(:id) :void)))
     3128      (#_class_replaceMethod class sel deallocate-nsobject types))))
    30993130(def-ccl-pointers install-deallocate-hook ()
    31003131  (install-lisp-deallocate-hook))
    31023133(defun uninstall-lisp-deallocate-hook ()
    31033134  (clrhash *objc-object-slot-vectors*)
    3104   (setf #&_dealloc *original-deallocate-hook*))
     3135  (let* ((class (@class "NSObject"))
     3136         (sel (@selector "dealloc")))
     3137    (with-cstrs ((types (encode-objc-method-arglist '(:id) :void)))
     3138      (#_class_replaceMethod class sel *original-deallocate-hook* types))))
    31063140(pushnew #'uninstall-lisp-deallocate-hook *save-exit-functions* :test #'eq
Note: See TracChangeset for help on using the changeset viewer.