ruby-changes:13023
From: ko1 <ko1@a...>
Date: Sun, 6 Sep 2009 16:41:53 +0900 (JST)
Subject: [ruby-changes:13023] Ruby:r24768 (trunk): * insns.def (setinstancevariable), vm_insnhelper.c (vm_setivar):
ko1 2009-09-06 16:40:24 +0900 (Sun, 06 Sep 2009) New Revision: 24768 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=24768 Log: * insns.def (setinstancevariable), vm_insnhelper.c (vm_setivar): fix to use inline cache (trivial optimization). Modified files: trunk/ChangeLog trunk/insns.def trunk/vm_insnhelper.c Index: ChangeLog =================================================================== --- ChangeLog (revision 24767) +++ ChangeLog (revision 24768) @@ -1,3 +1,8 @@ +Sun Sep 6 16:13:06 2009 Koichi Sasada <ko1@a...> + + * insns.def (setinstancevariable), vm_insnhelper.c (vm_setivar): + fix to use inline cache (trivial optimization). + Sun Sep 6 10:34:19 2009 Nobuyoshi Nakada <nobu@r...> * io.c: fixed rdoc, a patch from Nobuhiro IMAI at [ruby-core:25433]. Index: insns.def =================================================================== --- insns.def (revision 24767) +++ insns.def (revision 24768) @@ -165,11 +165,11 @@ */ DEFINE_INSN setinstancevariable -(ID id) +(ID id, IC ic) (VALUE val) () { - rb_ivar_set(GET_SELF(), id, val); + vm_setivar(GET_SELF(), id, val, ic); } /** Index: vm_insnhelper.c =================================================================== --- vm_insnhelper.c (revision 24767) +++ vm_insnhelper.c (revision 24768) @@ -1182,10 +1182,15 @@ return klass; } + +#ifndef ENABLE_IC_FOR_IVAR +#define ENABLE_IC_FOR_IVAR 1 +#endif + static VALUE vm_getivar(VALUE obj, ID id, IC ic) { -#if 1 +#if ENABLE_IC_FOR_IVAR if (TYPE(obj) == T_OBJECT) { VALUE val = Qundef; VALUE klass = RBASIC(obj)->klass; @@ -1210,7 +1215,7 @@ if (index < len) { val = ptr[index]; } - ic->ic_class = RBASIC(obj)->klass; + ic->ic_class = klass; ic->ic_index = index; } } @@ -1229,6 +1234,47 @@ #endif } +static void +vm_setivar(VALUE obj, ID id, VALUE val, IC ic) +{ +#if ENABLE_IC_FOR_IVAR + if (!OBJ_UNTRUSTED(obj) && rb_safe_level() >= 4) { + rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable"); + } + if (OBJ_FROZEN(obj)) { + rb_error_frozen("object"); + } + + if (TYPE(obj) == T_OBJECT) { + VALUE klass = RBASIC(obj)->klass; + st_data_t index; + + if (ic->ic_class == klass) { + long index = ic->ic_index; + long len = ROBJECT_NUMIV(obj); + VALUE *ptr = ROBJECT_IVPTR(obj); + + if (index < len) { + ptr[index] = val; + return; /* inline cache hit */ + } + } + else { + struct st_table *iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj); + + if (iv_index_tbl && st_lookup(iv_index_tbl, (st_data_t)id, &index)) { + ic->ic_class = klass; + ic->ic_index = index; + } + /* fall through */ + } + } + rb_ivar_set(obj, id, val); +#else + rb_ivar_set(obj, id, val); +#endif +} + static inline const rb_method_entry_t * vm_method_search(VALUE id, VALUE klass, IC ic) { -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/