mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
internal/hash.h rework
Reduce macros to make them inline functions, as well as mark MJIT_FUNC_EXPORTED functions explicitly as such. Definition of ar_hint_t is simplified. This has been the only possible definition so far.
This commit is contained in:
parent
f0c02a0949
commit
e72b8592d9
Notes:
git
2019-12-26 20:46:04 +09:00
2 changed files with 166 additions and 81 deletions
4
hash.c
4
hash.c
|
@ -56,7 +56,7 @@ copy_default(struct RHash *hash, const struct RHash *hash2)
|
||||||
{
|
{
|
||||||
hash->basic.flags &= ~RHASH_PROC_DEFAULT;
|
hash->basic.flags &= ~RHASH_PROC_DEFAULT;
|
||||||
hash->basic.flags |= hash2->basic.flags & RHASH_PROC_DEFAULT;
|
hash->basic.flags |= hash2->basic.flags & RHASH_PROC_DEFAULT;
|
||||||
RHASH_SET_IFNONE(hash, RHASH_IFNONE(hash2));
|
RHASH_SET_IFNONE(hash, RHASH_IFNONE((VALUE)hash2));
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -1637,7 +1637,7 @@ struct update_arg {
|
||||||
typedef int (*tbl_update_func)(st_data_t *, st_data_t *, st_data_t, int);
|
typedef int (*tbl_update_func)(st_data_t *, st_data_t *, st_data_t, int);
|
||||||
|
|
||||||
int
|
int
|
||||||
rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func func, st_data_t arg)
|
rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func *func, st_data_t arg)
|
||||||
{
|
{
|
||||||
if (RHASH_AR_TABLE_P(hash)) {
|
if (RHASH_AR_TABLE_P(hash)) {
|
||||||
int result = ar_update(hash, (st_data_t)key, func, arg);
|
int result = ar_update(hash, (st_data_t)key, func, arg);
|
||||||
|
|
243
internal/hash.h
243
internal/hash.h
|
@ -9,77 +9,38 @@
|
||||||
* modify this file, provided that the conditions mentioned in the
|
* modify this file, provided that the conditions mentioned in the
|
||||||
* file COPYING are met. Consult the file for details.
|
* file COPYING are met. Consult the file for details.
|
||||||
*/
|
*/
|
||||||
|
#include "ruby/config.h"
|
||||||
|
#include <stddef.h> /* for size_t */
|
||||||
|
#include "internal/stdbool.h" /* for bool */
|
||||||
|
#include "ruby/ruby.h" /* for struct RBasic */
|
||||||
|
#include "ruby/st.h" /* for struct st_table */
|
||||||
|
|
||||||
|
#define RHASH_AR_TABLE_MAX_SIZE SIZEOF_VALUE
|
||||||
|
|
||||||
|
struct ar_table_struct;
|
||||||
|
typedef unsigned char ar_hint_t;
|
||||||
|
|
||||||
enum ruby_rhash_flags {
|
enum ruby_rhash_flags {
|
||||||
RHASH_PASS_AS_KEYWORDS = FL_USER1, /* FL 1 */
|
RHASH_PASS_AS_KEYWORDS = FL_USER1, /* FL 1 */
|
||||||
RHASH_PROC_DEFAULT = FL_USER2, /* FL 2 */
|
RHASH_PROC_DEFAULT = FL_USER2, /* FL 2 */
|
||||||
RHASH_ST_TABLE_FLAG = FL_USER3, /* FL 3 */
|
RHASH_ST_TABLE_FLAG = FL_USER3, /* FL 3 */
|
||||||
#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_MASK = (FL_USER4|FL_USER5|FL_USER6|FL_USER7), /* FL 4..7 */
|
||||||
RHASH_AR_TABLE_SIZE_SHIFT = (FL_USHIFT+4),
|
RHASH_AR_TABLE_SIZE_SHIFT = (FL_USHIFT+4),
|
||||||
RHASH_AR_TABLE_BOUND_MASK = (FL_USER8|FL_USER9|FL_USER10|FL_USER11), /* FL 8..11 */
|
RHASH_AR_TABLE_BOUND_MASK = (FL_USER8|FL_USER9|FL_USER10|FL_USER11), /* FL 8..11 */
|
||||||
RHASH_AR_TABLE_BOUND_SHIFT = (FL_USHIFT+8),
|
RHASH_AR_TABLE_BOUND_SHIFT = (FL_USHIFT+8),
|
||||||
|
|
||||||
// we can not put it in "enum" because it can exceed "int" range.
|
|
||||||
#define RHASH_LEV_MASK (FL_USER13 | FL_USER14 | FL_USER15 | /* FL 13..19 */ \
|
|
||||||
FL_USER16 | FL_USER17 | FL_USER18 | FL_USER19)
|
|
||||||
|
|
||||||
#if USE_TRANSIENT_HEAP
|
#if USE_TRANSIENT_HEAP
|
||||||
RHASH_TRANSIENT_FLAG = FL_USER12, /* FL 12 */
|
RHASH_TRANSIENT_FLAG = FL_USER12, /* FL 12 */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// we can not put it in "enum" because it can exceed "int" range.
|
||||||
|
#define RHASH_LEV_MASK (FL_USER13 | FL_USER14 | FL_USER15 | /* FL 13..19 */ \
|
||||||
|
FL_USER16 | FL_USER17 | FL_USER18 | FL_USER19)
|
||||||
|
|
||||||
RHASH_LEV_SHIFT = (FL_USHIFT + 13),
|
RHASH_LEV_SHIFT = (FL_USHIFT + 13),
|
||||||
RHASH_LEV_MAX = 127, /* 7 bits */
|
RHASH_LEV_MAX = 127, /* 7 bits */
|
||||||
|
|
||||||
RHASH_ENUM_END
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RHASH_AR_TABLE_SIZE_RAW(h) \
|
|
||||||
((unsigned int)((RBASIC(h)->flags & RHASH_AR_TABLE_SIZE_MASK) >> RHASH_AR_TABLE_SIZE_SHIFT))
|
|
||||||
|
|
||||||
void rb_hash_st_table_set(VALUE hash, st_table *st);
|
|
||||||
|
|
||||||
#if 0 /* for debug */
|
|
||||||
int rb_hash_ar_table_p(VALUE hash);
|
|
||||||
struct ar_table_struct *rb_hash_ar_table(VALUE hash);
|
|
||||||
st_table *rb_hash_st_table(VALUE hash);
|
|
||||||
#define RHASH_AR_TABLE_P(hash) rb_hash_ar_table_p(hash)
|
|
||||||
#define RHASH_AR_TABLE(h) rb_hash_ar_table(h)
|
|
||||||
#define RHASH_ST_TABLE(h) rb_hash_st_table(h)
|
|
||||||
#else
|
|
||||||
#define RHASH_AR_TABLE_P(hash) (!FL_TEST_RAW((hash), RHASH_ST_TABLE_FLAG))
|
|
||||||
#define RHASH_AR_TABLE(hash) (RHASH(hash)->as.ar)
|
|
||||||
#define RHASH_ST_TABLE(hash) (RHASH(hash)->as.st)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define RHASH(obj) (R_CAST(RHash)(obj))
|
|
||||||
#define RHASH_ST_SIZE(h) (RHASH_ST_TABLE(h)->num_entries)
|
|
||||||
#define RHASH_ST_TABLE_P(h) (!RHASH_AR_TABLE_P(h))
|
|
||||||
#define RHASH_ST_CLEAR(h) (FL_UNSET_RAW(h, RHASH_ST_TABLE_FLAG), RHASH(h)->as.ar = NULL)
|
|
||||||
|
|
||||||
#define RHASH_AR_TABLE_SIZE_MASK (VALUE)RHASH_AR_TABLE_SIZE_MASK
|
|
||||||
#define RHASH_AR_TABLE_SIZE_SHIFT RHASH_AR_TABLE_SIZE_SHIFT
|
|
||||||
#define RHASH_AR_TABLE_BOUND_MASK (VALUE)RHASH_AR_TABLE_BOUND_MASK
|
|
||||||
#define RHASH_AR_TABLE_BOUND_SHIFT RHASH_AR_TABLE_BOUND_SHIFT
|
|
||||||
|
|
||||||
#if USE_TRANSIENT_HEAP
|
|
||||||
#define RHASH_TRANSIENT_P(hash) FL_TEST_RAW((hash), RHASH_TRANSIENT_FLAG)
|
|
||||||
#define RHASH_SET_TRANSIENT_FLAG(h) FL_SET_RAW(h, RHASH_TRANSIENT_FLAG)
|
|
||||||
#define RHASH_UNSET_TRANSIENT_FLAG(h) FL_UNSET_RAW(h, RHASH_TRANSIENT_FLAG)
|
|
||||||
#else
|
|
||||||
#define RHASH_TRANSIENT_P(hash) 0
|
|
||||||
#define RHASH_SET_TRANSIENT_FLAG(h) ((void)0)
|
|
||||||
#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 RHash {
|
||||||
struct RBasic basic;
|
struct RBasic basic;
|
||||||
union {
|
union {
|
||||||
|
@ -93,51 +54,175 @@ struct RHash {
|
||||||
} ar_hint;
|
} ar_hint;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef RHASH_IFNONE
|
#define RHASH(obj) (R_CAST(RHash)(obj))
|
||||||
# undef RHASH_IFNONE
|
#undef RHASH_IFNONE
|
||||||
# undef RHASH_SIZE
|
#undef RHASH_SIZE
|
||||||
|
|
||||||
# define RHASH_IFNONE(h) (RHASH(h)->ifnone)
|
|
||||||
# define RHASH_SIZE(h) (RHASH_AR_TABLE_P(h) ? RHASH_AR_TABLE_SIZE_RAW(h) : RHASH_ST_SIZE(h))
|
|
||||||
#endif /* ifdef RHASH_IFNONE */
|
|
||||||
|
|
||||||
/* hash.c */
|
/* hash.c */
|
||||||
#if RHASH_CONVERT_TABLE_DEBUG
|
void rb_hash_st_table_set(VALUE hash, st_table *st);
|
||||||
struct st_table *rb_hash_tbl_raw(VALUE hash, const char *file, int line);
|
|
||||||
#define RHASH_TBL_RAW(h) rb_hash_tbl_raw(h, __FILE__, __LINE__)
|
|
||||||
#else
|
|
||||||
struct st_table *rb_hash_tbl_raw(VALUE hash);
|
|
||||||
#define RHASH_TBL_RAW(h) rb_hash_tbl_raw(h)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VALUE rb_hash_new_with_size(st_index_t size);
|
|
||||||
VALUE rb_hash_has_key(VALUE hash, VALUE key);
|
|
||||||
VALUE rb_hash_default_value(VALUE hash, VALUE key);
|
VALUE rb_hash_default_value(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_dbl_long_hash(double d);
|
long rb_dbl_long_hash(double d);
|
||||||
st_table *rb_init_identtable(void);
|
st_table *rb_init_identtable(void);
|
||||||
VALUE rb_hash_compare_by_id_p(VALUE hash);
|
|
||||||
VALUE rb_to_hash_type(VALUE obj);
|
VALUE rb_to_hash_type(VALUE obj);
|
||||||
VALUE rb_hash_key_str(VALUE);
|
VALUE rb_hash_key_str(VALUE);
|
||||||
VALUE rb_hash_keys(VALUE hash);
|
|
||||||
VALUE rb_hash_values(VALUE hash);
|
VALUE rb_hash_values(VALUE hash);
|
||||||
VALUE rb_hash_rehash(VALUE hash);
|
VALUE rb_hash_rehash(VALUE hash);
|
||||||
VALUE rb_hash_resurrect(VALUE hash);
|
|
||||||
int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val);
|
int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val);
|
||||||
VALUE rb_hash_set_pair(VALUE hash, VALUE pair);
|
VALUE rb_hash_set_pair(VALUE hash, VALUE pair);
|
||||||
|
|
||||||
int rb_hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval);
|
|
||||||
int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval);
|
int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval);
|
||||||
RUBY_SYMBOL_EXPORT_BEGIN
|
|
||||||
int rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg);
|
|
||||||
RUBY_SYMBOL_EXPORT_END
|
|
||||||
int rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg);
|
int rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg);
|
||||||
int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func func, st_data_t arg);
|
int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func *func, st_data_t arg);
|
||||||
|
static inline unsigned RHASH_AR_TABLE_SIZE_RAW(VALUE h);
|
||||||
|
static inline VALUE RHASH_IFNONE(VALUE h);
|
||||||
|
static inline size_t RHASH_SIZE(VALUE h);
|
||||||
|
static inline bool RHASH_AR_TABLE_P(VALUE h);
|
||||||
|
static inline bool RHASH_ST_TABLE_P(VALUE h);
|
||||||
|
static inline struct ar_table_struct *RHASH_AR_TABLE(VALUE h);
|
||||||
|
static inline st_table *RHASH_ST_TABLE(VALUE h);
|
||||||
|
static inline size_t RHASH_ST_SIZE(VALUE h);
|
||||||
|
static inline void RHASH_ST_CLEAR(VALUE h);
|
||||||
|
static inline bool RHASH_TRANSIENT_P(VALUE h);
|
||||||
|
static inline void RHASH_SET_TRANSIENT_FLAG(VALUE h);
|
||||||
|
static inline void RHASH_UNSET_TRANSIENT_FLAG(VALUE h);
|
||||||
|
|
||||||
RUBY_SYMBOL_EXPORT_BEGIN
|
RUBY_SYMBOL_EXPORT_BEGIN
|
||||||
/* hash.c (export) */
|
/* hash.c (export) */
|
||||||
VALUE rb_hash_delete_entry(VALUE hash, VALUE key);
|
VALUE rb_hash_delete_entry(VALUE hash, VALUE key);
|
||||||
VALUE rb_ident_hash_new(void);
|
VALUE rb_ident_hash_new(void);
|
||||||
|
int rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg);
|
||||||
RUBY_SYMBOL_EXPORT_END
|
RUBY_SYMBOL_EXPORT_END
|
||||||
|
|
||||||
|
MJIT_SYMBOL_EXPORT_BEGIN
|
||||||
|
VALUE rb_hash_new_with_size(st_index_t size);
|
||||||
|
VALUE rb_hash_resurrect(VALUE hash);
|
||||||
|
int rb_hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval);
|
||||||
|
VALUE rb_hash_keys(VALUE hash);
|
||||||
|
VALUE rb_hash_has_key(VALUE hash, VALUE key);
|
||||||
|
VALUE rb_hash_compare_by_id_p(VALUE hash);
|
||||||
|
|
||||||
|
#if RHASH_CONVERT_TABLE_DEBUG
|
||||||
|
st_table *rb_hash_tbl_raw(VALUE hash, const char *file, int line);
|
||||||
|
#define RHASH_TBL_RAW(h) rb_hash_tbl_raw(h, __FILE__, __LINE__)
|
||||||
|
#else
|
||||||
|
st_table *rb_hash_tbl_raw(VALUE hash);
|
||||||
|
#define RHASH_TBL_RAW(h) rb_hash_tbl_raw(h)
|
||||||
|
#endif
|
||||||
|
MJIT_SYMBOL_EXPORT_END
|
||||||
|
|
||||||
|
#if 0 /* for debug */
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
RHASH_AR_TABLE_P(VALUE h)
|
||||||
|
{
|
||||||
|
extern int rb_hash_ar_table_p(VALUE hash);
|
||||||
|
return rb_hash_ar_table_p(h)
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct ar_table_struct *
|
||||||
|
RHASH_AR_TABLE(VALUE h)
|
||||||
|
{
|
||||||
|
extern struct ar_table_struct *rb_hash_ar_table(VALUE hash);
|
||||||
|
return rb_hash_ar_table(h)
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline st_table *
|
||||||
|
RHASH_ST_TABLE(VALUE h)
|
||||||
|
{
|
||||||
|
extern st_table *rb_hash_st_table(VALUE hash);
|
||||||
|
return rb_hash_st_table(h)
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
RHASH_AR_TABLE_P(VALUE h)
|
||||||
|
{
|
||||||
|
return ! FL_TEST_RAW(h, RHASH_ST_TABLE_FLAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct ar_table_struct *
|
||||||
|
RHASH_AR_TABLE(VALUE h)
|
||||||
|
{
|
||||||
|
return RHASH(h)->as.ar;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline st_table *
|
||||||
|
RHASH_ST_TABLE(VALUE h)
|
||||||
|
{
|
||||||
|
return RHASH(h)->as.st;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline VALUE
|
||||||
|
RHASH_IFNONE(VALUE h)
|
||||||
|
{
|
||||||
|
return RHASH(h)->ifnone;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline size_t
|
||||||
|
RHASH_SIZE(VALUE h)
|
||||||
|
{
|
||||||
|
if (RHASH_AR_TABLE_P(h)) {
|
||||||
|
return RHASH_AR_TABLE_SIZE_RAW(h);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return RHASH_ST_SIZE(h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
RHASH_ST_TABLE_P(VALUE h)
|
||||||
|
{
|
||||||
|
return ! RHASH_AR_TABLE_P(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline size_t
|
||||||
|
RHASH_ST_SIZE(VALUE h)
|
||||||
|
{
|
||||||
|
return RHASH_ST_TABLE(h)->num_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RHASH_ST_CLEAR(VALUE h)
|
||||||
|
{
|
||||||
|
FL_UNSET_RAW(h, RHASH_ST_TABLE_FLAG);
|
||||||
|
RHASH(h)->as.ar = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
RHASH_AR_TABLE_SIZE_RAW(VALUE h)
|
||||||
|
{
|
||||||
|
unsigned ret = FL_TEST_RAW(h, RHASH_AR_TABLE_SIZE_MASK);
|
||||||
|
ret >>= RHASH_AR_TABLE_SIZE_SHIFT;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
RHASH_TRANSIENT_P(VALUE h)
|
||||||
|
{
|
||||||
|
#if USE_TRANSIENT_HEAP
|
||||||
|
return FL_TEST_RAW(h, RHASH_TRANSIENT_FLAG);
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RHASH_SET_TRANSIENT_FLAG(VALUE h)
|
||||||
|
{
|
||||||
|
#if USE_TRANSIENT_HEAP
|
||||||
|
FL_SET_RAW(h, RHASH_TRANSIENT_FLAG);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RHASH_UNSET_TRANSIENT_FLAG(VALUE h)
|
||||||
|
{
|
||||||
|
#if USE_TRANSIENT_HEAP
|
||||||
|
FL_UNSET_RAW(h, RHASH_TRANSIENT_FLAG);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* INTERNAL_HASH_H */
|
#endif /* INTERNAL_HASH_H */
|
||||||
|
|
Loading…
Reference in a new issue