aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Horn2009-05-08 09:53:10 +0000
committerMax Horn2009-05-08 09:53:10 +0000
commitd8738b9090c1b8d866f18962be428076de6faae2 (patch)
tree873675d8f4d5bf696f836998d38b21da7929f09a
parent76a48947dec0a79ca674948fb199adfdc911d01c (diff)
downloadscummvm-rg350-d8738b9090c1b8d866f18962be428076de6faae2.tar.gz
scummvm-rg350-d8738b9090c1b8d866f18962be428076de6faae2.tar.bz2
scummvm-rg350-d8738b9090c1b8d866f18962be428076de6faae2.zip
SCI: Started to merge SegInterface into MemObject
svn-id: r40373
-rw-r--r--engines/sci/engine/gc.cpp6
-rw-r--r--engines/sci/engine/scriptdebug.cpp20
-rw-r--r--engines/sci/engine/seg_manager.cpp110
-rw-r--r--engines/sci/engine/seg_manager.h13
-rw-r--r--engines/sci/engine/vm.h30
5 files changed, 76 insertions, 103 deletions
diff --git a/engines/sci/engine/gc.cpp b/engines/sci/engine/gc.cpp
index f8be73f26a..09c8469197 100644
--- a/engines/sci/engine/gc.cpp
+++ b/engines/sci/engine/gc.cpp
@@ -150,8 +150,8 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {
#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]->listAllOutgoingReferences(s, reg, &wm, add_outgoing_refs);
+ if (reg.segment < sm->_heap.size() && sm->_heap[reg.segment])
+ sm->_heap[reg.segment]->listAllOutgoingReferences(s, reg, &wm, add_outgoing_refs);
}
}
@@ -210,7 +210,7 @@ void run_gc(EngineState *s) {
#ifdef DEBUG_GC
deallocator.segnames[deallocator.interfce->getType()] = deallocator.interfce->type;
#endif
- deallocator.interfce->listAllDeallocatable(&deallocator, free_unless_used);
+ sm->_heap[seg_nr]->listAllDeallocatable(seg_nr, &deallocator, free_unless_used);
delete deallocator.interfce;
}
}
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index 738b74367c..b60b73b324 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -2802,12 +2802,14 @@ static void _print_address(void * _, reg_t addr) {
static int c_gc_show_reachable(EngineState *s) {
reg_t addr = cmd_params[0].reg;
- GET_SEG_INTERFACE(addr.segment);
+ MemObject *mobj = GET_SEGMENT_ANY(*s->seg_manager, addr.segment);
+ if (!mobj) {
+ sciprintf("Unknown segment : %x\n", addr.segment);
+ return 1;
+ }
sciprintf("Reachable from "PREG":\n", PRINT_REG(addr));
- seg_interface->listAllOutgoingReferences(s, addr, NULL, _print_address);
-
- delete seg_interface;
+ mobj->listAllOutgoingReferences(s, addr, NULL, _print_address);
return 0;
}
@@ -2815,12 +2817,14 @@ static int c_gc_show_reachable(EngineState *s) {
static int c_gc_show_freeable(EngineState *s) {
reg_t addr = cmd_params[0].reg;
- GET_SEG_INTERFACE(addr.segment);
+ MemObject *mobj = GET_SEGMENT_ANY(*s->seg_manager, addr.segment);
+ if (!mobj) {
+ sciprintf("Unknown segment : %x\n", addr.segment);
+ return 1;
+ }
sciprintf("Freeable in segment %04x:\n", addr.segment);
- seg_interface->listAllDeallocatable(NULL, _print_address);
-
- delete seg_interface;
+ mobj->listAllDeallocatable(addr.segment, NULL, _print_address);
return 0;
}
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index c7b971549e..6effe8d881 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -1195,12 +1195,6 @@ reg_t SegInterface::findCanonicAddress(reg_t addr) {
void SegInterface::freeAtAddress(reg_t sub_addr) {
}
-void SegInterface::listAllDeallocatable(void *param, NoteCallback note) {
-}
-
-void SegInterface::listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note) {
-}
-
//-------------------- base --------------------
class SegInterfaceBase : public SegInterface {
@@ -1209,7 +1203,6 @@ protected:
SegInterface(segmgr, mobj, segId, typeId) {}
public:
reg_t findCanonicAddress(reg_t addr);
- void listAllDeallocatable(void *param, NoteCallback note);
};
reg_t SegInterfaceBase::findCanonicAddress(reg_t addr) {
@@ -1217,8 +1210,12 @@ reg_t SegInterfaceBase::findCanonicAddress(reg_t addr) {
return addr;
}
-void SegInterfaceBase::listAllDeallocatable(void *param, NoteCallback note) {
- (*note)(param, make_reg(_segId, 0));
+void Script::listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) {
+ (*note)(param, make_reg(segId, 0));
+}
+
+void DynMem::listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) {
+ (*note)(param, make_reg(segId, 0));
}
@@ -1228,7 +1225,6 @@ public:
SegInterfaceScript(SegManager *segmgr, MemObject *mobj, SegmentId segId) :
SegInterfaceBase(segmgr, mobj, segId, MEM_OBJ_SCRIPT) {}
void freeAtAddress(reg_t addr);
- void listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note);
};
void SegInterfaceScript::freeAtAddress(reg_t addr) {
@@ -1243,8 +1239,8 @@ void SegInterfaceScript::freeAtAddress(reg_t addr) {
_segmgr->deallocateScript(script->nr);
}
-void SegInterfaceScript::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
- Script *script = (Script *)_mobj;
+void Script::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
+ Script *script = this;
if (addr.offset <= script->buf_size && addr.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && RAW_IS_OBJECT(script->buf + addr.offset)) {
int idx = RAW_GET_CLASS_INDEX(script, addr);
@@ -1274,25 +1270,21 @@ public:
SegInterfaceClones(SegManager *segmgr, MemObject *mobj, SegmentId segId) :
SegInterface(segmgr, mobj, segId, MEM_OBJ_CLONES) {}
void freeAtAddress(reg_t addr);
- void listAllDeallocatable(void *param, NoteCallback note);
- void listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note);
};
-void SegInterfaceClones::listAllDeallocatable(void *param, NoteCallback note) {
- CloneTable *table = (CloneTable *)_mobj;
- for (int i = 0; i < table->max_entry; i++)
- if (ENTRY_IS_VALID(table, i))
- (*note)(param, make_reg(_segId, i));
-
-
+template<typename T, int INITIAL, int INCREMENT>
+void Table<T, INITIAL, INCREMENT>::listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) {
+ for (int i = 0; i < max_entry; i++)
+ if (isValidEntry(i))
+ (*note)(param, make_reg(segId, i));
}
-void SegInterfaceClones::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
- CloneTable *clone_table = (CloneTable *)_mobj;
+void CloneTable::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
+ CloneTable *clone_table = this;
Clone *clone;
int i;
- assert(addr.segment == _segId);
+// assert(addr.segment == _segId);
if (!(ENTRY_IS_VALID(clone_table, addr.offset))) {
fprintf(stderr, "Unexpected request for outgoing references from clone at "PREG"\n", PRINT_REG(addr));
@@ -1344,7 +1336,6 @@ public:
SegInterface(segmgr, mobj, segId, MEM_OBJ_LOCALS) {}
reg_t findCanonicAddress(reg_t addr);
void freeAtAddress(reg_t addr);
- void listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note);
};
reg_t SegInterfaceLocals::findCanonicAddress(reg_t addr) {
@@ -1362,13 +1353,11 @@ void SegInterfaceLocals::freeAtAddress(reg_t sub_addr) {
// STUB
}
-void SegInterfaceLocals::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
- LocalVariables *locals = (LocalVariables *)_mobj;
+void LocalVariables::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
+// assert(addr.segment == _segId);
- assert(addr.segment == _segId);
-
- for (int i = 0; i < locals->nr; i++)
- (*note)(param, locals->locals[i]);
+ for (int i = 0; i < nr; i++)
+ (*note)(param, locals[i]);
}
@@ -1378,7 +1367,6 @@ public:
SegInterfaceStack(SegManager *segmgr, MemObject *mobj, SegmentId segId) :
SegInterface(segmgr, mobj, segId, MEM_OBJ_STACK) {}
reg_t findCanonicAddress(reg_t addr);
- void listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note);
};
reg_t SegInterfaceStack::findCanonicAddress(reg_t addr) {
@@ -1386,12 +1374,10 @@ reg_t SegInterfaceStack::findCanonicAddress(reg_t addr) {
return addr;
}
-void SegInterfaceStack::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
- int i;
- dstack_t &d = *(dstack_t *)_mobj;
- fprintf(stderr, "Emitting %d stack entries\n", d.nr);
- for (i = 0; i < d.nr; i++)
- (*note)(param, d.entries[i]);
+void dstack_t::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
+ fprintf(stderr, "Emitting %d stack entries\n", nr);
+ for (int i = 0; i < nr; i++)
+ (*note)(param, entries[i]);
fprintf(stderr, "DONE");
}
@@ -1417,8 +1403,6 @@ public:
SegInterfaceLists(SegManager *segmgr, MemObject *mobj, SegmentId segId) :
SegInterface(segmgr, mobj, segId, MEM_OBJ_LISTS) {}
void freeAtAddress(reg_t addr);
- void listAllDeallocatable(void *param, NoteCallback note);
- void listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note);
};
void SegInterfaceLists::freeAtAddress(reg_t sub_addr) {
@@ -1426,22 +1410,14 @@ void SegInterfaceLists::freeAtAddress(reg_t sub_addr) {
table->freeEntry(sub_addr.offset);
}
-void SegInterfaceLists::listAllDeallocatable(void *param, NoteCallback note) {
- ListTable *table = (ListTable *)_mobj;
- for (int i = 0; i < table->max_entry; i++)
- if (ENTRY_IS_VALID(table, i))
- (*note) (param, make_reg(_segId, i));
-}
-
-void SegInterfaceLists::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
- ListTable *table = (ListTable *)_mobj;
- List *list = &(table->table[addr.offset]);
-
- if (!ENTRY_IS_VALID(table, addr.offset)) {
- fprintf(stderr, "Invalid list referenced for outgoing references: "PREG"\n", PRINT_REG(addr));
+void ListTable::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
+ if (!isValidEntry(addr.offset)) {
+ warning("Invalid list referenced for outgoing references: "PREG"", PRINT_REG(addr));
return;
}
+ List *list = &(table[addr.offset]);
+
note(param, list->first);
note(param, list->last);
// We could probably get away with just one of them, but
@@ -1455,8 +1431,6 @@ public:
SegInterfaceNodes(SegManager *segmgr, MemObject *mobj, SegmentId segId) :
SegInterface(segmgr, mobj, segId, MEM_OBJ_NODES) {}
void freeAtAddress(reg_t addr);
- void listAllDeallocatable(void *param, NoteCallback note);
- void listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note);
};
void SegInterfaceNodes::freeAtAddress(reg_t sub_addr) {
@@ -1464,21 +1438,12 @@ void SegInterfaceNodes::freeAtAddress(reg_t sub_addr) {
table->freeEntry(sub_addr.offset);
}
-void SegInterfaceNodes::listAllDeallocatable(void *param, NoteCallback note) {
- NodeTable *table = (NodeTable *)_mobj;
- for (int i = 0; i < table->max_entry; i++)
- if (ENTRY_IS_VALID(table, i))
- (*note) (param, make_reg(_segId, i));
-}
-
-void SegInterfaceNodes::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
- NodeTable *table = (NodeTable *)_mobj;
- Node *node = &(table->table[addr.offset]);
-
- if (!ENTRY_IS_VALID(table, addr.offset)) {
- fprintf(stderr, "Invalid node referenced for outgoing references: "PREG"\n", PRINT_REG(addr));
+void NodeTable::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
+ if (!isValidEntry(addr.offset)) {
+ warning("Invalid node referenced for outgoing references: "PREG"", PRINT_REG(addr));
return;
}
+ Node *node = &(table[addr.offset]);
// We need all four here. Can't just stick with 'pred' OR 'succ' because node operations allow us
// to walk around from any given node
@@ -1495,7 +1460,6 @@ public:
SegInterfaceHunk(SegManager *segmgr, MemObject *mobj, SegmentId segId) :
SegInterface(segmgr, mobj, segId, MEM_OBJ_HUNK) {}
void freeAtAddress(reg_t addr);
- void listAllDeallocatable(void *param, NoteCallback note);
};
void SegInterfaceHunk::freeAtAddress(reg_t sub_addr) {
@@ -1503,14 +1467,6 @@ void SegInterfaceHunk::freeAtAddress(reg_t sub_addr) {
// STUB
}
-void SegInterfaceHunk::listAllDeallocatable(void *param, NoteCallback note) {
- HunkTable *table = (HunkTable *)_mobj;
- for (int i = 0; i < table->max_entry; i++)
- if (ENTRY_IS_VALID(table, i))
- (*note) (param, make_reg(_segId, i));
-}
-
-
//-------------------- dynamic memory --------------------
class SegInterfaceDynMem : public SegInterfaceBase {
public:
diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h
index c76d056383..8729500c7f 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -462,19 +462,6 @@ public:
// Parameters: (reg_t) sub_addr: The address (within the given segment) to deallocate
virtual void freeAtAddress(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
- // (void *) param: Parameter passed to 'note'
- virtual void listAllDeallocatable(void *param, NoteCallback note);
-
- // Iterates over all references reachable from the specified object
- // Parameters: (reg_t) object: The object (within the current segment) to analyse
- // (void *) param: Parameter passed to 'note'
- // note : (voidptr * addr) -> (): Invoked for each outgoing reference within the object
- // Note: This function may also choose to report numbers (segment 0) as adresses
- virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
-
// Get the memory object
MemObject *getMobj() { return _mobj; }
diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h
index cb08f10cb2..912145c982 100644
--- a/engines/sci/engine/vm.h
+++ b/engines/sci/engine/vm.h
@@ -56,6 +56,8 @@ struct MemObject /* : public Common::Serializable */ {
MemObjectType _type;
int _segmgrId; /**< Internal value used by the seg_manager's hash map */
+ typedef void (*NoteCallback)(void *param, reg_t addr); // FIXME: Bad choice of name
+
public:
static MemObject *createMemObject(MemObjectType type);
@@ -72,6 +74,19 @@ public:
inline MemObjectType getType() const { return _type; }
inline int getSegMgrId() const { return _segmgrId; }
+
+ // 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
+ // (void *) param: Parameter passed to 'note'
+ virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) {}
+
+ // Iterates over all references reachable from the specified object
+ // Parameters: (reg_t) object: The object (within the current segment) to analyse
+ // (void *) param: Parameter passed to 'note'
+ // note : (voidptr * addr) -> (): Invoked for each outgoing reference within the object
+ // Note: This function may also choose to report numbers (segment 0) as adresses
+ virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note) {}
};
@@ -230,6 +245,7 @@ public:
}
virtual byte *dereference(reg_t pointer, int *size);
+ virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
// virtual void saveLoadWithSerializer(Common::Serializer &ser);
};
@@ -343,11 +359,13 @@ public:
freeScript();
}
+ void freeScript();
+
virtual byte *dereference(reg_t pointer, int *size);
+ virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note);
+ virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
// virtual void saveLoadWithSerializer(Common::Serializer &ser);
-
- void freeScript();
};
/** Data stack */
@@ -366,6 +384,7 @@ public:
}
virtual byte *dereference(reg_t pointer, int *size);
+ virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
// virtual void saveLoadWithSerializer(Common::Serializer &ser);
};
@@ -467,6 +486,8 @@ public:
entries_used--;
}
+ virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note);
+
// virtual void saveLoadWithSerializer(Common::Serializer &ser);
};
@@ -481,16 +502,20 @@ struct CloneTable : public Table<Clone, 16, 4> {
free(table[idx].variables); // Free the dynamically allocated memory part
}
+
+ virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
};
/* NodeTable */
struct NodeTable : public Table<Node, 32, 16> {
+ virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
};
/* ListTable */
struct ListTable : public Table<List, 8, 4> {
+ virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
};
@@ -520,6 +545,7 @@ public:
}
virtual byte *dereference(reg_t pointer, int *size);
+ virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note);
// virtual void saveLoadWithSerializer(Common::Serializer &ser);
};