diff options
author | Max Horn | 2009-05-08 09:53:10 +0000 |
---|---|---|
committer | Max Horn | 2009-05-08 09:53:10 +0000 |
commit | d8738b9090c1b8d866f18962be428076de6faae2 (patch) | |
tree | 873675d8f4d5bf696f836998d38b21da7929f09a | |
parent | 76a48947dec0a79ca674948fb199adfdc911d01c (diff) | |
download | scummvm-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.cpp | 6 | ||||
-rw-r--r-- | engines/sci/engine/scriptdebug.cpp | 20 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.cpp | 110 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.h | 13 | ||||
-rw-r--r-- | engines/sci/engine/vm.h | 30 |
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); }; |