From 0d555c497d7208d0fa686f1b2369a52841873990 Mon Sep 17 00:00:00 2001 From: md5 Date: Mon, 28 Feb 2011 14:22:16 +0200 Subject: SCI: Moved hunk pointer handling to the GC, and removed some related workarounds SCI scripts can contain stale pointers, which are used later on. We now delete the contents of hunk entries without invalidating the relevant pointers and let the GC clear the references. Many thanks to waltervn and wjp for all their work and help on this. --- engines/sci/engine/segment.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'engines/sci/engine/segment.cpp') diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp index 05d914cffb..d1f56f0da2 100644 --- a/engines/sci/engine/segment.cpp +++ b/engines/sci/engine/segment.cpp @@ -275,6 +275,11 @@ Common::Array DataStack::listAllOutgoingReferences(reg_t object) const { } +//-------------------- hunk --------------------- +void HunkTable::freeAtAddress(SegManager *segMan, reg_t sub_addr) { + freeEntry(sub_addr.offset); +} + //-------------------- lists -------------------- void ListTable::freeAtAddress(SegManager *segMan, reg_t sub_addr) { freeEntry(sub_addr.offset); -- cgit v1.2.3 From 0642b30933b464ddffff591ca672345d0ec55103 Mon Sep 17 00:00:00 2001 From: md5 Date: Tue, 8 Mar 2011 14:46:03 +0200 Subject: SCI: Cleanup --- engines/sci/engine/segment.cpp | 58 ++++-------------------------------------- 1 file changed, 5 insertions(+), 53 deletions(-) (limited to 'engines/sci/engine/segment.cpp') diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp index d1f56f0da2..2af4771cea 100644 --- a/engines/sci/engine/segment.cpp +++ b/engines/sci/engine/segment.cpp @@ -39,7 +39,6 @@ namespace Sci { //#define GC_DEBUG // Debug garbage collection //#define GC_DEBUG_VERBOSE // Debug garbage verbosely - SegmentObj *SegmentObj::createSegmentObj(SegmentType type) { SegmentObj *mem = 0; switch (type) { @@ -85,47 +84,6 @@ SegmentObj *SegmentObj::createSegmentObj(SegmentType type) { return mem; } -const char *SegmentObj::getSegmentTypeName(SegmentType type) { - switch (type) { - case SEG_TYPE_SCRIPT: - return "script"; - break; - case SEG_TYPE_CLONES: - return "clones"; - break; - case SEG_TYPE_LOCALS: - return "locals"; - break; - case SEG_TYPE_STACK: - return "stack"; - break; - case SEG_TYPE_HUNK: - return "hunk"; - break; - case SEG_TYPE_LISTS: - return "lists"; - break; - case SEG_TYPE_NODES: - return "nodes"; - break; - case SEG_TYPE_DYNMEM: - return "dynmem"; - break; -#ifdef ENABLE_SCI32 - case SEG_TYPE_ARRAY: - return "array"; - break; - case SEG_TYPE_STRING: - return "string"; - break; -#endif - default: - error("Unknown SegmentObj type %d", type); - break; - } - return NULL; -} - SegmentRef SegmentObj::dereference(reg_t pointer) { error("Error: Trying to dereference pointer %04x:%04x to inappropriate segment", PRINT_REG(pointer)); @@ -220,8 +178,6 @@ Common::Array CloneTable::listAllOutgoingReferences(reg_t addr) const { void CloneTable::freeAtAddress(SegManager *segMan, reg_t addr) { #ifdef GC_DEBUG - // assert(addr.segment == _segId); - Object *victim_obj = &(_table[addr.offset]); if (!(victim_obj->_flags & OBJECT_FLAG_FREED)) @@ -229,12 +185,11 @@ void CloneTable::freeAtAddress(SegManager *segMan, reg_t addr) { #ifdef GC_DEBUG_VERBOSE else warning("[GC-DEBUG] Clone %04x:%04x: Freeing", PRINT_REG(addr)); + + warning("[GC] Clone had pos %04x:%04x", PRINT_REG(victim_obj->pos)); #endif #endif - /* - warning("[GC] Clone %04x:%04x: Freeing", PRINT_REG(addr)); - warning("[GC] Clone had pos %04x:%04x", PRINT_REG(victim_obj->pos)); - */ + freeEntry(addr.offset); } @@ -251,7 +206,6 @@ reg_t LocalVariables::findCanonicAddress(SegManager *segMan, reg_t addr) const { Common::Array LocalVariables::listAllOutgoingReferences(reg_t addr) const { Common::Array tmp; -// assert(addr.segment == _segId); for (uint i = 0; i < _locals.size(); i++) tmp.push_back(_locals[i]); @@ -262,8 +216,7 @@ Common::Array LocalVariables::listAllOutgoingReferences(reg_t addr) const //-------------------- stack -------------------- reg_t DataStack::findCanonicAddress(SegManager *segMan, reg_t addr) const { - addr.offset = 0; - return addr; + return make_reg(addr.segment, 0); } Common::Array DataStack::listAllOutgoingReferences(reg_t object) const { @@ -327,8 +280,7 @@ Common::Array NodeTable::listAllOutgoingReferences(reg_t addr) const { //-------------------- dynamic memory -------------------- reg_t DynMem::findCanonicAddress(SegManager *segMan, reg_t addr) const { - addr.offset = 0; - return addr; + return make_reg(addr.segment, 0); } Common::Array DynMem::listAllDeallocatable(SegmentId segId) const { -- cgit v1.2.3 From 12e7d3078b8dade7e9c109d1141889886fa4048e Mon Sep 17 00:00:00 2001 From: md5 Date: Tue, 8 Mar 2011 20:13:08 +0200 Subject: SCI: Cleanup --- engines/sci/engine/segment.cpp | 141 ++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 93 deletions(-) (limited to 'engines/sci/engine/segment.cpp') diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp index 2af4771cea..2bb77c707a 100644 --- a/engines/sci/engine/segment.cpp +++ b/engines/sci/engine/segment.cpp @@ -90,69 +90,6 @@ SegmentRef SegmentObj::dereference(reg_t pointer) { return SegmentRef(); } - -bool LocalVariables::isValidOffset(uint16 offset) const { - return offset < _locals.size() * 2; -} - -SegmentRef LocalVariables::dereference(reg_t pointer) { - SegmentRef ret; - ret.isRaw = false; // reg_t based data! - ret.maxSize = (_locals.size() - pointer.offset / 2) * 2; - - if (pointer.offset & 1) { - ret.maxSize -= 1; - ret.skipByte = true; - } - - if (ret.maxSize > 0) { - ret.reg = &_locals[pointer.offset / 2]; - } else { - if ((g_sci->getEngineState()->currentRoomNumber() == 660 || g_sci->getEngineState()->currentRoomNumber() == 660) - && g_sci->getGameId() == GID_LAURABOW2) { - // Happens in two places during the intro of LB2CD, both from kMemory(peek): - // - room 160: Heap 160 has 83 local variables (0-82), and the game - // asks for variables at indices 83 - 90 too. - // - room 220: Heap 220 has 114 local variables (0-113), and the - // game asks for variables at indices 114-120 too. - } else { - error("LocalVariables::dereference: Offset at end or out of bounds %04x:%04x", PRINT_REG(pointer)); - } - ret.reg = 0; - } - return ret; -} - -bool DataStack::isValidOffset(uint16 offset) const { - return offset < _capacity * 2; -} - -SegmentRef DataStack::dereference(reg_t pointer) { - SegmentRef ret; - ret.isRaw = false; // reg_t based data! - ret.maxSize = (_capacity - pointer.offset / 2) * 2; - - if (pointer.offset & 1) { - ret.maxSize -= 1; - ret.skipByte = true; - } - - ret.reg = &_entries[pointer.offset / 2]; - return ret; -} - -bool DynMem::isValidOffset(uint16 offset) const { - return offset < _size; -} - -SegmentRef DynMem::dereference(reg_t pointer) { - SegmentRef ret; - ret.isRaw = true; - ret.maxSize = _size - pointer.offset; - ret.raw = _buf + pointer.offset; - return ret; -} - //-------------------- clones -------------------- Common::Array CloneTable::listAllOutgoingReferences(reg_t addr) const { @@ -195,18 +132,44 @@ void CloneTable::freeAtAddress(SegManager *segMan, reg_t addr) { //-------------------- locals -------------------- + +SegmentRef LocalVariables::dereference(reg_t pointer) { + SegmentRef ret; + ret.isRaw = false; // reg_t based data! + ret.maxSize = (_locals.size() - pointer.offset / 2) * 2; + + if (pointer.offset & 1) { + ret.maxSize -= 1; + ret.skipByte = true; + } + + if (ret.maxSize > 0) { + ret.reg = &_locals[pointer.offset / 2]; + } else { + if ((g_sci->getEngineState()->currentRoomNumber() == 660 || g_sci->getEngineState()->currentRoomNumber() == 660) + && g_sci->getGameId() == GID_LAURABOW2) { + // Happens in two places during the intro of LB2CD, both from kMemory(peek): + // - room 160: Heap 160 has 83 local variables (0-82), and the game + // asks for variables at indices 83 - 90 too. + // - room 220: Heap 220 has 114 local variables (0-113), and the + // game asks for variables at indices 114-120 too. + } else { + error("LocalVariables::dereference: Offset at end or out of bounds %04x:%04x", PRINT_REG(pointer)); + } + ret.reg = 0; + } + return ret; +} + reg_t LocalVariables::findCanonicAddress(SegManager *segMan, reg_t addr) const { // Reference the owning script SegmentId owner_seg = segMan->getScriptSegment(script_id); - assert(owner_seg > 0); - return make_reg(owner_seg, 0); } Common::Array LocalVariables::listAllOutgoingReferences(reg_t addr) const { Common::Array tmp; - for (uint i = 0; i < _locals.size(); i++) tmp.push_back(_locals[i]); @@ -215,8 +178,19 @@ Common::Array LocalVariables::listAllOutgoingReferences(reg_t addr) const //-------------------- stack -------------------- -reg_t DataStack::findCanonicAddress(SegManager *segMan, reg_t addr) const { - return make_reg(addr.segment, 0); + +SegmentRef DataStack::dereference(reg_t pointer) { + SegmentRef ret; + ret.isRaw = false; // reg_t based data! + ret.maxSize = (_capacity - pointer.offset / 2) * 2; + + if (pointer.offset & 1) { + ret.maxSize -= 1; + ret.skipByte = true; + } + + ret.reg = &_entries[pointer.offset / 2]; + return ret; } Common::Array DataStack::listAllOutgoingReferences(reg_t object) const { @@ -227,16 +201,7 @@ Common::Array DataStack::listAllOutgoingReferences(reg_t object) const { return tmp; } - -//-------------------- hunk --------------------- -void HunkTable::freeAtAddress(SegManager *segMan, reg_t sub_addr) { - freeEntry(sub_addr.offset); -} - //-------------------- lists -------------------- -void ListTable::freeAtAddress(SegManager *segMan, reg_t sub_addr) { - freeEntry(sub_addr.offset); -} Common::Array ListTable::listAllOutgoingReferences(reg_t addr) const { Common::Array tmp; @@ -254,11 +219,7 @@ Common::Array ListTable::listAllOutgoingReferences(reg_t addr) const { return tmp; } - //-------------------- nodes -------------------- -void NodeTable::freeAtAddress(SegManager *segMan, reg_t sub_addr) { - freeEntry(sub_addr.offset); -} Common::Array NodeTable::listAllOutgoingReferences(reg_t addr) const { Common::Array tmp; @@ -279,13 +240,12 @@ Common::Array NodeTable::listAllOutgoingReferences(reg_t addr) const { //-------------------- dynamic memory -------------------- -reg_t DynMem::findCanonicAddress(SegManager *segMan, reg_t addr) const { - return make_reg(addr.segment, 0); -} - -Common::Array DynMem::listAllDeallocatable(SegmentId segId) const { - const reg_t r = make_reg(segId, 0); - return Common::Array(&r, 1); +SegmentRef DynMem::dereference(reg_t pointer) { + SegmentRef ret; + ret.isRaw = true; + ret.maxSize = _size - pointer.offset; + ret.raw = _buf + pointer.offset; + return ret; } #ifdef ENABLE_SCI32 @@ -350,11 +310,6 @@ SegmentRef StringTable::dereference(reg_t pointer) { return ret; } -void StringTable::freeAtAddress(SegManager *segMan, reg_t sub_addr) { - _table[sub_addr.offset].destroy(); - freeEntry(sub_addr.offset); -} - #endif } // End of namespace Sci -- cgit v1.2.3