[Openmcl-cvs-notifications] r13591 - /trunk/source/lib/read.lisp
gb at clozure.com
gb at clozure.com
Sat Apr 10 22:07:58 UTC 2010
Author: gb
Date: Sat Apr 10 16:07:57 2010
New Revision: 13591
Log:
Try to speed up #n=3D/#n# a bit:
- maintain %READ-OBJECTS% as a hash table if its length as an alist
exceeds *READ-OBJECTS-HASH-THRESHOLD*.
- make #n# indicate whether or not the label has been referenced
- only process circularity in #n=3D if the label was referenced while
the form was being read
- at most, only process circularity for the current label
While processing circulariy, only descend arrays of element-type T and
structures (and skip the 0th element of structures).
Modified:
trunk/source/lib/read.lisp
Modified: trunk/source/lib/read.lisp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/source/lib/read.lisp (original)
+++ trunk/source/lib/read.lisp Sat Apr 10 16:07:57 2010
@@ -195,15 +195,42 @@
index))))
=
=
+(defun get-read-object (arg)
+ (if (listp %read-objects%)
+ (assoc arg %read-objects%)
+ (gethash arg %read-objects%)))
+
+(defparameter *read-objects-hash-threshold* 30)
+
+(defun note-read-object (data)
+ (let* ((lab (car data)))
+ (if (get-read-object lab)
+ (%err-disp $xduprdlbl lab)
+ (if (listp %read-objects%)
+ (if (< (length %read-objects%) *read-objects-hash-threshold*)
+ (push data %read-objects%)
+ (let* ((hash (make-hash-table :test #'eql :shared nil :rehash-si=
ze 2.0)))
+ (dolist (info %read-objects%)
+ (let* ((lab (car info)))
+ (setf (gethash lab hash) info)))
+ (setf (gethash lab hash) data)
+ (setq %read-objects% hash)))
+ (setf (gethash lab %read-objects%) data)))))
+
+
+ =
+
(set-dispatch-macro-character #\# #\#
#'(lambda (stream char arg)
(declare (ignore stream))
(if *read-suppress* =
nil
(if arg
- (let ((pair (assoc arg %read-objects%))) ;Not assq, could be big=
num!
+ (let ((pair (get-read-object arg)))
(if pair
- (cdr pair)
+ (let* ((cell (cdr pair)))
+ (setf (car cell) t)
+ (cdr cell))
(%err-disp $xnordlbl arg)))
(%err-disp $xrdndarg char)))))
=
@@ -213,38 +240,57 @@
#'(lambda (stream char arg &aux lab form)
(cond (*read-suppress* (values))
((null arg) (%err-disp $xrdndarg char))
- ((assoc arg %read-objects%) ;Not assq, could be bignum!
- (%err-disp $xduprdlbl arg))
(t (setq lab (cons arg nil))
- (push (%rplacd lab lab) %read-objects%)
+ (%rplacd lab (cons nil lab))
+ (note-read-object lab)
(setq form (read stream t nil t))
- (when (eq form lab) ;#n=3D #n#. No can do.
+ (when (eq form lab) ;#n=3D #n#. No can do.
(%err-disp $xnordlbl (%car lab)))
- (%rplacd lab form)
- (let ((scanned nil))
- (labels ((circle-subst (tree)
- (if (memq tree %read-objects%)
- (progn
- (unless (memq tree scanned)
- (setq scanned (%temp-cons tree scanned))
- (circle-subst (cdr tree)))
- (cdr tree))
- (let ((gvectorp (and (gvectorp tree) (not =
(or (symbolp tree) (functionp tree))))))
- (unless (or (and (atom tree) (not gvector=
p)) (memq tree scanned))
- (setq scanned (%temp-cons tree scanned))
- (if gvectorp
- (let* ((subtype (typecode tree)))
- (dotimes (i (uvsize tree))
- (declare (fixnum i))
- (unless (and (eql i 0) (eql subty=
pe target::subtag-instance))
- (setf (uvref tree i) (circle-su=
bst (uvref tree i))))))
- (locally =
- (declare (type cons tree))
- (rplaca tree (circle-subst (car tree=
)))
- (rplacd tree (circle-subst (cdr tree=
))))))
- tree))))
- (declare (dynamic-extent #'circle-subst))
- (circle-subst form)))))))
-
-
-
+ (%rplacd (cdr lab) form)
+ (let* ((reffed (cadr lab)))
+ (if (not reffed)
+ form
+ (let ((scanned nil))
+ (labels ((circle-subst (tree)
+ (if (eq tree lab)
+ (progn
+ (unless (memq tree scanned)
+ (setq scanned (%temp-cons tree scanne=
d))
+ (circle-subst (cddr tree)))
+ (cddr tree))
+ (progn
+ (cond ((consp tree)
+ (unless (memq tree scanned)
+ (push tree scanned)
+ (locally =
+ (declare (type cons tree))
+ (let* ((orig (car tree))
+ (new (circle-subst or=
ig)))
+ (unless (eq orig new)
+ (rplaca tree new))
+ (setq orig (cdr tree)
+ new (circle-subst or=
ig))
+ (unless (eq orig new)
+ (rplacd tree new))))))
+ ((let* ((typecode (typecode tree)=
))
+ (declare (type (unsigned-byte =
8) typecode))
+ (or (=3D typecode target::subt=
ag-simple-vector)
+ (=3D typecode target::subt=
ag-struct)
+ (=3D typecode target::subt=
ag-arrayH)))
+ (unless (memq tree scanned)
+ (push tree scanned)
+ (let* ((n (uvsize tree)))
+ (declare (fixnum n))
+ (do* ((i (if (eql (typecode =
tree) target::subtag-struct) 1 0) (1+ i)))
+ ((=3D i n))
+ (declare (fixnum i))
+ (let* ((old (%svref tree i=
))
+ (new (circle-subst =
old)))
+ (unless (eq old new)
+ (setf (%svref tree i) new=
))))))))
+ tree))))
+ (declare (dynamic-extent #'circle-subst))
+ (circle-subst form)))))))))
+
+
+
More information about the Openmcl-cvs-notifications
mailing list