aboutsummaryrefslogtreecommitdiffstats
path: root/insns.def
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-08-20 17:41:13 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-08-20 17:41:13 +0000
commit30b1947df2da2192f7fcc812ac88dc1884715322 (patch)
treef5f2969d24420e851e1b580f6a0696e0c944617c /insns.def
parenta8fbb064a7beb29bf34e532ba49c1bdf59cf0f99 (diff)
downloadruby-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.def67
1 files changed, 38 insertions, 29 deletions
diff --git a/insns.def b/insns.def
index b5ca35c44b..ff622fa987 100644
--- a/insns.def
+++ b/insns.def
@@ -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 文で、可能なら表引きでジャンプする。
*/