[armedbear-cvs] r11747 - trunk/abcl/src/org/armedbear/lisp

Erik Huelsmann ehuelsmann at common-lisp.net
Tue Apr 7 21:14:31 UTC 2009


Author: ehuelsmann
Date: Tue Apr  7 17:14:28 2009
New Revision: 11747

Log:
Fix excessive stack use while resolving #n= and #n#:
  Don't recurse into the CDR of lists being read;
  instead, loop over the successive CDRs in the list.

Modified:
   trunk/abcl/src/org/armedbear/lisp/boot.lisp

Modified: trunk/abcl/src/org/armedbear/lisp/boot.lisp
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/boot.lisp	(original)
+++ trunk/abcl/src/org/armedbear/lisp/boot.lisp	Tue Apr  7 17:14:28 2009
@@ -154,14 +154,18 @@
 ;; substitutes in arrays and structures as well as lists. The first arg is an
 ;; alist of the things to be replaced assoc'd with the things to replace them.
 (defun circle-subst (old-new-alist tree)
-  (cond ((not (typep tree
-                     '(or cons (array t) structure-object standard-object)))
-         (let ((entry (find tree old-new-alist :key #'second)))
-           (if entry (third entry) tree)))
+  (macrolet ((recursable-element-p (subtree)
+                `(typep ,subtree
+                       '(or cons (array t) structure-object standard-object)))
+             (element-replacement (subtree)
+               `(let ((entry (find ,subtree old-new-alist :key #'second)))
+                  (if entry (third entry) ,subtree))))
+  (cond ((not (recursable-element-p tree))
+         (element-replacement tree))
         ((null (gethash tree *sharp-equal-circle-table*))
-         (setf (gethash tree *sharp-equal-circle-table*) t)
          (cond
           ((typep tree 'structure-object)
+           (setf (gethash tree *sharp-equal-circle-table*) t)
            (do ((i 0 (1+ i))
                 (end (structure-length tree)))
                ((= i end))
@@ -170,6 +174,7 @@
                (unless (eq old new)
                  (structure-set tree i new)))))
 ;;           ((typep tree 'standard-object)
+;;            (setf (gethash tree *sharp-equal-circle-table*) t)
 ;;            (do ((i 1 (1+ i))
 ;;                 (end (%instance-length tree)))
 ;;                ((= i end))
@@ -178,6 +183,7 @@
 ;;                (unless (eq old new)
 ;;                  (setf (%instance-ref tree i) new)))))
           ((arrayp tree)
+           (setf (gethash tree *sharp-equal-circle-table*) t)
            (do ((i 0 (1+ i))
                 (end (array-total-size tree)))
                ((>= i end))
@@ -185,15 +191,35 @@
                     (new (circle-subst old-new-alist old)))
                (unless (eq old new)
                  (setf (row-major-aref tree i) new)))))
-         (t
-          (let ((a (circle-subst old-new-alist (car tree)))
-                (d (circle-subst old-new-alist (cdr tree))))
-            (unless (eq a (car tree))
-              (rplaca tree a))
-            (unless (eq d (cdr tree))
-              (rplacd tree d)))))
+         (t ;; being CONSP as all the other cases have been handled
+            (do ((subtree tree (cdr subtree)))
+                ((or (not (consp subtree))
+                     (gethash subtree *sharp-equal-circle-table*)))
+                ;; CDR no longer a CONS; no need to recurse any further:
+                ;; the case where the CDR is a symbol to be replaced
+                ;; has been handled in the last iteration
+              (setf (gethash subtree *sharp-equal-circle-table*) t)
+              (let* ((c (car subtree))
+                     (d (cdr subtree))
+                     (a (if (recursable-element-p c)
+                            (circle-subst old-new-alist c)
+                            (element-replacement c)))
+                     (b (cond
+                         ((consp d) ;; CONSes handled in the loop
+                          (setf (gethash d *sharp-equal-circle-table*) t)
+                          d)
+                         ((recursable-element-p d)
+                          ;; ARRAY, STRUCTURE-OBJECT and STANDARD-OBJECT
+                          ;; handled in recursive calls
+                          (circle-subst old-new-alist d))
+                         (t
+                          (element-replacement d)))))
+                (unless (eq a c)
+                  (rplaca subtree a))
+                (unless (eq d b)
+                  (rplacd subtree b))))))
         tree)
-  (t tree)))
+  (t tree))))
 
 ;;; Sharp-equal works as follows. When a label is assigned (i.e. when
 ;;; #= is called) we GENSYM a symbol is which is used as an




More information about the armedbear-cvs mailing list