/* destroy the given context and associated memory files (if not in use by a shared context) exit interpreter if all contexts are destroyed. */ XPAPI void xpost_destroy(Xpost_Context *ctx) { if (!xpost_dict_known_key(ctx, ctx->gl, xpost_stack_bottomup_fetch(ctx->lo, ctx->ds, 0), xpost_name_cons(ctx, "QUIET"))) { printf("bye!\n"); fflush(NULL); } /*xpost_garbage_collect(itpdata->ctab->gl, 1, 1); */ /*xpost_garbage_collect(itpdata->ctab->lo, 1, 1); */ #if 0 #ifndef XPOST_NO_GC xpost_garbage_collect(ctx->gl, 1, 1); xpost_garbage_collect(ctx->lo, 1, 0); #endif #endif /* exit if all contexts are destroyed */ /*xpost_interpreter_exit(itpdata); */ /*free(itpdata); */ }
/* determine GLOBAL/LOCAL clear all marks, mark all root stacks, sweep. return reclaimed size or -1 if error occured. */ int xpost_garbage_collect(Xpost_Memory_File *mem, int dosweep, int markall) { unsigned int i; unsigned int *cid; Xpost_Context *ctx = NULL; int isglobal; unsigned int sz = 0; unsigned int ad; int ret; if (mem->interpreter_get_initializing()) /* do not collect while initializing */ return 0; /* printf("\ncollect:\n"); */ /* determine global/local */ isglobal = 0; ret = xpost_memory_table_get_addr(mem, XPOST_MEMORY_TABLE_SPECIAL_CONTEXT_LIST, &ad); if (!ret) { XPOST_LOG_ERR("cannot load context list"); return -1; } cid = (void *)(mem->base + ad); for (i = 0; i < MAXCONTEXT && cid[i]; i++) { ctx = mem->interpreter_cid_get_context(cid[i]); if (ctx->state != 0) { if (mem == ctx->gl) { isglobal = 1; break; } } } #ifdef DEBUG_GC printf("using cid=%d\n", ctx->id); #endif if (isglobal) { return 0; /* do not perform global collections at this time */ _xpost_garbage_unmark(mem); ret = xpost_memory_table_get_addr(mem, XPOST_MEMORY_TABLE_SPECIAL_SAVE_STACK, &ad); if (!ret) { XPOST_LOG_ERR("cannot load save stack for %s memory", mem == ctx->gl? "global" : "local"); return -1; } if (!_xpost_garbage_mark_save(ctx, mem, ad)) return -1; ret = xpost_memory_table_get_addr(mem, XPOST_MEMORY_TABLE_SPECIAL_NAME_STACK, &ad); if (!ret) { XPOST_LOG_ERR("cannot load name stack for %s memory", mem == ctx->gl? "global" : "local"); return -1; } if (!_xpost_garbage_mark_stack(ctx, mem, ad, markall)) return -1; for (i = 0; i < MAXCONTEXT && cid[i]; i++) { ctx = mem->interpreter_cid_get_context(cid[i]); xpost_garbage_collect(ctx->lo, 0, markall); } } else { /* local */ //printf("collect!\n"); _xpost_garbage_unmark(mem); ret = xpost_memory_table_get_addr(mem, XPOST_MEMORY_TABLE_SPECIAL_SAVE_STACK, &ad); if (!ret) { XPOST_LOG_ERR("cannot load save stack for %s memory", mem == ctx->gl? "global" : "local"); return -1; } if (!_xpost_garbage_mark_save(ctx, mem, ad)) return -1; ret = xpost_memory_table_get_addr(mem, XPOST_MEMORY_TABLE_SPECIAL_NAME_STACK, &ad); if (!ret) { XPOST_LOG_ERR("cannot load name stack for %s memory", mem == ctx->gl? "global" : "local"); return -1; } #ifdef DEBUG_GC printf("marking name stack\n"); #endif if (!_xpost_garbage_mark_stack(ctx, mem, ad, markall)) return -1; for (i = 0; i < MAXCONTEXT && cid[i]; i++) { ctx = mem->interpreter_cid_get_context(cid[i]); #ifdef DEBUG_GC printf("marking os\n"); #endif if (!_xpost_garbage_mark_stack(ctx, mem, ctx->os, markall)) return -1; #ifdef DEBUG_GC printf("marking ds\n"); #endif if (!_xpost_garbage_mark_stack(ctx, mem, ctx->ds, markall)) return -1; #ifdef DEBUG_GC printf("marking es\n"); #endif if (!_xpost_garbage_mark_stack(ctx, mem, ctx->es, markall)) return -1; #ifdef DEBUG_GC printf("marking hold\n"); #endif if (!_xpost_garbage_mark_stack(ctx, mem, ctx->hold, markall)) return -1; #ifdef DEBUG_GC printf("marking window device\n"); #endif if (!_xpost_garbage_mark_object(ctx, mem, ctx->window_device, markall)) return -1; } } if (dosweep) { #ifdef DEBUG_GC printf("sweep\n"); #endif sz += _xpost_garbage_sweep(mem); if (isglobal) { for (i = 0; i < MAXCONTEXT && cid[i]; i++) { ctx = mem->interpreter_cid_get_context(cid[i]); sz += _xpost_garbage_sweep(ctx->lo); } } } printf("collect recovered %u bytes\n", sz); return sz; }