Remove `nregs` member from `mrb_callinfo`.

This means reducing one word per a call frame.
parent e89cc9b9
...@@ -123,7 +123,6 @@ typedef struct { ...@@ -123,7 +123,6 @@ typedef struct {
mrb_sym mid; mrb_sym mid;
struct RProc *proc; struct RProc *proc;
mrb_value *stackent; mrb_value *stackent;
int nregs;
int ridx; int ridx;
int epos; int epos;
struct REnv *env; struct REnv *env;
......
...@@ -127,7 +127,6 @@ fiber_init(mrb_state *mrb, mrb_value self) ...@@ -127,7 +127,6 @@ fiber_init(mrb_state *mrb, mrb_value self)
ci->proc = p; ci->proc = p;
mrb_field_write_barrier(mrb, (struct RBasic*)mrb_obj_ptr(self), (struct RBasic*)p); mrb_field_write_barrier(mrb, (struct RBasic*)mrb_obj_ptr(self), (struct RBasic*)p);
ci->pc = p->body.irep->iseq; ci->pc = p->body.irep->iseq;
ci->nregs = p->body.irep->nregs;
ci[1] = ci[0]; ci[1] = ci[0];
c->ci++; /* push dummy callinfo */ c->ci++; /* push dummy callinfo */
......
...@@ -548,21 +548,39 @@ add_gray_list(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) ...@@ -548,21 +548,39 @@ add_gray_list(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
gc->gray_list = obj; gc->gray_list = obj;
} }
static int
ci_nregs(mrb_callinfo *ci)
{
struct RProc *p = ci->proc;
int n = 0;
if (!p) {
if (ci->argc < 0) return 3;
return ci->argc+2;
}
if (!MRB_PROC_CFUNC_P(p) && p->body.irep) {
n = p->body.irep->nregs;
}
if (ci->argc < 0) {
if (n < 3) n = 3; /* self + args + blk */
}
if (ci->argc > n) {
n = ci->argc + 2; /* self + blk */
}
return n;
}
static void static void
mark_context_stack(mrb_state *mrb, struct mrb_context *c) mark_context_stack(mrb_state *mrb, struct mrb_context *c)
{ {
size_t i; size_t i;
size_t e; size_t e;
mrb_value nil; mrb_value nil;
mrb_int nregs;
if (c->stack == NULL) return; if (c->stack == NULL) return;
e = c->stack - c->stbase; e = c->stack - c->stbase;
if (c->ci) { if (c->ci) {
nregs = c->ci->argc + 2; e += ci_nregs(c->ci);
if (c->ci->nregs > nregs)
nregs = c->ci->nregs;
e += nregs;
} }
if (c->stbase + e > c->stend) e = c->stend - c->stbase; if (c->stbase + e > c->stend) e = c->stend - c->stbase;
for (i=0; i<e; i++) { for (i=0; i<e; i++) {
...@@ -950,7 +968,9 @@ gc_gray_mark(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) ...@@ -950,7 +968,9 @@ gc_gray_mark(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
if (!c) break; if (!c) break;
/* mark stack */ /* mark stack */
i = c->stack - c->stbase; i = c->stack - c->stbase;
if (c->ci) i += c->ci->nregs; if (c->ci) {
i += ci_nregs(c->ci);
}
if (c->stbase + i > c->stend) i = c->stend - c->stbase; if (c->stbase + i > c->stend) i = c->stend - c->stbase;
children += i; children += i;
......
...@@ -356,7 +356,6 @@ ecall(mrb_state *mrb) ...@@ -356,7 +356,6 @@ ecall(mrb_state *mrb)
ci->acc = CI_ACC_SKIP; ci->acc = CI_ACC_SKIP;
ci->argc = 0; ci->argc = 0;
ci->proc = p; ci->proc = p;
ci->nregs = p->body.irep->nregs;
ci->target_class = MRB_PROC_TARGET_CLASS(p); ci->target_class = MRB_PROC_TARGET_CLASS(p);
env = MRB_PROC_ENV(p); env = MRB_PROC_ENV(p);
mrb_assert(env); mrb_assert(env);
...@@ -396,6 +395,30 @@ mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, mrb_int argc, ...) ...@@ -396,6 +395,30 @@ mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, mrb_int argc, ...)
return mrb_funcall_argv(mrb, self, mid, argc, argv); return mrb_funcall_argv(mrb, self, mid, argc, argv);
} }
static int
ci_nregs(mrb_callinfo *ci)
{
struct RProc *p;
int n = 0;
if (!ci) return 3;
p = ci->proc;
if (!p) {
if (ci->argc < 0) return 3;
return ci->argc+2;
}
if (!MRB_PROC_CFUNC_P(p) && p->body.irep) {
n = p->body.irep->nregs;
}
if (ci->argc < 0) {
if (n < 3) n = 3; /* self + args + blk */
}
if (ci->argc > n) {
n = ci->argc + 2; /* self + blk */
}
return n;
}
MRB_API mrb_value MRB_API mrb_value
mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, const mrb_value *argv, mrb_value blk) mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, const mrb_value *argv, mrb_value blk)
{ {
...@@ -426,13 +449,12 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc ...@@ -426,13 +449,12 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
mrb_method_t m; mrb_method_t m;
struct RClass *c; struct RClass *c;
mrb_callinfo *ci; mrb_callinfo *ci;
int n; int n = ci_nregs(mrb->c->ci);
ptrdiff_t voff = -1; ptrdiff_t voff = -1;
if (!mrb->c->stack) { if (!mrb->c->stack) {
stack_init(mrb); stack_init(mrb);
} }
n = mrb->c->ci->nregs;
if (argc < 0) { if (argc < 0) {
mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%S)", mrb_fixnum_value(argc)); mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%S)", mrb_fixnum_value(argc));
} }
...@@ -463,22 +485,22 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc ...@@ -463,22 +485,22 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
voff = argv - mrb->c->stbase; voff = argv - mrb->c->stbase;
} }
if (MRB_METHOD_CFUNC_P(m)) { if (MRB_METHOD_CFUNC_P(m)) {
ci->nregs = (int)(argc + 2); mrb_stack_extend(mrb, argc + 2);
mrb_stack_extend(mrb, ci->nregs);
} }
else if (argc >= CALL_MAXARGS) { else if (argc >= CALL_MAXARGS) {
mrb_value args = mrb_ary_new_from_values(mrb, argc, argv); mrb_value args = mrb_ary_new_from_values(mrb, argc, argv);
mrb_stack_extend(mrb, ci->nregs+2);
mrb_stack_extend(mrb, 3);
mrb->c->stack[1] = args; mrb->c->stack[1] = args;
ci->argc = -1; ci->argc = -1;
argc = 1; argc = 1;
} }
else { else {
struct RProc *p = MRB_METHOD_PROC(m); struct RProc *p = MRB_METHOD_PROC(m);
ci->proc = p; ci->proc = p;
if (argc < 0) argc = 1; if (argc < 0) argc = 1;
ci->nregs = (int)(p->body.irep->nregs + argc); mrb_stack_extend(mrb, p->body.irep->nregs + argc);
mrb_stack_extend(mrb, ci->nregs);
} }
if (voff >= 0) { if (voff >= 0) {
argv = mrb->c->stbase + voff; argv = mrb->c->stbase + voff;
...@@ -520,26 +542,25 @@ mrb_value ...@@ -520,26 +542,25 @@ mrb_value
mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p)
{ {
mrb_callinfo *ci = mrb->c->ci; mrb_callinfo *ci = mrb->c->ci;
int keep; int keep, nregs;
mrb->c->stack[0] = self; mrb->c->stack[0] = self;
ci->proc = p; ci->proc = p;
if (MRB_PROC_CFUNC_P(p)) { if (MRB_PROC_CFUNC_P(p)) {
return MRB_PROC_CFUNC(p)(mrb, self); return MRB_PROC_CFUNC(p)(mrb, self);
} }
ci->nregs = p->body.irep->nregs; nregs = p->body.irep->nregs;
if (ci->argc < 0) keep = 3; if (ci->argc < 0) keep = 3;
else keep = ci->argc + 2; else keep = ci->argc + 2;
if (ci->nregs < keep) { if (nregs < keep) {
mrb_stack_extend(mrb, keep); mrb_stack_extend(mrb, keep);
} }
else { else {
mrb_stack_extend(mrb, ci->nregs); mrb_stack_extend(mrb, nregs);
stack_clear(mrb->c->stack+keep, ci->nregs-keep); stack_clear(mrb->c->stack+keep, nregs-keep);
} }
ci = cipush(mrb); ci = cipush(mrb);
ci->nregs = 0;
ci->target_class = 0; ci->target_class = 0;
ci->pc = p->body.irep->iseq; ci->pc = p->body.irep->iseq;
ci->stackent = mrb->c->stack; ci->stackent = mrb->c->stack;
...@@ -618,6 +639,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) ...@@ -618,6 +639,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c)
{ {
struct RProc *p; struct RProc *p;
mrb_callinfo *ci; mrb_callinfo *ci;
int nregs;
if (mrb_nil_p(blk)) { if (mrb_nil_p(blk)) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
...@@ -639,13 +661,12 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) ...@@ -639,13 +661,12 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c)
mrb->c->stack[2] = mrb_nil_value(); mrb->c->stack[2] = mrb_nil_value();
return MRB_PROC_CFUNC(p)(mrb, self); return MRB_PROC_CFUNC(p)(mrb, self);
} }
ci->nregs = p->body.irep->nregs; nregs = p->body.irep->nregs;
mrb_stack_extend(mrb, (ci->nregs < 3) ? 3 : ci->nregs); mrb_stack_extend(mrb, (nregs < 3) ? 3 : nregs);
mrb->c->stack[0] = self; mrb->c->stack[0] = self;
mrb->c->stack[1] = self; mrb->c->stack[1] = self;
mrb->c->stack[2] = mrb_nil_value(); mrb->c->stack[2] = mrb_nil_value();
ci = cipush(mrb); ci = cipush(mrb);
ci->nregs = 0;
ci->target_class = 0; ci->target_class = 0;
ci->pc = p->body.irep->iseq; ci->pc = p->body.irep->iseq;
ci->stackent = mrb->c->stack; ci->stackent = mrb->c->stack;
...@@ -728,13 +749,15 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value ...@@ -728,13 +749,15 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value
struct RProc *p; struct RProc *p;
mrb_sym mid = mrb->c->ci->mid; mrb_sym mid = mrb->c->ci->mid;
mrb_callinfo *ci; mrb_callinfo *ci;
int n = mrb->c->ci->nregs;
mrb_value val; mrb_value val;
int n;
if (mrb_nil_p(b)) { if (mrb_nil_p(b)) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
} }
if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { ci = mrb->c->ci;
n = ci_nregs(ci);
if (ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
} }
p = mrb_proc_ptr(b); p = mrb_proc_ptr(b);
...@@ -745,9 +768,9 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value ...@@ -745,9 +768,9 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value
ci->argc = (int)argc; ci->argc = (int)argc;
ci->target_class = c; ci->target_class = c;
ci->acc = CI_ACC_SKIP; ci->acc = CI_ACC_SKIP;
n = MRB_PROC_CFUNC_P(p) ? (int)(argc+2) : p->body.irep->nregs;
mrb->c->stack = mrb->c->stack + n; mrb->c->stack = mrb->c->stack + n;
ci->nregs = MRB_PROC_CFUNC_P(p) ? (int)(argc+2) : p->body.irep->nregs; mrb_stack_extend(mrb, n);
mrb_stack_extend(mrb, ci->nregs);
mrb->c->stack[0] = self; mrb->c->stack[0] = self;
if (argc > 0) { if (argc > 0) {
...@@ -1009,7 +1032,6 @@ RETRY_TRY_BLOCK: ...@@ -1009,7 +1032,6 @@ RETRY_TRY_BLOCK:
} }
mrb->jmp = &c_jmp; mrb->jmp = &c_jmp;
mrb->c->ci->proc = proc; mrb->c->ci->proc = proc;
mrb->c->ci->nregs = irep->nregs;
#define regs (mrb->c->stack) #define regs (mrb->c->stack)
INIT_DISPATCH { INIT_DISPATCH {
...@@ -1363,6 +1385,8 @@ RETRY_TRY_BLOCK: ...@@ -1363,6 +1385,8 @@ RETRY_TRY_BLOCK:
a = mrb->c->eidx - epos; a = mrb->c->eidx - epos;
pc = pc + 1; pc = pc + 1;
for (n=0; n<a; n++) { for (n=0; n<a; n++) {
int nregs = irep->nregs;
proc = mrb->c->ensure[epos+n]; proc = mrb->c->ensure[epos+n];
mrb->c->ensure[epos+n] = NULL; mrb->c->ensure[epos+n] = NULL;
if (proc == NULL) continue; if (proc == NULL) continue;
...@@ -1372,12 +1396,11 @@ RETRY_TRY_BLOCK: ...@@ -1372,12 +1396,11 @@ RETRY_TRY_BLOCK:
ci->argc = 0; ci->argc = 0;
ci->proc = proc; ci->proc = proc;
ci->stackent = mrb->c->stack; ci->stackent = mrb->c->stack;
ci->nregs = irep->nregs;
ci->target_class = target_class; ci->target_class = target_class;
ci->pc = pc; ci->pc = pc;
ci->acc = ci[-1].nregs; ci->acc = nregs;
mrb->c->stack += ci->acc; mrb->c->stack += ci->acc;
mrb_stack_extend(mrb, ci->nregs); mrb_stack_extend(mrb, irep->nregs);
regs[0] = self; regs[0] = self;
pc = irep->iseq; pc = irep->iseq;
} }
...@@ -1414,7 +1437,7 @@ RETRY_TRY_BLOCK: ...@@ -1414,7 +1437,7 @@ RETRY_TRY_BLOCK:
mrb_value recv, blk; mrb_value recv, blk;
mrb_sym mid = syms[b]; mrb_sym mid = syms[b];
mrb_assert(bidx < ci->nregs); mrb_assert(bidx < irep->nregs);
recv = regs[a]; recv = regs[a];
if (GET_OPCODE(i) != OP_SENDB) { if (GET_OPCODE(i) != OP_SENDB) {
...@@ -1466,7 +1489,6 @@ RETRY_TRY_BLOCK: ...@@ -1466,7 +1489,6 @@ RETRY_TRY_BLOCK:
mrb->c->stack += a; mrb->c->stack += a;
if (MRB_METHOD_CFUNC_P(m)) { if (MRB_METHOD_CFUNC_P(m)) {
ci->nregs = (argc < 0) ? 3 : n+2;
if (MRB_METHOD_PROC_P(m)) { if (MRB_METHOD_PROC_P(m)) {
struct RProc *p = MRB_METHOD_PROC(m); struct RProc *p = MRB_METHOD_PROC(m);
...@@ -1514,8 +1536,7 @@ RETRY_TRY_BLOCK: ...@@ -1514,8 +1536,7 @@ RETRY_TRY_BLOCK:
irep = proc->body.irep; irep = proc->body.irep;
pool = irep->pool; pool = irep->pool;
syms = irep->syms; syms = irep->syms;
ci->nregs = irep->nregs; mrb_stack_extend(mrb, (argc < 0 && irep->nregs < 3) ? 3 : irep->nregs);
mrb_stack_extend(mrb, (argc < 0 && ci->nregs < 3) ? 3 : ci->nregs);
pc = irep->iseq; pc = irep->iseq;
JUMP; JUMP;
} }
...@@ -1575,8 +1596,7 @@ RETRY_TRY_BLOCK: ...@@ -1575,8 +1596,7 @@ RETRY_TRY_BLOCK:
} }
pool = irep->pool; pool = irep->pool;
syms = irep->syms; syms = irep->syms;
ci->nregs = irep->nregs; mrb_stack_extend(mrb, irep->nregs);
mrb_stack_extend(mrb, ci->nregs);
if (ci->argc < 0) { if (ci->argc < 0) {
if (irep->nregs > 3) { if (irep->nregs > 3) {
stack_clear(regs+3, irep->nregs-3); stack_clear(regs+3, irep->nregs-3);
...@@ -1606,7 +1626,7 @@ RETRY_TRY_BLOCK: ...@@ -1606,7 +1626,7 @@ RETRY_TRY_BLOCK:
mrb_sym mid = ci->mid; mrb_sym mid = ci->mid;
struct RClass* target_class = MRB_PROC_TARGET_CLASS(ci->proc); struct RClass* target_class = MRB_PROC_TARGET_CLASS(ci->proc);
mrb_assert(bidx < ci->nregs); mrb_assert(bidx < irep->nregs);
if (mid == 0 || !target_class) { if (mid == 0 || !target_class) {
mrb_value exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method"); mrb_value exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method");
...@@ -1652,7 +1672,7 @@ RETRY_TRY_BLOCK: ...@@ -1652,7 +1672,7 @@ RETRY_TRY_BLOCK:
} }
mid = missing; mid = missing;
if (argc >= 0) { if (argc >= 0) {
if (a+2 >= ci->nregs) { if (a+2 >= irep->nregs) {
mrb_stack_extend(mrb, a+3); mrb_stack_extend(mrb, a+3);
} }
regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1); regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1);
...@@ -1676,7 +1696,7 @@ RETRY_TRY_BLOCK: ...@@ -1676,7 +1696,7 @@ RETRY_TRY_BLOCK:
if (MRB_METHOD_CFUNC_P(m)) { if (MRB_METHOD_CFUNC_P(m)) {
mrb_value v; mrb_value v;
ci->nregs = (argc < 0) ? 3 : n+2;
if (MRB_METHOD_PROC_P(m)) { if (MRB_METHOD_PROC_P(m)) {
ci->proc = MRB_METHOD_PROC(m); ci->proc = MRB_METHOD_PROC(m);
} }
...@@ -1713,8 +1733,7 @@ RETRY_TRY_BLOCK: ...@@ -1713,8 +1733,7 @@ RETRY_TRY_BLOCK:
irep = proc->body.irep; irep = proc->body.irep;
pool = irep->pool; pool = irep->pool;
syms = irep->syms; syms = irep->syms;
ci->nregs = irep->nregs; mrb_stack_extend(mrb, (argc < 0 && irep->nregs < 3) ? 3 : irep->nregs);
mrb_stack_extend(mrb, (argc < 0 && ci->nregs < 3) ? 3 : ci->nregs);
pc = irep->iseq; pc = irep->iseq;
JUMP; JUMP;
} }
...@@ -2884,9 +2903,8 @@ RETRY_TRY_BLOCK: ...@@ -2884,9 +2903,8 @@ RETRY_TRY_BLOCK:
irep = p->body.irep; irep = p->body.irep;
pool = irep->pool; pool = irep->pool;
syms = irep->syms; syms = irep->syms;
ci->nregs = irep->nregs; mrb_stack_extend(mrb, irep->nregs);
mrb_stack_extend(mrb, ci->nregs); stack_clear(regs+1, irep->nregs-1);
stack_clear(regs+1, ci->nregs-1);
pc = irep->iseq; pc = irep->iseq;
JUMP; JUMP;
} }
...@@ -3014,7 +3032,6 @@ mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int sta ...@@ -3014,7 +3032,6 @@ mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int sta
} }
ci = cipush(mrb); ci = cipush(mrb);
ci->mid = 0; ci->mid = 0;
ci->nregs = 1; /* protect the receiver */
ci->acc = CI_ACC_SKIP; ci->acc = CI_ACC_SKIP;
ci->target_class = mrb->object_class; ci->target_class = mrb->object_class;
v = mrb_vm_run(mrb, proc, self, stack_keep); v = mrb_vm_run(mrb, proc, self, stack_keep);
......
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