From: Kazuki Tsujimoto <kazuki@...> Date: 2011-06-30T22:12:10+09:00 Subject: [ruby-dev:44003] [Ruby 1.9 - Bug #4926] --gc-stress付きtest/ruby/enc/test_emoji.rbが失敗する Issue #4926 has been updated by Kazuki Tsujimoto. 辻本です。 > というわけで,この比較を見てから判断したいのですが,すみませんがこの観 > 点からベンチマークなどを取ってみては頂けないでしょうか. 了解しました。 # Bugの話からそれてしまったので、パフォーマンス向上が見込めそうなら # Featureとして改めてチケット登録します。 ---------------------------------------- Bug #4926: --gc-stress付きtest/ruby/enc/test_emoji.rbが失敗する http://redmine.ruby-lang.org/issues/4926 Author: Kazuki Tsujimoto Status: Assigned Priority: Normal Assignee: Koichi Sasada Category: core Target version: 1.9.3 ruby -v: - =begin 辻本です。 --gc-stressオプションをつけてtest/ruby/enc/test_emoji.rbを実行するとテストに失敗します。 $ make RUBYOPT=-W TESTS='ruby/enc/test_emoji.rb --gc-stress' test-all /home/k_tsj/work/ruby-trunk/test/ruby/enc/test_emoji.rb:154: warning: instance variable @aiueo_sjis not initialized 1) Failure: test_from_iso2022jp(Emoji::TestKDDI) [/home/k_tsj/work/ruby-trunk/test/ruby/enc/test_emoji.rb:154]: Exception raised: <#<NoMethodError: undefined method `force_encoding' for nil:NilClass>>. (全ログは長いので添付します。) この時の流れは以下の通りです。 (1) vm_setivarにてic->ic_classにRBASIC(obj)->klass(Emoji::TestDoCoMoオブジェクトの特異クラス)が代入される。 (2) 1.の特異クラスがGCで解放される。 (3) Emoji::TestKDDIオブジェクトの特異クラスが1.の特異クラスと同じアドレスで作成される。 (4) icのindexとklassのindexが不一致を起こしてインスタンス変数の参照に失敗する。 ivar_get/rb_ivar_setではRBASIC(obj)->klassではなくrb_obj_class(obj)を使ってIV_INDEX_TBLを扱っており、 そちらに揃えれば問題は起きなくなります。以下のパッチでどうでしょうか。 diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 366ac4a..3736055 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -1259,7 +1259,7 @@ vm_getivar(VALUE obj, ID id, IC ic) #if USE_IC_FOR_IVAR if (TYPE(obj) == T_OBJECT) { VALUE val = Qundef; - VALUE klass = RBASIC(obj)->klass; + VALUE klass = rb_obj_class(obj); if (ic->ic_class == klass) { long index = ic->ic_value.index; @@ -1311,7 +1311,7 @@ vm_setivar(VALUE obj, ID id, VALUE val, IC ic) rb_check_frozen(obj); if (TYPE(obj) == T_OBJECT) { - VALUE klass = RBASIC(obj)->klass; + VALUE klass = rb_obj_class(obj); st_data_t index; if (ic->ic_class == klass) { =end -- http://redmine.ruby-lang.org