merge revision(s) 49386:

hash.c: move Hash specific functions

	* hash.c (rb_ident_hash): move compare_by_identity specific
  function from st.c.

	* hash.c (rb_ident_hash_new): ditto from thread.c.

	* st.c (st_numhash): remove ruby's Hash specific implementation.

	* thread.c (recursive_list_access): use rb_ident_hash_new().

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_2@49668 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
naruse 2015-02-20 13:53:23 +00:00
parent 310ab79f53
commit c93b7404c1
5 changed files with 47 additions and 37 deletions

42
hash.c
View file

@ -177,7 +177,39 @@ static const struct st_hash_type objhash = {
rb_any_hash, rb_any_hash,
}; };
#define identhash st_hashtype_num #define rb_ident_cmp st_numcmp
static st_index_t
rb_ident_hash(st_data_t n)
{
/*
* This hash function is lightly-tuned for Ruby. Further tuning
* should be possible. Notes:
*
* - (n >> 3) alone is great for heap objects and OK for fixnum,
* however symbols perform poorly.
* - (n >> (RUBY_SPECIAL_SHIFT+3)) was added to make symbols hash well,
* n.b.: +3 to remove ID scope, +1 worked well initially, too
* - (n << 3) was finally added to avoid losing bits for fixnums
* - avoid expensive modulo instructions, it is currently only
* shifts and bitmask operations.
* - flonum (on 64-bit) is pathologically bad, mix the actual
* float value in, but do not use the float value as-is since
* many integers get interpreted as 2.0 or -2.0 [Bug #10761]
*/
#ifdef USE_FLONUM /* RUBY */
if (FLONUM_P(n)) {
n ^= (st_data_t)rb_float_value(n);
}
#endif
return (st_index_t)((n>>(RUBY_SPECIAL_SHIFT+3)|(n<<3)) ^ (n>>3));
}
static const struct st_hash_type identhash = {
rb_ident_cmp,
rb_ident_hash,
};
typedef int st_foreach_func(st_data_t, st_data_t, st_data_t); typedef int st_foreach_func(st_data_t, st_data_t, st_data_t);
@ -2507,6 +2539,14 @@ rb_hash_compare_by_id_p(VALUE hash)
return Qfalse; return Qfalse;
} }
VALUE
rb_ident_hash_new(void)
{
VALUE hash = rb_hash_new();
RHASH(hash)->ntbl = st_init_table(&identhash);
return hash;
}
st_table * st_table *
rb_init_identtable(void) rb_init_identtable(void)
{ {

View file

@ -704,6 +704,7 @@ struct st_table *rb_hash_tbl_raw(VALUE hash);
VALUE rb_hash_has_key(VALUE hash, VALUE key); VALUE rb_hash_has_key(VALUE hash, VALUE key);
VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc); VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc);
long rb_objid_hash(st_index_t index); long rb_objid_hash(st_index_t index);
VALUE rb_ident_hash_new(void);
st_table *rb_init_identtable(void); st_table *rb_init_identtable(void);
st_table *rb_init_identtable_with_size(st_index_t size); st_table *rb_init_identtable_with_size(st_index_t size);
@ -957,9 +958,6 @@ extern int ruby_enable_coredump;
int rb_get_next_signal(void); int rb_get_next_signal(void);
int rb_sigaltstack_size(void); int rb_sigaltstack_size(void);
/* st.c */
extern const struct st_hash_type st_hashtype_num;
/* strftime.c */ /* strftime.c */
#ifdef RUBY_ENCODING_H #ifdef RUBY_ENCODING_H
size_t rb_strftime_timespec(char *s, size_t maxsize, const char *format, rb_encoding *enc, size_t rb_strftime_timespec(char *s, size_t maxsize, const char *format, rb_encoding *enc,

24
st.c
View file

@ -1750,26 +1750,6 @@ st_numcmp(st_data_t x, st_data_t y)
st_index_t st_index_t
st_numhash(st_data_t n) st_numhash(st_data_t n)
{ {
/* enum {s1 = 11, s2 = 3};
* This hash function is lightly-tuned for Ruby. Further tuning return (st_index_t)((n>>s1|(n<<s2)) ^ (n>>s2));
* should be possible. Notes:
*
* - (n >> 3) alone is great for heap objects and OK for fixnum,
* however symbols perform poorly.
* - (n >> (RUBY_SPECIAL_SHIFT+3)) was added to make symbols hash well,
* n.b.: +3 to remove ID scope, +1 worked well initially, too
* - (n << 3) was finally added to avoid losing bits for fixnums
* - avoid expensive modulo instructions, it is currently only
* shifts and bitmask operations.
* - flonum (on 64-bit) is pathologically bad, mix the actual
* float value in, but do not use the float value as-is since
* many integers get interpreted as 2.0 or -2.0 [Bug #10761]
*/
#ifdef USE_FLONUM /* RUBY */
if (FLONUM_P(n)) {
n ^= (st_data_t)rb_float_value(n);
}
#endif
return (st_index_t)((n>>(RUBY_SPECIAL_SHIFT+3)|(n<<3)) ^ (n>>3));
} }

View file

@ -4679,14 +4679,6 @@ rb_thread_shield_destroy(VALUE self)
return rb_thread_shield_waiting(self) > 0 ? Qtrue : Qfalse; return rb_thread_shield_waiting(self) > 0 ? Qtrue : Qfalse;
} }
static VALUE
ident_hash_new(void)
{
VALUE hash = rb_hash_new();
rb_hash_tbl_raw(hash)->type = &st_hashtype_num;
return hash;
}
static VALUE static VALUE
threadptr_recursive_hash(rb_thread_t *th) threadptr_recursive_hash(rb_thread_t *th)
{ {
@ -4714,7 +4706,7 @@ recursive_list_access(VALUE sym)
VALUE hash = threadptr_recursive_hash(th); VALUE hash = threadptr_recursive_hash(th);
VALUE list; VALUE list;
if (NIL_P(hash) || !RB_TYPE_P(hash, T_HASH)) { if (NIL_P(hash) || !RB_TYPE_P(hash, T_HASH)) {
hash = ident_hash_new(); hash = rb_ident_hash_new();
threadptr_recursive_hash_set(th, hash); threadptr_recursive_hash_set(th, hash);
list = Qnil; list = Qnil;
} }
@ -4722,7 +4714,7 @@ recursive_list_access(VALUE sym)
list = rb_hash_aref(hash, sym); list = rb_hash_aref(hash, sym);
} }
if (NIL_P(list) || !RB_TYPE_P(list, T_HASH)) { if (NIL_P(list) || !RB_TYPE_P(list, T_HASH)) {
list = ident_hash_new(); list = rb_ident_hash_new();
rb_hash_aset(hash, sym, list); rb_hash_aset(hash, sym, list);
} }
return list; return list;

View file

@ -1,6 +1,6 @@
#define RUBY_VERSION "2.2.0" #define RUBY_VERSION "2.2.0"
#define RUBY_RELEASE_DATE "2015-02-20" #define RUBY_RELEASE_DATE "2015-02-20"
#define RUBY_PATCHLEVEL 69 #define RUBY_PATCHLEVEL 70
#define RUBY_RELEASE_YEAR 2015 #define RUBY_RELEASE_YEAR 2015
#define RUBY_RELEASE_MONTH 2 #define RUBY_RELEASE_MONTH 2