diff options
author | 卜部昌平 <shyouhei@ruby-lang.org> | 2019-12-03 12:37:15 +0900 |
---|---|---|
committer | 卜部昌平 <shyouhei@ruby-lang.org> | 2019-12-26 20:45:12 +0900 |
commit | e72b8592d9b4daa079d85d0ceb60f466edaec94d (patch) | |
tree | 58a3d1f6f28cdc30dbb694df40dbbf8814d1a588 | |
parent | f0c02a094988f804a339e9180a5e206fa123b902 (diff) |
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.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/2711
-rw-r--r-- | hash.c | 4 | ||||
-rw-r--r-- | internal/hash.h | 243 |
2 files changed, 166 insertions, 81 deletions
@@ -56,7 +56,7 @@ copy_default(struct RHash *hash, const struct RHash *hash2) { hash->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 @@ -1637,7 +1637,7 @@ struct update_arg { typedef int (*tbl_update_func)(st_data_t *, st_data_t *, st_data_t, 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)) { int result = ar_update(hash, (st_data_t)key, func, arg); diff --git a/internal/hash.h b/internal/hash.h index 3f27bb8d8c..634092e4c2 100644 --- a/internal/hash.h +++ b/internal/hash.h @@ -9,77 +9,38 @@ * modify this file, provided that the conditions mentioned in the * 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 { RHASH_PASS_AS_KEYWORDS = FL_USER1, /* FL 1 */ RHASH_PROC_DEFAULT = FL_USER2, /* FL 2 */ 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_SHIFT = (FL_USHIFT+4), RHASH_AR_TABLE_BOUND_MASK = (FL_USER8|FL_USER9|FL_USER10|FL_USER11), /* FL 8..11 */ 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 RHASH_TRANSIENT_FLAG = FL_USER12, /* FL 12 */ #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_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 RBasic basic; union { @@ -93,51 +54,175 @@ struct RHash { } ar_hint; }; -#ifdef RHASH_IFNONE -# undef RHASH_IFNONE -# 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 */ +#define RHASH(obj) (R_CAST(RHash)(obj)) +#undef RHASH_IFNONE +#undef RHASH_SIZE /* hash.c */ -#if RHASH_CONVERT_TABLE_DEBUG -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); +void rb_hash_st_table_set(VALUE hash, st_table *st); VALUE rb_hash_default_value(VALUE hash, VALUE key); VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc); long rb_dbl_long_hash(double d); st_table *rb_init_identtable(void); -VALUE rb_hash_compare_by_id_p(VALUE hash); VALUE rb_to_hash_type(VALUE obj); VALUE rb_hash_key_str(VALUE); -VALUE rb_hash_keys(VALUE hash); VALUE rb_hash_values(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); 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); -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_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 /* hash.c (export) */ VALUE rb_hash_delete_entry(VALUE hash, VALUE key); 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 +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 */ |