fixing bug in hash table. growth schedule made it possible for
maxprobe to decrease, causing growth during rehashing, which leaks the table.
This commit is contained in:
		
							parent
							
								
									e3158b8640
								
							
						
					
					
						commit
						2ddbac400a
					
				| 
						 | 
				
			
			@ -8,7 +8,7 @@
 | 
			
		|||
 | 
			
		||||
(define Instructions
 | 
			
		||||
  (make-enum-table
 | 
			
		||||
   [:nop :dup :pop :popn :call :jmp :brf :brt :jmp.s :brf.s :brt.s :ret
 | 
			
		||||
   [:nop :dup :pop :popn :call :jmp :brf :brt :jmp.l :brf.l :brt.l :ret
 | 
			
		||||
 | 
			
		||||
    :eq? :eqv? :equal? :atom? :not :null? :boolean? :symbol?
 | 
			
		||||
    :number? :bound? :pair? :builtin? :vector? :fixnum?
 | 
			
		||||
| 
						 | 
				
			
			@ -20,9 +20,9 @@
 | 
			
		|||
 | 
			
		||||
    :vector :aref :aset :length :for
 | 
			
		||||
 | 
			
		||||
    :loadt :loadf :loadnil :load0 :load1 :loadv :loadv.s
 | 
			
		||||
    :loadt :loadf :loadnil :load0 :load1 :loadv :loadv.l
 | 
			
		||||
    :loadg :loada :loadc
 | 
			
		||||
    :setg  :seta  :setc  :loadg.s :setg.s
 | 
			
		||||
    :setg  :seta  :setc  :loadg.l :setg.l
 | 
			
		||||
 | 
			
		||||
    :closure :trycatch]))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -41,21 +41,38 @@
 | 
			
		|||
			      (- nconst 1)))))
 | 
			
		||||
	(aset! e 2 nconst)
 | 
			
		||||
	(set! args (list vind))
 | 
			
		||||
	(if (< vind 256)
 | 
			
		||||
	(if (>= vind 256)
 | 
			
		||||
	    (set! inst (case inst
 | 
			
		||||
			 (:loadv :loadv.s)
 | 
			
		||||
			 (:loadg :loadg.s)
 | 
			
		||||
			 (:setg  :setg.s))))))
 | 
			
		||||
			 (:loadv :loadv.l)
 | 
			
		||||
			 (:loadg :loadg.l)
 | 
			
		||||
			 (:setg  :setg.l))))))
 | 
			
		||||
  (aset! e 0 (nreconc (cons inst args) (aref e 0)))
 | 
			
		||||
  e)
 | 
			
		||||
 | 
			
		||||
(define (make-label e)   (gensym))
 | 
			
		||||
(define (mark-label e l) (emit e :label l))
 | 
			
		||||
 | 
			
		||||
(define (count- f l n)
 | 
			
		||||
  (if (null? l)
 | 
			
		||||
      n
 | 
			
		||||
      (count- f (cdr l) (if (f (car l))
 | 
			
		||||
			    (+ n 1)
 | 
			
		||||
			    n))))
 | 
			
		||||
(define (count f l) (count- f l 0))
 | 
			
		||||
 | 
			
		||||
(define (peephole c) c)
 | 
			
		||||
 | 
			
		||||
; convert symbolic bytecode representation to a byte array.
 | 
			
		||||
; labels are fixed-up.
 | 
			
		||||
