mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-26 20:59:00 +00:00
SCI: Moved freeAtAddress from SegInterface to MemObject
svn-id: r40375
This commit is contained in:
parent
b49dd22173
commit
8d4a4271bb
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user