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>
|
Sat Sep 13 04:40:04 2014 Eric Wong <e@80x24.org>
|
||||||
|
|
||||||
* process.c (Init_process): subclass Thread as Process::Waiter
|
* 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
|
VALUE
|
||||||
rb_proc_alloc(VALUE klass)
|
rb_proc_wrap(VALUE klass, rb_proc_t *proc)
|
||||||
{
|
{
|
||||||
rb_proc_t *proc;
|
proc->block.proc = TypedData_Wrap_Struct(klass, &proc_data_type, proc);
|
||||||
return TypedData_Make_Struct(klass, rb_proc_t, &proc_data_type, proc);
|
|
||||||
|
return proc->block.proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
@ -105,17 +106,14 @@ rb_obj_is_proc(VALUE proc)
|
||||||
static VALUE
|
static VALUE
|
||||||
proc_dup(VALUE self)
|
proc_dup(VALUE self)
|
||||||
{
|
{
|
||||||
VALUE procval = rb_proc_alloc(rb_cProc);
|
VALUE procval;
|
||||||
rb_proc_t *src, *dst;
|
rb_proc_t *src;
|
||||||
GetProcPtr(self, src);
|
rb_proc_t *dst = ALLOC(rb_proc_t);
|
||||||
GetProcPtr(procval, dst);
|
|
||||||
|
|
||||||
dst->block = src->block;
|
GetProcPtr(self, src);
|
||||||
dst->block.proc = procval;
|
*dst = *src;
|
||||||
dst->blockprocval = src->blockprocval;
|
procval = rb_proc_wrap(rb_cProc, dst);
|
||||||
dst->envval = src->envval;
|
RB_GC_GUARD(self); /* for: body = proc_dup(body) */
|
||||||
dst->safe_level = src->safe_level;
|
|
||||||
dst->is_lambda = src->is_lambda;
|
|
||||||
|
|
||||||
return procval;
|
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;
|
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
|
VALUE
|
||||||
rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass)
|
rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass)
|
||||||
{
|
{
|
||||||
VALUE procval, envval, blockprocval = 0;
|
VALUE procval, envval, blockprocval = 0;
|
||||||
rb_proc_t *proc;
|
|
||||||
rb_control_frame_t *cfp = RUBY_VM_GET_CFP_FROM_BLOCK_PTR(block);
|
rb_control_frame_t *cfp = RUBY_VM_GET_CFP_FROM_BLOCK_PTR(block);
|
||||||
|
|
||||||
if (block->proc) {
|
if (block->proc) {
|
||||||
|
@ -667,16 +691,9 @@ rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass)
|
||||||
if (PROCDEBUG) {
|
if (PROCDEBUG) {
|
||||||
check_env_value(envval);
|
check_env_value(envval);
|
||||||
}
|
}
|
||||||
procval = rb_proc_alloc(klass);
|
|
||||||
GetProcPtr(procval, proc);
|
procval = rb_proc_alloc(klass, block, envval, blockprocval,
|
||||||
proc->blockprocval = blockprocval;
|
th->safe_level, 0, 0);
|
||||||
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;
|
|
||||||
|
|
||||||
if (VMDEBUG) {
|
if (VMDEBUG) {
|
||||||
if (th->stack < block->ep && block->ep < th->stack + th->stack_size) {
|
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 */
|
/* VM related object allocate functions */
|
||||||
VALUE rb_thread_alloc(VALUE klass);
|
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 */
|
/* for debug */
|
||||||
extern void rb_vmdebug_stack_dump_raw(rb_thread_t *, rb_control_frame_t *);
|
extern void rb_vmdebug_stack_dump_raw(rb_thread_t *, rb_control_frame_t *);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue