From 8d4a4271bb0cf78508f600d80893874d436e9883 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Fri, 8 May 2009 09:53:49 +0000 Subject: SCI: Moved freeAtAddress from SegInterface to MemObject svn-id: r40375 --- engines/sci/engine/gc.cpp | 15 ++++++----- engines/sci/engine/seg_manager.cpp | 54 +++++++++----------------------------- engines/sci/engine/seg_manager.h | 4 --- engines/sci/engine/vm.h | 10 +++++++ 4 files changed, 30 insertions(+), 53 deletions(-) (limited to 'engines/sci/engine') 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 @@ -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 { 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 { + 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 { + virtual void freeAtAddress(SegManager *segmgr, reg_t sub_addr); virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note); }; -- cgit v1.2.3