manage ireps using reference count
This commit is contained in:
		
							parent
							
								
									6488e315d3
								
							
						
					
					
						commit
						64788af4b9
					
				|  | @ -694,7 +694,8 @@ codegen_context_destroy(pic_state *pic, codegen_context *cxt) | |||
|   struct pic_irep *irep; | ||||
| 
 | ||||
|   /* create irep */ | ||||
|   irep = (struct pic_irep *)pic_obj_alloc(pic, sizeof(struct pic_irep), PIC_TT_IREP); | ||||
|   irep = pic_malloc(pic, sizeof(struct pic_irep)); | ||||
|   irep->refc = 1; | ||||
|   irep->varg = cxt->rest != NULL; | ||||
|   irep->argc = (int)cxt->args->len + 1; | ||||
|   irep->localc = (int)cxt->locals->len; | ||||
|  | @ -705,6 +706,11 @@ codegen_context_destroy(pic_state *pic, codegen_context *cxt) | |||
|   irep->pool = pic_realloc(pic, cxt->pool, sizeof(pic_value) * cxt->plen); | ||||
|   irep->plen = cxt->plen; | ||||
| 
 | ||||
|   irep->list.next = pic->ireps.next; | ||||
|   irep->list.prev = &pic->ireps; | ||||
|   irep->list.next->prev = &irep->list; | ||||
|   irep->list.prev->next = &irep->list; | ||||
| 
 | ||||
|   return irep; | ||||
| } | ||||
| 
 | ||||
