Update of /project/movitz/cvsroot/movitz In directory clnet:/tmp/cvs-serv32262
Modified Files: compiler.lisp Log Message: Fix (again) the borrowing/lending of function-bindings. The compiler would get confused when local functions called eachother.
--- /project/movitz/cvsroot/movitz/compiler.lisp 2008/03/17 23:23:30 1.197 +++ /project/movitz/cvsroot/movitz/compiler.lisp 2008/03/19 15:06:10 1.198 @@ -8,7 +8,7 @@ ;;;; Created at: Wed Oct 25 12:30:49 2000 ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: compiler.lisp,v 1.197 2008/03/17 23:23:30 ffjeld Exp $ +;;;; $Id: compiler.lisp,v 1.198 2008/03/19 15:06:10 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------
@@ -611,13 +611,14 @@ (check-type toplevel-funobj movitz-funobj) (let ((function-binding-usage ())) (labels ((process-binding (funobj binding usages) + (when (typep binding 'function-binding) + (dolist (usage usages) + (pushnew usage + (getf (sub-function-binding-usage (function-binding-parent binding)) + binding)) + (pushnew usage (getf function-binding-usage binding)))) (cond ((typep binding 'constant-object-binding)) - ((and (typep binding 'function-binding) - (equal usages '(:call))) - (pushnew :call (getf (sub-function-binding-usage (function-binding-parent binding)) - binding)) - (pushnew :call (getf function-binding-usage binding))) ((not (eq funobj (binding-funobj binding))) (let ((borrowing-binding (or (find binding (borrowed-bindings funobj) @@ -643,17 +644,7 @@ (t ; Binding is local to this funobj (typecase binding (forwarding-binding - (process-binding funobj (forwarding-binding-target binding) usages) - #+ignore - (setf (forwarding-binding-target binding) - (process-binding funobj (forwarding-binding-target binding) usages))) - (function-binding - (dolist (usage usages) - (pushnew usage - (getf (sub-function-binding-usage (function-binding-parent binding)) - binding)) - (pushnew usage (getf function-binding-usage binding))) - binding) + (process-binding funobj (forwarding-binding-target binding) usages)) (t binding))))) (resolve-sub-funobj (funobj sub-funobj) (dolist (binding-we-lend (borrowed-bindings (resolve-funobj-borrowing sub-funobj))) @@ -760,6 +751,22 @@ (t (change-class function-binding 'closure-binding) (setf (movitz-funobj-extent sub-funobj) :indefinite-extent)))))) + ;; Each time we change a function-binding to funobj-binding, that binding + ;; no longer needs to be borrowed (because it doesn't share lexical bindings), + ;; and therefore should be removed from any borrowed-binding list, which in + ;; turn can cause the borrowing funobj to become a funobj-binding, and so on. + (loop for modified-p = nil + do (loop for function-binding in function-binding-usage by #'cddr + do (let ((sub-funobj (function-binding-funobj function-binding))) + (when (not (null (borrowed-bindings sub-funobj))) + (check-type function-binding closure-binding) + (when (null (setf (borrowed-bindings sub-funobj) + (delete-if (lambda (b) + (when (typep (borrowed-binding-target b) 'funobj-binding) + (setf modified-p t))) + (borrowed-bindings sub-funobj)))) + (change-class function-binding 'funobj-binding))))) + while modified-p) (loop for function-binding in function-binding-usage by #'cddr do (finalize-funobj (function-binding-funobj function-binding))) (finalize-funobj toplevel-funobj)) @@ -2526,7 +2533,7 @@ (incf (getf constants funobj 0)))) (closure-binding) (function-binding - (warn "No function-binding now..: ~S" binding)))) + (error "No function-binding now..: ~S" binding)))) (process (sub-code) "This local function side-effects the variables jumper-sets and constants." (loop for instruction in sub-code @@ -3791,8 +3798,9 @@ (mapcar #'binding-funobj (getf (binding-lending lended-binding) :lended-to)))) (when (typep lended-binding 'funobj-binding) - (break "Lending ~S ?" lended-binding)) - (append (unless (or (typep lended-binding 'borrowed-binding) + (break "Lending ~S from ~S: ~S" lended-binding funobj (binding-lending lended-binding))) + (append (make-load-lexical lended-binding :eax funobj t frame-map) + (unless (or (typep lended-binding 'borrowed-binding) (getf (binding-lending lended-binding) :dynamic-extent-p) (every (lambda (borrower) (member (movitz-funobj-extent (binding-funobj borrower)) @@ -3811,7 +3819,7 @@ binding (or (find binding (borrowed-bindings funobj) :key #'borrowed-binding-target) - (error "Can't install non-local binding ~W." binding))))) + (error "Can't install non-local binding ~S for ~S." binding funobj))))) (labels ((fix-edi-offset (tree) (cond ((atom tree) @@ -3896,14 +3904,15 @@ no-alignment-needed) (make-load-constant sub-funobj :eax funobj frame-map) ))) - (t (assert (not (null (borrowed-bindings sub-funobj)))) + (t (assert (not (null (borrowed-bindings sub-funobj))) () + "Binding ~S with ~S borrows no nothing, which makes no sense." function-binding sub-funobj) (append (make-load-constant sub-funobj :eax funobj frame-map) `((:movl (:edi ,(global-constant-offset 'copy-funobj)) :esi) (:call (:esi ,(bt:slot-offset 'movitz-funobj 'code-vector%1op))) (:movl :eax :edx)) (make-store-lexical function-binding :eax nil funobj frame-map) (loop for bb in (borrowed-bindings sub-funobj) - append (make-lend-lexical bb :edx nil)))))) + append (make-lend-lexical bb :edx nil)))))) funobj frame-map))) (:load-lambda (destructuring-bind (function-binding register capture-env) @@ -3912,7 +3921,7 @@ (finalize-code (let* ((sub-funobj (function-binding-funobj function-binding)) (lend-code (loop for bb in (borrowed-bindings sub-funobj) - appending + appending (make-lend-lexical bb :edx nil)))) (cond ((null lend-code)