Avoid unnecessary write to hash-table instances during gc.
[sbcl.git] / src / code / target-hash-table.lisp
blob3800f3b232eeaa1389b543278fca8569359814cd
1 ;;;; that part of the implementation of HASH-TABLE which lives solely
2 ;;;; on the target system, not on the cross-compilation host
4 ;;;; This software is part of the SBCL system. See the README file for
5 ;;;; more information.
6 ;;;;
7 ;;;; This software is derived from the CMU CL system, which was
8 ;;;; written at Carnegie Mellon University and released into the
9 ;;;; public domain. The software is in the public domain and is
10 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
11 ;;;; files for more information.
13 (in-package "SB!IMPL")
15 ;;;; utilities
17 (defun hash-table-weakness (ht)
18 "Return the WEAKNESS of HASH-TABLE which is one of NIL, :KEY,
19 :VALUE, :KEY-AND-VALUE, :KEY-OR-VALUE."
20 (aref weak-hash-table-kinds (hash-table-%weakness ht)))
22 (declaim (inline hash-table-weak-p))
23 (defun hash-table-weak-p (ht)
24 (not (zerop (hash-table-%weakness ht))))
26 ;;; Code for detecting concurrent accesses to the same table from
27 ;;; multiple threads. Only compiled in when the :SB-HASH-TABLE-DEBUG
28 ;;; feature is enabled. The main reason for the existence of this code
29 ;;; is to detect thread-unsafe uses of hash-tables in sbcl itself,
30 ;;; where debugging anythign can be impossible after an important
31 ;;; internal hash-table has been corrupted. It's plausible that this
32 ;;; could be useful for some user code too, but the runtime cost is
33 ;;; really too high to enable it by default.
34 (defmacro with-concurrent-access-check (hash-table operation &body body)
35 (declare (ignorable hash-table operation)
36 (type (member :read :write) operation))
37 #!-sb-hash-table-debug
38 `(progn ,@body)
39 #!+sb-hash-table-debug
40 (let ((thread-slot-accessor (if (eq operation :read)
41 'hash-table-reading-thread
42 'hash-table-writing-thread)))
43 (once-only ((hash-table hash-table))
44 `(progn
45 (flet ((body-fun ()
46 ,@body)
47 (error-fun ()
48 ;; Don't signal more errors for this table.
49 (setf (hash-table-signal-concurrent-access ,hash-table) nil)
50 (cerror "Ignore the concurrent access"
51 "Concurrent access to ~A" ,hash-table)))
52 (declare (inline body-fun))
53 (if (hash-table-signal-concurrent-access ,hash-table)
54 (unwind-protect
55 (progn
56 (unless (and (null (hash-table-writing-thread
57 ,hash-table))
58 ,@(when (eq operation :write)
59 `((null (hash-table-reading-thread
60 ,hash-table)))))
61 (error-fun))
62 (setf (,thread-slot-accessor ,hash-table)
63 sb!thread::*current-thread*)
64 (body-fun))
65 (unless (and ,@(when (eq operation :read)
66 `((null (hash-table-writing-thread
67 ,hash-table))))
68 ,@(when (eq operation :write)
69 ;; no readers are allowed while writing
70 `((null (hash-table-reading-thread
71 ,hash-table))
72 (eq (hash-table-writing-thread
73 ,hash-table)
74 sb!thread::*current-thread*))))
75 (error-fun))
76 (when (eq (,thread-slot-accessor ,hash-table)
77 sb!thread::*current-thread*)
78 ;; this is not 100% correct here and may hide
79 ;; concurrent access in rare circumstances.
80 (setf (,thread-slot-accessor ,hash-table) nil)))
81 (body-fun)))))))
83 #!-sb-fluid (declaim (inline eq-hash))
84 (defun eq-hash (key)
85 (declare (values hash (member t nil)))
86 (values (pointer-hash key)
87 (oddp (get-lisp-obj-address key))))
89 #!-sb-fluid (declaim (inline equal-hash))
90 (defun equal-hash (key)
91 (declare (values hash (member t nil)))
92 (typecase key
93 ;; For some types the definition of EQUAL implies a special hash
94 ((or string cons number bit-vector pathname)
95 (values (sxhash key) nil))
96 ;; Otherwise use an EQ hash, rather than SXHASH, since the values
97 ;; of SXHASH will be extremely badly distributed due to the
98 ;; requirements of the spec fitting badly with our implementation
99 ;; strategy.
101 (eq-hash key))))
103 #!-sb-fluid (declaim (inline eql-hash))
104 (defun eql-hash (key)
105 (declare (values hash (member t nil)))
106 (if (numberp key)
107 (equal-hash key)
108 (eq-hash key)))
110 (defun equalp-hash (key)
111 (declare (values hash (member t nil)))
112 (typecase key
113 ;; Types requiring special treatment. Note that PATHNAME and
114 ;; HASH-TABLE are caught by the STRUCTURE-OBJECT test.
115 ((or array cons number character structure-object)
116 (values (psxhash key) nil))
118 (eq-hash key))))
120 (declaim (inline index-for-hashing))
121 (defun index-for-hashing (hash length)
122 (declare (type hash hash length))
123 ;; We're using power of two tables which obviously are very
124 ;; sensitive to the exact values of the low bits in the hash
125 ;; value. Do a little shuffling of the value to mix the high bits in
126 ;; there too.
127 (truly-the index
128 (logand (1- length)
129 (+ (logxor #b11100101010001011010100111
130 hash)
131 (ash hash -3)
132 (ash hash -12)
133 (ash hash -20)))))
136 ;;;; user-defined hash table tests
138 (defglobal *user-hash-table-tests* nil)
140 (defun register-hash-table-test (name hash-fun)
141 (declare (symbol name) (function hash-fun))
142 (unless (fboundp name)
143 (error "Cannot register ~S has a hash table test: undefined function."
144 name))
145 (with-single-package-locked-error
146 (:symbol name "defining ~S as a hash table test")
147 (let* ((test-fun (fdefinition name))
148 (this (list name test-fun hash-fun))
149 (spec (assoc name *user-hash-table-tests*)))
150 (cond (spec
151 (unless (and (eq (second spec) test-fun)
152 (eq (third spec) hash-fun))
153 (style-warn "Redefining hash table test ~S." name)
154 (setf (cdr spec) (cdr this))))
156 (push this *user-hash-table-tests*)))))
157 name)
159 (defmacro define-hash-table-test (name hash-function)
160 "Defines NAME as a new kind of hash table test for use with the :TEST
161 argument to MAKE-HASH-TABLE, and associates a default HASH-FUNCTION with it.
163 NAME must be a symbol naming a global two argument equivalence predicate.
164 Afterwards both 'NAME and #'NAME can be used with :TEST argument. In both
165 cases HASH-TABLE-TEST will return the symbol NAME.
167 HASH-FUNCTION must be a symbol naming a global hash function consistent with
168 the predicate, or be a LAMBDA form implementing one in the current lexical
169 environment. The hash function must compute the same hash code for any two
170 objects for which NAME returns true, and subsequent calls with already hashed
171 objects must always return the same hash code.
173 Note: The :HASH-FUNCTION keyword argument to MAKE-HASH-TABLE can be used to
174 override the specified default hash-function.
176 Attempting to define NAME in a locked package as hash-table test causes a
177 package lock violation.
179 Examples:
181 ;;; 1.
183 ;; We want to use objects of type FOO as keys (by their
184 ;; names.) EQUALP would work, but would make the names
185 ;; case-insensitive -- which we don't want.
186 (defstruct foo (name nil :type (or null string)))
188 ;; Define an equivalence test function and a hash function.
189 (defun foo-name= (f1 f2) (equal (foo-name f1) (foo-name f2)))
190 (defun sxhash-foo-name (f) (sxhash (foo-name f)))
192 (define-hash-table-test foo-name= sxhash-foo-name)
194 ;; #'foo-name would work too.
195 (defun make-foo-table () (make-hash-table :test 'foo-name=))
197 ;;; 2.
199 (defun == (x y) (= x y))
201 (define-hash-table-test ==
202 (lambda (x)
203 ;; Hash codes must be consistent with test, so
204 ;; not (SXHASH X), since
205 ;; (= 1 1.0) => T
206 ;; (= (SXHASH 1) (SXHASH 1.0)) => NIL
207 ;; Note: this doesn't deal with complex numbers or
208 ;; bignums too large to represent as double floats.
209 (sxhash (coerce x 'double-float))))
211 ;; #'== would work too
212 (defun make-number-table () (make-hash-table :test '==))
214 (check-type name symbol)
215 (if (member name '(eq eql equal equalp))
216 (error "Cannot redefine standard hash table test ~S." name)
217 (cond ((symbolp hash-function)
218 `(register-hash-table-test ',name (symbol-function ',hash-function)))
219 ((and (consp hash-function) (eq 'lambda (car hash-function)))
220 `(register-hash-table-test ',name #',hash-function))
222 (error "Malformed HASH-FUNCTION: ~S" hash-function)))))
224 ;;;; construction and simple accessors
226 (defconstant +min-hash-table-size+ 16)
227 (defconstant +min-hash-table-rehash-threshold+ (float 1/16 1.0))
229 ;; The GC will set this to 1 if it moves an EQ-based key. This used
230 ;; to be signaled by a bit in the header of the kv vector, but that
231 ;; implementation caused some concurrency issues when we stopped
232 ;; inhibiting GC during hash-table lookup.
234 ;; This indicator properly belongs to the k/v vector for at least 2 reasons:
235 ;; - if the vector is on an already-written page but the table is not,
236 ;; it avoids a write fault when setting to true. This a boon to gencgc
237 ;; - if there were lock-free tables - which presumably operate by atomically
238 ;; changing out the vector for a new one - whether the vector is bucketized
239 ;; correctly after GC is an aspect of the vector, not the table
241 ;; We could do it with a single bit by implementing vops for atomic
242 ;; read/modify/write on the header. In C there's sync_or_and_fetch, etc.
243 (defmacro kv-vector-needs-rehash (vector) `(svref ,vector 1))
245 (defun make-hash-table (&key
246 (test 'eql)
247 (size +min-hash-table-size+)
248 (rehash-size 1.5)
249 (rehash-threshold 1)
250 (hash-function nil)
251 (weakness nil)
252 (synchronized))
253 "Create and return a new hash table. The keywords are as follows:
255 :TEST
256 Determines how keys are compared. Must a designator for one of the
257 standard hash table tests, or a hash table test defined using
258 SB-EXT:DEFINE-HASH-TABLE-TEST. Additionally, when an explicit
259 HASH-FUNCTION is provided (see below), any two argument equivalence
260 predicate can be used as the TEST.
262 :SIZE
263 A hint as to how many elements will be put in this hash table.
265 :REHASH-SIZE
266 Indicates how to expand the table when it fills up. If an integer, add
267 space for that many elements. If a floating point number (which must be
268 greater than 1.0), multiply the size by that amount.
270 :REHASH-THRESHOLD
271 Indicates how dense the table can become before forcing a rehash. Can be
272 any positive number <=1, with density approaching zero as the threshold
273 approaches 0. Density 1 means an average of one entry per bucket.
275 :HASH-FUNCTION
276 If NIL (the default), a hash function based on the TEST argument is used,
277 which then must be one of the standardized hash table test functions, or
278 one for which a default hash function has been defined using
279 SB-EXT:DEFINE-HASH-TABLE-TEST. If HASH-FUNCTION is specified, the TEST
280 argument can be any two argument predicate consistent with it. The
281 HASH-FUNCTION is expected to return a non-negative fixnum hash code.
283 :WEAKNESS
284 When :WEAKNESS is not NIL, garbage collection may remove entries from the
285 hash table. The value of :WEAKNESS specifies how the presence of a key or
286 value in the hash table preserves their entries from garbage collection.
288 Valid values are:
290 :KEY means that the key of an entry must be live to guarantee that the
291 entry is preserved.
293 :VALUE means that the value of an entry must be live to guarantee that
294 the entry is preserved.
296 :KEY-AND-VALUE means that both the key and the value must be live to
297 guarantee that the entry is preserved.
299 :KEY-OR-VALUE means that either the key or the value must be live to
300 guarantee that the entry is preserved.
302 NIL (the default) means that entries are always preserved.
304 :SYNCHRONIZED
305 If NIL (the default), the hash-table may have multiple concurrent readers,
306 but results are undefined if a thread writes to the hash-table
307 concurrently with another reader or writer. If T, all concurrent accesses
308 are safe, but note that CLHS 3.6 (Traversal Rules and Side Effects)
309 remains in force. See also: SB-EXT:WITH-LOCKED-HASH-TABLE. This keyword
310 argument is experimental, and may change incompatibly or be removed in the
311 future."
312 (declare (type (or function symbol) test))
313 (declare (type unsigned-byte size))
314 (multiple-value-bind (test test-fun hash-fun)
315 (cond ((or (eq test #'eq) (eq test 'eq))
316 (values 'eq #'eq #'eq-hash))
317 ((or (eq test #'eql) (eq test 'eql))
318 (values 'eql #'eql #'eql-hash))
319 ((or (eq test #'equal) (eq test 'equal))
320 (values 'equal #'equal #'equal-hash))
321 ((or (eq test #'equalp) (eq test 'equalp))
322 (values 'equalp #'equalp #'equalp-hash))
324 ;; FIXME: It would be nice to have a compiler-macro
325 ;; that resolved this at compile time: we could grab
326 ;; the alist cell in a LOAD-TIME-VALUE, etc.
327 (dolist (info *user-hash-table-tests*
328 (if hash-function
329 (if (functionp test)
330 (values (%fun-name test) test nil)
331 (values test (%coerce-callable-to-fun test) nil))
332 (error "Unknown :TEST for MAKE-HASH-TABLE: ~S"
333 test)))
334 (destructuring-bind (test-name test-fun hash-fun) info
335 (when (or (eq test test-name) (eq test test-fun))
336 (return (values test-name test-fun hash-fun)))))))
337 (when hash-function
338 (setf hash-fun
339 ;; Quickly check if the function has return return type which
340 ;; guarantees that the secondary return value is always NIL:
341 ;; (VALUES * &OPTIONAL), (VALUES * NULL ...) or (VALUES *
342 ;; &OPTIONAL NULL ...)
343 (let* ((actual (%coerce-callable-to-fun hash-function))
344 (type-spec (%fun-type actual))
345 (return-spec (when (consp type-spec)
346 (caddr type-spec)))
347 (extra-vals (when (consp return-spec)
348 (cddr return-spec))))
349 (if (and (consp extra-vals)
350 (or (eq 'null (car extra-vals))
351 (and (eq '&optional (car extra-vals))
352 (or (not (cdr extra-vals))
353 (eq 'null (cadr extra-vals))))))
354 actual
355 ;; If there is a potential secondary value, make sure we
356 ;; don't accidentally claim EQ based hashing...
357 (lambda (object)
358 (declare (optimize (safety 0) (speed 3)))
359 (values (funcall actual object) nil))))))
360 (let* ((size (max +min-hash-table-size+
361 (min size
362 ;; SIZE is just a hint, so if the user asks
363 ;; for a SIZE which'd be too big for us to
364 ;; easily implement, we bump it down.
365 (floor array-dimension-limit 1024))))
366 (rehash-size (if (integerp rehash-size)
367 rehash-size
368 (float rehash-size 1.0)))
369 ;; FIXME: Original REHASH-THRESHOLD default should be 1.0,
370 ;; not 1, to make it easier for the compiler to avoid
371 ;; boxing.
372 (rehash-threshold (max +min-hash-table-rehash-threshold+
373 (float rehash-threshold 1.0)))
374 (size+1 (1+ size)) ; The first element is not usable.
375 ;; KLUDGE: The most natural way of expressing the below is
376 ;; (round (/ (float size+1) rehash-threshold)), and indeed
377 ;; it was expressed like that until 0.7.0. However,
378 ;; MAKE-HASH-TABLE is called very early in cold-init, and
379 ;; the SPARC has no primitive instructions for rounding,
380 ;; but only for truncating; therefore, we fudge this issue
381 ;; a little. The other uses of truncate, below, similarly
382 ;; used to be round. -- CSR, 2002-10-01
384 ;; Note that this has not yet been audited for
385 ;; correctness. It just seems to work. -- CSR, 2002-11-02
386 (scaled-size (truncate (/ (float size+1) rehash-threshold)))
387 (length (power-of-two-ceiling (max scaled-size
388 (1+ +min-hash-table-size+))))
389 ;; FIXME: this is completely insane for 64-bit.
390 ;; We can not possibly support hash-tables that need
391 ;; such large indices. It doesn't work.
392 ;; Reducing this to (unsigned-byte 32) would save memory.
393 (index-vector (make-array length
394 :element-type
395 '(unsigned-byte #.sb!vm:n-word-bits)
396 :initial-element 0))
397 ;; Needs to be the half the length of the KV vector to link
398 ;; KV entries - mapped to indeces at 2i and 2i+1 -
399 ;; together.
400 (next-vector (make-array size+1
401 :element-type
402 '(unsigned-byte #.sb!vm:n-word-bits)))
403 (kv-vector (make-array (* 2 size+1)
404 :initial-element +empty-ht-slot+))
405 (table (%make-hash-table
406 test
407 test-fun
408 hash-fun
409 rehash-size
410 rehash-threshold
411 size
412 kv-vector
413 (position weakness weak-hash-table-kinds :test #'eq)
414 index-vector
415 next-vector
416 (unless (eq test 'eq)
417 ;; See FIXME at INDEX-VECTOR. Same concern.
418 (make-array size+1
419 :element-type '(unsigned-byte
420 #.sb!vm:n-word-bits)
421 :initial-element +magic-hash-vector-value+))
422 synchronized)))
423 (declare (type index size+1 scaled-size length))
424 (setf (kv-vector-needs-rehash kv-vector) 0)
425 ;; Set up the free list, all free. These lists are 0 terminated.
426 (do ((i 1 (1+ i)))
427 ((>= i size))
428 (setf (aref next-vector i) (1+ i)))
429 (setf (aref next-vector size) 0)
430 (setf (hash-table-next-free-kv table) 1)
431 (setf (aref kv-vector 0) table)
432 table)))
434 (defun hash-table-count (hash-table)
435 "Return the number of entries in the given HASH-TABLE."
436 (declare (type hash-table hash-table)
437 (values index))
438 (hash-table-number-entries hash-table))
440 (setf (fdocumentation 'hash-table-rehash-size 'function)
441 "Return the rehash-size HASH-TABLE was created with.")
443 (setf (fdocumentation 'hash-table-rehash-threshold 'function)
444 "Return the rehash-threshold HASH-TABLE was created with.")
446 (setf (fdocumentation 'hash-table-synchronized-p 'function)
447 "Returns T if HASH-TABLE is synchronized.")
449 (defun hash-table-size (hash-table)
450 "Return a size that can be used with MAKE-HASH-TABLE to create a hash
451 table that can hold however many entries HASH-TABLE can hold without
452 having to be grown."
453 (hash-table-rehash-trigger hash-table))
455 (setf (fdocumentation 'hash-table-test 'function)
456 "Return the test HASH-TABLE was created with.")
458 ;;; Called when we detect circular chains in a hash-table.
459 (defun signal-corrupt-hash-table (hash-table)
460 (error "Corrupt NEXT-chain in ~A. This is probably caused by ~
461 multiple threads accessing the same hash-table without locking."
462 hash-table))
465 ;;;; accessing functions
467 ;;; Make new vectors for the table, extending the table based on the
468 ;;; rehash-size.
469 (defun rehash (table)
470 (declare (type hash-table table))
471 (aver *gc-inhibit*)
472 (let* ((old-kv-vector (hash-table-table table))
473 (old-next-vector (hash-table-next-vector table))
474 (old-hash-vector (hash-table-hash-vector table))
475 (old-size (length old-next-vector))
476 (new-size
477 (power-of-two-ceiling
478 (let ((rehash-size (hash-table-rehash-size table)))
479 (etypecase rehash-size
480 (fixnum
481 (+ rehash-size old-size))
482 (float
483 (the index (truncate (* rehash-size old-size))))))))
484 (new-kv-vector (make-array (* 2 new-size)
485 :initial-element +empty-ht-slot+))
486 (new-next-vector
487 (make-array new-size
488 :element-type '(unsigned-byte #.sb!vm:n-word-bits)
489 :initial-element 0))
490 (new-hash-vector
491 (when old-hash-vector
492 (make-array new-size
493 :element-type '(unsigned-byte #.sb!vm:n-word-bits)
494 :initial-element +magic-hash-vector-value+)))
495 (new-length new-size)
496 (new-index-vector
497 (make-array new-length
498 :element-type '(unsigned-byte #.sb!vm:n-word-bits)
499 :initial-element 0)))
500 (declare (type index new-size new-length old-size))
502 ;; Disable GC tricks on the OLD-KV-VECTOR.
503 (set-header-data old-kv-vector sb!vm:vector-normal-subtype)
505 ;; GC must never observe a value other than 0 or 1 in the 1st element
506 ;; of a vector marked as valid-hashing. The vector is initially filled
507 ;; with the unbound-marker, so rectify that. GC is inhibited (asserted
508 ;; on entry), so the store order here isn't terribly important.
509 (setf (kv-vector-needs-rehash new-kv-vector) 0)
511 ;; Non-empty weak hash tables always need GC support.
512 (when (and (hash-table-weak-p table) (plusp (hash-table-count table)))
513 (set-header-data new-kv-vector sb!vm:vector-valid-hashing-subtype))
515 ;; FIXME: here and in several other places in the hash table code,
516 ;; loops like this one are used when FILL or REPLACE would be
517 ;; appropriate. why are standard CL functions not used?
518 ;; Performance issues? General laziness? -- NJF, 2004-03-10
520 ;; Copy over the kv-vector. The element positions should not move
521 ;; in case there are active scans.
522 (dotimes (i (* old-size 2))
523 (declare (type index i))
524 (setf (aref new-kv-vector i) (aref old-kv-vector i)))
526 ;; Copy over the hash-vector.
527 (when old-hash-vector
528 (dotimes (i old-size)
529 (setf (aref new-hash-vector i) (aref old-hash-vector i))))
531 (setf (hash-table-next-free-kv table) 0)
532 ;; Rehash all the entries; last to first so that after the pushes
533 ;; the chains are first to last.
534 (do ((i (1- new-size) (1- i)))
535 ((zerop i))
536 (declare (type index/2 i))
537 (let ((key (aref new-kv-vector (* 2 i)))
538 (value (aref new-kv-vector (1+ (* 2 i)))))
539 (cond ((and (empty-ht-slot-p key) (empty-ht-slot-p value))
540 ;; Slot is empty, push it onto the free list.
541 (setf (aref new-next-vector i)
542 (hash-table-next-free-kv table))
543 (setf (hash-table-next-free-kv table) i))
544 ((and new-hash-vector
545 (not (= (aref new-hash-vector i)
546 +magic-hash-vector-value+)))
547 ;; Can use the existing hash value (not EQ based)
548 (let* ((hashing (aref new-hash-vector i))
549 (index (index-for-hashing hashing new-length))
550 (next (aref new-index-vector index)))
551 (declare (type index index)
552 (type hash hashing))
553 ;; Push this slot into the next chain.
554 (setf (aref new-next-vector i) next)
555 (setf (aref new-index-vector index) i)))
557 ;; EQ base hash.
558 ;; Enable GC tricks.
559 (set-header-data new-kv-vector
560 sb!vm:vector-valid-hashing-subtype)
561 (let* ((hashing (pointer-hash key))
562 (index (index-for-hashing hashing new-length))
563 (next (aref new-index-vector index)))
564 (declare (type index index)
565 (type hash hashing))
566 ;; Push this slot onto the next chain.
567 (setf (aref new-next-vector i) next)
568 (setf (aref new-index-vector index) i))))))
569 (setf (hash-table-table table) new-kv-vector)
570 (setf (hash-table-index-vector table) new-index-vector)
571 (setf (hash-table-next-vector table) new-next-vector)
572 (setf (hash-table-hash-vector table) new-hash-vector)
573 ;; Fill the old kv-vector with 0 to help the conservative GC. Even
574 ;; if nothing else were zeroed, it's important to clear the
575 ;; special first cell in old-kv-vector.
576 (fill old-kv-vector 0)
577 (setf (hash-table-rehash-trigger table) new-size))
578 (values))
580 ;;; Use the same size as before, re-using the vectors.
581 (defun rehash-without-growing (table)
582 (declare (type hash-table table))
583 (aver *gc-inhibit*)
584 (let* ((kv-vector (hash-table-table table))
585 (next-vector (hash-table-next-vector table))
586 (hash-vector (hash-table-hash-vector table))
587 (size (length next-vector))
588 (index-vector (hash-table-index-vector table))
589 (length (length index-vector)))
590 (declare (type index size length))
592 ;; Non-empty weak hash tables always need GC support.
593 (unless (and (hash-table-weak-p table) (plusp (hash-table-count table)))
594 ;; Disable GC tricks, they will be re-enabled during the re-hash
595 ;; if necessary.
596 (set-header-data kv-vector sb!vm:vector-normal-subtype))
598 ;; Rehash all the entries.
599 (setf (hash-table-next-free-kv table) 0)
600 (dotimes (i size)
601 (setf (aref next-vector i) 0))
602 (dotimes (i length)
603 (setf (aref index-vector i) 0))
604 (do ((i (1- size) (1- i)))
605 ((zerop i))
606 (declare (type index/2 i))
607 (let ((key (aref kv-vector (* 2 i)))
608 (value (aref kv-vector (1+ (* 2 i)))))
609 (cond ((and (empty-ht-slot-p key) (empty-ht-slot-p value))
610 ;; Slot is empty, push it onto free list.
611 (setf (aref next-vector i) (hash-table-next-free-kv table))
612 (setf (hash-table-next-free-kv table) i))
613 ((and hash-vector (not (= (aref hash-vector i)
614 +magic-hash-vector-value+)))
615 ;; Can use the existing hash value (not EQ based)
616 (let* ((hashing (aref hash-vector i))
617 (index (index-for-hashing hashing length))
618 (next (aref index-vector index)))
619 (declare (type index index))
620 ;; Push this slot into the next chain.
621 (setf (aref next-vector i) next)
622 (setf (aref index-vector index) i)))
624 ;; EQ base hash.
625 ;; Enable GC tricks.
626 (set-header-data kv-vector sb!vm:vector-valid-hashing-subtype)
627 (let* ((hashing (pointer-hash key))
628 (index (index-for-hashing hashing length))
629 (next (aref index-vector index)))
630 (declare (type index index)
631 (type hash hashing))
632 ;; Push this slot into the next chain.
633 (setf (aref next-vector i) next)
634 (setf (aref index-vector index) i))))))
635 ;; Clear the rehash bit only at the very end, otherwise another thread
636 ;; might see a partially rehashed table as a normal one.
637 (setf (kv-vector-needs-rehash kv-vector) 0))
638 (values))
640 (declaim (inline maybe-rehash))
641 (defun maybe-rehash (hash-table ensure-free-slot-p)
642 (when (hash-table-weak-p hash-table)
643 (aver *gc-inhibit*))
644 (flet ((rehash-p ()
645 (and ensure-free-slot-p
646 (zerop (hash-table-next-free-kv hash-table))))
647 (rehash-without-growing-p ()
648 (not (eql 0 (kv-vector-needs-rehash (hash-table-table hash-table))))))
649 (declare (inline rehash-p rehash-without-growing-p))
650 (cond ((rehash-p)
651 ;; Use recursive locks since for weak tables the lock has
652 ;; already been acquired. GC must be inhibited to prevent
653 ;; the GC from seeing a rehash in progress.
654 (sb!thread::with-recursive-system-lock
655 ((hash-table-lock hash-table) :without-gcing t)
656 ;; Repeat the condition inside the lock to ensure that if
657 ;; two reader threads enter MAYBE-REHASH at the same time
658 ;; only one rehash is performed.
659 (when (rehash-p)
660 (rehash hash-table))))
661 ((rehash-without-growing-p)
662 (sb!thread::with-recursive-system-lock
663 ((hash-table-lock hash-table) :without-gcing t)
664 (when (rehash-without-growing-p)
665 (rehash-without-growing hash-table)))))))
667 (declaim (inline update-hash-table-cache))
668 (defun update-hash-table-cache (hash-table index)
669 (unless (hash-table-weak-p hash-table)
670 (setf (hash-table-cache hash-table) index)))
672 (defmacro with-hash-table-locks ((hash-table
673 &key (operation :write) inline pin
674 (synchronized `(hash-table-synchronized-p ,hash-table)))
675 &body body)
676 (declare (type (member :read :write) operation))
677 (with-unique-names (body-fun)
678 `(flet ((,body-fun ()
679 (with-concurrent-access-check ,hash-table ,operation
680 (locally (declare (inline ,@inline))
681 ,@body))))
682 (if (hash-table-weak-p ,hash-table)
683 (sb!thread::with-recursive-system-lock
684 ((hash-table-lock ,hash-table) :without-gcing t)
685 (,body-fun))
686 (with-pinned-objects ,pin
687 (if ,synchronized
688 ;; We use a "system" lock here because it is very
689 ;; slightly faster, as it doesn't re-enable
690 ;; interrupts.
691 (sb!thread::with-recursive-system-lock
692 ((hash-table-lock ,hash-table))
693 (,body-fun))
694 (,body-fun)))))))
696 (defun gethash (key hash-table &optional default)
697 "Finds the entry in HASH-TABLE whose key is KEY and returns the
698 associated value and T as multiple values, or returns DEFAULT and NIL
699 if there is no such entry. Entries can be added using SETF."
700 (declare (type hash-table hash-table)
701 (values t (member t nil)))
702 (gethash3 key hash-table default))
704 (declaim (maybe-inline %gethash3))
705 (defun %gethash3 (key hash-table default)
706 (declare (type hash-table hash-table)
707 (optimize speed)
708 (values t (member t nil)))
709 (tagbody
710 start
711 (let ((start-epoch sb!kernel::*gc-epoch*))
712 (macrolet ((result (value foundp)
713 ;; When the table has multiple concurrent readers,
714 ;; it's possible that there was a GC after this
715 ;; thread called MAYBE-REHASH from %GETHASH3, and
716 ;; some other thread then rehashed the table. If
717 ;; this happens, we might not find the key even if
718 ;; it's in the table. To protect against this,
719 ;; redo the lookup if the GC epoch counter has changed.
720 ;; -- JES, 2007-09-30
721 `(if (and (not ,foundp)
722 (not (eq start-epoch sb!kernel::*gc-epoch*)))
723 (go start)
724 (return-from %gethash3 (values ,value ,foundp))))
725 (overflow ()
726 ;; The next-vector chain is circular. This is caused
727 ;; caused by thread-unsafe mutations of the table.
728 `(signal-corrupt-hash-table hash-table)))
729 (maybe-rehash hash-table nil)
730 ;; Note that it's OK for a GC + a REHASH-WITHOUT-GROWING to
731 ;; be triggered by another thread after this point, since the
732 ;; GC epoch check will catch it.
733 (let ((cache (hash-table-cache hash-table))
734 (table (hash-table-table hash-table)))
735 ;; First check the cache. Use EQ here for speed.
736 (if (and cache
737 (< cache (length table))
738 (eq (aref table cache) key))
739 (let ((value (aref table (1+ cache))))
740 (result value t))
741 ;; Search for key in the hash table.
742 (multiple-value-bind (hashing eq-based)
743 (funcall (hash-table-hash-fun hash-table) key)
744 (declare (type hash hashing))
745 (let* ((index-vector (hash-table-index-vector hash-table))
746 (length (length index-vector))
747 (index (index-for-hashing hashing length))
748 (next (aref index-vector index))
749 (next-vector (hash-table-next-vector hash-table))
750 (hash-vector (hash-table-hash-vector hash-table))
751 (test-fun (hash-table-test-fun hash-table)))
752 (declare (type index index))
753 ;; Search next-vector chain for a matching key.
754 (if (or eq-based (not hash-vector))
755 (do ((next next (aref next-vector next))
756 (i 0 (1+ i)))
757 ((zerop next) (result default nil))
758 (declare (type index/2 next i))
759 (when (> i length)
760 (overflow))
761 (when (eq key (aref table (* 2 next)))
762 (update-hash-table-cache hash-table (* 2 next))
763 (let ((value (aref table (1+ (* 2 next)))))
764 (result value t))))
765 (do ((next next (aref next-vector next))
766 (i 0 (1+ i)))
767 ((zerop next) (result default nil))
768 (declare (type index/2 next i))
769 (when (> i length)
770 (overflow))
771 (when (and (= hashing (aref hash-vector next))
772 (funcall test-fun key
773 (aref table (* 2 next))))
774 ;; Found.
775 (update-hash-table-cache hash-table (* 2 next))
776 (let ((value (aref table (1+ (* 2 next)))))
777 (result value t)))))))))))))
778 ;;; Three argument version of GETHASH
779 (defun gethash3 (key hash-table default)
780 (declare (type hash-table hash-table))
781 (truly-the (values t boolean)
782 (with-hash-table-locks (hash-table :operation :read :inline (%gethash3)
783 :pin (key))
784 (%gethash3 key hash-table default))))
786 ;;; so people can call #'(SETF GETHASH)
787 ;;; FIXME: this function is not mandated. Why do we have it?
788 (defun (setf gethash) (new-value key table &optional default)
789 (declare (ignore default))
790 (%puthash key table new-value))
792 (declaim (maybe-inline %%puthash))
793 (defun %%puthash (key hash-table value)
794 (declare (optimize speed))
795 ;; We need to rehash here so that a current key can be found if it
796 ;; exists. Check that there is room for one more entry. May not be
797 ;; needed if the key is already present.
798 (maybe-rehash hash-table t)
799 ;; Search for key in the hash table.
800 (multiple-value-bind (hashing eq-based)
801 (funcall (hash-table-hash-fun hash-table) key)
802 (declare (type hash hashing))
803 (let* ((index-vector (hash-table-index-vector hash-table))
804 (length (length index-vector))
805 (index (index-for-hashing hashing length))
806 (next (aref index-vector index))
807 (kv-vector (hash-table-table hash-table))
808 (next-vector (hash-table-next-vector hash-table))
809 (hash-vector (hash-table-hash-vector hash-table))
810 (test-fun (hash-table-test-fun hash-table)))
811 (declare (type index index next))
812 (when (hash-table-weak-p hash-table)
813 (set-header-data kv-vector sb!vm:vector-valid-hashing-subtype))
814 (cond ((or eq-based (not hash-vector))
815 (when eq-based
816 (set-header-data kv-vector
817 sb!vm:vector-valid-hashing-subtype))
818 ;; Search next-vector chain for a matching key.
819 (do ((next next (aref next-vector next))
820 (i 0 (1+ i)))
821 ((zerop next))
822 (declare (type index/2 next i))
823 (when (> i length)
824 (signal-corrupt-hash-table hash-table))
825 (when (eq key (aref kv-vector (* 2 next)))
826 ;; Found, just replace the value.
827 (update-hash-table-cache hash-table (* 2 next))
828 (setf (aref kv-vector (1+ (* 2 next))) value)
829 (return-from %%puthash value))))
831 ;; Search next-vector chain for a matching key.
832 (do ((next next (aref next-vector next))
833 (i 0 (1+ i)))
834 ((zerop next))
835 (declare (type index/2 next i))
836 (when (> i length)
837 (signal-corrupt-hash-table hash-table))
838 (when (and (= hashing (aref hash-vector next))
839 (funcall test-fun key
840 (aref kv-vector (* 2 next))))
841 ;; Found, just replace the value.
842 (update-hash-table-cache hash-table (* 2 next))
843 (setf (aref kv-vector (1+ (* 2 next))) value)
844 (return-from %%puthash value)))))
845 ;; Pop a KV slot off the free list
846 (let ((free-kv-slot (hash-table-next-free-kv hash-table)))
847 (declare (type index/2 free-kv-slot))
848 ;; Double-check for overflow.
849 (aver (not (zerop free-kv-slot)))
850 (setf (hash-table-next-free-kv hash-table)
851 (aref next-vector free-kv-slot))
852 (incf (hash-table-number-entries hash-table))
853 (update-hash-table-cache hash-table (* 2 free-kv-slot))
854 (setf (aref kv-vector (* 2 free-kv-slot)) key)
855 (setf (aref kv-vector (1+ (* 2 free-kv-slot))) value)
856 ;; Setup the hash-vector if necessary.
857 (when hash-vector
858 (if (not eq-based)
859 (setf (aref hash-vector free-kv-slot) hashing)
860 (aver (= (aref hash-vector free-kv-slot)
861 +magic-hash-vector-value+))))
862 ;; Push this slot into the next chain.
863 (setf (aref next-vector free-kv-slot) next)
864 (setf (aref index-vector index) free-kv-slot)))
865 value))
867 (defun %puthash (key hash-table value)
868 (declare (type hash-table hash-table))
869 (aver (hash-table-index-vector hash-table))
870 (macrolet ((put-it (lockedp)
871 `(let ((cache (hash-table-cache hash-table))
872 (kv-vector (hash-table-table hash-table)))
873 ;; Check the cache
874 (if (and cache
875 (< cache (length kv-vector))
876 (eq (aref kv-vector cache) key))
877 ;; If cached, just store here
878 (setf (aref kv-vector (1+ cache)) value)
879 ;; Otherwise do things the hard way
880 ,(if lockedp
881 '(%%puthash key hash-table value)
882 '(with-hash-table-locks
883 (hash-table :inline (%%puthash) :pin (key)
884 :synchronized nil)
885 (%%puthash key hash-table value)))))))
886 (if (hash-table-synchronized-p hash-table)
887 (with-hash-table-locks (hash-table :pin (key) :synchronized t)
888 (put-it t))
889 (put-it nil))))
891 (declaim (maybe-inline %remhash))
892 (defun %remhash (key hash-table)
893 ;; We need to rehash here so that a current key can be found if it
894 ;; exists.
896 ;; Note that if a GC happens after MAYBE-REHASH returns and another
897 ;; thread the accesses the table (triggering a rehash), we might not
898 ;; find the key even if it is in the table. But that's ok, since the
899 ;; only concurrent case that we safely allow is multiple readers
900 ;; with no writers.
901 (maybe-rehash hash-table nil)
902 ;; Search for key in the hash table.
903 (multiple-value-bind (hashing eq-based)
904 (funcall (hash-table-hash-fun hash-table) key)
905 (declare (type hash hashing))
906 (let* ((index-vector (hash-table-index-vector hash-table))
907 (length (length index-vector))
908 (index (index-for-hashing hashing length))
909 (next (aref index-vector index))
910 (table (hash-table-table hash-table))
911 (next-vector (hash-table-next-vector hash-table))
912 (hash-vector (hash-table-hash-vector hash-table))
913 (test-fun (hash-table-test-fun hash-table)))
914 (declare (type index index)
915 (type index/2 next))
916 (flet ((clear-slot (chain-vector prior-slot-location slot-location)
917 (declare (type index/2 slot-location))
918 ;; Mark slot as empty.
919 (setf (aref table (* 2 slot-location)) +empty-ht-slot+
920 (aref table (1+ (* 2 slot-location))) +empty-ht-slot+)
921 ;; Update the prior pointer in the chain to skip this.
922 (setf (aref chain-vector prior-slot-location)
923 (aref next-vector slot-location))
924 ;; Push KV slot onto free chain.
925 (setf (aref next-vector slot-location)
926 (hash-table-next-free-kv hash-table))
927 (setf (hash-table-next-free-kv hash-table) slot-location)
928 (when hash-vector
929 (setf (aref hash-vector slot-location)
930 +magic-hash-vector-value+))
931 ;; On parallel accesses this may turn out to be a
932 ;; type-error, so don't turn down the safety!
933 (decf (hash-table-number-entries hash-table))
935 (cond ((zerop next)
936 nil)
937 ((if (or eq-based (not hash-vector))
938 (eq key (aref table (* 2 next)))
939 (and (= hashing (aref hash-vector next))
940 (funcall test-fun key (aref table (* 2 next)))))
941 (clear-slot index-vector index next))
942 ;; Search next-vector chain for a matching key.
943 ((or eq-based (not hash-vector))
944 ;; EQ based
945 (do ((prior next next)
946 (i 0 (1+ i))
947 (next (aref next-vector next) (aref next-vector next)))
948 ((zerop next) nil)
949 (declare (type index next))
950 (when (> i length)
951 (signal-corrupt-hash-table hash-table))
952 (when (eq key (aref table (* 2 next)))
953 (return-from %remhash (clear-slot next-vector prior next)))))
955 ;; not EQ based
956 (do ((prior next next)
957 (i 0 (1+ i))
958 (next (aref next-vector next) (aref next-vector next)))
959 ((zerop next) nil)
960 (declare (type index/2 next))
961 (when (> i length)
962 (signal-corrupt-hash-table hash-table))
963 (when (and (= hashing (aref hash-vector next))
964 (funcall test-fun key (aref table (* 2 next))))
965 (return-from %remhash
966 (clear-slot next-vector prior next))))))))))
968 (defun remhash (key hash-table)
969 "Remove the entry in HASH-TABLE associated with KEY. Return T if
970 there was such an entry, or NIL if not."
971 (declare (type hash-table hash-table)
972 (values (member t nil)))
973 (with-hash-table-locks (hash-table :inline (%remhash) :pin (key))
974 ;; For now, just clear the cache
975 (setf (hash-table-cache hash-table) nil)
976 (%remhash key hash-table)))
978 (defun clrhash (hash-table)
979 "This removes all the entries from HASH-TABLE and returns the hash
980 table itself."
981 (when (plusp (hash-table-number-entries hash-table))
982 (with-hash-table-locks (hash-table)
983 (let* ((kv-vector (hash-table-table hash-table))
984 (next-vector (hash-table-next-vector hash-table))
985 (hash-vector (hash-table-hash-vector hash-table))
986 (size (length next-vector))
987 (index-vector (hash-table-index-vector hash-table)))
988 ;; Disable GC tricks.
989 (set-header-data kv-vector sb!vm:vector-normal-subtype)
990 ;; Mark all slots as empty by setting all keys and values to magic
991 ;; tag.
992 (aver (eq (aref kv-vector 0) hash-table))
993 (fill kv-vector +empty-ht-slot+ :start 2)
994 ;; Set up the free list, all free.
995 (do ((i 1 (1+ i)))
996 ((>= i (1- size)))
997 (setf (aref next-vector i) (1+ i)))
998 (setf (aref next-vector (1- size)) 0)
999 (setf (hash-table-next-free-kv hash-table) 1)
1000 ;; Clear the index-vector.
1001 (fill index-vector 0)
1002 ;; Clear the hash-vector.
1003 (when hash-vector
1004 (fill hash-vector +magic-hash-vector-value+)))
1005 (setf (hash-table-cache hash-table) nil)
1006 (setf (hash-table-number-entries hash-table) 0)))
1007 hash-table)
1009 ;; Helper for atomic read/update of a synchronized table
1010 ;; in a limited sort of way using a double-checked lock.
1011 ;; You don't get to see the old value first.
1012 ;; It wouldn't be too hard to add that feature.
1013 (defun puthash-if-absent (key table constructor)
1014 (or (gethash key table)
1015 (let ((val (funcall constructor)))
1016 (with-locked-system-table (table)
1017 ;; VAL is discarded if KEY is found this time.
1018 (or (gethash key table) (setf (gethash key table) val))))))
1020 ;;;; methods on HASH-TABLE
1022 ;;; Return a list of keyword args and values to use for MAKE-HASH-TABLE
1023 ;;; when reconstructing HASH-TABLE.
1024 (defun %hash-table-ctor-args (hash-table)
1025 `(:test ',(hash-table-test hash-table)
1026 :size ',(hash-table-size hash-table)
1027 :rehash-size ',(hash-table-rehash-size hash-table)
1028 :rehash-threshold ',(hash-table-rehash-threshold hash-table)
1029 :weakness ',(hash-table-weakness hash-table)))
1031 ;;; Stuff an association list into HASH-TABLE. Return the hash table,
1032 ;;; so that we can use this for the *PRINT-READABLY* case in
1033 ;;; PRINT-OBJECT (HASH-TABLE T) without having to worry about LET
1034 ;;; forms and readable gensyms and stuff.
1035 (defun %stuff-hash-table (hash-table alist)
1036 (dolist (x alist)
1037 (setf (gethash (car x) hash-table) (cdr x)))
1038 hash-table)
1040 (defmethod print-object ((hash-table hash-table) stream)
1041 (declare (type stream stream))
1042 (cond ((or (not *print-readably*) (not *read-eval*))
1043 (print-unreadable-object (hash-table stream :type t :identity t)
1044 (format stream
1045 ":TEST ~S :COUNT ~S~@[ :WEAKNESS ~S~]"
1046 (hash-table-test hash-table)
1047 (hash-table-count hash-table)
1048 (hash-table-weakness hash-table))))
1050 (write-string "#." stream)
1051 (write `(%stuff-hash-table (make-hash-table ,@(%hash-table-ctor-args
1052 hash-table))
1053 ',(%hash-table-alist hash-table))
1054 :stream stream))))
1056 (defmethod make-load-form ((hash-table hash-table) &optional environment)
1057 (declare (ignore environment))
1058 (values `(make-hash-table ,@(%hash-table-ctor-args hash-table))
1059 `(%stuff-hash-table ,hash-table ',(%hash-table-alist hash-table))))