aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--benchmark/bm_vm2_newlambda.rb5
-rw-r--r--proc.c24
-rw-r--r--vm.c39
-rw-r--r--vm_core.h2
5 files changed, 59 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index 91b4819cb2..6ea53dead4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+Sat Sep 13 05:52:15 2014 Eric Wong <e@80x24.org>
+
+ * 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@80x24.org>
* process.c (Init_process): subclass Thread as Process::Waiter
diff --git a/benchmark/bm_vm2_newlambda.rb b/benchmark/bm_vm2_newlambda.rb
new file mode 100644
index 0000000000..6422c9b0d0
--- /dev/null
+++ b/benchmark/bm_vm2_newlambda.rb
@@ -0,0 +1,5 @@
+i = 0
+while i<6_000_000 # benchmark loop 2
+ i += 1
+ lambda {}
+end
diff --git a/proc.c b/proc.c
index 2c60574725..04ed7b71e8 100644
--- a/proc.c
+++ b/proc.c
@@ -84,10 +84,11 @@ static const rb_data_type_t proc_data_type = {
};
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)
static VALUE
proc_dup(VALUE self)
{
- VALUE procval = rb_proc_alloc(rb_cProc);
- rb_proc_t *src, *dst;
+ VALUE procval;
+ rb_proc_t *src;
+ rb_proc_t *dst = ALLOC(rb_proc_t);
+
GetProcPtr(self, src);
- GetProcPtr(procval, dst);
-
- 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;
+ *dst = *src;
+ procval = rb_proc_wrap(rb_cProc, dst);
+ RB_GC_GUARD(self); /* for: body = proc_dup(body) */
return procval;
}
diff --git a/vm.c b/vm.c
index f5fb5a7d57..7591f97130 100644
--- a/vm.c
+++ b/vm.c
@@ -651,11 +651,35 @@ vm_make_proc_from_block(rb_thread_t *th, rb_block_t *block)
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 rb_block_t *block, VALUE klass)
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) {
diff --git a/vm_core.h b/vm_core.h
index 1c3d0cc548..3f1ddc80f9 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -884,7 +884,7 @@ rb_block_t *rb_vm_control_frame_block_ptr(rb_control_frame_t *cfp);
/* 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 *);