ruby-changes:35460
From: normal <ko1@a...>
Date: Fri, 12 Sep 2014 04:25:49 +0900 (JST)
Subject: [ruby-changes:35460] normal:r47542 (trunk): iseq_inline_storage_entry: 24=>16 bytes on 64-bit
normal 2014-09-12 04:25:32 +0900 (Fri, 12 Sep 2014) New Revision: 47542 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=47542 Log: 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 Modified files: trunk/ChangeLog trunk/insns.def trunk/vm_core.h Index: insns.def =================================================================== --- insns.def (revision 47541) +++ insns.def (revision 47542) @@ -1239,28 +1239,27 @@ once https://github.com/ruby/ruby/blob/trunk/insns.def#L1239 { 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; } } Index: ChangeLog =================================================================== --- ChangeLog (revision 47541) +++ ChangeLog (revision 47542) @@ -1,3 +1,12 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Fri Sep 12 04:24:03 2014 Eric Wong <e@8...> + + * 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 + [Feature #10187] + Thu Sep 11 20:10:00 2014 Koichi Sasada <ko1@a...> * vm.c (rb_thread_mark): use rb_gc_mark_values() to mark VM stack. Index: vm_core.h =================================================================== --- vm_core.h (revision 47541) +++ vm_core.h (revision 47542) @@ -127,7 +127,6 @@ union iseq_inline_storage_entry { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L127 struct { struct rb_thread_struct *running_thread; VALUE value; - VALUE done; } once; struct iseq_inline_cache_entry cache; }; -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/