* [PATCH] vm_core.h (rb_env_t): use flexible array
@ 2014-09-08 10:44 Eric Wong
0 siblings, 0 replies; only message in thread
From: Eric Wong @ 2014-09-08 10:44 UTC (permalink / raw)
To: misc; +Cc: Eric Wong
This reduces allocations and speeds up the lambda calculus fizzbuzz
benchmark.
---
proc.c | 2 +-
vm.c | 40 ++++++++++++++++------------------------
vm_core.h | 2 +-
3 files changed, 18 insertions(+), 26 deletions(-)
diff --git a/proc.c b/proc.c
index a98bc4b..63e2319 100644
--- a/proc.c
+++ b/proc.c
@@ -401,7 +401,7 @@ bind_eval(int argc, VALUE *argv, VALUE bindval)
static VALUE *
get_local_variable_ptr(VALUE envval, ID lid)
{
- const rb_env_t *env;
+ rb_env_t *env;
do {
const rb_iseq_t *iseq;
diff --git a/vm.c b/vm.c
index f43228f..7738220 100644
--- a/vm.c
+++ b/vm.c
@@ -354,11 +354,9 @@ env_mark(void * const ptr)
if (ptr) {
const rb_env_t * const env = ptr;
- if (env->env) {
- /* TODO: should mark more restricted range */
- RUBY_GC_INFO("env->env\n");
- rb_gc_mark_locations(env->env, env->env + env->env_size);
- }
+ /* TODO: should mark more restricted range */
+ RUBY_GC_INFO("env->env\n");
+ rb_gc_mark_locations(env->env, env->env + env->env_size);
RUBY_GC_INFO("env->prev_envval\n");
RUBY_MARK_UNLESS_NULL(env->prev_envval);
@@ -382,8 +380,6 @@ env_free(void * const ptr)
{
RUBY_FREE_ENTER("env");
if (ptr) {
- rb_env_t *const env = ptr;
- RUBY_FREE_UNLESS_NULL(env->env);
ruby_xfree(ptr);
}
RUBY_FREE_LEAVE("env");
@@ -395,9 +391,8 @@ env_memsize(const void *ptr)
if (ptr) {
const rb_env_t * const env = ptr;
size_t size = sizeof(rb_env_t);
- if (env->env) {
- size += env->env_size * sizeof(VALUE);
- }
+
+ size += (env->env_size - 1) * sizeof(VALUE);
return size;
}
return 0;
@@ -410,15 +405,15 @@ static const rb_data_type_t env_data_type = {
};
static VALUE
-env_alloc(void)
+env_alloc(int local_size)
{
- VALUE obj;
rb_env_t *env;
- obj = TypedData_Make_Struct(rb_cEnv, rb_env_t, &env_data_type, env);
- env->env = 0;
- env->prev_envval = 0;
- env->block.iseq = 0;
- return obj;
+
+ 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);
@@ -485,10 +480,6 @@ vm_make_env_each(const rb_thread_t *const th, rb_control_frame_t *const cfp,
}
}
- /* allocate env */
- envval = env_alloc();
- GetEnvPtr(envval, env);
-
if (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
local_size = 2;
}
@@ -496,9 +487,10 @@ vm_make_env_each(const rb_thread_t *const th, rb_control_frame_t *const cfp,
local_size = cfp->iseq->local_size;
}
- env->env_size = local_size + 1 + 1;
- env->local_size = local_size;
- env->env = ALLOC_N(VALUE, env->env_size);
+ /* allocate env */
+ envval = env_alloc(local_size);
+ GetEnvPtr(envval, env);
+
env->prev_envval = penvval;
for (i = 0; i <= local_size; i++) {
diff --git a/vm_core.h b/vm_core.h
index 1afa1b2..939fd87 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -753,11 +753,11 @@ typedef struct {
GetCoreDataFromValue((obj), rb_env_t, (ptr))
typedef struct {
- VALUE *env;
int env_size;
int local_size;
VALUE prev_envval; /* for GC mark */
rb_block_t block;
+ VALUE env[1]; /* flexible array */
} rb_env_t;
extern const rb_data_type_t ruby_binding_data_type;
--
EW
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2014-09-08 10:44 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-08 10:44 [PATCH] vm_core.h (rb_env_t): use flexible array Eric Wong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).