SCI: Fix DEBUG_GC mode and permanently enable it

svn-id: r50430
This commit is contained in:
Max Horn 2010-06-28 11:23:00 +00:00
parent 31b2902714
commit 6c0205b104
3 changed files with 64 additions and 48 deletions

View file

@ -28,8 +28,6 @@
namespace Sci {
//#define DEBUG_GC
struct WorklistManager {
Common::Array<reg_t> _worklist;
reg_t_hash_map _map;
@ -151,68 +149,41 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {
return normal_map;
}
struct deallocator_t {
SegManager *segMan;
SegmentObj *mobj;
#ifdef DEBUG_GC
char *segnames[SEG_TYPE_MAX + 1];
int segcount[SEG_TYPE_MAX + 1];
#endif
reg_t_hash_map *use_map;
};
static void free_unless_used(deallocator_t *deallocator, reg_t addr) {
reg_t_hash_map *use_map = deallocator->use_map;
if (!use_map->contains(addr)) {
// Not found -> we can free it
deallocator->mobj->freeAtAddress(deallocator->segMan, addr);
#ifdef DEBUG_GC
debugC(2, kDebugLevelGC, "[GC] Deallocating %04x:%04x", PRINT_REG(addr));
deallocator->segcount[deallocator->mobj->getType()]++;
#endif
}
}
void run_gc(EngineState *s) {
uint seg_nr;
deallocator_t deallocator;
SegManager *segMan = s->_segMan;
#ifdef DEBUG_GC
const char *segnames[SEG_TYPE_MAX + 1];
int segcount[SEG_TYPE_MAX + 1];
debugC(2, kDebugLevelGC, "[GC] Running...");
memset(&(deallocator.segcount), 0, sizeof(int) * (SEG_TYPE_MAX + 1));
#endif
memset(segcount, 0, sizeof(segcount));
deallocator.segMan = segMan;
deallocator.use_map = find_all_used_references(s);
reg_t_hash_map *use_map = find_all_used_references(s);
for (seg_nr = 1; seg_nr < segMan->_heap.size(); seg_nr++) {
if (segMan->_heap[seg_nr] != NULL) {
deallocator.mobj = segMan->_heap[seg_nr];
#ifdef DEBUG_GC
deallocator.segnames[deallocator.mobj->getType()] = deallocator.mobj->type; // FIXME: add a segment "name"
#endif
const Common::Array<reg_t> tmp = deallocator.mobj->listAllDeallocatable(seg_nr);
SegmentObj *mobj = segMan->_heap[seg_nr];
segnames[mobj->getType()] = SegmentObj::getSegmentTypeName(mobj->getType());
const Common::Array<reg_t> tmp = mobj->listAllDeallocatable(seg_nr);
for (Common::Array<reg_t>::const_iterator it = tmp.begin(); it != tmp.end(); ++it) {
free_unless_used(&deallocator, *it);
const reg_t addr = *it;
if (!use_map->contains(addr)) {
// Not found -> we can free it
mobj->freeAtAddress(segMan, addr);
debugC(2, kDebugLevelGC, "[GC] Deallocating %04x:%04x", PRINT_REG(addr));
segcount[mobj->getType()]++;
}
}
}
}
delete deallocator.use_map;
delete use_map;
#ifdef DEBUG_GC
{
int i;
debugC(2, kDebugLevelGC, "[GC] Summary:");
for (i = 0; i <= SEG_TYPE_MAX; i++)
if (deallocator.segcount[i])
debugC(2, kDebugLevelGC, "\t%d\t* %s", deallocator.segcount[i], deallocator.segnames[i]);
}
#endif
for (int i = 0; i <= SEG_TYPE_MAX; i++)
if (segcount[i])
debugC(2, kDebugLevelGC, "\t%d\t* %s", segcount[i], segnames[i]);
}
} // End of namespace Sci

View file

@ -86,6 +86,50 @@ SegmentObj *SegmentObj::createSegmentObj(SegmentType type) {
return mem;
}
const char *SegmentObj::getSegmentTypeName(SegmentType type) {
switch (type) {
case SEG_TYPE_SCRIPT:
return "script";
break;
case SEG_TYPE_CLONES:
return "clones";
break;
case SEG_TYPE_LOCALS:
return "locals";
break;
case SEG_TYPE_SYS_STRINGS:
return "strings";
break;
case SEG_TYPE_STACK:
return "stack";
break;
case SEG_TYPE_HUNK:
return "hunk";
break;
case SEG_TYPE_LISTS:
return "lists";
break;
case SEG_TYPE_NODES:
return "nodes";
break;
case SEG_TYPE_DYNMEM:
return "dynmem";
break;
#ifdef ENABLE_SCI32
case SEG_TYPE_ARRAY:
return "array";
break;
case SEG_TYPE_STRING:
return "string";
break;
#endif
default:
error("Unknown SegmentObj type %d", type);
break;
}
return NULL;
}
// This helper function is used by Script::relocateLocal and Object::relocate
// Duplicate in segment.cpp and script.cpp
static bool relocateBlock(Common::Array<reg_t> &block, int block_location, SegmentId segment, int location, size_t scriptSize) {

View file

@ -82,6 +82,7 @@ struct SegmentObj : public Common::Serializable {
public:
static SegmentObj *createSegmentObj(SegmentType type);
static const char *getSegmentTypeName(SegmentType type);
public:
SegmentObj(SegmentType type) : _type(type) {}