diff options
author | Peter Zhu <[email protected]> | 2023-04-19 16:02:36 -0400 |
---|---|---|
committer | Peter Zhu <[email protected]> | 2023-05-17 09:19:40 -0400 |
commit | 0938964ba1af3924cf969fb809fc3598892bc20d (patch) | |
tree | c87a84dcbec890a0e35a4a84c96a0892653dbbc0 /hash.c | |
parent | 5199f2aaf9527c97e6ec371e19748d0c2ac7a70e (diff) |
Implement Hash ST tables on VWA
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/7742
Diffstat (limited to 'hash.c')
-rw-r--r-- | hash.c | 110 |
1 files changed, 39 insertions, 71 deletions
@@ -378,27 +378,6 @@ typedef st_index_t st_hash_t; #define RHASH_AR_TABLE_REF(hash, n) (&RHASH_AR_TABLE(hash)->pairs[n]) #define RHASH_AR_CLEARED_HINT 0xff -typedef struct ar_table_pair_struct { - VALUE key; - VALUE val; -} ar_table_pair; - -typedef struct ar_table_struct { - /* 64bit CPU: 8B * 2 * 8 = 128B */ - ar_table_pair pairs[RHASH_AR_TABLE_MAX_SIZE]; -} ar_table; - -#define RHASH_EMBED_SIZE (offsetof(struct RHash, as.st) + sizeof(ar_table)) - -size_t -rb_hash_size_as_embedded(VALUE hash) -{ - if (RHASH_AR_TABLE_P(hash)) { - return RHASH_EMBED_SIZE; - } - return sizeof(struct RHash); -} - static inline st_hash_t ar_do_hash(st_data_t key) { @@ -539,6 +518,7 @@ hash_verify_(VALUE hash, const char *file, int line) HASH_ASSERT(RHASH_AR_TABLE_SIZE_RAW(hash) == 0); HASH_ASSERT(RHASH_AR_TABLE_BOUND_RAW(hash) == 0); } + return hash; } @@ -564,25 +544,25 @@ RHASH_TABLE_EMPTY_P(VALUE hash) return RHASH_SIZE(hash) == 0; } +#define RHASH_SET_ST_FLAG(h) FL_SET_RAW(h, RHASH_ST_TABLE_FLAG) +#define RHASH_UNSET_ST_FLAG(h) FL_UNSET_RAW(h, RHASH_ST_TABLE_FLAG) + +static void +hash_st_table_init(VALUE hash, const struct st_hash_type *type, st_index_t size) +{ + st_init_existing_table_with_size(RHASH_ST_TABLE(hash), type, size); + RHASH_SET_ST_FLAG(hash); +} + void rb_hash_st_table_set(VALUE hash, st_table *st) { HASH_ASSERT(st != NULL); - FL_SET_RAW((hash), RHASH_ST_TABLE_FLAG); - RHASH(hash)->as.st = st; -} + RHASH_SET_ST_FLAG(hash); -static void -hash_ar_table_set(VALUE hash, ar_table *ar) -{ - HASH_ASSERT(RHASH_AR_TABLE_P(hash)); - *(RHASH_AR_TABLE(hash)) = *ar; - hash_verify(hash); + *RHASH_ST_TABLE(hash) = *st; } -#define RHASH_SET_ST_FLAG(h) FL_SET_RAW(h, RHASH_ST_TABLE_FLAG) -#define RHASH_UNSET_ST_FLAG(h) FL_UNSET_RAW(h, RHASH_ST_TABLE_FLAG) - static inline void RHASH_AR_TABLE_BOUND_SET(VALUE h, st_index_t n) { @@ -646,9 +626,6 @@ ar_alloc_table(VALUE hash) ar_table *tab = RHASH_AR_TABLE(hash); memset(tab, 0, sizeof(ar_table)); - // RHASH_UNSET_ST_FLAG(hash); - // hash_ar_table_set(hash, tab); - RHASH_AR_TABLE_SIZE_SET(hash, 0); RHASH_AR_TABLE_BOUND_SET(hash, 0); @@ -730,28 +707,29 @@ ar_try_convert_table(VALUE hash) const unsigned size = RHASH_AR_TABLE_SIZE(hash); - st_table *new_tab; - st_index_t i; - if (size < RHASH_AR_TABLE_MAX_SIZE) { return; } - new_tab = st_init_table_with_size(&objhash, size * 2); + st_table tab; + st_table *new_tab = &tab; + rb_st_init_existing_table_with_size(new_tab, &objhash, size * 2); - for (i = 0; i < RHASH_AR_TABLE_MAX_BOUND; i++) { + for (st_index_t i = 0; i < RHASH_AR_TABLE_MAX_BOUND; i++) { ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i); st_add_direct(new_tab, pair->key, pair->val); } + ar_free_and_clear_table(hash); RHASH_ST_TABLE_SET(hash, new_tab); - return; } static st_table * ar_force_convert_table(VALUE hash, const char *file, int line) { st_table *new_tab; + st_table tab; + new_tab = &tab; if (RHASH_ST_TABLE_P(hash)) { return RHASH_ST_TABLE(hash); @@ -760,13 +738,7 @@ ar_force_convert_table(VALUE hash, const char *file, int line) if (RHASH_AR_TABLE(hash)) { unsigned i, bound = RHASH_AR_TABLE_BOUND(hash); -#if defined(RHASH_CONVERT_TABLE_DEBUG) && RHASH_CONVERT_TABLE_DEBUG - rb_obj_info_dump(hash); - fprintf(stderr, "force_convert: %s:%d\n", file, line); - RB_DEBUG_COUNTER_INC(obj_hash_force_convert); -#endif - - new_tab = st_init_table_with_size(&objhash, RHASH_AR_TABLE_SIZE(hash)); + rb_st_init_existing_table_with_size(new_tab, &objhash, RHASH_AR_TABLE_SIZE(hash)); for (i = 0; i < bound; i++) { if (ar_cleared_entry(hash, i)) continue; @@ -777,10 +749,13 @@ ar_force_convert_table(VALUE hash, const char *file, int line) ar_free_and_clear_table(hash); } else { - new_tab = st_init_table(&objhash); + rb_st_init_existing_table_with_size(new_tab, &objhash, 0); } + RHASH_ST_TABLE_SET(hash, new_tab); + new_tab = RHASH_ST_TABLE(hash); + return new_tab; } @@ -1193,7 +1168,6 @@ ar_copy(VALUE hash1, VALUE hash2) RHASH(hash1)->ar_hint.word = RHASH(hash2)->ar_hint.word; RHASH_AR_TABLE_BOUND_SET(hash1, RHASH_AR_TABLE_BOUND(hash2)); RHASH_AR_TABLE_SIZE_SET(hash1, RHASH_AR_TABLE_SIZE(hash2)); - hash_ar_table_set(hash1, new_tab); rb_gc_writebarrier_remember(hash1); @@ -1454,7 +1428,7 @@ static VALUE hash_alloc_flags(VALUE klass, VALUE flags, VALUE ifnone) { const VALUE wb = (RGENGC_WB_PROTECTED_HASH ? FL_WB_PROTECTED : 0); - NEWOBJ_OF(hash, struct RHash, klass, T_HASH | wb | flags, RHASH_EMBED_SIZE, 0); + NEWOBJ_OF(hash, struct RHash, klass, T_HASH | wb | flags, RHASH_SLOT_SIZE, 0); RHASH_SET_IFNONE((VALUE)hash, ifnone); @@ -1498,7 +1472,7 @@ rb_hash_new_with_size(st_index_t size) /* do nothing */ } else if (size > RHASH_AR_TABLE_MAX_SIZE) { - RHASH_ST_TABLE_SET(ret, st_init_table_with_size(&objhash, size)); + hash_st_table_init(ret, &objhash, size); } return ret; } @@ -1981,10 +1955,12 @@ rb_hash_rehash(VALUE hash) else if (RHASH_ST_TABLE_P(hash)) { st_table *old_tab = RHASH_ST_TABLE(hash); tmp = hash_alloc(0); - tbl = st_init_table_with_size(old_tab->type, old_tab->num_entries); - RHASH_ST_TABLE_SET(tmp, tbl); + + hash_st_table_init(tmp, old_tab->type, old_tab->num_entries); + tbl = RHASH_ST_TABLE(tmp); + rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp); - st_free_table(old_tab); + RHASH_ST_TABLE_SET(hash, tbl); RHASH_ST_CLEAR(tmp); } @@ -2925,13 +2901,12 @@ rb_hash_replace(VALUE hash, VALUE hash2) ar_free_and_clear_table(hash); } else { - st_free_table(RHASH_ST_TABLE(hash)); RHASH_ST_CLEAR(hash); } hash_copy(hash, hash2); if (RHASH_EMPTY_P(hash2) && RHASH_ST_TABLE_P(hash2)) { /* ident hash */ - RHASH_ST_TABLE_SET(hash, st_init_table_with_size(RHASH_TYPE(hash2), 0)); + hash_st_table_init(hash, RHASH_TYPE(hash2), 0); } rb_gc_writebarrier_remember(hash); @@ -4306,8 +4281,6 @@ rb_hash_compact_bang(VALUE hash) return Qnil; } -static st_table *rb_init_identtable_with_size(st_index_t size); - /* * call-seq: * hash.compare_by_identity -> self @@ -4349,10 +4322,11 @@ rb_hash_compare_by_id(VALUE hash) HASH_ASSERT(RHASH_ST_TABLE_P(hash)); tmp = hash_alloc(0); - identtable = rb_init_identtable_with_size(RHASH_SIZE(hash)); - RHASH_ST_TABLE_SET(tmp, identtable); + hash_st_table_init(tmp, &identhash, RHASH_SIZE(hash)); + identtable = RHASH_ST_TABLE(tmp); + rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp); - st_free_table(RHASH_ST_TABLE(hash)); + RHASH_ST_TABLE_SET(hash, identtable); RHASH_ST_CLEAR(tmp); @@ -4376,7 +4350,7 @@ VALUE rb_ident_hash_new(void) { VALUE hash = rb_hash_new(); - RHASH_ST_TABLE_SET(hash, st_init_table(&identhash)); + hash_st_table_init(hash, &identhash, 0); return hash; } @@ -4384,7 +4358,7 @@ VALUE rb_ident_hash_new_with_size(st_index_t size) { VALUE hash = rb_hash_new(); - RHASH_ST_TABLE_SET(hash, st_init_table_with_size(&identhash, size)); + hash_st_table_init(hash, &identhash, size); return hash; } @@ -4394,12 +4368,6 @@ rb_init_identtable(void) return st_init_table(&identhash); } -static st_table * -rb_init_identtable_with_size(st_index_t size) -{ - return st_init_table_with_size(&identhash, size); -} - static int any_p_i(VALUE key, VALUE value, VALUE arg) { |