[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]