From 03770e700a55a111d9d350b4c2a6fae98662e1ed Mon Sep 17 00:00:00 2001 From: Nikodemus Siivola Date: Mon, 4 Aug 2008 15:58:35 +0000 Subject: [PATCH] 1.0.19.20: fast CLRHASH on empty hash-tables * Patch by Alec Berryman. --- NEWS | 2 ++ src/code/target-hash-table.lisp | 57 +++++++++++++++++++++-------------------- version.lisp-expr | 2 +- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/NEWS b/NEWS index ea294313f..745603c7a 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,8 @@ changes in sbcl-1.0.20 relative to 1.0.19: elided in more cases, eg: (let ((x 'foo)) (funcall foo)). * optimization: compiler is able to derive the return type of (AREF (THE STRING X) Y) as being CHARACTER. + * optimization: CLRHASH on empty hash-tables no longer does pointless + work. (thanks to Alec Berryman) * bug fix: fixed #427: unused local aliens no longer cause compiler breakage. (reported by Stelian Ionescu, Andy Hefner and Stanislaw Halik) diff --git a/src/code/target-hash-table.lisp b/src/code/target-hash-table.lisp index 2a926166c..9ee1e9206 100644 --- a/src/code/target-hash-table.lisp +++ b/src/code/target-hash-table.lisp @@ -816,40 +816,41 @@ there was such an entry, or NIL if not." (declare (type hash-table hash-table) (values (member t nil))) (with-hash-table-locks (hash-table :inline (%remhash) :pin (key)) - ;; For now, just clear the cache - (setf (hash-table-cache hash-table) nil) + ;; For now, just clear the cache + (setf (hash-table-cache hash-table) nil) (%remhash key hash-table))) (defun clrhash (hash-table) #!+sb-doc "This removes all the entries from HASH-TABLE and returns the hash table itself." - (with-hash-table-locks (hash-table) - (let* ((kv-vector (hash-table-table hash-table)) - (next-vector (hash-table-next-vector hash-table)) - (hash-vector (hash-table-hash-vector hash-table)) - (size (length next-vector)) - (index-vector (hash-table-index-vector hash-table))) - ;; Disable GC tricks. - (set-header-data kv-vector sb!vm:vector-normal-subtype) - ;; Mark all slots as empty by setting all keys and values to magic - ;; tag. - (aver (eq (aref kv-vector 0) hash-table)) - (fill kv-vector +empty-ht-slot+ :start 2) - ;; Set up the free list, all free. - (do ((i 1 (1+ i))) - ((>= i (1- size))) - (setf (aref next-vector i) (1+ i))) - (setf (aref next-vector (1- size)) 0) - (setf (hash-table-next-free-kv hash-table) 1) - ;; Clear the index-vector. - (fill index-vector 0) - ;; Clear the hash-vector. - (when hash-vector - (fill hash-vector +magic-hash-vector-value+))) - (setf (hash-table-cache hash-table) nil) - (setf (hash-table-number-entries hash-table) 0) - hash-table)) + (when (plusp (hash-table-number-entries hash-table)) + (with-hash-table-locks (hash-table) + (let* ((kv-vector (hash-table-table hash-table)) + (next-vector (hash-table-next-vector hash-table)) + (hash-vector (hash-table-hash-vector hash-table)) + (size (length next-vector)) + (index-vector (hash-table-index-vector hash-table))) + ;; Disable GC tricks. + (set-header-data kv-vector sb!vm:vector-normal-subtype) + ;; Mark all slots as empty by setting all keys and values to magic + ;; tag. + (aver (eq (aref kv-vector 0) hash-table)) + (fill kv-vector +empty-ht-slot+ :start 2) + ;; Set up the free list, all free. + (do ((i 1 (1+ i))) + ((>= i (1- size))) + (setf (aref next-vector i) (1+ i))) + (setf (aref next-vector (1- size)) 0) + (setf (hash-table-next-free-kv hash-table) 1) + ;; Clear the index-vector. + (fill index-vector 0) + ;; Clear the hash-vector. + (when hash-vector + (fill hash-vector +magic-hash-vector-value+))) + (setf (hash-table-cache hash-table) nil) + (setf (hash-table-number-entries hash-table) 0))) + hash-table) ;;;; MAPHASH diff --git a/version.lisp-expr b/version.lisp-expr index 8e51dbc9e..ae24ebd8d 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"1.0.19.19" +"1.0.19.20" -- 2.11.4.GIT