diff options
author | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-09-11 19:25:32 +0000 |
---|---|---|
committer | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-09-11 19:25:32 +0000 |
commit | f0c968a778ee35f483a05c6d206eb815b1da177b (patch) | |
tree | c3e3672ef1ef7d24d825e926a1912597abda8d34 /insns.def | |
parent | 1d0de2a513cf84a4b74d1cada2b05c2dce49042f (diff) | |
download | ruby-f0c968a778ee35f483a05c6d206eb815b1da177b.tar.gz |
iseq_inline_storage_entry: 24=>16 bytes on 64-bit
We may tag the running_thread pointer to avoid making the "once" struct
bigger than "struct iseq_inline_cache_entry".
This only saves a small amount with "valgrind ruby -e exit"
before:
total heap usage: 48,122 allocs, 19,248 frees, 8,110,149 bytes allocated
after:
total heap usage: 48,122 allocs, 19,253 frees, 8,099,197 bytes allocated
* insns.def (once): define and use fake RUNNING_THREAD_ONCE_DONE
pointer to indicate is->once.running_thread is done.
* vm_core.h (iseq_inline_storage_entry): remove done field,
allowing the union to be reduced from 24=>16 bytes on 64-bit
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47542 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'insns.def')
-rw-r--r-- | insns.def | 37 |
1 files changed, 18 insertions, 19 deletions
@@ -1239,28 +1239,27 @@ once { union iseq_inline_storage_entry *is = (union iseq_inline_storage_entry *)ic; +#define RUNNING_THREAD_ONCE_DONE ((rb_thread_t *)(0x1)) 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((VALUE)iseq); - } - else { - /* waiting for finish */ - RUBY_VM_CHECK_INTS(th); - rb_thread_schedule(); - goto retry; - } + if (is->once.running_thread == RUNNING_THREAD_ONCE_DONE) { + val = is->once.value; + } + else 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.running_thread = RUNNING_THREAD_ONCE_DONE; /* success */ + rb_iseq_add_mark_object(GET_ISEQ(), val); + } + else if (is->once.running_thread == th) { + /* recursive once */ + val = vm_once_exec((VALUE)iseq); } else { - val = is->once.value; + /* waiting for finish */ + RUBY_VM_CHECK_INTS(th); + rb_thread_schedule(); + goto retry; } } |