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
5685 5685
      case NODE_IVAR:{
5686 5686
	debugi("nd_vid", node->nd_vid);
5687 5687
	if (!popped) {
5688
	    ADD_INSN2(ret, line, getinstancevariable,
5688
            if (RTEST(ruby_verbose)) {
5689
		ADD_INSN2(ret, line, getinstancevariable,
5689 5690
		      ID2SYM(node->nd_vid),
5690 5691
		      get_ivar_ic_value(iseq,node->nd_vid));
5692
	    } else {
5693
		ADD_INSN2(ret, line, getinstancevariablefast,
5694
		      ID2SYM(node->nd_vid),
5695
		      get_ivar_ic_value(iseq,node->nd_vid));
5696
	    }
5691 5697
	}
5692 5698
	break;
5693 5699
      }
insns.def
121 121

  
122 122
/**
123 123
  @c variable
124
  @e Get value of instance variable id of self (optimized version
125
     used when $VERBOSE is not true).
126
 */
127
DEFINE_INSN
128
getinstancevariablefast
129
(ID id, IC ic)
130
()
131
(VALUE val)
132
{
133
    val = vm_getinstancevariablefast(GET_SELF(), id, ic);
134
}
135

  
136
/**
137
  @c variable
124 138
  @e Set value of instance variable id of self to val.
125 139
     If is_local is not 0, set value of class local variable.
126 140
  @j self のインスタンス変数 id を val にする。
test/ruby/test_exception.rb
995 995
  end
996 996

  
997 997
  def test_warning_warn
998
    warning = capture_warning_warn {@a}
998
    warning = capture_warning_warn {eval '@a'}
999 999
    assert_match(/instance variable @a not initialized/, warning[0])
1000 1000

  
1001 1001
    assert_equal(["a\nz\n"], capture_warning_warn {warn "a\n", "z"})
test/ruby/test_module.rb
1970 1970
      attr_accessor :cattr
1971 1971
    end
1972 1972
    attr_accessor :iattr
1973
    def ivar
1974
      @ivar
1975
    end
1976 1973
  end
1977 1974

  
1978 1975
  def test_uninitialized_instance_variable
1979 1976
    a = AttrTest.new
1980 1977
    assert_warning(/instance variable @ivar not initialized/) do
1978
      eval 'def a.ivar; @ivar end'
1981 1979
      assert_nil(a.ivar)
1982 1980
    end
1983 1981
    a.instance_variable_set(:@ivar, 42)
vm_insnhelper.c
1010 1010
}
1011 1011

  
1012 1012
static inline VALUE
1013
vm_getinstancevariablefast(VALUE obj, ID id, IC ic)
1014
{
1015
#if USE_IC_FOR_IVAR
1016
    if (LIKELY(RB_TYPE_P(obj, T_OBJECT))) {
1017
	VALUE val = Qnil;
1018
	if (RB_DEBUG_COUNTER_INC_UNLESS(ivar_get_ic_miss_serial,
1019
					       ic->ic_serial == RCLASS_SERIAL(RBASIC(obj)->klass))) {
1020
	    st_index_t index = ic->ic_value.index;
1021
	    if (LIKELY(index < ROBJECT_NUMIV(obj))) {
1022
		val = ROBJECT_IVPTR(obj)[index];
1023
		if (UNLIKELY(val == Qundef)) {
1024
		    val = Qnil;
1025
		}
1026
	    }
1027
	    RB_DEBUG_COUNTER_INC(ivar_get_ic_hit);
1028
	    return val;
1029
	}
1030
	else {
1031
	    st_data_t index;
1032
	    struct st_table *iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
1033

  
1034
	    if (iv_index_tbl) {
1035
		if (st_lookup(iv_index_tbl, id, &index)) {
1036
		    if (index < ROBJECT_NUMIV(obj)) {
1037
			val = ROBJECT_IVPTR(obj)[index];
1038
			if (UNLIKELY(val == Qundef)) {
1039
			    val = Qnil;
1040
			}
1041
		    }
1042
		    ic->ic_value.index = index;
1043
		    ic->ic_serial = RCLASS_SERIAL(RBASIC(obj)->klass);
1044
		}
1045
	    }
1046
	    RB_DEBUG_COUNTER_INC(ivar_get_ic_hit);
1047
	    return val;
1048
	}
1049
    }
1050
    else {
1051
	RB_DEBUG_COUNTER_INC(ivar_get_ic_miss_noobject);
1052
    }
1053
#endif
1054
    RB_DEBUG_COUNTER_INC(ivar_get_ic_miss);
1055
    return rb_attr_get(obj, id);
1056
}
1057

  
1058
static inline VALUE
1013 1059
vm_getinstancevariable(VALUE obj, ID id, IC ic)
1014 1060
{
1015 1061
    return vm_getivar(obj, id, ic, 0, 0);