cache gref slot

This commit is contained in:
Yuichi Nishiwaki 2015-07-07 14:42:50 +09:00
parent d53f0cf9e4
commit 1e104921eb
4 changed files with 53 additions and 45 deletions

View File

@ -578,9 +578,6 @@ typedef struct codegen_context {
/* constant object pool */ /* constant object pool */
pic_value *pool; pic_value *pool;
size_t plen, pcapa; size_t plen, pcapa;
/* symbol pool */
pic_sym **syms;
size_t slen, scapa;
struct codegen_context *up; struct codegen_context *up;
} codegen_context; } codegen_context;
@ -609,10 +606,6 @@ codegen_context_init(pic_state *pic, codegen_context *cxt, codegen_context *up,
cxt->plen = 0; cxt->plen = 0;
cxt->pcapa = PIC_POOL_SIZE; cxt->pcapa = PIC_POOL_SIZE;
cxt->syms = pic_calloc(pic, PIC_SYMS_SIZE, sizeof(pic_sym *));
cxt->slen = 0;
cxt->scapa = PIC_SYMS_SIZE;
create_activation(pic, cxt); create_activation(pic, cxt);
} }
@ -633,8 +626,6 @@ codegen_context_destroy(pic_state *pic, codegen_context *cxt)
irep->ilen = cxt->ilen; irep->ilen = cxt->ilen;
irep->pool = pic_realloc(pic, cxt->pool, sizeof(pic_value) * cxt->plen); irep->pool = pic_realloc(pic, cxt->pool, sizeof(pic_value) * cxt->plen);
irep->plen = cxt->plen; irep->plen = cxt->plen;
irep->syms = pic_realloc(pic, cxt->syms, sizeof(pic_sym *) * cxt->slen);
irep->slen = cxt->slen;
return irep; return irep;
} }
@ -647,7 +638,6 @@ codegen_context_destroy(pic_state *pic, codegen_context *cxt)
} while (0) } while (0)
#define check_code_size(pic, cxt) check_size(pic, cxt, c, code, pic_code) #define check_code_size(pic, cxt) check_size(pic, cxt, c, code, pic_code)
#define check_syms_size(pic, cxt) check_size(pic, cxt, s, syms, pic_sym *)
#define check_irep_size(pic, cxt) check_size(pic, cxt, i, irep, struct pic_irep *) #define check_irep_size(pic, cxt) check_size(pic, cxt, i, irep, struct pic_irep *)
#define check_pool_size(pic, cxt) check_size(pic, cxt, p, pool, pic_value) #define check_pool_size(pic, cxt) check_size(pic, cxt, p, pool, pic_value)
@ -716,18 +706,19 @@ index_local(codegen_context *cxt, pic_sym *sym)
} }
static int static int
index_symbol(pic_state *pic, codegen_context *cxt, pic_sym *sym) index_global(pic_state *pic, codegen_context *cxt, pic_sym *name)
{ {
size_t i; extern pic_value pic_vm_gref_slot(pic_state *, pic_sym *);
int pidx;
pic_value slot;
for (i = 0; i < cxt->slen; ++i) { slot = pic_vm_gref_slot(pic, name);
if (cxt->syms[i] == sym) {
return i; check_pool_size(pic, cxt);
} pidx = (int)cxt->plen++;
} cxt->pool[pidx] = slot;
check_syms_size(pic, cxt);
cxt->syms[cxt->slen++] = sym; return pidx;
return i;
} }
static void static void
@ -758,7 +749,10 @@ codegen_ref(pic_state *pic, codegen_context *cxt, pic_value obj, bool tailpos)
sym = pic_sym_ptr(pic_car(pic, obj)); sym = pic_sym_ptr(pic_car(pic, obj));
if (sym == pic->sGREF) { if (sym == pic->sGREF) {
emit_i(pic, cxt, OP_GREF, index_symbol(pic, cxt, pic_sym_ptr(pic_list_ref(pic, obj, 1)))); pic_sym *name;
name = pic_sym_ptr(pic_list_ref(pic, obj, 1));
emit_i(pic, cxt, OP_GREF, index_global(pic, cxt, name));
emit_ret(pic, cxt, tailpos); emit_ret(pic, cxt, tailpos);
} }
else if (sym == pic->sCREF) { else if (sym == pic->sCREF) {
@ -797,7 +791,10 @@ codegen_set(pic_state *pic, codegen_context *cxt, pic_value obj, bool tailpos)
var = pic_list_ref(pic, obj, 1); var = pic_list_ref(pic, obj, 1);
type = pic_sym_ptr(pic_list_ref(pic, var, 0)); type = pic_sym_ptr(pic_list_ref(pic, var, 0));
if (type == pic->sGREF) { if (type == pic->sGREF) {
emit_i(pic, cxt, OP_GSET, index_symbol(pic, cxt, pic_sym_ptr(pic_list_ref(pic, var, 1)))); pic_sym *name;
name = pic_sym_ptr(pic_list_ref(pic, var, 1));
emit_i(pic, cxt, OP_GSET, index_global(pic, cxt, name));
emit_ret(pic, cxt, tailpos); emit_ret(pic, cxt, tailpos);
} }
else if (type == pic->sCREF) { else if (type == pic->sCREF) {

View File

@ -435,9 +435,6 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
for (i = 0; i < irep->plen; ++i) { for (i = 0; i < irep->plen; ++i) {
gc_mark(pic, irep->pool[i]); gc_mark(pic, irep->pool[i]);
} }
for (i = 0; i < irep->slen; ++i) {
gc_mark_object(pic, (struct pic_object *)irep->syms[i]);
}
break; break;
} }
case PIC_TT_DATA: { case PIC_TT_DATA: {
@ -712,7 +709,6 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj)
pic_free(pic, irep->code); pic_free(pic, irep->code);
pic_free(pic, irep->irep); pic_free(pic, irep->irep);
pic_free(pic, irep->pool); pic_free(pic, irep->pool);
pic_free(pic, irep->syms);
break; break;
} }
case PIC_TT_DATA: { case PIC_TT_DATA: {

View File

@ -74,7 +74,6 @@ struct pic_irep {
bool varg; bool varg;
struct pic_irep **irep; struct pic_irep **irep;
pic_value *pool; pic_value *pool;
pic_sym **syms;
size_t clen, ilen, plen, slen; size_t clen, ilen, plen, slen;
}; };

View File

@ -389,6 +389,34 @@ pic_get_args(pic_state *pic, const char *format, ...)
return argc; return argc;
} }
pic_value
pic_vm_gref_slot(pic_state *pic, pic_sym *uid)
{
pic_value slot;
if (pic_dict_has(pic, pic->globals, uid)) {
return pic_dict_ref(pic, pic->globals, uid);
}
slot = pic_cons(pic, pic_obj_value(uid), pic_invalid_value());
pic_dict_set(pic, pic->globals, uid, slot);
return slot;
}
static pic_value
vm_gref(pic_state *pic, pic_value slot)
{
if (pic_invalid_p(pic_cdr(pic, slot))) {
pic_errorf(pic, "uninitialized global variable: ~a", pic_car(pic, slot));
}
return pic_cdr(pic, slot);
}
static void
vm_gset(pic_state *pic, pic_value slot, pic_value value)
{
pic_set_cdr(pic, slot, value);
}
static void static void
vm_push_cxt(pic_state *pic) vm_push_cxt(pic_state *pic)
{ {
@ -605,23 +633,11 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
NEXT; NEXT;
} }
CASE(OP_GREF) { CASE(OP_GREF) {
pic_sym *sym; PUSH(vm_gref(pic, pic->ci->irep->pool[c.u.i]));
sym = pic->ci->irep->syms[c.u.i];
if (! pic_dict_has(pic, pic->globals, sym)) {
pic_errorf(pic, "uninitialized global variable: %s", pic_symbol_name(pic, sym));
}
PUSH(pic_dict_ref(pic, pic->globals, sym));
NEXT; NEXT;
} }
CASE(OP_GSET) { CASE(OP_GSET) {
pic_sym *sym; vm_gset(pic, pic->ci->irep->pool[c.u.i], POP());
pic_value val;
sym = pic->ci->irep->syms[c.u.i];
val = POP();
pic_dict_set(pic, pic->globals, sym, val);
PUSH(pic_undef_value()); PUSH(pic_undef_value());
NEXT; NEXT;
} }
@ -840,7 +856,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
} }
#define check_condition(name, n) do { \ #define check_condition(name, n) do { \
if (! pic_eq_p(pic->p##name, pic_dict_ref(pic, pic->globals, pic->u##name))) \ if (! pic_eq_p(pic->p##name, vm_gref(pic, pic_vm_gref_slot(pic, pic->u##name)))) \
goto L_CALL; \ goto L_CALL; \
if (c.u.i != n + 1) \ if (c.u.i != n + 1) \
goto L_CALL; \ goto L_CALL; \
@ -1106,7 +1122,7 @@ pic_define_(pic_state *pic, const char *name, pic_value val)
} }
} }
pic_dict_set(pic, pic->globals, uid, val); pic_set(pic, pic->lib, name, val);
} }
void void
@ -1153,7 +1169,7 @@ pic_ref(pic_state *pic, struct pic_lib *lib, const char *name)
pic_errorf(pic, "symbol \"%s\" not defined in library ~s", name, lib->name); pic_errorf(pic, "symbol \"%s\" not defined in library ~s", name, lib->name);
} }
return pic_dict_ref(pic, pic->globals, uid); return vm_gref(pic, pic_vm_gref_slot(pic, uid));
} }
void void
@ -1167,7 +1183,7 @@ pic_set(pic_state *pic, struct pic_lib *lib, const char *name, pic_value val)
pic_errorf(pic, "symbol \"%s\" not defined in library ~s", name, lib->name); pic_errorf(pic, "symbol \"%s\" not defined in library ~s", name, lib->name);
} }
pic_dict_set(pic, pic->globals, uid, val); vm_gset(pic, pic_vm_gref_slot(pic, uid), val);
} }
pic_value pic_value