diff options
author | Koichi Sasada <ko1@cookpad.com> | 2019-01-16 10:48:30 +0000 |
---|---|---|
committer | Koichi Sasada <ko1@atdot.net> | 2019-07-31 09:44:23 +0900 |
commit | ebd398ac5a4147a1e652d6943c39a29a62f12e66 (patch) | |
tree | 79dba6622c591db987f0a9c065fe37cd09a58e98 /variable.c | |
parent | 4afd8975242917d319cfb20c7ed635b979ad48d5 (diff) |
remove RHash::iter_lev.
iter_lev is used to detect the hash is iterating or not.
Usually, iter_lev should be very small number (1 or 2) so
`int` is overkill.
This patch introduce iter_lev in flags (7 bits, FL13 to FL19)
and if iter_lev exceeds this range, save it in hidden attribute.
We can get 1 word in RHash.
We can't modify frozen objects. Therefore I added new internal API
`rb_ivar_set_internal()` which allows us to set an attribute
even if the target object is frozen
if the name is hidden ivar (the name without `@` prefix).
Diffstat (limited to 'variable.c')
-rw-r--r-- | variable.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/variable.c b/variable.c index 7d6905f390..b839f3067b 100644 --- a/variable.c +++ b/variable.c @@ -1340,16 +1340,15 @@ obj_ivar_set(VALUE obj, ID id, VALUE val) return val; } -VALUE -rb_ivar_set(VALUE obj, ID id, VALUE val) +static void +ivar_set(VALUE obj, ID id, VALUE val) { RB_DEBUG_COUNTER_INC(ivar_set_base); - rb_check_frozen(obj); - switch (BUILTIN_TYPE(obj)) { case T_OBJECT: - return obj_ivar_set(obj, id, val); + obj_ivar_set(obj, id, val); + break; case T_CLASS: case T_MODULE: if (!RCLASS_IV_TBL(obj)) RCLASS_IV_TBL(obj) = st_init_numtable(); @@ -1359,9 +1358,25 @@ rb_ivar_set(VALUE obj, ID id, VALUE val) generic_ivar_set(obj, id, val); break; } +} + +VALUE +rb_ivar_set(VALUE obj, ID id, VALUE val) +{ + rb_check_frozen(obj); + ivar_set(obj, id, val); return val; } +void +rb_ivar_set_internal(VALUE obj, ID id, VALUE val) +{ + // should be internal instance variable name (no @ prefix) + VM_ASSERT(!rb_is_instance_id(id)); + + ivar_set(obj, id, val); +} + VALUE rb_ivar_defined(VALUE obj, ID id) { |