Changeset 10613


Ignore:
Timestamp:
Sep 3, 2008, 1:32:36 PM (12 years ago)
Author:
gz
Message:

private branch

Location:
branches/gz
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • branches/gz/level-0/l0-hash.lisp

    r10156 r10613  
    183183
    184184(defun %cons-hash-table (rehash-function keytrans-function compare-function vector
    185                                          threshold rehash-ratio rehash-size address-based find find-new owner)
     185                                         threshold rehash-ratio rehash-size address-based find find-new owner &optional lock)
    186186  (%istruct
    187187   'HASH-TABLE                          ; type
     
    200200   rehash-size                          ; nhash.rehash-size
    201201   0                                    ; nhash.puthash-count
    202    (unless owner
    203      (make-read-write-lock))              ; nhash.exclusion-lock
     202   (or lock
     203       (unless owner (make-read-write-lock))) ; nhash.exclusion-lock
    204204   nil ;;(make-lock)                            ; nhash.rehash-lock
    205205   nil                                  ; nhash.iterator
     
    235235            (= typecode target::subtag-complex)))))
    236236
     237(defun %needs-rehashing-p (hash)
     238  (%vector-needs-rehashing-p (nhash.vector hash)))
     239
    237240;;; Don't rehash at all, unless some key is address-based (directly or
    238241;;; indirectly.)
    239 (defun %needs-rehashing-p (hash)
    240   (let ((flags (nhash.vector.flags (nhash.vector hash))))
     242(defun-inline %vector-needs-rehashing-p (hashv)
     243  (let ((flags (nhash.vector.flags hashv)))
    241244    (declare (fixnum flags))
    242245    (if (logbitp $nhash_track_keys_bit flags)
     
    245248      ;; GC is not tracking key movement
    246249      (if (logbitp $nhash_component_address_bit flags)
    247         (not (eql (the fixnum (gc-count)) (the fixnum (nhash.gc-count hash))))))))
     250        ;; TODO:Why is this in the hash table rather than the vector?  Certainly is specific
     251        ;; to the vector.
     252        (not (eql (the fixnum (gc-count)) (the fixnum (nhash.gc-count (nhash.vector.hash hashv)))))))))
     253 
     254 
    248255
    249256(defun %set-does-not-need-rehashing (hash)
     
    479486                             (weak nil)
    480487                             (finalizeable nil)
    481                              (address-based t)
     488                             (address-based t)  ;; Ignored
     489                             (lock-free nil)    ;; Experimental
    482490                             (shared *shared-hash-table-default*))
    483491  "Create and return a new hash table. The keywords are as follows:
     
    535543    (multiple-value-bind (size total-size)
    536544        (compute-hash-size (1- size) 1 rehash-threshold)
    537       (let* ((flags (if weak
    538                       (+ (+
    539                           (ash 1 $nhash_weak_bit)
    540                           (ecase weak
    541                             ((t :key) 0)
    542                             (:value (ash 1 $nhash_weak_value_bit))))
    543                          (if finalizeable (ash 1 $nhash_finalizeable_bit) 0))
    544                       0))
     545      (let* ((flags (+ (if weak (ash 1 $nhash_weak_bit) 0)
     546                       (ecase weak
     547                         ((t nil :key) 0)
     548                         (:value (ash 1 $nhash_weak_value_bit)))
     549                       (if finalizeable (ash 1 $nhash_finalizeable_bit) 0)
     550                       (if lock-free (ash 1 $nhash_keys_frozen_bit) 0)))
    545551             (hash (%cons-hash-table
    546552                    #'%no-rehash hash-function test
     
    548554                    size rehash-threshold rehash-size address-based
    549555                    find-function find-put-function
    550                     (unless shared *current-process*))))
     556                    (unless shared *current-process*)
     557                    (and lock-free (make-lock)))))
     558        (when lock-free
     559          (setf (nhash.lock hash) (logior (nhash.lock hash) $nhash.lock-free)))
    551560        (setf (nhash.vector.hash (nhash.vector hash)) hash)
    552561        hash))))
     
    697706
    698707
     708(declaim (inline lock-free-gethash))
     709(defun lock-free-gethash (key hash default)
     710  (declare (optimize (speed 3) (safety 0) (debug 0)))
     711  (loop named gethash
     712    do (let* ((vector (nhash.vector hash))
     713              ;; **TODO make this return nil if FREE, then won't have to refetch.
     714              (vector-index (funcall (the function (nhash.find hash)) hash key)))
     715         (cond ((or (null vector-index)
     716                    (neq vector (nhash.vector hash))
     717                    (eq (%svref vector vector-index) free-hash-key-marker))
     718                ;; It's kinda risky to use lock-free hash tables with address-based
     719                ;; keys, because it will thrash in low-memory situations, but we don't
     720                ;; disallow it because there are situations where it won't be a problem.
     721                (unless (or (%needs-rehashing-p hash)
     722                            (neq vector (nhash.vector hash)))
     723                  (return-from gethash (values default nil))))
     724               (t (let ((value (%svref vector (%i+ vector-index 1))))
     725                    (unless (or (eq value free-hash-key-marker)
     726                                (neq vector (nhash.vector hash)))
     727                      (if (eq value deleted-hash-key-marker)
     728                        (return-from gethash (values default nil))
     729                        (return-from gethash (values value t)))))))
     730         ;; We're here because the table needs rehashing or it was getting rehashed
     731         ;; while we were searching.
     732         (with-lock-context
     733           (without-interrupts
     734             (let ((lock (nhash.exclusion-lock hash)))
     735               (grab-lock lock)
     736               (%lock-gc-lock)
     737               (when (%needs-rehashing-p hash)
     738                 (%rehash hash))
     739               (%unlock-gc-lock)
     740               (release-lock lock)))))))
    699741
    700742(defun gethash (key hash &optional default)
     
    704746  (unless (typep hash 'hash-table)
    705747    (report-bad-arg hash 'hash-table))
     748  (when (logbitp $nhash.lock-free (nhash.lock hash))
     749    (return-from gethash (lock-free-gethash key hash default)))
    706750  (let* ((value nil)
     751         (vector-index nil)
    707752         (vector-key nil)
    708753         (gc-locked nil)
    709754         (readonly nil)
    710          (foundp nil))
     755         (foundp nil)
     756         (vector nil))
    711757    (with-lock-context
    712758      (without-interrupts
    713        (setq readonly (eq (read-lock-hash-table hash) :readonly))
    714        (let* ((vector (nhash.vector hash)))
    715          (if (and (eq key (nhash.vector.cache-key vector))
    716                   ;; Check twice: the GC might nuke the cached key/value pair
    717                   (progn (setq value (nhash.vector.cache-value vector))
    718                          (eq key (nhash.vector.cache-key vector))))
    719            (setq foundp t)
    720            (loop
    721              (let* ((vector-index (funcall (nhash.find hash) hash key)))
    722                (declare (fixnum vector-index))
    723                ;; Referencing both key and value here - and referencing
    724                ;; value first - is an attempt to compensate for the
    725                ;; possibility that the GC deletes a weak-on-key pair.
    726                (setq value (%svref vector (the fixnum (1+ vector-index)))
    727                      vector-key (%svref vector vector-index))
    728                (cond ((setq foundp (and (not (eq vector-key free-hash-key-marker))
    729                                         (not (eq vector-key deleted-hash-key-marker))))
    730                       (when (nhash.owner hash)
    731                         (setf (nhash.vector.cache-key vector) vector-key
    732                               (nhash.vector.cache-value vector) value
    733                               (nhash.vector.cache-idx vector) (vector-index->index
    734                                                                vector-index)))
    735                       (return))
    736                      ((%needs-rehashing-p hash)
    737                       (%lock-gc-lock)
    738                       (setq gc-locked t)
    739                       (unless readonly
    740                         (let* ((lock (nhash.exclusion-lock hash)))
    741                           (when lock (%promote-rwlock lock))))
    742                       (when (%needs-rehashing-p hash)
    743                         (%rehash hash)))
    744                      (t (return)))))))
    745        (when gc-locked (%unlock-gc-lock))
    746        (unlock-hash-table hash readonly)))
     759        (setq readonly (eq (read-lock-hash-table hash) :readonly))
     760        (let* ((vector (nhash.vector hash)))
     761          (if (and (eq key (nhash.vector.cache-key vector))
     762                   ;; Check twice: the GC might nuke the cached key/value pair
     763                   (progn (setq value (nhash.vector.cache-value vector))
     764                          (eq key (nhash.vector.cache-key vector))))
     765            (setq foundp t)
     766            (loop
     767              (let* ((vector-index (funcall (nhash.find hash) hash key)))
     768                (declare (fixnum vector-index))
     769                ;; Referencing both key and value here - and referencing
     770                ;; value first - is an attempt to compensate for the
     771                ;; possibility that the GC deletes a weak-on-key pair.
     772                (setq value (%svref vector (the fixnum (1+ vector-index)))
     773                      vector-key (%svref vector vector-index))
     774                (cond ((setq foundp (and (not (eq vector-key free-hash-key-marker))
     775                                         (not (eq vector-key deleted-hash-key-marker))))
     776                       (when (nhash.owner hash)
     777                         (setf (nhash.vector.cache-key vector) vector-key
     778                               (nhash.vector.cache-value vector) value
     779                               (nhash.vector.cache-idx vector) (vector-index->index
     780                                                                vector-index)))
     781                       (return))
     782                      ((%needs-rehashing-p hash)
     783                       (%lock-gc-lock)
     784                       (setq gc-locked t)
     785                       (unless readonly
     786                         (let* ((lock (nhash.exclusion-lock hash)))
     787                           (when lock (%promote-rwlock lock))))
     788                       (when (%needs-rehashing-p hash)
     789                         (%rehash hash)))
     790                      (t (return)))))))
     791        (when gc-locked (%unlock-gc-lock))
     792        (unlock-hash-table hash readonly)))
    747793    (if foundp
    748794      (values value t)
     
    809855    foundp))
    810856
     857#|
     858 (b) Add entry: if key not found, pick a place with key=Free (this is different from
     859   non-lock-free, where it might reuse deleted entries).  First, to
     860   ConditionalSet(key <- Normal if Free).  If wasn't free, go to locking case.
     861   Next, ConditionalSet(value <- value if Delete).  If wasn't delete, go to locking case
     862
     863 (c) Set entry: if key found, get value, if value is Free, go to locking case, else
     864   ConditionalSet(value <- new value if old value).  If fails, go to locking case.
     865|#
     866
     867(defun lock-free-puthash (key hash value)
     868  (when (eq key free-hash-key-marker)
     869    (error "Can't use ~s as a hash-table key" key))
     870  (when (or (eq value free-hash-key-marker)
     871            (eq value deleted-hash-key-marker))
     872    (error "Illegal value ~s for storing in a hash table" value))
     873  (let* ((vector (nhash.vector  hash))
     874         (vector-index (funcall (nhash.find-new hash) hash key))
     875         (rehashed (neq vector (nhash.vector hash))))
     876    (cond ((or rehashed
     877               (null vector-index)
     878               (eq (%svref vector vector-index) free-hash-key-marker))
     879           (unless (or rehashed
     880                       (%needs-rehashing-p hash)
     881                       (eql 0 (nhash.grow-threshold hash)))
     882             ;; Ok to add
     883             ;; *** LIKE %set but need to do SetConditional on free-marker
     884             (%claim-hash-table-vector-key
     885             ;; not found
     886             (unless (eq 0 (nhash.grow-threshold hash))
     887               ;; Allowed to add
     888
     889               (%set-hash-table-vector-key vector vector-index key)
     890                     (setf (%svref vector (the fixnum (1+ vector-index))) value)
     891                     (decf (the fixnum (nhash.grow-threshold hash)))
     892                     (incf (the fixnum (nhash.count hash))))
     893
     894               
     895
     896
     897             (when vector-index ;;else table full!!
     898               (when (%CONDITIONAL-SET (%svref vector vector-index)
     899                                       :from free-hash-key-marker
     900                                       :to key)
     901                 (when (%CONDITIONAL-SET (%svref vector (%i+ vector-index 1))
     902                                         :from deleted-hash-key-marker
     903                                         :to value)
     904                   (return-from lock-free-puthash value)))
     905               ;; here if either rehashing, somebody else claimed this slot
     906               )
     907             ;; Here if either table full or rehashing or lost race
     908             )
     909           ;; Here if needs rehashing (so might be looking at wrong chain)
     910           ;; or table full or currently rehashing or lost race.
     911           
     912
     913                  (return-from gethash (values default nil)))
     914
     915           ;; Ok, adding new entry -- unless the problem is
     916
     917
     918              (cond ((eq old-value deleted-hash-key-marker)
     919                     (%set-hash-table-vector-key vector vector-index key)
     920                     (setf (%svref vector (the fixnum (1+ vector-index))) value)
     921                     (setf (nhash.count hash) (the fixnum (1+ (the fixnum (nhash.count hash)))))
     922                     ;; Adjust deleted-count
     923                     (when (> 0 (the fixnum
     924                                  (decf (the fixnum
     925                                          (nhash.vector.deleted-count vector)))))
     926                       (let ((weak-deletions (nhash.vector.weak-deletions-count vector)))
     927                         (declare (fixnum weak-deletions))
     928                         (setf (nhash.vector.weak-deletions-count vector) 0)
     929                         (incf (the fixnum (nhash.vector.deleted-count vector)) weak-deletions)
     930                         (decf (the fixnum (nhash.count hash)) weak-deletions))))
     931                    ((eq old-value free-hash-key-marker)
     932                     (when (eql 0 (nhash.grow-threshold hash))
     933                       (%unlock-gc-lock)
     934                       (grow-hash-table hash)
     935                       (go AGAIN))
     936                     (%set-hash-table-vector-key vector vector-index key)
     937                     (setf (%svref vector (the fixnum (1+ vector-index))) value)
     938                     (decf (the fixnum (nhash.grow-threshold hash)))
     939                     (incf (the fixnum (nhash.count hash))))
     940                    (t
     941                     ;; Key was already there, update value.
     942                     (setf (%svref vector (the fixnum (1+ vector-index))) value)))
     943              (setf (nhash.vector.cache-idx vector) (vector-index->index vector-index)
     944                    (nhash.vector.cache-key vector) key
     945                    (nhash.vector.cache-value vector) value)))))
     946     (%unlock-gc-lock)
     947     (unlock-hash-table hash nil))))
     948
    811949(defun puthash (key hash default &optional (value default))
    812950  (declare (optimize (speed 3) (space 0)))
    813951  (unless (typep hash 'hash-table)
    814952    (report-bad-arg hash 'hash-table))
     953  (when (logbitp $nhash.lock-free (nhash.lock hash))
     954    (return-from gethash (lock-free-puthash key hash value)))
    815955  (if (eq key (%unbound-marker))
    816956    (error "Can't use ~s as a hash-table key" (%unbound-marker)))
  • branches/gz/lib/macros.lisp

    r10514 r10613  
    666666         (%defun (nfunction ,spec ,lambda-expression) ',info)
    667667         ',spec))))
     668
     669(defmacro defun-inline (spec &body body)
     670  `(progn
     671     (declaim (inline ,spec))
     672     (defun ,spec ,@body)))
    668673
    669674(defmacro %defvar-init (var initform doc)
  • branches/gz/lisp-kernel/ppc-spentry.s

    r8476 r10613  
    68746874        __(b _SPbind_interrupt_level)
    68756875
    6876 _spentry(unused_6)
    6877          __(b _SPbreakpoint)
    6878                        
    68796876       
    68806877
  • branches/gz/lisp-kernel/ppc-spjump.s

    r6518 r10613  
    175175        _spjump(poweropen_ffcall_return_registers)
    176176        _spjump(nmkunwind)
    177         _spjump(unused_6)
     177        _spjump(set_hash_key_conditional)
    178178        _spjump(unbind_interrupt_level)
    179179        _spjump(unbind)
  • branches/gz/lisp-kernel/x86-exceptions.c

    r10598 r10613  
    20572057
    20582058extern opcode egc_write_barrier_start, egc_write_barrier_end,
     2059  egc_set_hash_key_conditional, egc_set_hash_key_conditional_success_test,
     2060  egc_store_node_conditional_success_end,
    20592061  egc_store_node_conditional_success_test,egc_store_node_conditional,
    20602062  egc_set_hash_key, egc_gvset, egc_rplacd;
     
    22792281    Boolean need_store = true, need_check_memo = true, need_memoize_root = false;
    22802282
    2281     if (program_counter >= &egc_store_node_conditional) {
     2283    if (program_counter >= &egc_set_hash_key_conditional) {
     2284      if ((program_counter < &egc_set_hash_key_conditional_success_test) ||
     2285          ((program_counter == &egc_set_hash_key_conditional_success_test) &&
     2286           !(eflags_register(xp) & (1 << X86_ZERO_FLAG_BIT)))) {
     2287        /* Back up the PC, try again */
     2288        xpPC(xp) = (LispObj) &egc_set_hash_key_conditional;
     2289        return;
     2290      }
     2291      /* The conditional store succeeded.  Set the refbit, return to ra0 */
     2292      val = xpGPR(xp,Iarg_z);
     2293#ifdef X8664
     2294      root = xpGPR(xp,Iarg_x);
     2295      ea = (LispObj*)(root + (unbox_fixnum((signed_natural) xpGPR(xp,Itemp0))));
     2296#else
     2297      root = xpGPR(xp,Itemp1);
     2298      ea = (LispObj *)(root + misc_data_offset + xpGPR(xp,Itemp0));
     2299#endif
     2300      need_memoize_root = true;
     2301      need_store = false;
     2302      xpGPR(xp,Iarg_z) = t_value;
     2303    } else if (program_counter >= &egc_store_node_conditional) {
    22822304      if ((program_counter < &egc_store_node_conditional_success_test) ||
    22832305          ((program_counter == &egc_store_node_conditional_success_test) &&
     
    22872309        return;
    22882310      }
     2311      if (program_counter >= &egc_store_node_conditional_success_end) {
     2312        return;
     2313      }
     2314
    22892315      /* The conditional store succeeded.  Set the refbit, return to ra0 */
    22902316      val = xpGPR(xp,Iarg_z);
  • branches/gz/lisp-kernel/x86-spentry32.s

    r10583 r10613  
    18071807        __(lock)
    18081808        __(btsl %imm0,(%temp1))
     1809        .globl C(egc_store_node_conditional_success_end)
     1810C(egc_store_node_conditional_success_end)
     18112:      __(movl $t_value,%arg_z)
     1812        __(ret)
     18133:      __(movl $nil_value,%arg_z)
     1814        __(ret)
     1815_endsubp(store_node_conditional)
     1816
     1817        /* %temp0 = offset, %temp1 = object, %arg_y = old, %arg_z = new */
     1818_spentry(set_hash_key_conditional)
     1819        .globl C(egc_set_hash_key_conditional)
     1820C(egc_set_hash_key_conditional):
     1821        __(subl $misc_data_offset*fixnumone,%temp0) /* undo pre-added offset */
     1822        __(sarl $fixnumshift,%temp0)    /* will be fixnum-tagged */
     18230:      __(cmpl %arg_y,misc_data_offset(%temp1,%temp0))
     1824        __(movl misc_data_offset(%temp1,%temp0),%imm0)
     1825        __(jne 3f)
     1826        __(lock)
     1827        __(cmpxchgl %arg_z,misc_data_offset(%temp1,%temp0))
     1828        .globl C(egc_set_hash_key_conditional_success_test)
     1829C(egc_set_hash_key_conditional_success_test):
     1830        __(jne 0b)
     1831        __(leal misc_data_offset(%temp1,%temp0),%imm0)
     1832        __(subl lisp_global(heap_start),%imm0)
     1833        __(shrl $dnode_shift,%imm0)
     1834        __(cmpl lisp_global(oldspace_dnode_count),%imm0)
     1835        __(jae 2f)
     1836        __(ref_global(refbits,%temp0))
     1837        __(xorb $31,%imm0_b)
     1838        __(lock)
     1839        __(btsl %imm0,(%temp0))
     1840        /* Now memoize the address of the hash vector */
     1841        __(movl %temp1,%imm0)
     1842        __(subl lisp_global(heap_start),%imm0)
     1843        __(shrl $dnode_shift,%imm0)
     1844        __(xorb $31,%imm0_b)
     1845        __(lock)
     1846        __(btsl %imm0,(%temp0))
    18091847        .globl C(egc_write_barrier_end)
    18101848C(egc_write_barrier_end):
     
    45954633*/
    45964634
    4597 _spentry(unused_6)
    4598         __(int $3)
    4599 Xspentry_end:           
    4600 _endsubp(unused_6)
    46014635        .data
    46024636        .globl C(spentry_start)
  • branches/gz/lisp-kernel/x86-spentry64.s

    r10571 r10613  
    18791879        __(lock)
    18801880        __(btsq %imm0,(%temp1))
     1881        .globl C(egc_store_node_conditional_success_end)
     1882C(egc_store_node_conditional_success_end):
     18832:      __(movl $t_value,%arg_z_l)
     1884        __(ret)
     18853:      __(movl $nil_value,%arg_z_l)
     1886        __(ret)
     1887_endsubp(store_node_conditional)
     1888                               
     1889        _spentry(set_hash_key_conditional)
     1890        .globl C(egc_set_hash_key_conditional)
     1891C(egc_set_hash_key_conditional):
     1892        __(unbox_fixnum(%temp0,%imm1))
     18930:      __(movq (%arg_x,%imm1),%temp1)
     1894        __(cmpq %arg_y,%temp1)
     1895        __(movq %temp1,%imm0)
     1896        __(jne 3f)
     1897        __(lock)
     1898        __(cmpxchgq %arg_z,(%arg_x,%imm1))
     1899        .globl C(egc_set_hash_key_conditional_success_test)
     1900C(egc_set_hash_key_conditional_success_test):
     1901        __(jne 0b)
     1902        __(lea (%arg_x,%imm1),%imm0)
     1903        __(subq lisp_global(heap_start),%imm0)
     1904        __(shrq $dnode_shift,%imm0)
     1905        __(cmpq lisp_global(oldspace_dnode_count),%imm0)
     1906        __(ref_global(refbits,%temp1))
     1907        __(jae 2f)
     1908        __(xorb $63,%imm0_b)
     1909        __(lock)
     1910        __(btsq %imm0,(%temp1))
     1911        /* Now memoize the address of the hash vector   */
     1912        __(movq %arg_x,%imm0)
     1913        __(subq lisp_global(heap_start),%imm0)
     1914        __(shrq $dnode_shift,%imm0)
     1915        __(xorb $63,%imm0_b)
     1916        __(lock)
     1917        __(btsq %imm0,(%temp1))
    18811918        .globl C(egc_write_barrier_end)
    18821919C(egc_write_barrier_end):
     
    188519223:      __(movl $nil_value,%arg_z_l)
    18861923        __(ret)
    1887 _endsubp(store_node_conditional)
    1888                                
     1924_endsubp(set_hash_key_conditional)
     1925
     1926       
     1927
     1928
    18891929_spentry(setqsym)
    18901930        __(btq $sym_vbit_const,symbol.flags(%arg_y))
     
    50335073_endsubp(breakpoint)
    50345074
    5035                
    5036 
    5037 
    5038 _spentry(unused_5)
    5039         __(int $3)
    5040 _endsubp(unused_5)
    5041 
    50425075
    50435076        __ifdef([DARWIN])
     
    51205153        __endif
    51215154       
    5122 _spentry(unused_6)
     5155_spentry(unused_5)
    51235156        __(int $3)
    51245157Xspentry_end:           
    5125 _endsubp(unused_6)
     5158_endsubp(unused_5)
    51265159       
    51275160        .data
  • branches/gz/lisp-kernel/x86-spjump32.s

    r10088 r10613  
    173173        _spjump(ffcall_return_registers)
    174174        _spjump(aset1)
    175         _spjump(unused_6)
     175        _spjump(set_hash_key_conditional)
    176176        _spjump(unbind_interrupt_level)
    177177        _spjump(unbind)
  • branches/gz/lisp-kernel/x86-spjump64.s

    r6530 r10613  
    173173        _spjump(ffcall_return_registers)
    174174        _spjump(unused_5)
    175         _spjump(unused_6)
     175        _spjump(set_hash_key_conditional)
    176176        _spjump(unbind_interrupt_level)
    177177        _spjump(unbind)
  • branches/gz/xdump/hashenv.lisp

    r10268 r10613  
    2626
    2727;;; undistinguished values of nhash.lock
     28(defconstant $nhash.lock-free #x80000)
     29
     30;; The ones below don't seem to be used.
    2831(defconstant $nhash.lock-while-growing #x10000)
    2932(defconstant $nhash.lock-while-rehashing #x20000)
     
    3134(defconstant $nhash.lock-map-count-mask #xffff)
    3235(defconstant $nhash.lock-not-while-rehashing #x-20001)
     36(defconstant $nhash.lock-grow-or-rehash #x30000)
     37
     38
    3339
    3440; The hash.vector cell contains a vector with some longwords of overhead
     
    6066(defconstant $nhash_weak_value_bit 11)  ; weak on value vice key if this bit set
    6167(defconstant $nhash_finalizeable_bit 10)
     68(defconstant $nhash_keys_frozen_bit 9)  ; GC must not change key slots when deleting
    6269(defconstant $nhash_weak_flags_mask
    63   (bitset $nhash_weak_bit (bitset $nhash_weak_value_bit (bitset $nhash_finalizeable_bit 0))))
     70  (bitset $nhash_keys_frozen_bit (bitset $nhash_weak_bit (bitset $nhash_weak_value_bit (bitset $nhash_finalizeable_bit 0)))))
     71
    6472
    6573(defconstant $nhash_track_keys_bit 28)  ; request GC to track relocation of keys.
     
    6876                                        ; in ephemeral space
    6977(defconstant $nhash_component_address_bit 25) ; a hash code was computed from a key's component
     78
    7079
    7180
Note: See TracChangeset for help on using the changeset viewer.