Just check if iteration level is non-zero

The level in ivar is no longer needed to check if iterating, only used
for increment/decrement.
This commit is contained in:
Nobuyoshi Nakada 2023-11-12 01:16:27 +09:00
parent 9ab64b1d70
commit 60e19a0b5f
No known key found for this signature in database
GPG Key ID: 3582D74E1FEE4465

39
hash.c
View File

@ -1307,17 +1307,10 @@ iter_lev_in_flags_set(VALUE hash, unsigned long lev)
RBASIC(hash)->flags = ((RBASIC(hash)->flags & ~RHASH_LEV_MASK) | ((VALUE)lev << RHASH_LEV_SHIFT)); RBASIC(hash)->flags = ((RBASIC(hash)->flags & ~RHASH_LEV_MASK) | ((VALUE)lev << RHASH_LEV_SHIFT));
} }
static unsigned long static inline bool
RHASH_ITER_LEV(VALUE hash) hash_iterating_p(VALUE hash)
{ {
unsigned long lev = iter_lev_in_flags(hash); return iter_lev_in_flags(hash) > 0;
if (lev == RHASH_LEV_MAX) {
return iter_lev_in_ivar(hash);
}
else {
return lev;
}
} }
static void static void
@ -1436,7 +1429,7 @@ void rb_st_compact_table(st_table *tab);
static void static void
compact_after_delete(VALUE hash) compact_after_delete(VALUE hash)
{ {
if (RHASH_ITER_LEV(hash) == 0 && RHASH_ST_TABLE_P(hash)) { if (!hash_iterating_p(hash) && RHASH_ST_TABLE_P(hash)) {
rb_st_compact_table(RHASH_ST_TABLE(hash)); rb_st_compact_table(RHASH_ST_TABLE(hash));
} }
} }
@ -1691,14 +1684,14 @@ tbl_update(VALUE hash, VALUE key, tbl_update_func func, st_data_t optional_arg)
return ret; return ret;
} }
#define UPDATE_CALLBACK(iter_lev, func) ((iter_lev) > 0 ? func##_noinsert : func##_insert) #define UPDATE_CALLBACK(iter_p, func) ((iter_p) ? func##_noinsert : func##_insert)
#define RHASH_UPDATE_ITER(h, iter_lev, key, func, a) do { \ #define RHASH_UPDATE_ITER(h, iter_p, key, func, a) do { \
tbl_update((h), (key), UPDATE_CALLBACK((iter_lev), func), (st_data_t)(a)); \ tbl_update((h), (key), UPDATE_CALLBACK(iter_p, func), (st_data_t)(a)); \
} while (0) } while (0)
#define RHASH_UPDATE(hash, key, func, arg) \ #define RHASH_UPDATE(hash, key, func, arg) \
RHASH_UPDATE_ITER(hash, RHASH_ITER_LEV(hash), key, func, arg) RHASH_UPDATE_ITER(hash, hash_iterating_p(hash), key, func, arg)
static void static void
set_proc_default(VALUE hash, VALUE proc) set_proc_default(VALUE hash, VALUE proc)
@ -1986,7 +1979,7 @@ rb_hash_rehash(VALUE hash)
VALUE tmp; VALUE tmp;
st_table *tbl; st_table *tbl;
if (RHASH_ITER_LEV(hash) > 0) { if (hash_iterating_p(hash)) {
rb_raise(rb_eRuntimeError, "rehash during iteration"); rb_raise(rb_eRuntimeError, "rehash during iteration");
} }
rb_hash_modify_check(hash); rb_hash_modify_check(hash);
@ -2465,7 +2458,7 @@ rb_hash_shift(VALUE hash)
rb_hash_modify_check(hash); rb_hash_modify_check(hash);
if (RHASH_AR_TABLE_P(hash)) { if (RHASH_AR_TABLE_P(hash)) {
var.key = Qundef; var.key = Qundef;
if (RHASH_ITER_LEV(hash) == 0) { if (!hash_iterating_p(hash)) {
if (ar_shift(hash, &var.key, &var.val)) { if (ar_shift(hash, &var.key, &var.val)) {
return rb_assoc_new(var.key, var.val); return rb_assoc_new(var.key, var.val);
} }
@ -2480,7 +2473,7 @@ rb_hash_shift(VALUE hash)
} }
if (RHASH_ST_TABLE_P(hash)) { if (RHASH_ST_TABLE_P(hash)) {
var.key = Qundef; var.key = Qundef;
if (RHASH_ITER_LEV(hash) == 0) { if (!hash_iterating_p(hash)) {
if (st_shift(RHASH_ST_TABLE(hash), &var.key, &var.val)) { if (st_shift(RHASH_ST_TABLE(hash), &var.key, &var.val)) {
return rb_assoc_new(var.key, var.val); return rb_assoc_new(var.key, var.val);
} }
@ -2838,7 +2831,7 @@ rb_hash_clear(VALUE hash)
{ {
rb_hash_modify_check(hash); rb_hash_modify_check(hash);
if (RHASH_ITER_LEV(hash) > 0) { if (hash_iterating_p(hash)) {
rb_hash_foreach(hash, clear_i, 0); rb_hash_foreach(hash, clear_i, 0);
} }
else if (RHASH_AR_TABLE_P(hash)) { else if (RHASH_AR_TABLE_P(hash)) {
@ -2909,15 +2902,15 @@ NOINSERT_UPDATE_CALLBACK(hash_aset_str)
VALUE VALUE
rb_hash_aset(VALUE hash, VALUE key, VALUE val) rb_hash_aset(VALUE hash, VALUE key, VALUE val)
{ {
unsigned long iter_lev = RHASH_ITER_LEV(hash); bool iter_p = hash_iterating_p(hash);
rb_hash_modify(hash); rb_hash_modify(hash);
if (RHASH_TYPE(hash) == &identhash || rb_obj_class(key) != rb_cString) { if (RHASH_TYPE(hash) == &identhash || rb_obj_class(key) != rb_cString) {
RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset, val); RHASH_UPDATE_ITER(hash, iter_p, key, hash_aset, val);
} }
else { else {
RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset_str, val); RHASH_UPDATE_ITER(hash, iter_p, key, hash_aset_str, val);
} }
return val; return val;
} }
@ -2937,7 +2930,7 @@ rb_hash_replace(VALUE hash, VALUE hash2)
{ {
rb_hash_modify_check(hash); rb_hash_modify_check(hash);
if (hash == hash2) return hash; if (hash == hash2) return hash;
if (RHASH_ITER_LEV(hash) > 0) { if (hash_iterating_p(hash)) {
rb_raise(rb_eRuntimeError, "can't replace hash during iteration"); rb_raise(rb_eRuntimeError, "can't replace hash during iteration");
} }
hash2 = to_hash(hash2); hash2 = to_hash(hash2);