|  | @ -1086,6 +1092,7 @@ struct pic_proc * | |||
| pic_compile(pic_state *pic, pic_value obj, struct pic_env *env) | ||||
| { | ||||
|   struct pic_irep *irep; | ||||
|   struct pic_proc *proc; | ||||
|   size_t ai = pic_gc_arena_preserve(pic); | ||||
| 
 | ||||
| #if DEBUG | ||||
|  | @ -1143,7 +1150,9 @@ pic_compile(pic_state *pic, pic_value obj, struct pic_env *env) | |||
|   puts(""); | ||||
| #endif | ||||
| 
 | ||||
|   SAVE(pic, ai, pic_obj_value(irep)); | ||||
|   proc = pic_make_proc_irep(pic, irep, NULL); | ||||
| 
 | ||||
|   return pic_make_proc_irep(pic, irep, NULL); | ||||
|   pic_irep_decref(pic, irep); | ||||
| 
 | ||||
|   return proc; | ||||
| } | ||||
|  |  | |||
|  | @ -32,7 +32,6 @@ struct pic_object { | |||
|     struct pic_env env; | ||||
|     struct pic_proc proc; | ||||
|     struct pic_context cxt; | ||||
|     struct pic_irep irep; | ||||
|     struct pic_port port; | ||||
|     struct pic_error err; | ||||
|     struct pic_lib lib; | ||||
|  | @ -300,7 +299,6 @@ gc_mark_object(pic_state *pic, struct pic_object *obj) | |||
|   } | ||||
|   case PIC_TT_PROC: { | ||||
|     if (pic_proc_irep_p(&obj->u.proc)) { | ||||
|       gc_mark_object(pic, (struct pic_object *)obj->u.proc.u.i.irep); | ||||
|       if (obj->u.proc.u.i.cxt) { | ||||
|         LOOP(obj->u.proc.u.i.cxt); | ||||
|       } | ||||
|  | @ -360,17 +358,6 @@ gc_mark_object(pic_state *pic, struct pic_object *obj) | |||
|     LOOP(obj->u.lib.exports); | ||||
|     break; | ||||
|   } | ||||
|   case PIC_TT_IREP: { | ||||
|     size_t i; | ||||
| 
 | ||||
|     for (i = 0; i < obj->u.irep.ilen; ++i) { | ||||
|       gc_mark_object(pic, (struct pic_object *)obj->u.irep.irep[i]); | ||||
|     } | ||||
|     for (i = 0; i < obj->u.irep.plen; ++i) { | ||||
|       gc_mark(pic, obj->u.irep.pool[i]); | ||||
|     } | ||||
|     break; | ||||
|   } | ||||
|   case PIC_TT_DATA: { | ||||
|     if (obj->u.data.type->mark) { | ||||
|       obj->u.data.type->mark(pic, obj->u.data.data, gc_mark); | ||||
|  | @ -441,6 +428,7 @@ gc_mark_phase(pic_state *pic) | |||
|   pic_value *stack; | ||||
|   pic_callinfo *ci; | ||||
|   struct pic_proc **xhandler; | ||||
|   struct pic_list *list; | ||||
|   size_t j; | ||||
| 
 | ||||
|   assert(pic->heap->regs == NULL); | ||||
|  | @ -472,6 +460,14 @@ gc_mark_phase(pic_state *pic) | |||
|     gc_mark_object(pic, (struct pic_object *)pic->arena[j]); | ||||
|   } | ||||
| 
 | ||||
|   /* ireps */ | ||||
|   for (list = pic->ireps.next; list != &pic->ireps; list = list->next) { | ||||
|     struct pic_irep *irep = (struct pic_irep *)list; | ||||
|     for (j = 0; j < irep->plen; ++j) { | ||||
|       gc_mark(pic, irep->pool[j]); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /* mark reserved symbols */ | ||||
|   M(sQUOTE); M(sQUASIQUOTE); M(sUNQUOTE); M(sUNQUOTE_SPLICING); | ||||
|   M(sSYNTAX_QUOTE); M(sSYNTAX_QUASIQUOTE); M(sSYNTAX_UNQUOTE); M(sSYNTAX_UNQUOTE_SPLICING); | ||||
|  | @ -564,12 +560,6 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj) | |||
|     kh_destroy(env, &obj->u.env.map); | ||||
|     break; | ||||
|   } | ||||
|   case PIC_TT_IREP: { | ||||
|     pic_free(pic, obj->u.irep.code); | ||||
|     pic_free(pic, obj->u.irep.irep); | ||||
|     pic_free(pic, obj->u.irep.pool); | ||||
|     break; | ||||
|   } | ||||
|   case PIC_TT_DATA: { | ||||
|     if (obj->u.data.type->dtor) { | ||||
|       obj->u.data.type->dtor(pic, obj->u.data.data); | ||||
|  | @ -588,10 +578,15 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj) | |||
|     kh_destroy(reg, &obj->u.reg.hash); | ||||
|     break; | ||||
|   } | ||||
|   case PIC_TT_PROC: { | ||||
|     if (pic_proc_irep_p(&obj->u.proc)) { | ||||
|       pic_irep_decref(pic, obj->u.proc.u.i.irep); | ||||
|     } | ||||
|     break; | ||||
|   } | ||||
| 
 | ||||
|   case PIC_TT_PAIR: | ||||
|   case PIC_TT_CXT: | ||||
|   case PIC_TT_PROC: | ||||
|   case PIC_TT_PORT: | ||||
|   case PIC_TT_ERROR: | ||||
|   case PIC_TT_ID: | ||||
|  |  | |||
|  | @ -121,6 +121,7 @@ struct pic_state { | |||
|   struct pic_reg *globals; | ||||
|   struct pic_reg *macros; | ||||
|   pic_value libs; | ||||
|   struct pic_list ireps;        /* chain */ | ||||
| 
 | ||||
|   pic_reader reader; | ||||
|   xFILE files[XOPEN_MAX]; | ||||
|  |  | |||
|  | @ -20,16 +20,25 @@ typedef struct { | |||
|   } u; | ||||
| } pic_code; | ||||
| 
 | ||||
| struct pic_list { | ||||
|   struct pic_list *prev, *next; | ||||
| }; | ||||
| 
 | ||||
| struct pic_irep { | ||||
|   PIC_OBJECT_HEADER | ||||
|   struct pic_list list; | ||||
|   int refc; | ||||
|   pic_code *code; | ||||
|   int argc, localc, capturec; | ||||
|   bool varg; | ||||
|   struct pic_irep **irep; | ||||
|   size_t ilen; | ||||
|   pic_value *pool; | ||||
|   size_t ilen, plen; | ||||
|   size_t plen; | ||||
| }; | ||||
| 
 | ||||
| void pic_irep_incref(pic_state *, struct pic_irep *); | ||||
| void pic_irep_decref(pic_state *, struct pic_irep *); | ||||
| 
 | ||||
| pic_sym *pic_resolve(pic_state *, pic_value, struct pic_env *); | ||||
| pic_value pic_expand(pic_state *, pic_value, struct pic_env *); | ||||
| pic_value pic_analyze(pic_state *, pic_value); | ||||
|  |  | |||
|  | @ -158,7 +158,6 @@ enum pic_tt { | |||
|   PIC_TT_RECORD, | ||||
|   PIC_TT_BOX, | ||||
|   PIC_TT_CXT, | ||||
|   PIC_TT_IREP, | ||||
|   PIC_TT_CP | ||||
| }; | ||||
| 
 | ||||
|  | @ -305,8 +304,6 @@ pic_type_repr(enum pic_tt tt) | |||
|     return "env"; | ||||
|   case PIC_TT_LIB: | ||||
|     return "lib"; | ||||
|   case PIC_TT_IREP: | ||||
|     return "irep"; | ||||
|   case PIC_TT_DATA: | ||||
|     return "data"; | ||||
|   case PIC_TT_DICT: | ||||
|  |  | |||
|  | @ -4,6 +4,33 @@ | |||
| 
 | ||||
| #include "picrin.h" | ||||
| 
 | ||||
| void | ||||
| pic_irep_incref(pic_state PIC_UNUSED(*pic), struct pic_irep *irep) | ||||
| { | ||||
|   irep->refc++; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| pic_irep_decref(pic_state *pic, struct pic_irep *irep) | ||||
| { | ||||
|   size_t i; | ||||
| 
 | ||||
|   if (--irep->refc == 0) { | ||||
|     pic_free(pic, irep->code); | ||||
|     pic_free(pic, irep->pool); | ||||
| 
 | ||||
|     /* unchain before decref children ireps */ | ||||
|     irep->list.prev->next = irep->list.next; | ||||
|     irep->list.next->prev = irep->list.prev; | ||||
| 
 | ||||
|     for (i = 0; i < irep->ilen; ++i) { | ||||
|       pic_irep_decref(pic, irep->irep[i]); | ||||
|     } | ||||
|     pic_free(pic, irep->irep); | ||||
|     pic_free(pic, irep); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| struct pic_proc * | ||||
| pic_make_proc(pic_state *pic, pic_func_t func) | ||||
| { | ||||
|  | @ -25,6 +52,7 @@ pic_make_proc_irep(pic_state *pic, struct pic_irep *irep, struct pic_context *cx | |||
|   proc->tag = PIC_PROC_TAG_IREP; | ||||
|   proc->u.i.irep = irep; | ||||
|   proc->u.i.cxt = cxt; | ||||
|   pic_irep_incref(pic, irep); | ||||
|   return proc; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -316,6 +316,10 @@ pic_open(pic_allocf allocf, void *userdata) | |||
|   pic->libs = pic_nil_value(); | ||||
|   pic->lib = NULL; | ||||
| 
 | ||||
|   /* ireps */ | ||||
|   pic->ireps.next = &pic->ireps; | ||||
|   pic->ireps.prev = &pic->ireps; | ||||
| 
 | ||||
|   /* raised error object */ | ||||
|   pic->err = pic_invalid_value(); | ||||
| 
 | ||||
|  | @ -478,6 +482,18 @@ pic_close(pic_state *pic) | |||
|   /* free all heap objects */ | ||||
|   pic_gc_run(pic); | ||||
| 
 | ||||
| #if 0 | ||||
|   { | ||||
|     /* FIXME */ | ||||
|     int i = 0; | ||||
|     struct pic_list *list; | ||||
|     for (list = pic->ireps.next; list != &pic->ireps; list = list->next) { | ||||
|       i++; | ||||
|     } | ||||
|     printf("%d\n", i); | ||||
|   } | ||||
| #endif | ||||
| 
 | ||||
|   /* flush all xfiles */ | ||||
|   xfflush(pic, NULL); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Yuichi Nishiwaki
						Yuichi Nishiwaki