diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-08-20 17:41:13 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-08-20 17:41:13 +0000 |
commit | 30b1947df2da2192f7fcc812ac88dc1884715322 (patch) | |
tree | f5f2969d24420e851e1b580f6a0696e0c944617c /insns.def | |
parent | a8fbb064a7beb29bf34e532ba49c1bdf59cf0f99 (diff) | |
download | ruby-30b1947df2da2192f7fcc812ac88dc1884715322.tar.gz |
* insns.def: fix regexp's once option behavior.
fix [ruby-trunk - Bug #6701]
* insns.def: remove `onceinlinecache' and introduce `once' instruction.
`once' doesn't use `setinlinecache' insn any more.
* vm_core.h: `union iseq_inline_storage_entry' to store once data.
* compile.c: catch up above changes.
* iseq.c: ditto.
* vm.c, vm_insnhelper.c: ditto. fix `m_core_set_postexe()' which
is depend on `onceinlinecache' insn.
* test/ruby/test_regexp.rb: add tests.
* iseq.c: ISEQ_MINOR_VERSION to 1 (should increment major?)
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42637 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'insns.def')
-rw-r--r-- | insns.def | 67 |
1 files changed, 38 insertions, 29 deletions
@@ -1198,35 +1198,6 @@ getinlinecache /** @c optimize - @e inline cache (once) - @j once を実現する。 - */ -DEFINE_INSN -onceinlinecache -(OFFSET dst, IC ic) -() -(VALUE val) -{ - retry: - if (ic->ic_vmstat) { - val = ic->ic_value.value; - JUMP(dst); - } - else if (ic->ic_value.value == Qundef) - { - RUBY_VM_CHECK_INTS(th); - rb_thread_schedule(); - goto retry; - } - else { - /* none */ - ic->ic_value.value = Qundef; - val = Qnil; - } -} - -/** - @c optimize @e set inline cache @j インラインキャッシュの値を設定する。 */ @@ -1246,6 +1217,44 @@ setinlinecache /** @c optimize + @e once + @j once を実現する。 + */ +DEFINE_INSN +once +(ISEQ iseq, IC ic) +() +(VALUE val) +{ + union iseq_inline_storage_entry *is = (union iseq_inline_storage_entry *)ic; + + retry: + if (is->once.done == Qfalse) { + if (is->once.running_thread == NULL) { + is->once.running_thread = th; + val = is->once.value = rb_ensure(vm_once_exec, (VALUE)iseq, vm_once_clear, (VALUE)is); + /* is->once.running_thread is cleared by vm_once_clear() */ + is->once.done = Qtrue; + rb_iseq_add_mark_object(GET_ISEQ(), val); + } + else if (is->once.running_thread == th) { + /* recursive once */ + val = vm_once_exec(iseq); + } + else { + /* waiting for finish */ + RUBY_VM_CHECK_INTS(th); + rb_thread_schedule(); + goto retry; + } + } + else { + val = is->once.value; + } +} + +/** + @c optimize @e case dispatcher @j case 文で、可能なら表引きでジャンプする。 */ |