From 3a6f51ee35da5d49973aba8f7d8128a65a9d8c4a Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Thu, 1 Aug 2019 16:04:40 +0900 Subject: [PATCH] introduce ar_hint_t. Hash hint for ar_array is 1 byte (unsigned char). This patch introduce ar_hint_t which represents hint type. --- hash.c | 19 ++++++++++--------- internal.h | 12 ++++++++++-- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/hash.c b/hash.c index 661083d1de..dd4c2a3f87 100644 --- a/hash.c +++ b/hash.c @@ -325,7 +325,6 @@ typedef st_index_t st_hash_t; * * as.st points st_table. */ -#define RHASH_AR_TABLE_MAX_SIZE sizeof(VALUE) #define RHASH_AR_TABLE_MAX_BOUND RHASH_AR_TABLE_MAX_SIZE #define RHASH_AR_TABLE_REF(hash, n) (&RHASH_AR_TABLE(hash)->pairs[n]) @@ -353,20 +352,20 @@ ar_do_hash(st_data_t key) return (st_hash_t)rb_any_hash(key); } -static inline unsigned char +static inline ar_hint_t ar_do_hash_hint(st_hash_t hash_value) { - return (unsigned char)hash_value; + return (ar_hint_t)hash_value; } -static inline unsigned char +static inline ar_hint_t ar_hint(VALUE hash, unsigned int index) { return RHASH(hash)->ar_hint.ary[index]; } static inline void -ar_hint_set_hint(VALUE hash, unsigned int index, unsigned char hint) +ar_hint_set_hint(VALUE hash, unsigned int index, ar_hint_t hint) { RHASH(hash)->ar_hint.ary[index] = hint; } @@ -650,10 +649,10 @@ ar_equal(VALUE x, VALUE y) } static unsigned -ar_find_entry_hint(VALUE hash, unsigned char hint, st_data_t key) +ar_find_entry_hint(VALUE hash, ar_hint_t hint, st_data_t key) { unsigned i, bound = RHASH_AR_TABLE_BOUND(hash); - const unsigned char *hints = RHASH(hash)->ar_hint.ary; + const ar_hint_t *hints = RHASH(hash)->ar_hint.ary; /* if table is NULL, then bound also should be 0 */ @@ -695,7 +694,7 @@ ar_find_entry_hint(VALUE hash, unsigned char hint, st_data_t key) static unsigned ar_find_entry(VALUE hash, st_hash_t hash_value, st_data_t key) { - unsigned char hint = ar_do_hash_hint(hash_value); + ar_hint_t hint = ar_do_hash_hint(hash_value); return ar_find_entry_hint(hash, hint, key); } @@ -908,7 +907,7 @@ ar_foreach_check(VALUE hash, int (*func)(ANYARGS), st_data_t arg, enum st_retval retval; st_data_t key; ar_table_pair *pair; - unsigned char hint; + ar_hint_t hint; for (i = 0; i < bound; i++) { if (ar_cleared_entry(hash, i)) continue; @@ -6214,4 +6213,6 @@ Init_Hash(void) /* for callcc */ ruby_register_rollback_func_for_ensure(hash_foreach_ensure, hash_foreach_ensure_rollback); + + HASH_ASSERT(sizeof(ar_hint_t) * RHASH_AR_TABLE_MAX_SIZE == sizeof(VALUE)); } diff --git a/internal.h b/internal.h index 832428bd03..fac8ece2a5 100644 --- a/internal.h +++ b/internal.h @@ -817,7 +817,7 @@ struct RComplex { enum ruby_rhash_flags { RHASH_PROC_DEFAULT = FL_USER2, /* FL 2 */ RHASH_ST_TABLE_FLAG = FL_USER3, /* FL 3 */ - RHASH_AR_TABLE_MAX_SIZE = 8, +#define RHASH_AR_TABLE_MAX_SIZE SIZEOF_VALUE RHASH_AR_TABLE_SIZE_MASK = (FL_USER4|FL_USER5|FL_USER6|FL_USER7), /* FL 4..7 */ RHASH_AR_TABLE_SIZE_SHIFT = (FL_USHIFT+4), RHASH_AR_TABLE_BOUND_MASK = (FL_USER8|FL_USER9|FL_USER10|FL_USER11), /* FL 8..11 */ @@ -875,6 +875,14 @@ void rb_hash_st_table_set(VALUE hash, st_table *st); #define RHASH_UNSET_TRANSIENT_FLAG(h) ((void)0) #endif +#if SIZEOF_VALUE / RHASH_AR_TABLE_MAX_SIZE == 2 +typedef uint16_t ar_hint_t; +#elif SIZEOF_VALUE / RHASH_AR_TABLE_MAX_SIZE == 1 +typedef unsigned char ar_hint_t; +#else +#error unsupported +#endif + struct RHash { struct RBasic basic; union { @@ -883,7 +891,7 @@ struct RHash { } as; const VALUE ifnone; union { - unsigned char ary[sizeof(VALUE)]; + ar_hint_t ary[RHASH_AR_TABLE_MAX_SIZE]; VALUE word; } ar_hint; };