summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-02-20 13:53:23 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-02-20 13:53:23 +0000
commitc93b7404c1fe0995df074115806d2bea333610b1 (patch)
tree8898eddf4ab5871e48e8208891ecc9ba335a996d
parent310ab79f5392f102ab0ef0434c8e25f203f9a287 (diff)
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
-rw-r--r--hash.c42
-rw-r--r--internal.h4
-rw-r--r--st.c24
-rw-r--r--thread.c12
-rw-r--r--version.h2
5 files changed, 47 insertions, 37 deletions
diff --git a/hash.c b/hash.c
index e9772bc283..8d37dc6368 100644
--- a/hash.c
+++ b/hash.c
@@ -177,7 +177,39 @@ static const struct st_hash_type objhash = {
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);
@@ -2507,6 +2539,14 @@ rb_hash_compare_by_id_p(VALUE hash)
return Qfalse;
}
+VALUE
+rb_ident_hash_new(void)
+{
+ VALUE hash = rb_hash_new();
+ RHASH(hash)->ntbl = st_init_table(&identhash);
+ return hash;
+}
+
st_table *
rb_init_identtable(void)
{
diff --git a/internal.h b/internal.h
index 186e6f884b..4da45a4712 100644
--- a/internal.h
+++ b/internal.h
@@ -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_set_default_proc(VALUE hash, VALUE proc);
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_with_size(st_index_t size);
@@ -957,9 +958,6 @@ extern int ruby_enable_coredump;
int rb_get_next_signal(void);
int rb_sigaltstack_size(void);
-/* st.c */
-extern const struct st_hash_type st_hashtype_num;
-
/* strftime.c */
#ifdef RUBY_ENCODING_H
size_t rb_strftime_timespec(char *s, size_t maxsize, const char *format, rb_encoding *enc,
diff --git a/st.c b/st.c
index e630c1ec48..e238062336 100644
--- a/st.c
+++ b/st.c
@@ -1750,26 +1750,6 @@ st_numcmp(st_data_t x, st_data_t y)
st_index_t
st_numhash(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));
+ enum {s1 = 11, s2 = 3};
+ return (st_index_t)((n>>s1|(n<<s2)) ^ (n>>s2));
}
diff --git a/thread.c b/thread.c
index 35da97cde2..b7056a764d 100644
--- a/thread.c
+++ b/thread.c
@@ -4680,14 +4680,6 @@ rb_thread_shield_destroy(VALUE self)
}
static VALUE
-ident_hash_new(void)
-{
- VALUE hash = rb_hash_new();
- rb_hash_tbl_raw(hash)->type = &st_hashtype_num;
- return hash;
-}
-
-static VALUE
threadptr_recursive_hash(rb_thread_t *th)
{
return th->local_storage_recursive_hash;
@@ -4714,7 +4706,7 @@ recursive_list_access(VALUE sym)
VALUE hash = threadptr_recursive_hash(th);
VALUE list;
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);
list = Qnil;
}
@@ -4722,7 +4714,7 @@ recursive_list_access(VALUE sym)
list = rb_hash_aref(hash, sym);
}
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);
}
return list;
diff --git a/version.h b/version.h
index a4bbbb00bc..ebf21d0faf 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
#define RUBY_VERSION "2.2.0"
#define RUBY_RELEASE_DATE "2015-02-20"
-#define RUBY_PATCHLEVEL 69
+#define RUBY_PATCHLEVEL 70
#define RUBY_RELEASE_YEAR 2015
#define RUBY_RELEASE_MONTH 2