@@ -175,8 +175,7 @@ any_hash(VALUE a, st_index_t (*other_func)(VALUE))
175
175
}
176
176
else if (BUILTIN_TYPE (a ) == T_FLOAT ) {
177
177
flt :
178
- hval = rb_dbl_hash (rb_float_value (a ));
179
- hnum = FIX2LONG (hval );
178
+ hnum = rb_dbl_hash_long (rb_float_value (a ));
180
179
}
181
180
else {
182
181
hnum = other_func (a );
@@ -199,34 +198,29 @@ rb_any_hash(VALUE a)
199
198
return any_hash (a , obj_any_hash );
200
199
}
201
200
202
- static st_index_t
203
- rb_num_hash_start ( st_index_t n )
201
+ long
202
+ rb_dbl_hash_long ( double d )
204
203
{
205
- /*
206
- * This hash function is lightly-tuned for Ruby. Further tuning
207
- * should be possible. Notes:
208
- *
209
- * - (n >> 3) alone is great for heap objects and OK for fixnum,
210
- * however symbols perform poorly.
211
- * - (n >> (RUBY_SPECIAL_SHIFT+3)) was added to make symbols hash well,
212
- * n.b.: +3 to remove most ID scope, +1 worked well initially, too
213
- * n.b.: +1 (instead of 3) worked well initially, too
214
- * - (n << 16) was finally added to avoid losing bits for fixnums
215
- * - avoid expensive modulo instructions, it is currently only
216
- * shifts and bitmask operations.
217
- */
218
- return ( n >> ( RUBY_SPECIAL_SHIFT + 3 ) ^ ( n << 16 )) ^ ( n >> 3 );
204
+ long hash ;
205
+ unsigned i ;
206
+ #define ind_in_dbl type_roomof(double, st_index_t)
207
+ union {
208
+ st_index_t i [ ind_in_dbl ];
209
+ double d ;
210
+ } v = { { 0 } };
211
+ /* normalize -0.0 to 0.0 */
212
+ v . d = d == 0.0 ? 0.0 : d ;
213
+ hash = rb_hash_start ( v . i [ 0 ]);
214
+ for ( i = 1 ; i < ind_in_dbl ; i ++ ) {
215
+ hash = rb_hash_uint ( hash , v . i [ i ]);
216
+ }
217
+ return rb_hash_end ( hash );
219
218
}
220
219
221
220
long
222
221
rb_objid_hash (st_index_t index )
223
222
{
224
- st_index_t hnum = rb_num_hash_start (index );
225
-
226
- hnum = rb_hash_start (hnum );
227
- hnum = rb_hash_uint (hnum , (st_index_t )rb_any_hash );
228
- hnum = rb_hash_end (hnum );
229
- return hnum ;
223
+ return rb_hash_end (index );
230
224
}
231
225
232
226
static st_index_t
@@ -258,18 +252,7 @@ static const struct st_hash_type objhash = {
258
252
static st_index_t
259
253
rb_ident_hash (st_data_t n )
260
254
{
261
- #ifdef USE_FLONUM /* RUBY */
262
- /*
263
- * - flonum (on 64-bit) is pathologically bad, mix the actual
264
- * float value in, but do not use the float value as-is since
265
- * many integers get interpreted as 2.0 or -2.0 [Bug #10761]
266
- */
267
- if (FLONUM_P (n )) {
268
- n ^= (st_data_t )rb_float_value (n );
269
- }
270
- #endif
271
-
272
- return (st_index_t )rb_num_hash_start ((st_index_t )n );
255
+ return rb_hash_end ((st_index_t )n );
273
256
}
274
257
275
258
static const struct st_hash_type identhash = {
0 commit comments