Feature #13602 » 0001-Optimize-instance-variable-access-if-VERBOSE-is-not-.patch
| 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); 
   | 
||