fix eq[v]? hashing with many collisions

Normally, it's impossible to generate lots of `eq?`-hashing
collisions, but when the compiler inlines a function, it can duplicate
variables in a way that gives each copy the same `eq?` hash code. The
immutable-hash tree implementation failed when more than 32 collisions
occurred (which triggers a subtree in the collision node).

It's similarly very difficult to generate > 32 values that collide on
`eqv?` hashes but are not `eqv?` (although it must be possible using
exact rationals or complex numbers).
This commit is contained in:
Matthew Flatt 2017-09-07 17:29:41 +01:00
parent 94cee519e1
commit 1f02cf226e
2 changed files with 151 additions and 1 deletions

View File

@ -6043,6 +6043,156 @@
(test 'fail "compilation took too long" (/ b a 1.0))
(loop (sub1 tries)))))))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Try a program that triggers lots of inlining, which at one point
;; exposed a bug related to the closing of `lambda` forms within
;; an inlined function. Thanks to Tom Gilray for the test.
(module inline-a-lot racket/base
((((((((((((((lambda (x84)
(lambda (x85)
(lambda (x86)
(lambda (x87)
(lambda (x88)
(lambda (x89)
(lambda (x90)
(lambda (x91)
(lambda (x92)
(lambda (x93)
(lambda (x94)
(lambda (x95)
(lambda (x96)
((lambda (x97)
(x97
(lambda (x98)
(lambda (x99)
(x98
(x98
(x98 (x98 (x98 x99)))))))))
(x84
(lambda (x100)
(lambda (x101)
((((x95
(lambda (x102)
(lambda (x103) x103)))
x101)
(lambda (x104)
(lambda (x105)
(lambda (x106)
(x105 x106)))))
(lambda (x107)
((x93 x101)
(x100
((x92 x101)
(lambda (x108)
(lambda (x109)
(x108
x109)))))))))))))))))))))))))
((lambda (x110) (x110 x110))
(lambda (x111)
(lambda (x112)
(x112 (lambda (x113) (((x111 x111) x112) x113)))))))
(lambda (x114)
((x114
(lambda (x115)
(lambda (x116)
(lambda (x117)
(lambda (x118) (x118 (lambda (x119) x119)))))))
(lambda (x120)
(lambda (x121)
(lambda (x122) (x121 (lambda (x123) x123))))))))
(lambda (x124)
(lambda (x125)
(lambda (x126) (lambda (x127) ((x126 x124) x125))))))
(lambda (x128)
((x128 (lambda (x129) (lambda (x130) x129)))
(lambda (x131) (lambda (x132) x132)))))
(lambda (x133)
((x133 (lambda (x134) (lambda (x135) x135)))
(lambda (x136) (lambda (x137) x137)))))
(lambda (x138)
(lambda (x139) (lambda (x140) (x139 ((x138 x139) x140))))))
(lambda (x141)
(lambda (x142)
(lambda (x143)
(((x141 (lambda (x144) (lambda (x145) (x145 (x144 x142)))))
(lambda (x146) x143))
(lambda (x147) x147))))))
(lambda (x148)
(lambda (x149)
(lambda (x150) (lambda (x151) ((x149 x150) ((x148 x150) x151)))))))
(lambda (x152)
(lambda (x153)
((x153
(lambda (x154)
(lambda (x155)
(lambda (x156)
(((x154 (lambda (x157) (lambda (x158) (x158 (x157 x155)))))
(lambda (x159) x156))
(lambda (x160) x160))))))
x152))))
(lambda (x161)
(lambda (x162)
(lambda (x163) (lambda (x164) ((x161 (x162 x163)) x164))))))
(lambda (x165)
((x165
(lambda (x166)
(lambda (x167) (lambda (x168) (x168 (lambda (x169) x169))))))
(lambda (x170) (lambda (x171) (x170 (lambda (x172) x172)))))))
(lambda (x173)
(lambda (x174)
((((lambda (x175)
((x175
(lambda (x176)
(lambda (x177) (lambda (x178) (x178 (lambda (x179) x179))))))
(lambda (x180) (lambda (x181) (x180 (lambda (x182) x182))))))
(((lambda (x183)
(lambda (x184)
((x184
(lambda (x185)
(lambda (x186)
(lambda (x187)
(((x185
(lambda (x188) (lambda (x189) (x189 (x188 x186)))))
(lambda (x190) x187))
(lambda (x191) x191))))))
x183)))
x173)
x174))
(lambda (x192)
((((lambda (x193)
((x193
(lambda (x194)
(lambda (x195)
(lambda (x196) (x196 (lambda (x197) x197))))))
(lambda (x198) (lambda (x199) (x198 (lambda (x200) x200))))))
(((lambda (x201)
(lambda (x202)
((x202
(lambda (x203)
(lambda (x204)
(lambda (x205)
(((x203
(lambda (x206)
(lambda (x207) (x207 (x206 x204)))))
(lambda (x208) x205))
(lambda (x209) x209))))))
x201)))
x174)
x173))
(lambda (x210)
(lambda (x211) (lambda (x212) (x211 (lambda (x213) x213))))))
(lambda (x214)
(lambda (x215) (lambda (x216) (x216 (lambda (x217) x217))))))))
(lambda (x218)
(lambda (x219) (lambda (x220) (x220 (lambda (x221) x221)))))))))
(lambda (x222)
((x222
(lambda (x223)
(lambda (x224) (lambda (x225) (x225 (lambda (x226) x226))))))
(lambda (x227)
(lambda (x228) (lambda (x229) (x228 (lambda (x230) x230)))))))))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(report-errs)

View File

@ -2494,7 +2494,7 @@ XFORM_NONGCING Scheme_Object *_mzHAMT_VAL(Scheme_Hash_Tree *ht, int pos, int pop
XFORM_NONGCING uintptr_t mzHAMT_KEY_CODE(Scheme_Object *o)
{
while (1) {
if (HASHTR_COLLISIONP(o))
if (HASHTR_COLLISIONP(o) || HASHTR_SUBTREEP(o))
o = ((Scheme_Hash_Tree *)o)->els[0];
else {
uintptr_t h;