SCI: Moved freeAtAddress from SegInterface to MemObject

svn-id: r40375
This commit is contained in:
Max Horn 2009-05-08 09:53:49 +00:00
parent b49dd22173
commit 8d4a4271bb
4 changed files with 30 additions and 53 deletions

View File

@ -167,7 +167,8 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {
}
struct deallocator_t {
SegInterface *interfce;
SegManager *segmgr;
MemObject *mobj;
#ifdef DEBUG_GC
char *segnames[MEM_OBJ_MAX + 1];
int segcount[MEM_OBJ_MAX + 1];
@ -181,10 +182,10 @@ void free_unless_used(void *refcon, reg_t addr) {
if (!use_map->contains(addr)) {
// Not found -> we can free it
deallocator->interfce->freeAtAddress(addr);
deallocator->mobj->freeAtAddress(deallocator->segmgr, addr);
#ifdef DEBUG_GC
sciprintf("[GC] Deallocating "PREG"\n", PRINT_REG(addr));
deallocator->segcount[deallocator->interfce->getType()]++;
deallocator->segcount[deallocator->mobj->getType()]++;
#endif
}
@ -202,16 +203,16 @@ void run_gc(EngineState *s) {
memset(&(deallocator.segcount), 0, sizeof(int) * (MEM_OBJ_MAX + 1));
#endif
deallocator.segmgr = sm;
deallocator.use_map = find_all_used_references(s);
for (seg_nr = 1; seg_nr < sm->_heap.size(); seg_nr++) {
if (sm->_heap[seg_nr] != NULL) {
deallocator.interfce = sm->getSegInterface(seg_nr);
deallocator.mobj = sm->_heap[seg_nr];
#ifdef DEBUG_GC
deallocator.segnames[deallocator.interfce->getType()] = deallocator.interfce->type;
deallocator.segnames[deallocator.mobj->getType()] = deallocator.mobj->type; // FIXME: add a segment "name"
#endif
sm->_heap[seg_nr]->listAllDeallocatable(seg_nr, &deallocator, free_unless_used);
delete deallocator.interfce;
deallocator.mobj->listAllDeallocatable(seg_nr, &deallocator, free_unless_used);
}
}

View File

@ -1192,10 +1192,6 @@ reg_t SegInterface::findCanonicAddress(reg_t addr) {
return addr;
}
void SegInterface::freeAtAddress(reg_t sub_addr) {
}
//-------------------- base --------------------
class SegInterfaceBase : public SegInterface {
protected:
@ -1224,19 +1220,17 @@ class SegInterfaceScript : public SegInterfaceBase {
public:
SegInterfaceScript(SegManager *segmgr, MemObject *mobj, SegmentId segId) :
SegInterfaceBase(segmgr, mobj, segId, MEM_OBJ_SCRIPT) {}
void freeAtAddress(reg_t addr);
};
void SegInterfaceScript::freeAtAddress(reg_t addr) {
Script *script = (Script *)_mobj;
void Script::freeAtAddress(SegManager *segmgr, reg_t addr) {
/*
sciprintf("[GC] Freeing script "PREG"\n", PRINT_REG(addr));
if (script->locals_segment)
sciprintf("[GC] Freeing locals %04x:0000\n", script->locals_segment);
if (locals_segment)
sciprintf("[GC] Freeing locals %04x:0000\n", locals_segment);
*/
if (script->marked_as_deleted)
_segmgr->deallocateScript(script->nr);
if (marked_as_deleted)
segmgr->deallocateScript(nr);
}
void Script::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
@ -1269,7 +1263,6 @@ class SegInterfaceClones : public SegInterface {
public:
SegInterfaceClones(SegManager *segmgr, MemObject *mobj, SegmentId segId) :
SegInterface(segmgr, mobj, segId, MEM_OBJ_CLONES) {}
void freeAtAddress(reg_t addr);
};
template<typename T, int INITIAL, int INCREMENT>
@ -1303,11 +1296,11 @@ void CloneTable::listAllOutgoingReferences(EngineState *s, reg_t addr, void *par
//sciprintf("[GC] Reporting clone-pos "PREG"\n", PRINT_REG(clone->pos));
}
void SegInterfaceClones::freeAtAddress(reg_t addr) {
CloneTable *clone_table = (CloneTable *)_mobj;
void CloneTable::freeAtAddress(SegManager *segmgr, reg_t addr) {
CloneTable *clone_table = this;
Object *victim_obj;
assert(addr.segment == _segId);
// assert(addr.segment == _segId);
victim_obj = &(clone_table->table[addr.offset]);
@ -1335,7 +1328,6 @@ public:
SegInterfaceLocals(SegManager *segmgr, MemObject *mobj, SegmentId segId) :
SegInterface(segmgr, mobj, segId, MEM_OBJ_LOCALS) {}
reg_t findCanonicAddress(reg_t addr);
void freeAtAddress(reg_t addr);
};
reg_t SegInterfaceLocals::findCanonicAddress(reg_t addr) {
@ -1348,11 +1340,6 @@ reg_t SegInterfaceLocals::findCanonicAddress(reg_t addr) {
return make_reg(owner_seg, 0);
}
void SegInterfaceLocals::freeAtAddress(reg_t sub_addr) {
//sciprintf(" Request to free "PREG"\n", PRINT_REG(sub_addr));
// STUB
}
void LocalVariables::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
// assert(addr.segment == _segId);
@ -1402,12 +1389,10 @@ class SegInterfaceLists : public SegInterface {
public:
SegInterfaceLists(SegManager *segmgr, MemObject *mobj, SegmentId segId) :
SegInterface(segmgr, mobj, segId, MEM_OBJ_LISTS) {}
void freeAtAddress(reg_t addr);
};
void SegInterfaceLists::freeAtAddress(reg_t sub_addr) {
ListTable *table = (ListTable *)_mobj;
table->freeEntry(sub_addr.offset);
void ListTable::freeAtAddress(SegManager *segmgr, reg_t sub_addr) {
freeEntry(sub_addr.offset);
}
void ListTable::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
@ -1430,12 +1415,10 @@ class SegInterfaceNodes : public SegInterface {
public:
SegInterfaceNodes(SegManager *segmgr, MemObject *mobj, SegmentId segId) :
SegInterface(segmgr, mobj, segId, MEM_OBJ_NODES) {}
void freeAtAddress(reg_t addr);
};
void SegInterfaceNodes::freeAtAddress(reg_t sub_addr) {
NodeTable *table = (NodeTable *)_mobj;
table->freeEntry(sub_addr.offset);
void NodeTable::freeAtAddress(SegManager *segmgr, reg_t sub_addr) {
freeEntry(sub_addr.offset);
}
void NodeTable::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
@ -1459,28 +1442,15 @@ class SegInterfaceHunk : public SegInterface {
public:
SegInterfaceHunk(SegManager *segmgr, MemObject *mobj, SegmentId segId) :
SegInterface(segmgr, mobj, segId, MEM_OBJ_HUNK) {}
void freeAtAddress(reg_t addr);
};
void SegInterfaceHunk::freeAtAddress(reg_t sub_addr) {
//sciprintf(" Request to free "PREG"\n", PRINT_REG(sub_addr));
// STUB
}
//-------------------- dynamic memory --------------------
class SegInterfaceDynMem : public SegInterfaceBase {
public:
SegInterfaceDynMem(SegManager *segmgr, MemObject *mobj, SegmentId segId) :
SegInterfaceBase(segmgr, mobj, segId, MEM_OBJ_DYNMEM) {}
void freeAtAddress(reg_t addr);
};
void SegInterfaceDynMem::freeAtAddress(reg_t sub_addr) {
//sciprintf(" Request to free "PREG"\n", PRINT_REG(sub_addr));
// STUB
}
SegInterface *SegManager::getSegInterface(SegmentId segid) {
if (!check(segid))
return NULL; // Invalid segment

View File

@ -458,10 +458,6 @@ public:
// This address "governs" a in the sense that deallocating c(a) will deallocate a.
virtual reg_t findCanonicAddress(reg_t sub_addr);
// Deallocates all memory associated with the specified address
// Parameters: (reg_t) sub_addr: The address (within the given segment) to deallocate
virtual void freeAtAddress(reg_t sub_addr);
// Get the memory object
MemObject *getMobj() { return _mobj; }

View File

@ -36,6 +36,8 @@
namespace Sci {
class SegManager;
enum MemObjectType {
MEM_OBJ_INVALID = 0,
MEM_OBJ_SCRIPT = 1,
@ -75,6 +77,10 @@ public:
inline MemObjectType getType() const { return _type; }
inline int getSegMgrId() const { return _segmgrId; }
// Deallocates all memory associated with the specified address
// Parameters: (reg_t) sub_addr: The address (within the given segment) to deallocate
virtual void freeAtAddress(SegManager *segmgr, reg_t sub_addr) {}
// Iterates over and reports all addresses within the current segment
// Parameters: note : (voidptr * addr) -> (): Invoked for each address on which free_at_address()
// makes sense
@ -362,6 +368,7 @@ public:
void freeScript();
virtual byte *dereference(reg_t pointer, int *size);
virtual void freeAtAddress(SegManager *segmgr, reg_t sub_addr);
virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note);
virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
@ -503,18 +510,21 @@ struct CloneTable : public Table<Clone, 16, 4> {
free(table[idx].variables); // Free the dynamically allocated memory part
}
virtual void freeAtAddress(SegManager *segmgr, reg_t sub_addr);
virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
};
/* NodeTable */
struct NodeTable : public Table<Node, 32, 16> {
virtual void freeAtAddress(SegManager *segmgr, reg_t sub_addr);
virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
};
/* ListTable */
struct ListTable : public Table<List, 8, 4> {
virtual void freeAtAddress(SegManager *segmgr, reg_t sub_addr);
virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
};