diff options
author | Ole Friis Østergaard <olefriis@gmail.com> | 2023-02-28 13:44:57 +0100 |
---|---|---|
committer | John Hawthorn <john@hawthorn.email> | 2023-03-08 09:34:31 -0800 |
commit | 1a3f8e1c9f6ce4b1cd7236fdcdd17a8719654320 (patch) | |
tree | 1c98ce45d048e918923d7e5267062af5072538cf /vm_insnhelper.c | |
parent | dc1e6573f2a1e3f85dd35c2acc26b647bd44e3b7 (diff) |
Add defined_ivar instruction
This is a variation of the `defined` instruction, for use when we
are checking for an instance variable. Splitting this out as a
separate instruction lets us skip some checks, and it also allows
us to use an instance variable cache, letting shape analysis
speed up the operation further.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/7433
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r-- | vm_insnhelper.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 74181ac131..ff91c3c362 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -1143,9 +1143,9 @@ fill_ivar_cache(const rb_iseq_t *iseq, IVC ic, const struct rb_callcache *cc, in #define ATTR_INDEX_NOT_SET (attr_index_t)-1 -ALWAYS_INLINE(static VALUE vm_getivar(VALUE, ID, const rb_iseq_t *, IVC, const struct rb_callcache *, int)); +ALWAYS_INLINE(static VALUE vm_getivar(VALUE, ID, const rb_iseq_t *, IVC, const struct rb_callcache *, int, VALUE)); static inline VALUE -vm_getivar(VALUE obj, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_callcache *cc, int is_attr) +vm_getivar(VALUE obj, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_callcache *cc, int is_attr, VALUE default_value) { #if OPT_IC_FOR_IVAR VALUE val = Qundef; @@ -1153,7 +1153,7 @@ vm_getivar(VALUE obj, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_call VALUE * ivar_list; if (SPECIAL_CONST_P(obj)) { - return Qnil; + return default_value; } #if SHAPE_IN_BASIC_FLAGS @@ -1200,7 +1200,7 @@ vm_getivar(VALUE obj, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_call ivar_list = ivtbl->ivptr; } else { - return Qnil; + return default_value; } } @@ -1218,7 +1218,7 @@ vm_getivar(VALUE obj, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_call RUBY_ASSERT(cached_id != OBJ_TOO_COMPLEX_SHAPE_ID); if (index == ATTR_INDEX_NOT_SET) { - return Qnil; + return default_value; } val = ivar_list[index]; @@ -1260,7 +1260,7 @@ vm_getivar(VALUE obj, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_call if (shape_id == OBJ_TOO_COMPLEX_SHAPE_ID) { if (!rb_id_table_lookup(ROBJECT_IV_HASH(obj), id, &val)) { - val = Qnil; + val = default_value; } } else { @@ -1281,13 +1281,15 @@ vm_getivar(VALUE obj, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_call vm_ic_attr_index_initialize(ic, shape_id); } - val = Qnil; + val = default_value; } } } - RUBY_ASSERT(!UNDEF_P(val)); + if (default_value != Qundef) { + RUBY_ASSERT(!UNDEF_P(val)); + } return val; @@ -1572,7 +1574,7 @@ rb_vm_setclassvariable(const rb_iseq_t *iseq, const rb_control_frame_t *cfp, ID static inline VALUE vm_getinstancevariable(const rb_iseq_t *iseq, VALUE obj, ID id, IVC ic) { - return vm_getivar(obj, id, iseq, ic, NULL, FALSE); + return vm_getivar(obj, id, iseq, ic, NULL, FALSE, Qnil); } static inline void @@ -3459,7 +3461,7 @@ vm_call_ivar(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_call const struct rb_callcache *cc = calling->cc; RB_DEBUG_COUNTER_INC(ccf_ivar); cfp->sp -= 1; - VALUE ivar = vm_getivar(calling->recv, vm_cc_cme(cc)->def->body.attr.id, NULL, NULL, cc, TRUE); + VALUE ivar = vm_getivar(calling->recv, vm_cc_cme(cc)->def->body.attr.id, NULL, NULL, cc, TRUE, Qnil); return ivar; } |