ruby-changes:53001
From: k0kubun <ko1@a...>
Date: Sat, 20 Oct 2018 16:54:40 +0900 (JST)
Subject: [ruby-changes:53001] k0kubun:r65215 (trunk): vm_insnhelper.c: never cache setinstancevariable twice
k0kubun 2018-10-20 16:54:34 +0900 (Sat, 20 Oct 2018) New Revision: 65215 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=65215 Log: vm_insnhelper.c: never cache setinstancevariable twice same as r65213 Modified files: trunk/vm_insnhelper.c Index: vm_insnhelper.c =================================================================== --- vm_insnhelper.c (revision 65214) +++ vm_insnhelper.c (revision 65215) @@ -976,10 +976,7 @@ vm_getivar(VALUE obj, ID id, IC ic, stru https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L976 if (index < ROBJECT_NUMIV(obj)) { val = ROBJECT_IVPTR(obj)[index]; } - if (is_attr) { /* call_info */ - cc->aux.index = (int)index + 1; - } - else { /* getinstancevariable */ + if (!is_attr) { /* getinstancevariable */ if (ic->ic_serial == RUBY_VM_CLASS_SERIAL_UNSET) { /* set ic_serial only for the first time */ ic->ic_value.index = index; @@ -990,7 +987,10 @@ vm_getivar(VALUE obj, ID id, IC ic, stru https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L987 and to reduce the number of JIT cancellations by code generated for IC hit. */ ic->ic_serial = RUBY_VM_CLASS_SERIAL_INVALID; } - } + } + else { /* call_info */ + cc->aux.index = (int)index + 1; + } } } } @@ -1039,10 +1039,18 @@ vm_setivar(VALUE obj, ID id, VALUE val, https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L1039 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)) { - if (!is_attr) { - ic->ic_value.index = index; - ic->ic_serial = RCLASS_SERIAL(klass); - } + if (!is_attr) { /* setinstancevariable */ + if (ic->ic_serial == RUBY_VM_CLASS_SERIAL_UNSET) { + /* set ic_serial only for the first time */ + ic->ic_value.index = index; + ic->ic_serial = RCLASS_SERIAL(klass); + } + else if (ic->ic_serial != RUBY_VM_CLASS_SERIAL_INVALID) { + /* never use cache for another class, to avoid race condition with MJIT worker + and to reduce the number of JIT cancellations by code generated for IC hit. */ + ic->ic_serial = RUBY_VM_CLASS_SERIAL_INVALID; + } + } else if (index >= INT_MAX) { rb_raise(rb_eArgError, "too many instance variables"); } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/