diff options
author | Filippos Karapetis | 2011-01-04 12:29:23 +0000 |
---|---|---|
committer | Filippos Karapetis | 2011-01-04 12:29:23 +0000 |
commit | d050b811bb27e1c552cf42af8c9890653c32db3e (patch) | |
tree | 2dc2dcf2d99b129cfb0409e97793ac9d73cdc878 /engines/sci/engine | |
parent | 77a1915377f175282029358e49eae422c44d12ed (diff) | |
download | scummvm-rg350-d050b811bb27e1c552cf42af8c9890653c32db3e.tar.gz scummvm-rg350-d050b811bb27e1c552cf42af8c9890653c32db3e.tar.bz2 scummvm-rg350-d050b811bb27e1c552cf42af8c9890653c32db3e.zip |
SCI: Slight cleanup to the garbage collector
svn-id: r55116
Diffstat (limited to 'engines/sci/engine')
-rw-r--r-- | engines/sci/engine/gc.cpp | 56 |
1 files changed, 26 insertions, 30 deletions
diff --git a/engines/sci/engine/gc.cpp b/engines/sci/engine/gc.cpp index b5dfb3a4c3..7f29b53f01 100644 --- a/engines/sci/engine/gc.cpp +++ b/engines/sci/engine/gc.cpp @@ -32,7 +32,7 @@ namespace Sci { struct WorklistManager { Common::Array<reg_t> _worklist; - AddrSet _map; + AddrSet _map; // used for 2 contains() calls, inside push() and run_gc() void push(reg_t reg) { if (!reg.segment) // No numbers @@ -69,20 +69,31 @@ static AddrSet *normalizeAddresses(SegManager *segMan, const AddrSet &nonnormal_ return normal_map; } +static void processWorkList(SegManager *segMan, WorklistManager &wm, const Common::Array<SegmentObj *> &heap) { + SegmentId stackSegment = segMan->findSegmentByType(SEG_TYPE_STACK); + while (!wm._worklist.empty()) { + reg_t reg = wm._worklist.back(); + wm._worklist.pop_back(); + if (reg.segment != stackSegment) { // No need to repeat this one + debugC(kDebugLevelGC, "[GC] Checking %04x:%04x", PRINT_REG(reg)); + if (reg.segment < heap.size() && heap[reg.segment]) { + // Valid heap object? Find its outgoing references! + wm.pushArray(heap[reg.segment]->listAllOutgoingReferences(reg)); + } + } + } +} AddrSet *findAllActiveReferences(EngineState *s) { - SegManager *segMan = s->_segMan; - AddrSet *normal_map = NULL; - WorklistManager wm; - uint i; - assert(!s->_executionStack.empty()); - // Initialise - // Init: Registers + WorklistManager wm; + + // Initialize registers wm.push(s->r_acc); wm.push(s->r_prev); - // Init: Value Stack + + // Initialize value stack // We do this one by hand since the stack doesn't know the current execution stack Common::List<ExecStack>::iterator iter = s->_executionStack.reverse_begin(); @@ -93,9 +104,8 @@ AddrSet *findAllActiveReferences(EngineState *s) { assert((iter != s->_executionStack.end()) && ((*iter).type != EXEC_STACK_TYPE_KERNEL)); ExecStack &xs = *iter; - reg_t *pos; - for (pos = s->stack_base; pos < xs.sp; pos++) + for (reg_t *pos = s->stack_base; pos < xs.sp; pos++) wm.push(*pos); debugC(kDebugLevelGC, "[GC] -- Finished adding value stack"); @@ -115,10 +125,11 @@ AddrSet *findAllActiveReferences(EngineState *s) { debugC(kDebugLevelGC, "[GC] -- Finished adding execution stack"); - const Common::Array<SegmentObj *> &heap = segMan->getSegments(); + const Common::Array<SegmentObj *> &heap = s->_segMan->getSegments(); + uint heapSize = heap.size(); // Init: Explicitly loaded scripts - for (i = 1; i < heap.size(); i++) { + for (uint i = 1; i < heapSize; i++) { if (heap[i] && heap[i]->getType() == SEG_TYPE_SCRIPT) { Script *script = (Script *)heap[i]; @@ -130,24 +141,9 @@ AddrSet *findAllActiveReferences(EngineState *s) { debugC(kDebugLevelGC, "[GC] -- Finished explicitly loaded scripts, done with root set"); - // Run Worklist Algorithm - SegmentId stack_seg = segMan->findSegmentByType(SEG_TYPE_STACK); - while (!wm._worklist.empty()) { - reg_t reg = wm._worklist.back(); - wm._worklist.pop_back(); - if (reg.segment != stack_seg) { // No need to repeat this one - debugC(kDebugLevelGC, "[GC] Checking %04x:%04x", PRINT_REG(reg)); - if (reg.segment < heap.size() && heap[reg.segment]) { - // Valid heap object? Find its outgoing references! - wm.pushArray(heap[reg.segment]->listAllOutgoingReferences(reg)); - } - } - } - - // Normalise - normal_map = normalizeAddresses(segMan, wm._map); + processWorkList(s->_segMan, wm, heap); - return normal_map; + return normalizeAddresses(s->_segMan, wm._map); } void run_gc(EngineState *s) { |