From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-2.1 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00 shortcircuit=no autolearn=unavailable version=3.3.2 X-Original-To: misc@80x24.org Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 58C961FF3D; Mon, 8 Sep 2014 20:44:12 +0000 (UTC) From: Eric Wong To: misc@80x24.org Cc: Eric Wong Subject: [PATCH] avoid redundant zero-ing in proc/env alloc Date: Mon, 8 Sep 2014 20:44:09 +0000 Message-Id: <1410209049-23179-1-git-send-email-e@80x24.org> X-Mailer: git-send-email 2.1.0 List-Id: * proc.c (rb_proc_alloc): do not zero memory, callers must be careful not to trigger GC before filling out rb_proc_t * proc.c (proc_dup): initialize proc->is_from_method * vm.c (vm_make_env_each): inline env_alloc to simplify reading. We must be careful about invoking GC while rb_env_t is uninitialized. * vm.c (env_alloc): remove * vm.c (rb_vm_make_proc): initialize proc->{is_from_method,is_lambda} --- proc.c | 5 +++-- vm.c | 32 ++++++++++++++++---------------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/proc.c b/proc.c index 63e2319..c793c01 100644 --- a/proc.c +++ b/proc.c @@ -86,8 +86,8 @@ static const rb_data_type_t proc_data_type = { VALUE rb_proc_alloc(VALUE klass) { - rb_proc_t *proc; - return TypedData_Make_Struct(klass, rb_proc_t, &proc_data_type, proc); + rb_proc_t *proc = ALLOC(rb_proc_t); + return TypedData_Wrap_Struct(klass, &proc_data_type, proc); } VALUE @@ -115,6 +115,7 @@ proc_dup(VALUE self) dst->blockprocval = src->blockprocval; dst->envval = src->envval; dst->safe_level = src->safe_level; + dst->is_from_method = 0; dst->is_lambda = src->is_lambda; return procval; diff --git a/vm.c b/vm.c index 7738220..0a4adc5 100644 --- a/vm.c +++ b/vm.c @@ -404,18 +404,6 @@ static const rb_data_type_t env_data_type = { NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY }; -static VALUE -env_alloc(int local_size) -{ - rb_env_t *env; - - env = xcalloc(1, sizeof(rb_env_t) + ((local_size + 1) * sizeof(VALUE))); - env->env_size = local_size + 1 + 1; - env->local_size = local_size; - - return TypedData_Wrap_Struct(rb_cEnv, &env_data_type, env); -} - static VALUE check_env_value(VALUE envval); static int @@ -488,10 +476,9 @@ vm_make_env_each(const rb_thread_t *const th, rb_control_frame_t *const cfp, } /* allocate env */ - envval = env_alloc(local_size); - GetEnvPtr(envval, env); - - env->prev_envval = penvval; + env = xmalloc(sizeof(rb_env_t) + ((local_size + 1) * sizeof(VALUE))); + env->env_size = local_size + 1 + 1; + env->local_size = local_size; for (i = 0; i <= local_size; i++) { env->env[i] = envptr[-local_size + i]; @@ -504,6 +491,15 @@ vm_make_env_each(const rb_thread_t *const th, rb_control_frame_t *const cfp, #endif } + /* be careful not to trigger GC after this */ + envval = TypedData_Wrap_Struct(rb_cEnv, &env_data_type, env); + + /* + * must happen after TypedData_Wrap_Struct to ensure penvval is markable + * in case object allocation triggers GC and clobbers penvval. + */ + env->prev_envval = penvval; + *envptr = envval; /* GC mark */ nenvptr = &env->env[i - 1]; nenvptr[1] = envval; /* frame self */ @@ -513,8 +509,10 @@ vm_make_env_each(const rb_thread_t *const th, rb_control_frame_t *const cfp, /* as Binding */ env->block.self = cfp->self; + env->block.klass = 0; env->block.ep = cfp->ep; env->block.iseq = cfp->iseq; + env->block.proc = 0; if (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) { /* TODO */ @@ -679,6 +677,8 @@ rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass) proc->block.proc = procval; proc->envval = envval; proc->safe_level = th->safe_level; + proc->is_from_method = 0; + proc->is_lambda = 0; if (VMDEBUG) { if (th->stack < block->ep && block->ep < th->stack + th->stack_size) { -- EW