aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Horn2009-05-08 09:53:49 +0000
committerMax Horn2009-05-08 09:53:49 +0000
commit8d4a4271bb0cf78508f600d80893874d436e9883 (patch)
tree2629c1c70151587b58782af607507f0ccee93e0f
parentb49dd221737bd1291002fb6c4dc08384e176d632 (diff)
downloadscummvm-rg350-8d4a4271bb0cf78508f600d80893874d436e9883.tar.gz
scummvm-rg350-8d4a4271bb0cf78508f600d80893874d436e9883.tar.bz2
scummvm-rg350-8d4a4271bb0cf78508f600d80893874d436e9883.zip
SCI: Moved freeAtAddress from SegInterface to MemObject
svn-id: r40375
-rw-r--r--engines/sci/engine/gc.cpp15
-rw-r--r--engines/sci/engine/seg_manager.cpp54
-rw-r--r--engines/sci/engine/seg_manager.h4
-rw-r--r--engines/sci/engine/vm.h10
4 files changed, 30 insertions, 53 deletions
diff --git a/engines/sci/engine/gc.cpp b/engines/sci/engine/gc.cpp
index 09c8469197..f5f9c51051 100644
--- a/engines/sci/engine/gc.cpp
+++ b/engines/sci/engine/gc.cpp
@@ -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);
}
}
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index 97f9c799c4..dfd216e86e 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -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
diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h
index c7ae3235c9..1fac3287e9 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -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; }
diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h
index d57e667b38..5e617705f2 100644
--- a/engines/sci/engine/vm.h
+++ b/engines/sci/engine/vm.h
@@ -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);
};