diff options
author | Max Horn | 2010-06-28 11:22:41 +0000 |
---|---|---|
committer | Max Horn | 2010-06-28 11:22:41 +0000 |
commit | 31b29027144e3a76ab6e8c71a0014ca6121218c0 (patch) | |
tree | 722fd79896f1063fbdab7f336e9913dd9e2170a3 /engines/sci/engine/gc.cpp | |
parent | 30218a2c324bc67f724100051ab9884a351928fb (diff) | |
download | scummvm-rg350-31b29027144e3a76ab6e8c71a0014ca6121218c0.tar.gz scummvm-rg350-31b29027144e3a76ab6e8c71a0014ca6121218c0.tar.bz2 scummvm-rg350-31b29027144e3a76ab6e8c71a0014ca6121218c0.zip |
SCI: Revise GC interface: use Common::Array<reg_t> instead of callbacks
This means a little bit more overhead but makes the code much more readable
and understandable.
svn-id: r50429
Diffstat (limited to 'engines/sci/engine/gc.cpp')
-rw-r--r-- | engines/sci/engine/gc.cpp | 35 |
1 files changed, 16 insertions, 19 deletions
diff --git a/engines/sci/engine/gc.cpp b/engines/sci/engine/gc.cpp index c2f1c15776..59f62c8996 100644 --- a/engines/sci/engine/gc.cpp +++ b/engines/sci/engine/gc.cpp @@ -46,6 +46,11 @@ struct WorklistManager { _map.setVal(reg, true); _worklist.push_back(reg); } + + void push(const Common::Array<reg_t> &tmp) { + for (Common::Array<reg_t>::const_iterator it = tmp.begin(); it != tmp.end(); ++it) + push(*it); + } }; static reg_t_hash_map *normalise_hashmap_ptrs(SegManager *segMan, reg_t_hash_map &nonnormal_map) { @@ -65,11 +70,6 @@ static reg_t_hash_map *normalise_hashmap_ptrs(SegManager *segMan, reg_t_hash_map } -void add_outgoing_refs(void *refcon, reg_t addr) { - WorklistManager *wm = (WorklistManager *)refcon; - wm->push(addr); -} - reg_t_hash_map *find_all_used_references(EngineState *s) { SegManager *segMan = s->_segMan; reg_t_hash_map *normal_map = NULL; @@ -125,15 +125,7 @@ reg_t_hash_map *find_all_used_references(EngineState *s) { Script *script = (Script *)segMan->_heap[i]; if (script->getLockers()) { // Explicitly loaded? - // Locals, if present - wm.push(make_reg(script->_localsSegment, 0)); - - // All objects (may be classes, may be indirectly reachable) - ObjMap::iterator it; - const ObjMap::iterator end = script->_objects.end(); - for (it = script->_objects.begin(); it != end; ++it) { - wm.push(it->_value.getPos()); - } + wm.push(script->listObjectReferences()); } } @@ -146,8 +138,10 @@ reg_t_hash_map *find_all_used_references(EngineState *s) { wm._worklist.pop_back(); if (reg.segment != stack_seg) { // No need to repeat this one debugC(2, kDebugLevelGC, "[GC] Checking %04x:%04x", PRINT_REG(reg)); - if (reg.segment < segMan->_heap.size() && segMan->_heap[reg.segment]) - segMan->_heap[reg.segment]->listAllOutgoingReferences(reg, &wm, add_outgoing_refs); + if (reg.segment < segMan->_heap.size() && segMan->_heap[reg.segment]) { + // Valid heap object? Find its outgoing references! + wm.push(segMan->_heap[reg.segment]->listAllOutgoingReferences(reg)); + } } } @@ -167,8 +161,7 @@ struct deallocator_t { reg_t_hash_map *use_map; }; -void free_unless_used(void *refcon, reg_t addr) { - deallocator_t *deallocator = (deallocator_t *)refcon; +static void free_unless_used(deallocator_t *deallocator, reg_t addr) { reg_t_hash_map *use_map = deallocator->use_map; if (!use_map->contains(addr)) { @@ -201,7 +194,11 @@ void run_gc(EngineState *s) { #ifdef DEBUG_GC deallocator.segnames[deallocator.mobj->getType()] = deallocator.mobj->type; // FIXME: add a segment "name" #endif - deallocator.mobj->listAllDeallocatable(seg_nr, &deallocator, free_unless_used); + const Common::Array<reg_t> tmp = deallocator.mobj->listAllDeallocatable(seg_nr); + for (Common::Array<reg_t>::const_iterator it = tmp.begin(); it != tmp.end(); ++it) { + free_unless_used(&deallocator, *it); + } + } } |