mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47562 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
afa512d9e1
commit
ec475ab32d
5 changed files with 59 additions and 25 deletions
14
ChangeLog
14
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
|
||||
|
|
5
benchmark/bm_vm2_newlambda.rb
Normal file
5
benchmark/bm_vm2_newlambda.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
i = 0
|
||||
while i<6_000_000 # benchmark loop 2
|
||||
i += 1
|
||||
lambda {}
|
||||
end
|
24
proc.c
24
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;
|
||||
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;
|
||||
}
|
||||
|
|
39
vm.c
39
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) {
|
||||
|
|
|
@ -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 *);
|
||||
|
|
Loading…
Reference in a new issue