* vm_core.h, vm.c: remvoe rb_env_t::prev_envval because we can know it

via env->ep.
  rb_vm_env_prev_envval(env) returns prev_envval via env->ep.
* vm_core.h (rb_vm_env_local_variables): change parameter type
  from VALUE (T_DATA/env) to `const rb_env_t *' to make same as
  rb_vm_env_prev_envval().
* proc.c: catch up these changes.
* vm_dump.c: ditto.
* vm.c: rename macros.
  * ENV_IN_HEAP_P() to VM_EP_IN_HEAP_P() because it uses ep.
  * ENV_VAL() to VM_ENV_EP_ENVVAL() because it is too short.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51245 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2015-07-14 17:36:36 +00:00
parent af4cbc4fe0
commit e07dad00ee
5 changed files with 63 additions and 34 deletions

View File

@ -1,3 +1,23 @@
Wed Jul 15 02:27:22 2015 Koichi Sasada <ko1@atdot.net>
* vm_core.h, vm.c: remvoe rb_env_t::prev_envval because we can know it
via env->ep.
rb_vm_env_prev_envval(env) returns prev_envval via env->ep.
* vm_core.h (rb_vm_env_local_variables): change parameter type
from VALUE (T_DATA/env) to `const rb_env_t *' to make same as
rb_vm_env_prev_envval().
* proc.c: catch up these changes.
* vm_dump.c: ditto.
* vm.c: rename macros.
* ENV_IN_HEAP_P() to VM_EP_IN_HEAP_P() because it uses ep.
* ENV_VAL() to VM_ENV_EP_ENVVAL() because it is too short.
Wed Jul 15 01:09:09 2015 Koichi Sasada <ko1@atdot.net> Wed Jul 15 01:09:09 2015 Koichi Sasada <ko1@atdot.net>
* vm.c: refactoring Proc/Env related code. * vm.c: refactoring Proc/Env related code.

7
proc.c
View File

