Project

General

Profile

Feature #13602 » 0001-Optimize-instance-variable-access-if-VERBOSE-is-not-.patch

jeremyevans0 (Jeremy Evans), 05/26/2017 08:46 PM

View differences:

compile.c
case NODE_IVAR:{
debugi("nd_vid", node->nd_vid);
if (!popped) {
ADD_INSN2(ret, line, getinstancevariable,
if (RTEST(ruby_verbose)) {
ADD_INSN2(ret, line, getinstancevariable,
ID2SYM(node->nd_vid),
get_ivar_ic_value(iseq,node->nd_vid));
} else {
ADD_INSN2(ret, line, getinstancevariablefast,
ID2SYM(node->nd_vid),
get_ivar_ic_value(iseq,node->nd_vid));
}
}
break;
}
insns.def
/**
@c variable
@e Get value of instance variable id of self (optimized version
used when $VERBOSE is not true).
*/
DEFINE_INSN
getinstancevariablefast
(ID id, IC ic)
()
(VALUE val)
{
val = vm_getinstancevariablefast(GET_SELF(), id, ic);
}
/**
@c variable
@e Set value of instance variable id of self to val.
If is_local is not 0, set value of class local variable.
@j self のインスタンス変数 id を val にする。
test/ruby/test_exception.rb
end
def test_warning_warn
warning = capture_warning_warn {@a}
warning = capture_warning_warn {eval '@a'}
assert_match(/instance variable @a not initialized/, warning[0])
assert_equal(["a\nz\n"], capture_warning_warn {warn "a\n", "z"})
test/ruby/test_module.rb
attr_accessor :cattr
end
attr_accessor :iattr
def ivar
@ivar
end
end
def test_uninitialized_instance_variable
a = AttrTest.new
assert_warning(/instance variable @ivar not initialized/) do
eval 'def a.ivar; @ivar end'
assert_nil(a.ivar)
end
a.instance_variable_set(:@ivar, 42)
vm_insnhelper.c
}
static inline VALUE
vm_getinstancevariablefast(VALUE obj, ID id, IC ic)
{
#if USE_IC_FOR_IVAR
if (LIKELY(RB_TYPE_P(obj, T_OBJECT))) {
VALUE val = Qnil;
if (RB_DEBUG_COUNTER_INC_UNLESS(ivar_get_ic_miss_serial,
ic->ic_serial == RCLASS_SERIAL(RBASIC(obj)->klass))) {
st_index_t index = ic->ic_value.index;
if (LIKELY(index < ROBJECT_NUMIV(obj))) {
val = ROBJECT_IVPTR(obj)[index];
if (UNLIKELY(val == Qundef)) {
val = Qnil;
}
}
RB_DEBUG_COUNTER_INC(ivar_get_ic_hit);
return val;
}
else {
st_data_t index;
struct st_table *iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
if (iv_index_tbl) {
if (st_lookup(iv_index_tbl, id, &index)) {
if (index < ROBJECT_NUMIV(obj)) {
val = ROBJECT_IVPTR(obj)[index];
if (UNLIKELY(val == Qundef)) {
val = Qnil;
}
}
ic->ic_value.index = index;
ic->ic_serial = RCLASS_SERIAL(RBASIC(obj)->klass);
}
}
RB_DEBUG_COUNTER_INC(ivar_get_ic_hit);
return val;
}
}
else {
RB_DEBUG_COUNTER_INC(ivar_get_ic_miss_noobject);
}
#endif
RB_DEBUG_COUNTER_INC(ivar_get_ic_miss);
return rb_attr_get(obj, id);
}
static inline VALUE
vm_getinstancevariable(VALUE obj, ID id, IC ic)
{
return vm_getivar(obj, id, ic, 0, 0);
    (1-1/1)