[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: CLOS standard class cleanup



    Date: Wed, 31 Aug 88 15:28:13 EDT
    From: Michael J. Beckerle <BECKERLE@XX.LCS.MIT.EDU>


    Issue:		STANDARD-CLASS-OVERHEAD
    References:     CLOS 88-002R pg 1-43, 1-46.
    Category: 	CHANGE
    Edit History:   v0 27june88  mike beckerle


    Without class redefinition, foo-x can be inline coded as the following 
    common-lisp code:

    (defmacro foo-x (obj)
      `(let* ((obj ,obj)
	      (perm-vector (svref *perm-vectors* (object-class-number obj)))
	      (i-v-offset (svref perm-vector ,(i-v-number 'x 'foo)))
	  (instance-slot obj i-v-offset)))


    To support class-redefinition using similar technology:

    (defmacro foo-x (obj)
      `(let* ((obj ,obj)
	      (perm-vector (svref *perm-vectors* (object-class-number obj)))
	      (i-v-offset (svref perm-vector ,(i-v-number 'x 'foo)))
	  (if (slot-exists-p i-v-offset)
	     (let ((i-v-structure (instance-slot ,i-v-structure-offset)))
	       (svref i-v-structure i-v-offset))
	     (error "Slot ~A no longer exists in object ~S"
		    'x obj))))

Actually, there is an important bug in this code.  In both the class
redefinition and non class redefinition case there needs to be a check
to make certain the slot exists as a local slot in the instance.  If
not, a trap handler must be called to check whether it could be a shared
slot or just doesn't exist.  There is no way of knowing this at compile
time.  So, these should be re-written as:

; without redefinition
(defmacro foo-x (obj)
  `(let* ((obj ,obj)
	  (perm-vector (svref *perm-vectors* (object-class-number obj)))
	  (i-v-offset (svref perm-vector ,(i-v-number 'x 'foo))))
     (if (null i-v-offset)
	 (trap obj 'x)
	 (instance-slot obj i-v-offset))))


;with redefinition
(defmacro foo-x (obj)
  `(let* ((obj ,obj)
	  (perm-vector (svref *perm-vectors* (object-class-number obj)))
	  (i-v-offset (svref perm-vector ,(i-v-number 'x 'foo))))
     (if (null i-v-offset)
	 (trap obj 'x)
	 (let ((i-v-structure (instance-slot ,i-v-structure-offset)))
	   (svref i-v-structure i-v-offset)))))


So, you can see that both cases involve a test and jump.  The only
difference is one an additional memory read, and in a method which does
multiple slot accesses, this additional read can be amortized over all
those accesses.

In addition, it is worth pointing out that there is a trivial
implementation strategy which uses the faster case and allows
redefinition.  Under this strategy, classes which have been redefined
pay a penalty for instance access, but other classes do not.
-------