Commit 74bc53a5 authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto

Merge pull request #1030 from monaka/pr-some-optimizes-to-vm.c-20130318

Some optimizes to vm.c
parents 99b5d43a 3f3568a2
...@@ -209,7 +209,6 @@ mrb_state* mrb_open(void); ...@@ -209,7 +209,6 @@ mrb_state* mrb_open(void);
mrb_state* mrb_open_allocf(mrb_allocf, void *ud); mrb_state* mrb_open_allocf(mrb_allocf, void *ud);
void mrb_irep_free(mrb_state*, struct mrb_irep*); void mrb_irep_free(mrb_state*, struct mrb_irep*);
void mrb_close(mrb_state*); void mrb_close(mrb_state*);
int mrb_checkstack(mrb_state*,int);
mrb_value mrb_top_self(mrb_state *); mrb_value mrb_top_self(mrb_state *);
mrb_value mrb_run(mrb_state*, struct RProc*, mrb_value); mrb_value mrb_run(mrb_state*, struct RProc*, mrb_value);
......
...@@ -108,7 +108,7 @@ stack_init(mrb_state *mrb) ...@@ -108,7 +108,7 @@ stack_init(mrb_state *mrb)
mrb->ci->target_class = mrb->object_class; mrb->ci->target_class = mrb->object_class;
} }
static void static inline void
envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase) envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase)
{ {
mrb_callinfo *ci = mrb->cibase; mrb_callinfo *ci = mrb->cibase;
...@@ -129,8 +129,9 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase) ...@@ -129,8 +129,9 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase)
static void static void
stack_extend(mrb_state *mrb, int room, int keep) stack_extend(mrb_state *mrb, int room, int keep)
{ {
int size, off;
if (mrb->stack + room >= mrb->stend) { if (mrb->stack + room >= mrb->stend) {
int size, off;
mrb_value *oldbase = mrb->stbase; mrb_value *oldbase = mrb->stbase;
size = mrb->stend - mrb->stbase; size = mrb->stend - mrb->stbase;
...@@ -170,14 +171,7 @@ stack_extend(mrb_state *mrb, int room, int keep) ...@@ -170,14 +171,7 @@ stack_extend(mrb_state *mrb, int room, int keep)
} }
} }
int static inline struct REnv*
mrb_checkstack(mrb_state *mrb, int size)
{
stack_extend(mrb, size+1, 1);
return 0;
}
struct REnv*
uvenv(mrb_state *mrb, int up) uvenv(mrb_state *mrb, int up)
{ {
struct REnv *e = mrb->ci->proc->env; struct REnv *e = mrb->ci->proc->env;
...@@ -189,25 +183,6 @@ uvenv(mrb_state *mrb, int up) ...@@ -189,25 +183,6 @@ uvenv(mrb_state *mrb, int up)
return e; return e;
} }
static mrb_value
uvget(mrb_state *mrb, int up, int idx)
{
struct REnv *e = uvenv(mrb, up);
if (!e) return mrb_nil_value();
return e->stack[idx];
}
static void
uvset(mrb_state *mrb, int up, int idx, mrb_value v)
{
struct REnv *e = uvenv(mrb, up);
if (!e) return;
e->stack[idx] = v;
mrb_write_barrier(mrb, (struct RBasic*)e);
}
static inline int static inline int
is_strict(mrb_state *mrb, struct REnv *e) is_strict(mrb_state *mrb, struct REnv *e)
{ {
...@@ -220,7 +195,7 @@ is_strict(mrb_state *mrb, struct REnv *e) ...@@ -220,7 +195,7 @@ is_strict(mrb_state *mrb, struct REnv *e)
return 0; return 0;
} }
struct REnv* inline struct REnv*
top_env(mrb_state *mrb, struct RProc *proc) top_env(mrb_state *mrb, struct RProc *proc)
{ {
struct REnv *e = proc->env; struct REnv *e = proc->env;
...@@ -301,14 +276,13 @@ mrb_value ...@@ -301,14 +276,13 @@ mrb_value
mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...) mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...)
{ {
mrb_sym mid = mrb_intern(mrb, name); mrb_sym mid = mrb_intern(mrb, name);
va_list ap;
int i;
if (argc == 0) { if (argc == 0) {
return mrb_funcall_argv(mrb, self, mid, 0, 0); return mrb_funcall_argv(mrb, self, mid, 0, 0);
} }
else if (argc == 1) { else if (argc == 1) {
mrb_value v; mrb_value v;
va_list ap;
va_start(ap, argc); va_start(ap, argc);
v = va_arg(ap, mrb_value); v = va_arg(ap, mrb_value);
...@@ -317,6 +291,8 @@ mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...) ...@@ -317,6 +291,8 @@ mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...)
} }
else { else {
mrb_value argv[MRB_FUNCALL_ARGC_MAX]; mrb_value argv[MRB_FUNCALL_ARGC_MAX];
va_list ap;
int i;
if (argc > MRB_FUNCALL_ARGC_MAX) { if (argc > MRB_FUNCALL_ARGC_MAX) {
mrb_raisef(mrb, E_ARGUMENT_ERROR, "Too long arguments. (limit=%d)", MRB_FUNCALL_ARGC_MAX); mrb_raisef(mrb, E_ARGUMENT_ERROR, "Too long arguments. (limit=%d)", MRB_FUNCALL_ARGC_MAX);
...@@ -334,11 +310,6 @@ mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...) ...@@ -334,11 +310,6 @@ mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...)
mrb_value mrb_value
mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mrb_value *argv, mrb_value blk) mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mrb_value *argv, mrb_value blk)
{ {
struct RProc *p;
struct RClass *c;
mrb_sym undef = 0;
mrb_callinfo *ci;
int n;
mrb_value val; mrb_value val;
if (!mrb->jmp) { if (!mrb->jmp) {
...@@ -351,14 +322,21 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mr ...@@ -351,14 +322,21 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mr
cipop(mrb); cipop(mrb);
} }
mrb->jmp = 0; mrb->jmp = 0;
return mrb_nil_value(); val = mrb_nil_value();
} }
else {
mrb->jmp = &c_jmp; mrb->jmp = &c_jmp;
/* recursive call */ /* recursive call */
val = mrb_funcall_with_block(mrb, self, mid, argc, argv, blk); val = mrb_funcall_with_block(mrb, self, mid, argc, argv, blk);
mrb->jmp = 0; mrb->jmp = 0;
return val;
} }
}
else {
struct RProc *p;
struct RClass *c;
mrb_sym undef = 0;
mrb_callinfo *ci;
int n;
if (!mrb->stack) { if (!mrb->stack) {
stack_init(mrb); stack_init(mrb);
...@@ -412,6 +390,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mr ...@@ -412,6 +390,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mr
else { else {
val = mrb_run(mrb, p, self); val = mrb_run(mrb, p, self);
} }
}
return val; return val;
} }
...@@ -737,14 +716,34 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ...@@ -737,14 +716,34 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
CASE(OP_GETUPVAR) { CASE(OP_GETUPVAR) {
/* A B C R(A) := uvget(B,C) */ /* A B C R(A) := uvget(B,C) */
mrb_value *regs_a = regs + GETARG_A(i);
int up = GETARG_C(i);
struct REnv *e = uvenv(mrb, up);
regs[GETARG_A(i)] = uvget(mrb, GETARG_C(i), GETARG_B(i)); if (!e) {
*regs_a = mrb_nil_value();
}
else {
int idx = GETARG_B(i);
*regs_a = e->stack[idx];
}
NEXT; NEXT;
} }
CASE(OP_SETUPVAR) { CASE(OP_SETUPVAR) {
/* A B C uvset(B,C,R(A)) */ /* A B C uvset(B,C,R(A)) */
uvset(mrb, GETARG_C(i), GETARG_B(i), regs[GETARG_A(i)]); /* A B C R(A) := uvget(B,C) */
int up = GETARG_C(i);
struct REnv *e = uvenv(mrb, up);
if (e) {
mrb_value *regs_a = regs + GETARG_A(i);
int idx = GETARG_B(i);
e->stack[idx] = *regs_a;
mrb_write_barrier(mrb, (struct RBasic*)e);
}
NEXT; NEXT;
} }
...@@ -876,9 +875,8 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ...@@ -876,9 +875,8 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
mrb_ary_unshift(mrb, regs[a+1], sym); mrb_ary_unshift(mrb, regs[a+1], sym);
} }
else { else {
value_move(regs+a+2, regs+a+1, n+1); value_move(regs+a+2, regs+a+1, ++n);
regs[a+1] = sym; regs[a+1] = sym;
n++;
} }
} }
...@@ -887,8 +885,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ...@@ -887,8 +885,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
ci->mid = mid; ci->mid = mid;
ci->proc = m; ci->proc = m;
ci->stackidx = mrb->stack - mrb->stbase; ci->stackidx = mrb->stack - mrb->stbase;
if (n == CALL_MAXARGS) {
ci->argc = -1;
}
else {
ci->argc = n; ci->argc = n;
if (ci->argc == CALL_MAXARGS) ci->argc = -1; }
ci->target_class = c; ci->target_class = c;
ci->pc = pc + 1; ci->pc = pc + 1;
ci->acc = a; ci->acc = a;
...@@ -1015,9 +1017,8 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ...@@ -1015,9 +1017,8 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid)); mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid));
} }
else { else {
value_move(regs+a+2, regs+a+1, n+1); value_move(regs+a+2, regs+a+1, ++n);
SET_SYM_VALUE(regs[a+1], ci->mid); SET_SYM_VALUE(regs[a+1], ci->mid);
n++;
} }
} }
...@@ -1026,8 +1027,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ...@@ -1026,8 +1027,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
ci->mid = mid; ci->mid = mid;
ci->proc = m; ci->proc = m;
ci->stackidx = mrb->stack - mrb->stbase; ci->stackidx = mrb->stack - mrb->stbase;
if (n == CALL_MAXARGS) {
ci->argc = -1;
}
else {
ci->argc = n; ci->argc = n;
if (ci->argc == CALL_MAXARGS) ci->argc = -1; }
ci->target_class = m->target_class; ci->target_class = m->target_class;
ci->pc = pc + 1; ci->pc = pc + 1;
...@@ -1054,7 +1059,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ...@@ -1054,7 +1059,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
pool = irep->pool; pool = irep->pool;
syms = irep->syms; syms = irep->syms;
ci->nregs = irep->nregs; ci->nregs = irep->nregs;
if (ci->argc < 0) { if (n == CALL_MAXARGS) {
stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs, 3); stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs, 3);
} }
else { else {
...@@ -1334,9 +1339,8 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ...@@ -1334,9 +1339,8 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
mrb_ary_unshift(mrb, regs[a+1], sym); mrb_ary_unshift(mrb, regs[a+1], sym);
} }
else { else {
value_move(regs+a+2, regs+a+1, n+1); value_move(regs+a+2, regs+a+1, ++n);
regs[a+1] = sym; regs[a+1] = sym;
n++;
} }
} }
...@@ -1345,8 +1349,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ...@@ -1345,8 +1349,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
ci = mrb->ci; ci = mrb->ci;
ci->mid = mid; ci->mid = mid;
ci->target_class = m->target_class; ci->target_class = m->target_class;
if (n == CALL_MAXARGS) {
ci->argc = -1;
}
else {
ci->argc = n; ci->argc = n;
if (ci->argc == CALL_MAXARGS) ci->argc = -1; }
/* move stack */ /* move stack */
value_move(mrb->stack, &regs[a], ci->argc+1); value_move(mrb->stack, &regs[a], ci->argc+1);
...@@ -1403,7 +1411,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ...@@ -1403,7 +1411,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
#define attr_f value.f #define attr_f value.f
#endif #endif
#define TYPES2(a,b) (((((int)(a))<<8)|((int)(b)))&0xffff) #define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff))
#define OP_MATH_BODY(op,v1,v2) do {\ #define OP_MATH_BODY(op,v1,v2) do {\
regs[a].v1 = regs[a].v1 op regs[a+1].v2;\ regs[a].v1 = regs[a].v1 op regs[a+1].v2;\
} while(0) } while(0)
...@@ -1417,16 +1425,18 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ...@@ -1417,16 +1425,18 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
{ {
mrb_int x, y, z; mrb_int x, y, z;
mrb_value *regs_a = regs + a;
x = mrb_fixnum(regs[a]); x = mrb_fixnum(regs_a[0]);
y = mrb_fixnum(regs[a+1]); y = mrb_fixnum(regs_a[1]);
z = x + y; z = x + y;
if (((x < 0) ^ (y < 0)) == 0 && (x < 0) != (z < 0)) { if ((x < 0) != (z < 0) && ((x < 0) ^ (y < 0)) == 0) {
/* integer overflow */ /* integer overflow */
SET_FLT_VALUE(regs[a], (mrb_float)x + (mrb_float)y); SET_FLT_VALUE(regs_a[0], (mrb_float)x + (mrb_float)y);
break; }
else {
regs_a[0].attr_i = z;
} }
SET_INT_VALUE(regs[a], z);
} }
break; break;
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
...@@ -1598,28 +1608,30 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ...@@ -1598,28 +1608,30 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
CASE(OP_SUBI) { CASE(OP_SUBI) {
/* A B C R(A) := R(A)-C (Syms[B]=:+)*/ /* A B C R(A) := R(A)-C (Syms[B]=:+)*/
int a = GETARG_A(i); int a = GETARG_A(i);
mrb_value *regs_a = regs + a;
/* need to check if + is overridden */ /* need to check if + is overridden */
switch (mrb_type(regs[a])) { switch (mrb_type(regs_a[0])) {
case MRB_TT_FIXNUM: case MRB_TT_FIXNUM:
{ {
mrb_int x = regs[a].attr_i; mrb_int x = regs_a[0].attr_i;
mrb_int y = GETARG_C(i); mrb_int y = GETARG_C(i);
mrb_int z = x - y; mrb_int z = x - y;
if (((x < 0) ^ (y < 0)) != 0 && (x < 0) != (z < 0)) { if ((x < 0) != (z < 0) && ((x < 0) ^ (y < 0)) != 0) {
/* integer overflow */ /* integer overflow */
SET_FLT_VALUE(regs[a], (mrb_float)x - (mrb_float)y); SET_FLT_VALUE(regs_a[0], (mrb_float)x - (mrb_float)y);
break; }
else {
regs_a[0].attr_i = z;
} }
regs[a].attr_i = z;
} }
break; break;
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
regs[a].attr_f -= GETARG_C(i); regs_a[0].attr_f -= GETARG_C(i);
break; break;
default: default:
SET_INT_VALUE(regs[a+1], GETARG_C(i)); SET_INT_VALUE(regs_a[1], GETARG_C(i));
i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1); i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1);
goto L_SEND; goto L_SEND;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment