mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-15 22:28:10 +00:00
formating
svn-id: r38537
This commit is contained in:
parent
f3d8087dd3
commit
8ca98d41a2
@ -27,8 +27,8 @@
|
||||
|
||||
#define WORKLIST_CHUNK_SIZE 32
|
||||
|
||||
/*#define DEBUG_GC*/
|
||||
/*#define DEBUG_GC_VERBOSE*/
|
||||
//#define DEBUG_GC
|
||||
//#define DEBUG_GC_VERBOSE
|
||||
|
||||
typedef struct _worklist {
|
||||
int used;
|
||||
@ -36,33 +36,29 @@ typedef struct _worklist {
|
||||
struct _worklist *next;
|
||||
} worklist_t;
|
||||
|
||||
static worklist_t *
|
||||
fresh_worklist(worklist_t *old) {
|
||||
static worklist_t *fresh_worklist(worklist_t *old) {
|
||||
worklist_t *retval = (worklist_t*)sci_malloc(sizeof(worklist_t));
|
||||
retval->used = 0;
|
||||
retval->next = old;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static worklist_t *
|
||||
new_worklist() {
|
||||
static worklist_t *new_worklist() {
|
||||
return fresh_worklist(NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
worklist_push(worklist_t **wlp, reg_t_hash_map *hashmap, reg_t reg) {
|
||||
static void worklist_push(worklist_t **wlp, reg_t_hash_map *hashmap, reg_t reg) {
|
||||
worklist_t *wl = *wlp;
|
||||
|
||||
if (!reg.segment) /* No numbers */
|
||||
if (!reg.segment) // No numbers
|
||||
return;
|
||||
|
||||
#ifdef DEBUG_GC_VERBOSE
|
||||
sciprintf("[GC] Adding "PREG"\n", PRINT_REG(reg));
|
||||
#endif
|
||||
|
||||
|
||||
if (hashmap->contains(reg))
|
||||
return; /* already dealt with it */
|
||||
return; // already dealt with it
|
||||
|
||||
hashmap->setVal(reg, true);
|
||||
|
||||
@ -72,13 +68,11 @@ worklist_push(worklist_t **wlp, reg_t_hash_map *hashmap, reg_t reg) {
|
||||
wl->entries[wl->used++] = reg;
|
||||
}
|
||||
|
||||
static int
|
||||
worklist_has_next(worklist_t *wl) {
|
||||
static int worklist_has_next(worklist_t *wl) {
|
||||
return (wl && wl->used);
|
||||
}
|
||||
|
||||
static reg_t
|
||||
worklist_pop(worklist_t **wlp) {
|
||||
static reg_t worklist_pop(worklist_t **wlp) {
|
||||
worklist_t *wl = *wlp;
|
||||
reg_t retval;
|
||||
|
||||
@ -97,8 +91,7 @@ worklist_pop(worklist_t **wlp) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
free_worklist(worklist_t *wl) {
|
||||
static void free_worklist(worklist_t *wl) {
|
||||
if (wl) {
|
||||
if (wl->next)
|
||||
free_worklist(wl->next);
|
||||
@ -106,17 +99,14 @@ free_worklist(worklist_t *wl) {
|
||||
}
|
||||
}
|
||||
|
||||
static reg_t_hash_map *
|
||||
normalise_hashmap_ptrs(reg_t_hash_map *nonnormal_map, seg_interface_t **interfaces, int interfaces_nr) {
|
||||
static reg_t_hash_map * normalise_hashmap_ptrs(reg_t_hash_map *nonnormal_map, seg_interface_t **interfaces, int interfaces_nr) {
|
||||
reg_t_hash_map *normal_map = new reg_t_hash_map();
|
||||
|
||||
for (reg_t_hash_map::iterator i = nonnormal_map->begin(); i != nonnormal_map->end(); ++i) {
|
||||
seg_interface_t *interfce;
|
||||
reg_t reg = i->_key;
|
||||
interfce = (reg.segment < interfaces_nr)
|
||||
? interfaces[reg.segment]
|
||||
: NULL;
|
||||
|
||||
interfce = (reg.segment < interfaces_nr) ? interfaces[reg.segment] : NULL;
|
||||
|
||||
if (interfce) {
|
||||
reg = interfce->find_canonic_address(interfce, reg);
|
||||
normal_map->setVal(reg, true);
|
||||
@ -132,14 +122,12 @@ typedef struct {
|
||||
worklist_t **worklist_ref;
|
||||
} worklist_manager_t;
|
||||
|
||||
void
|
||||
add_outgoing_refs(void *pre_wm, reg_t addr) {
|
||||
void add_outgoing_refs(void *pre_wm, reg_t addr) {
|
||||
worklist_manager_t *wm = (worklist_manager_t *) pre_wm;
|
||||
worklist_push(wm->worklist_ref, wm->nonnormal_map, addr);
|
||||
}
|
||||
|
||||
reg_t_hash_map *
|
||||
find_all_used_references(state_t *s) {
|
||||
reg_t_hash_map *find_all_used_references(state_t *s) {
|
||||
seg_manager_t *sm = &(s->seg_manager);
|
||||
seg_interface_t **interfaces = (seg_interface_t**)sci_calloc(sizeof(seg_interface_t *), sm->heap_size);
|
||||
reg_t_hash_map *nonnormal_map = new reg_t_hash_map();
|
||||
@ -157,12 +145,12 @@ find_all_used_references(state_t *s) {
|
||||
else
|
||||
interfaces[i] = get_seg_interface(sm, i);
|
||||
|
||||
/* Initialise */
|
||||
/* Init: Registers */
|
||||
// Initialise
|
||||
// Init: Registers
|
||||
worklist_push(&worklist, nonnormal_map, s->r_acc);
|
||||
worklist_push(&worklist, nonnormal_map, s->r_prev);
|
||||
/* Init: Value Stack */
|
||||
/* We do this one by hand since the stack doesn't know the current execution stack */
|
||||
// Init: Value Stack
|
||||
// We do this one by hand since the stack doesn't know the current execution stack
|
||||
{
|
||||
exec_stack_t *xs = s->execution_stack + s->execution_stack_pos;
|
||||
reg_t *pos;
|
||||
@ -174,8 +162,7 @@ find_all_used_references(state_t *s) {
|
||||
sciprintf("[GC] -- Finished adding value stack");
|
||||
#endif
|
||||
|
||||
|
||||
/* Init: Execution Stack */
|
||||
// Init: Execution Stack
|
||||
for (i = 0; i <= s->execution_stack_pos; i++) {
|
||||
exec_stack_t *es = s->execution_stack + i;
|
||||
|
||||
@ -190,24 +177,22 @@ find_all_used_references(state_t *s) {
|
||||
sciprintf("[GC] -- Finished adding execution stack");
|
||||
#endif
|
||||
|
||||
/* Init: Explicitly loaded scripts */
|
||||
// Init: Explicitly loaded scripts
|
||||
for (i = 1; i < sm->heap_size; i++)
|
||||
if (interfaces[i]
|
||||
&& interfaces[i]->type_id == MEM_OBJ_SCRIPT) {
|
||||
script_t *script = &(interfaces[i]->mobj->data.script);
|
||||
|
||||
if (script->lockers) { /* Explicitly loaded? */
|
||||
if (script->lockers) { // Explicitly loaded?
|
||||
int obj_nr;
|
||||
|
||||
/* Locals, if present */
|
||||
// Locals, if present
|
||||
worklist_push(&worklist, nonnormal_map, make_reg(script->locals_segment, 0));
|
||||
|
||||
/* All objects (may be classes, may be indirectly reachable) */
|
||||
// All objects (may be classes, may be indirectly reachable)
|
||||
for (obj_nr = 0; obj_nr < script->objects_nr; obj_nr++) {
|
||||
object_t *obj = script->objects + obj_nr;
|
||||
worklist_push(&worklist,
|
||||
nonnormal_map,
|
||||
obj->pos);
|
||||
worklist_push(&worklist, nonnormal_map, obj->pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -215,37 +200,33 @@ find_all_used_references(state_t *s) {
|
||||
sciprintf("[GC] -- Finished explicitly loaded scripts, done with root set");
|
||||
#endif
|
||||
|
||||
|
||||
/* Run Worklist Algorithm */
|
||||
// Run Worklist Algorithm
|
||||
while (worklist_has_next(worklist)) {
|
||||
reg_t reg = worklist_pop(&worklist);
|
||||
if (reg.segment != s->stack_segment) { /* No need to repeat this one */
|
||||
if (reg.segment != s->stack_segment) { // No need to repeat this one
|
||||
#ifdef DEBUG_GC_VERBOSE
|
||||
sciprintf("[GC] Checking "PREG"\n", PRINT_REG(reg));
|
||||
#endif
|
||||
if (reg.segment < sm->heap_size
|
||||
&& interfaces[reg.segment])
|
||||
interfaces[reg.segment]->list_all_outgoing_references(interfaces[reg.segment],
|
||||
s,
|
||||
reg,
|
||||
&worklist_manager,
|
||||
add_outgoing_refs);
|
||||
if (reg.segment < sm->heap_size && interfaces[reg.segment])
|
||||
interfaces[reg.segment]->list_all_outgoing_references(interfaces[reg.segment], s, reg,
|
||||
&worklist_manager, add_outgoing_refs);
|
||||
}
|
||||
}
|
||||
|
||||
/* Normalise */
|
||||
// Normalise
|
||||
normal_map = normalise_hashmap_ptrs(nonnormal_map, interfaces, sm->heap_size);
|
||||
|
||||
/* Cleanup */
|
||||
// Cleanup
|
||||
for (i = 1; i < sm->heap_size; i++)
|
||||
if (interfaces[i])
|
||||
interfaces[i]->deallocate_self(interfaces[i]);
|
||||
|
||||
free(interfaces);
|
||||
delete nonnormal_map;
|
||||
|
||||
return normal_map;
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
seg_interface_t *interfce;
|
||||
#ifdef DEBUG_GC
|
||||
@ -255,13 +236,12 @@ typedef struct {
|
||||
reg_t_hash_map *use_map;
|
||||
} deallocator_t;
|
||||
|
||||
void
|
||||
free_unless_used(void *pre_use_map, reg_t addr) {
|
||||
deallocator_t *deallocator = (deallocator_t *) pre_use_map;
|
||||
void free_unless_used(void *pre_use_map, reg_t addr) {
|
||||
deallocator_t *deallocator = (deallocator_t *)pre_use_map;
|
||||
reg_t_hash_map *use_map = deallocator->use_map;
|
||||
|
||||
if (!use_map->contains(addr)) {
|
||||
/* Not found -> we can free it */
|
||||
// Not found -> we can free it
|
||||
deallocator->interfce->free_at_address(deallocator->interfce, addr);
|
||||
#ifdef DEBUG_GC
|
||||
sciprintf("[GC] Deallocating "PREG"\n", PRINT_REG(addr));
|
||||
@ -271,8 +251,7 @@ free_unless_used(void *pre_use_map, reg_t addr) {
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
run_gc(state_t *s) {
|
||||
void run_gc(state_t *s) {
|
||||
int seg_nr;
|
||||
deallocator_t deallocator;
|
||||
seg_manager_t *sm = &(s->seg_manager);
|
||||
@ -285,19 +264,16 @@ run_gc(state_t *s) {
|
||||
|
||||
deallocator.use_map = find_all_used_references(s);
|
||||
|
||||
for (seg_nr = 1; seg_nr < sm->heap_size; seg_nr++)
|
||||
for (seg_nr = 1; seg_nr < sm->heap_size; seg_nr++) {
|
||||
if (sm->heap[seg_nr] != NULL) {
|
||||
deallocator.interfce = get_seg_interface(sm, seg_nr);
|
||||
#ifdef DEBUG_GC
|
||||
deallocator.segnames[deallocator.interfce->type_id] = deallocator.interfce->type;
|
||||
#endif
|
||||
|
||||
deallocator.interfce->list_all_deallocatable(deallocator.interfce,
|
||||
&deallocator,
|
||||
free_unless_used);
|
||||
|
||||
deallocator.interfce->list_all_deallocatable(deallocator.interfce, &deallocator, free_unless_used);
|
||||
deallocator.interfce->deallocate_self(deallocator.interfce);
|
||||
}
|
||||
}
|
||||
|
||||
delete deallocator.use_map;
|
||||
|
||||
@ -307,9 +283,7 @@ run_gc(state_t *s) {
|
||||
sciprintf("[GC] Summary:\n");
|
||||
for (i = 0; i <= MEM_OBJ_MAX; i++)
|
||||
if (deallocator.segcount[i])
|
||||
sciprintf("\t%d\t* %s\n",
|
||||
deallocator.segcount[i],
|
||||
deallocator.segnames[i]);
|
||||
sciprintf("\t%d\t* %s\n", deallocator.segcount[i], deallocator.segnames[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user