(define (encode-byte-code e)
 | 
			
		||||
  (let ((v (list->vector (nreverse e))))
 | 
			
		||||
  (let* ((cl (peephole (nreverse e)))
 | 
			
		||||
	 (long? (>= (+ (length cl)
 | 
			
		||||
		       (* 3 (count (lambda (i)
 | 
			
		||||
				     (memq i '(:loadv :loadg :setg
 | 
			
		||||
						      :jmp :brt :brf)))
 | 
			
		||||
				   cl)))
 | 
			
		||||
		    65536))
 | 
			
		||||
	 (v  (list->vector cl)))
 | 
			
		||||
    (let ((n              (length v))
 | 
			
		||||
	  (i              0)
 | 
			
		||||
	  (label-to-loc   (table))
 | 
			
		||||
| 
						 | 
				
			
			@ -69,16 +86,25 @@
 | 
			
		|||
	      (begin (put! label-to-loc (aref v (+ i 1)) (sizeof bcode))
 | 
			
		||||
		     (set! i (+ i 2)))
 | 
			
		||||
	      (begin
 | 
			
		||||
		(io.write bcode (byte (get Instructions vi)))
 | 
			
		||||
		(io.write bcode
 | 
			
		||||
			  (byte
 | 
			
		||||
			   (get Instructions
 | 
			
		||||
				(if (and long?
 | 
			
		||||
					 (memq vi '(:jmp :brt :brf)))
 | 
			
		||||
				    (case vi
 | 
			
		||||
				      (:jmp :jmp.l)
 | 
			
		||||
				      (:brt :brt.l)
 | 
			
		||||
				      (:brf :brf.l))
 | 
			
		||||
				    vi))))
 | 
			
		||||
		(set! i (+ i 1))
 | 
			
		||||
		(if (< i n)
 | 
			
		||||
		    (let ((nxt (aref v i)))
 | 
			
		||||
		      (case vi
 | 
			
		||||
			((:loadv :loadg :setg)
 | 
			
		||||
			((:loadv.l :loadg.l :setg.l)
 | 
			
		||||
			 (io.write bcode (uint32 nxt))
 | 
			
		||||
			 (set! i (+ i 1)))
 | 
			
		||||
			
 | 
			
		||||
			((:loada :seta :call :loadv.s :loadg.s :setg.s :popn)
 | 
			
		||||
			((:loada :seta :call :loadv :loadg :setg :popn)
 | 
			
		||||
			 (io.write bcode (uint8 nxt))
 | 
			
		||||
			 (set! i (+ i 1)))
 | 
			
		||||
			
 | 
			
		||||
| 
						 | 
				
			
			@ -89,27 +115,16 @@
 | 
			
		|||
			 (set! i (+ i 1)))
 | 
			
		||||
			
 | 
			
		||||
			((:jmp :brf :brt)
 | 
			
		||||
			 (let ((dest (get label-to-loc nxt #uint32(-1))))
 | 
			
		||||
			   (if (< dest 256)
 | 
			
		||||
			       (begin (io.seek bcode (1- (sizeof bcode)))
 | 
			
		||||
				      (io.write bcode
 | 
			
		||||
						(byte
 | 
			
		||||
						 (get Instructions
 | 
			
		||||
						      (case vi
 | 
			
		||||
							(:jmp :jmp.s)
 | 
			
		||||
							(:brt :brt.s)
 | 
			
		||||
							(:brf :brf.s)))))
 | 
			
		||||
				      (io.write bcode (uint8 dest)))
 | 
			
		||||
			       (begin
 | 
			
		||||
				 (put! fixup-to-label (sizeof bcode) nxt)
 | 
			
		||||
				 (io.write bcode (uint32 0)))))
 | 
			
		||||
			 (put! fixup-to-label (sizeof bcode) nxt)
 | 
			
		||||
			 (io.write bcode ((if long? uint32 uint16) 0))
 | 
			
		||||
			 (set! i (+ i 1)))
 | 
			
		||||
			
 | 
			
		||||
			(else #f))))))))
 | 
			
		||||
      (table.foreach
 | 
			
		||||
       (lambda (addr labl)
 | 
			
		||||
	 (begin (io.seek bcode addr)
 | 
			
		||||
		(io.write bcode (uint32 (get label-to-loc labl)))))
 | 
			
		||||
		(io.write bcode ((if long? uint32 uint16)
 | 
			
		||||
				 (get label-to-loc labl)))))
 | 
			
		||||
       fixup-to-label)
 | 
			
		||||
      (io.tostring! bcode))))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -169,9 +184,11 @@
 | 
			
		|||
  (if (atom? lst)
 | 
			
		||||
      lst
 | 
			
		||||
    (let ((clause (car lst)))
 | 
			
		||||
      `(if ,(car clause)
 | 
			
		||||
           ,(cons 'begin (cdr clause))
 | 
			
		||||
         ,(cond-clauses->if (cdr lst))))))
 | 
			
		||||
      (if (eq? (car clause) 'else)
 | 
			
		||||
	  (cons 'begin (cdr clause))
 | 
			
		||||
	  `(if ,(car clause)
 | 
			
		||||
	       ,(cons 'begin (cdr clause))
 | 
			
		||||
	       ,(cond-clauses->if (cdr lst)))))))
 | 
			
		||||
 | 
			
		||||
(define (compile-if g x env)
 | 
			
		||||
  (let ((elsel (make-label g))
 | 
			
		||||
| 
						 | 
				
			
			@ -306,6 +323,10 @@
 | 
			
		|||
     (ash (aref a (+ i 2)) 16)
 | 
			
		||||
     (ash (aref a (+ i 3)) 24)))
 | 
			
		||||
 | 
			
		||||
(define (ref-uint16-LE a i)
 | 
			
		||||
  (+ (ash (aref a (+ i 0)) 0)
 | 
			
		||||
     (ash (aref a (+ i 1)) 8)))
 | 
			
		||||
 | 
			
		||||
(define (hex5 n)
 | 
			
		||||
  (pad-l (number->string n 16) 5 #\0))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -330,11 +351,11 @@
 | 
			
		|||
			  (string.tail (string inst) 1) "\t")
 | 
			
		||||
		   (set! i (+ i 1))
 | 
			
		||||
		   (case inst
 | 
			
		||||
		     ((:loadv :loadg :setg)
 | 
			
		||||
		     ((:loadv.l :loadg.l :setg.l)
 | 
			
		||||
		      (print-val (aref vals (ref-uint32-LE code i)))
 | 
			
		||||
		      (set! i (+ i 4)))
 | 
			
		||||
 | 
			
		||||
		     ((:loadv.s :loadg.s :setg.s)
 | 
			
		||||
		     ((:loadv :loadg :setg)
 | 
			
		||||
		      (print-val (aref vals (aref code i)))
 | 
			
		||||
		      (set! i (+ i 1)))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -349,13 +370,13 @@
 | 
			
		|||
		      (set! i (+ i 1)))
 | 
			
		||||
 | 
			
		||||
		     ((:jmp :brf :brt)
 | 
			
		||||
		      (princ "@" (hex5 (ref-uint16-LE code i)))
 | 
			
		||||
		      (set! i (+ i 2)))
 | 
			
		||||
 | 
			
		||||
		     ((:jmp.l :brf.l :brt.l)
 | 
			
		||||
		      (princ "@" (hex5 (ref-uint32-LE code i)))
 | 
			
		||||
		      (set! i (+ i 4)))
 | 
			
		||||
 | 
			
		||||
		     ((:jmp.s :brf.s :brt.s)
 | 
			
		||||
		      (princ "@" (hex5 (aref code i)))
 | 
			
		||||
		      (set! i (+ i 1)))
 | 
			
		||||
 | 
			
		||||
		     (else #f))))))))
 | 
			
		||||
 | 
			
		||||
(define (disassemble b) (disassemble- b 0))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,7 @@
 | 
			
		|||
#define hash_size(h) ((h)->size/2)
 | 
			
		||||
 | 
			
		||||
// compute empirical max-probe for a given size
 | 
			
		||||
#define max_probe(size) ((size)<=HT_N_INLINE/2 ? HT_N_INLINE/2 : (size)>>5)
 | 
			
		||||
#define max_probe(size) ((size)<=(HT_N_INLINE*2) ? (HT_N_INLINE/2) : (size)>>3)
 | 
			
		||||
 | 
			
		||||
#define HTIMPL(HTNAME, HFUNC, EQFUNC)                                   \
 | 
			
		||||
static void **HTNAME##_lookup_bp(htable_t *h, void *key)                \
 | 
			
		||||
| 
						 | 
				
			
			@ -47,7 +47,7 @@ static void **HTNAME##_lookup_bp(htable_t *h, void *key)                \
 | 
			
		|||
    /* lots of time rehashing all the keys over and over. */            \
 | 
			
		||||
    sz = h->size;                                                       \
 | 
			
		||||
    ol = h->table;                                                      \
 | 
			
		||||
    if (sz >= (1<<19))                                                  \
 | 
			
		||||
    if (sz >= (1<<19) || (sz <= (1<<8)))                                \
 | 
			
		||||
        newsz = sz<<1;                                                  \
 | 
			
		||||
    else if (sz <= HT_N_INLINE)                                         \
 | 
			
		||||
        newsz = 32;                                                     \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue