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

ruby-changes:35480

From: normal <ko1@a...>
Date: Sat, 13 Sep 2014 05:58:08 +0900 (JST)
Subject: [ruby-changes:35480] normal:r47562 (trunk): proc.c (rb_proc_alloc): inline and move to vm.c

normal	2014-09-13 05:57:45 +0900 (Sat, 13 Sep 2014)

  New Revision: 47562

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=47562

  Log:
    proc.c (rb_proc_alloc): inline and move to vm.c
    
    * proc.c (rb_proc_alloc): inline and move to vm.c
      (rb_proc_wrap): new wrapper function used by rb_proc_alloc
      (proc_dup): simplify alloc + copy + wrap operation
      [ruby-core:64994]
    
    * vm.c (rb_proc_alloc): new inline function
      (rb_vm_make_proc): call rb_proc_alloc
    
    * vm_core.h: remove rb_proc_alloc, add rb_proc_wrap
    
    * benchmark/bm_vm2_newlambda.rb: short test to show difference
    
    First we allocate and populate an rb_proc_t struct inline to avoid
    unnecessary zeroing of the large struct.  Inlining speeds up callers as
    this takes many parameters to ensure correctness.  We then call the new
    rb_proc_wrap function to create the object.
    
    rb_proc_wrap - wraps a rb_proc_t pointer as a Ruby object, but
    we only use it inside rb_proc_alloc.  We must call this before
    the compiler may clobber VALUE parameters passed to rb_proc_alloc.

  Added files:
    trunk/benchmark/bm_vm2_newlambda.rb
  Modified files:
    trunk/ChangeLog
    trunk/proc.c
    trunk/vm.c
    trunk/vm_core.h
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 47561)
+++ ChangeLog	(revision 47562)
@@ -1,3 +1,17 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sat Sep 13 05:52:15 2014  Eric Wong  <e@8...>
+
+	* proc.c (rb_proc_alloc): inline and move to vm.c
+	  (rb_proc_wrap): new wrapper function used by rb_proc_alloc
+	  (proc_dup): simplify alloc + copy + wrap operation
+	  [ruby-core:64994]
+
+	* vm.c (rb_proc_alloc): new inline function
+	  (rb_vm_make_proc): call rb_proc_alloc
+
+	* vm_core.h: remove rb_proc_alloc, add rb_proc_wrap
+
+	* benchmark/bm_vm2_newlambda.rb: short test to show difference
+
 Sat Sep 13 04:40:04 2014  Eric Wong  <e@8...>
 
 	* process.c (Init_process): subclass Thread as Process::Waiter
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 47561)
+++ vm_core.h	(revision 47562)
@@ -884,7 +884,7 @@ rb_block_t *rb_vm_control_frame_block_pt https://github.com/ruby/ruby/blob/trunk/vm_core.h#L884
 
 /* VM related object allocate functions */
 VALUE rb_thread_alloc(VALUE klass);
-VALUE rb_proc_alloc(VALUE klass);
+VALUE rb_proc_wrap(VALUE klass, rb_proc_t *); /* may use with rb_proc_alloc */
 
 /* for debug */
 extern void rb_vmdebug_stack_dump_raw(rb_thread_t *, rb_control_frame_t *);
Index: proc.c
===================================================================
--- proc.c	(revision 47561)
+++ proc.c	(revision 47562)
@@ -84,10 +84,11 @@ static const rb_data_type_t proc_data_ty https://github.com/ruby/ruby/blob/trunk/proc.c#L84
 };
 
 VALUE
-rb_proc_alloc(VALUE klass)
+rb_proc_wrap(VALUE klass, rb_proc_t *proc)
 {
-    rb_proc_t *proc;
-    return TypedData_Make_Struct(klass, rb_proc_t, &proc_data_type, proc);
+    proc->block.proc = TypedData_Wrap_Struct(klass, &proc_data_type, proc);
+
+    return proc->block.proc;
 }
 
 VALUE
@@ -105,17 +106,14 @@ rb_obj_is_proc(VALUE proc) https://github.com/ruby/ruby/blob/trunk/proc.c#L106
 static VALUE
 proc_dup(VALUE self)
 {
-    VALUE procval = rb_proc_alloc(rb_cProc);
-    rb_proc_t *src, *dst;
-    GetProcPtr(self, src);
-    GetProcPtr(procval, dst);
+    VALUE procval;
+    rb_proc_t *src;
+    rb_proc_t *dst = ALLOC(rb_proc_t);
 
-    dst->block = src->block;
-    dst->block.proc = procval;
-    dst->blockprocval = src->blockprocval;
-    dst->envval = src->envval;
-    dst->safe_level = src->safe_level;
-    dst->is_lambda = src->is_lambda;
+    GetProcPtr(self, src);
+    *dst = *src;
+    procval = rb_proc_wrap(rb_cProc, dst);
+    RB_GC_GUARD(self); /* for: body = proc_dup(body) */
 
     return procval;
 }
Index: vm.c
===================================================================
--- vm.c	(revision 47561)
+++ vm.c	(revision 47562)
@@ -651,11 +651,35 @@ vm_make_proc_from_block(rb_thread_t *th, https://github.com/ruby/ruby/blob/trunk/vm.c#L651
     return block->proc;
 }
 
+static inline VALUE
+rb_proc_alloc(VALUE klass, const rb_block_t *block,
+		VALUE envval, VALUE blockprocval,
+		int8_t safe_level, int8_t is_from_method, int8_t is_lambda)
+{
+    VALUE procval;
+    rb_proc_t *proc = ALLOC(rb_proc_t);
+
+    proc->block = *block;
+    proc->safe_level = safe_level;
+    proc->is_from_method = is_from_method;
+    proc->is_lambda = is_lambda;
+
+    procval = rb_proc_wrap(klass, proc);
+
+    /*
+     * ensure VALUEs are markable here as rb_proc_wrap may trigger allocation
+     * and clobber envval + blockprocval
+     */
+    proc->envval = envval;
+    proc->blockprocval = blockprocval;
+
+    return procval;
+}
+
 VALUE
 rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass)
 {
     VALUE procval, envval, blockprocval = 0;
-    rb_proc_t *proc;
     rb_control_frame_t *cfp = RUBY_VM_GET_CFP_FROM_BLOCK_PTR(block);
 
     if (block->proc) {
@@ -667,16 +691,9 @@ rb_vm_make_proc(rb_thread_t *th, const r https://github.com/ruby/ruby/blob/trunk/vm.c#L691
     if (PROCDEBUG) {
 	check_env_value(envval);
     }
-    procval = rb_proc_alloc(klass);
-    GetProcPtr(procval, proc);
-    proc->blockprocval = blockprocval;
-    proc->block.self = block->self;
-    proc->block.klass = block->klass;
-    proc->block.ep = block->ep;
-    proc->block.iseq = block->iseq;
-    proc->block.proc = procval;
-    proc->envval = envval;
-    proc->safe_level = th->safe_level;
+
+    procval = rb_proc_alloc(klass, block, envval, blockprocval,
+			    th->safe_level, 0, 0);
 
     if (VMDEBUG) {
 	if (th->stack < block->ep && block->ep < th->stack + th->stack_size) {
Index: benchmark/bm_vm2_newlambda.rb
===================================================================
--- benchmark/bm_vm2_newlambda.rb	(revision 0)
+++ benchmark/bm_vm2_newlambda.rb	(revision 47562)
@@ -0,0 +1,5 @@ https://github.com/ruby/ruby/blob/trunk/benchmark/bm_vm2_newlambda.rb#L1
+i = 0
+while i<6_000_000 # benchmark loop 2
+  i += 1
+  lambda {}
+end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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