aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorFilippos Karapetis2011-01-04 12:29:23 +0000
committerFilippos Karapetis2011-01-04 12:29:23 +0000
commitd050b811bb27e1c552cf42af8c9890653c32db3e (patch)
tree2dc2dcf2d99b129cfb0409e97793ac9d73cdc878 /engines
parent77a1915377f175282029358e49eae422c44d12ed (diff)
downloadscummvm-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')
-rw-r--r--engines/sci/engine/gc.cpp56
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) {