@ -379,7 +379,7 @@ get_local_variable_ptr(VALUE envval, ID lid)
else { else {
return NULL; return NULL;
} }
} while ((envval = env->prev_envval) != 0); } while ((envval = rb_vm_env_prev_envval(env)) != Qfalse);
return NULL; return NULL;
} }
@ -432,9 +432,12 @@ static VALUE
bind_local_variables(VALUE bindval) bind_local_variables(VALUE bindval)
{ {
const rb_binding_t *bind; const rb_binding_t *bind;
const rb_env_t *env;
GetBindingPtr(bindval, bind); GetBindingPtr(bindval, bind);
return rb_vm_env_local_variables(bind->env); GetEnvPtr(bind->env, env);
return rb_vm_env_local_variables(env);
} }
/* /*

58
vm.c
View File

@ -407,10 +407,6 @@ ruby_vm_run_at_exit_hooks(rb_vm_t *vm)
}; };
*/ */
#define ENV_IN_HEAP_P(th, env) \
(!((th)->stack <= (env) && (env) < ((th)->stack + (th)->stack_size)))
#define ENV_VAL(env) ((env)[1])
static void static void
env_mark(void * const ptr) env_mark(void * const ptr)
{ {
@ -420,8 +416,7 @@ env_mark(void * const ptr)
RUBY_GC_INFO("env->env\n"); RUBY_GC_INFO("env->env\n");
rb_gc_mark_values((long)env->env_size, env->env); rb_gc_mark_values((long)env->env_size, env->env);
RUBY_GC_INFO("env->prev_envval\n"); RUBY_MARK_UNLESS_NULL(rb_vm_env_prev_envval(env));
RUBY_MARK_UNLESS_NULL(env->prev_envval);
RUBY_MARK_UNLESS_NULL(env->block.self); RUBY_MARK_UNLESS_NULL(env->block.self);
RUBY_MARK_UNLESS_NULL(env->block.proc); RUBY_MARK_UNLESS_NULL(env->block.proc);
@ -452,6 +447,9 @@ static const rb_data_type_t env_data_type = {
0, 0, RUBY_TYPED_FREE_IMMEDIATELY 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
}; };
#define VM_EP_IN_HEAP_P(th, ep) (!((th)->stack <= (ep) && (ep) < ((th)->stack + (th)->stack_size)))
#define VM_ENV_EP_ENVVAL(ep) ((ep)[1])
static VALUE check_env_value(VALUE envval); static VALUE check_env_value(VALUE envval);
static int static int
@ -462,9 +460,9 @@ check_env(rb_env_t * const env)
fprintf(stderr, "envval: %10p ", (void *)env->block.ep[1]); fprintf(stderr, "envval: %10p ", (void *)env->block.ep[1]);
dp(env->block.ep[1]); dp(env->block.ep[1]);
fprintf(stderr, "ep: %10p\n", (void *)env->block.ep); fprintf(stderr, "ep: %10p\n", (void *)env->block.ep);
if (env->prev_envval) { if (rb_vm_env_prev_envval(env)) {
fprintf(stderr, ">>\n"); fprintf(stderr, ">>\n");
check_env_value(env->prev_envval); check_env_value(rb_vm_env_prev_envval(env));
fprintf(stderr, "<<\n"); fprintf(stderr, "<<\n");
} }
return 1; return 1;
@ -499,23 +497,20 @@ vm_make_proc_from_block(rb_thread_t *th, rb_block_t *block)
static VALUE static VALUE
vm_make_env_each(rb_thread_t *const th, rb_control_frame_t *const cfp) vm_make_env_each(rb_thread_t *const th, rb_control_frame_t *const cfp)
{ {
VALUE envval, penvval = 0, blockprocval = 0; VALUE envval, blockprocval = 0;
VALUE * const ep = cfp->ep; VALUE * const ep = cfp->ep;
rb_env_t *env; rb_env_t *env;
VALUE *new_ep; VALUE *new_ep;
int i, local_size, env_size; int i, local_size, env_size;
if (ENV_IN_HEAP_P(th, ep)) { if (VM_EP_IN_HEAP_P(th, ep)) {
return ENV_VAL(ep); return VM_ENV_EP_ENVVAL(ep);
} }
if (!VM_EP_LEP_P(ep)) { if (!VM_EP_LEP_P(ep)) {
VALUE *prev_ep = VM_EP_PREV_EP(ep); VALUE *prev_ep = VM_EP_PREV_EP(ep);
if (ENV_IN_HEAP_P(th, prev_ep)) { if (!VM_EP_IN_HEAP_P(th, prev_ep)) {
penvval = ENV_VAL(prev_ep);
}
else {
rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
while (prev_cfp->ep != prev_ep) { while (prev_cfp->ep != prev_ep) {
@ -523,7 +518,7 @@ vm_make_env_each(rb_thread_t *const th, rb_control_frame_t *const cfp)
if (VM_CHECK_MODE > 0 && prev_cfp->ep == 0) rb_bug("invalid ep"); if (VM_CHECK_MODE > 0 && prev_cfp->ep == 0) rb_bug("invalid ep");
} }
penvval = vm_make_env_each(th, prev_cfp); vm_make_env_each(th, prev_cfp);
*ep = VM_ENVVAL_PREV_EP_PTR(prev_cfp->ep); *ep = VM_ENVVAL_PREV_EP_PTR(prev_cfp->ep);
} }
} }
@ -571,9 +566,8 @@ vm_make_env_each(rb_thread_t *const th, rb_control_frame_t *const cfp)
* must happen after TypedData_Wrap_Struct to ensure penvval is markable * must happen after TypedData_Wrap_Struct to ensure penvval is markable
* in case object allocation triggers GC and clobbers penvval. * in case object allocation triggers GC and clobbers penvval.
*/ */
env->prev_envval = penvval;
*ep = envval; /* GC mark */ *ep = envval; /* GC mark */
new_ep = &env->env[i - 1]; new_ep = &env->env[i - 1];
new_ep[1] = envval; new_ep[1] = envval;
if (blockprocval) new_ep[2] = blockprocval; if (blockprocval) new_ep[2] = blockprocval;
@ -614,6 +608,19 @@ rb_vm_stack_to_heap(rb_thread_t *th)
} }
} }
VALUE
rb_vm_env_prev_envval(const rb_env_t *env)
{
const VALUE *ep = env->block.ep;
if (VM_EP_LEP_P(ep)) {
return Qfalse;
}
else {
return VM_ENV_EP_ENVVAL(VM_EP_PREV_EP(ep));
}
}
static int static int
collect_local_variables_in_iseq(const rb_iseq_t *iseq, const struct local_var_list *vars) collect_local_variables_in_iseq(const rb_iseq_t *iseq, const struct local_var_list *vars)
{ {
@ -628,19 +635,19 @@ collect_local_variables_in_iseq(const rb_iseq_t *iseq, const struct local_var_li
static void static void
collect_local_variables_in_env(const rb_env_t *env, const struct local_var_list *vars) collect_local_variables_in_env(const rb_env_t *env, const struct local_var_list *vars)
{ {
VALUE prev_envval;
while (collect_local_variables_in_iseq(env->block.iseq, vars), while (collect_local_variables_in_iseq(env->block.iseq, vars), (prev_envval = rb_vm_env_prev_envval(env)) != Qfalse) {
env->prev_envval) { GetEnvPtr(prev_envval, env);
GetEnvPtr(env->prev_envval, env);
} }
} }
static int static int
vm_collect_local_variables_in_heap(rb_thread_t *th, const VALUE *ep, const struct local_var_list *vars) vm_collect_local_variables_in_heap(rb_thread_t *th, const VALUE *ep, const struct local_var_list *vars)
{ {
if (ENV_IN_HEAP_P(th, ep)) { if (VM_EP_IN_HEAP_P(th, ep)) {
rb_env_t *env; rb_env_t *env;
GetEnvPtr(ENV_VAL(ep), env); GetEnvPtr(VM_ENV_EP_ENVVAL(ep), env);
collect_local_variables_in_env(env, vars); collect_local_variables_in_env(env, vars);
return 1; return 1;
} }
@ -650,12 +657,9 @@ vm_collect_local_variables_in_heap(rb_thread_t *th, const VALUE *ep, const struc
} }
VALUE VALUE
rb_vm_env_local_variables(VALUE envval) rb_vm_env_local_variables(const rb_env_t *env)
{ {
struct local_var_list vars; struct local_var_list vars;
const rb_env_t *env;
GetEnvPtr(envval, env);
local_var_list_init(&vars); local_var_list_init(&vars);
collect_local_variables_in_env(env, &vars); collect_local_variables_in_env(env, &vars);
return local_var_list_finish(&vars); return local_var_list_finish(&vars);

View File

@ -796,7 +796,6 @@ typedef struct {
typedef struct { typedef struct {
int env_size; int env_size;
VALUE prev_envval; /* for GC mark */
rb_block_t block; rb_block_t block;
VALUE env[1]; /* flexible array */ VALUE env[1]; /* flexible array */
} rb_env_t; } rb_env_t;
@ -958,7 +957,8 @@ VALUE rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc,
VALUE rb_vm_make_proc_lambda(rb_thread_t *th, const rb_block_t *block, VALUE klass, int8_t is_lambda); VALUE rb_vm_make_proc_lambda(rb_thread_t *th, const rb_block_t *block, VALUE klass, int8_t is_lambda);
VALUE rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass); VALUE rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass);
VALUE rb_vm_make_binding(rb_thread_t *th, const rb_control_frame_t *src_cfp); VALUE rb_vm_make_binding(rb_thread_t *th, const rb_control_frame_t *src_cfp);
VALUE rb_vm_env_local_variables(VALUE envval); VALUE rb_vm_env_local_variables(const rb_env_t *env);
VALUE rb_vm_env_prev_envval(const rb_env_t *env);
VALUE *rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars); VALUE *rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars);
void rb_vm_inc_const_missing_count(void); void rb_vm_inc_const_missing_count(void);
void rb_vm_gvl_destroy(rb_vm_t *vm); void rb_vm_gvl_destroy(rb_vm_t *vm);

View File

@ -185,6 +185,8 @@ rb_vmdebug_env_dump_raw(rb_env_t *env, VALUE *ep)
fprintf(stderr, "-- env --------------------\n"); fprintf(stderr, "-- env --------------------\n");
while (env) { while (env) {
VALUE prev_envval;
fprintf(stderr, "--\n"); fprintf(stderr, "--\n");
for (i = 0; i < env->env_size; i++) { for (i = 0; i < env->env_size; i++) {
fprintf(stderr, "%04d: %08"PRIxVALUE" (%p)", i, env->env[i], (void *)&env->env[i]); fprintf(stderr, "%04d: %08"PRIxVALUE" (%p)", i, env->env[i], (void *)&env->env[i]);
@ -192,11 +194,11 @@ rb_vmdebug_env_dump_raw(rb_env_t *env, VALUE *ep)
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
if (env->prev_envval != 0) { if ((prev_envval = rb_vm_env_prev_envval(env)) != Qfalse) {
GetEnvPtr(env->prev_envval, env); GetEnvPtr(prev_envval, env);
} }
else { else {
env = 0; env = NULL;
} }
} }
fprintf(stderr, "---------------------------\n"); fprintf(stderr, "---------------------------\n");