SCI: Started to merge SegInterface into MemObject

svn-id: r40373
This commit is contained in:
Max Horn 2009-05-08 09:53:10 +00:00
parent 76a48947de
commit d8738b9090
5 changed files with 76 additions and 103 deletions

View File

@ -150,8 +150,8 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {
#ifdef DEBUG_GC_VERBOSE
sciprintf("[GC] Checking "PREG"\n", PRINT_REG(reg));
#endif
if (reg.segment < sm->_heap.size() && interfaces[reg.segment])
interfaces[reg.segment]->listAllOutgoingReferences(s, reg, &wm, add_outgoing_refs);
if (reg.segment < sm->_heap.size() && sm->_heap[reg.segment])
sm->_heap[reg.segment]->listAllOutgoingReferences(s, reg, &wm, add_outgoing_refs);
}
}
@ -210,7 +210,7 @@ void run_gc(EngineState *s) {
#ifdef DEBUG_GC
deallocator.segnames[deallocator.interfce->getType()] = deallocator.interfce->type;
#endif
deallocator.interfce->listAllDeallocatable(&deallocator, free_unless_used);
sm->_heap[seg_nr]->listAllDeallocatable(seg_nr, &deallocator, free_unless_used);
delete deallocator.interfce;
}
}

View File

@ -2802,12 +2802,14 @@ static void _print_address(void * _, reg_t addr) {
static int c_gc_show_reachable(EngineState *s) {
reg_t addr = cmd_params[0].reg;
GET_SEG_INTERFACE(addr.segment);
MemObject *mobj = GET_SEGMENT_ANY(*s->seg_manager, addr.segment);
if (!mobj) {
sciprintf("Unknown segment : %x\n", addr.segment);
return 1;
}
sciprintf("Reachable from "PREG":\n", PRINT_REG(addr));
seg_interface->listAllOutgoingReferences(s, addr, NULL, _print_address);
delete seg_interface;
mobj->listAllOutgoingReferences(s, addr, NULL, _print_address);
return 0;
}
@ -2815,12 +2817,14 @@ static int c_gc_show_reachable(EngineState *s) {
static int c_gc_show_freeable(EngineState *s) {
reg_t addr = cmd_params[0].reg;
GET_SEG_INTERFACE(addr.segment);
MemObject *mobj = GET_SEGMENT_ANY(*s->seg_manager, addr.segment);
if (!mobj) {
sciprintf("Unknown segment : %x\n", addr.segment);
return 1;
}
sciprintf("Freeable in segment %04x:\n", addr.segment);
seg_interface->listAllDeallocatable(NULL, _print_address);
delete seg_interface;
mobj->listAllDeallocatable(addr.segment, NULL, _print_address);
return 0;
}

View File

@ -1195,12 +1195,6 @@ reg_t SegInterface::findCanonicAddress(reg_t addr) {
void SegInterface::freeAtAddress(reg_t sub_addr) {
}
void SegInterface::listAllDeallocatable(void *param, NoteCallback note) {
}
void SegInterface::listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note) {
}
//-------------------- base --------------------
class SegInterfaceBase : public SegInterface {
@ -1209,7 +1203,6 @@ protected:
SegInterface(segmgr, mobj, segId, typeId) {}
public:
reg_t findCanonicAddress(reg_t addr);
void listAllDeallocatable(void *param, NoteCallback note);
};
reg_t SegInterfaceBase::findCanonicAddress(reg_t addr) {
@ -1217,8 +1210,12 @@ reg_t SegInterfaceBase::findCanonicAddress(reg_t addr) {
return addr;
}
void SegInterfaceBase::listAllDeallocatable(void *param, NoteCallback note) {
(*note)(param, make_reg(_segId, 0));
void Script::listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) {
(*note)(param, make_reg(segId, 0));
}
void DynMem::listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) {
(*note)(param, make_reg(segId, 0));
}
@ -1228,7 +1225,6 @@ public:
SegInterfaceScript(SegManager *segmgr, MemObject *mobj, SegmentId segId) :
SegInterfaceBase(segmgr, mobj, segId, MEM_OBJ_SCRIPT) {}
void freeAtAddress(reg_t addr);
void listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note);
};
void SegInterfaceScript::freeAtAddress(reg_t addr) {
@ -1243,8 +1239,8 @@ void SegInterfaceScript::freeAtAddress(reg_t addr) {
_segmgr->deallocateScript(script->nr);
}
void SegInterfaceScript::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
Script *script = (Script *)_mobj;
void Script::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
Script *script = this;
if (addr.offset <= script->buf_size && addr.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && RAW_IS_OBJECT(script->buf + addr.offset)) {
int idx = RAW_GET_CLASS_INDEX(script, addr);
@ -1274,25 +1270,21 @@ public:
SegInterfaceClones(SegManager *segmgr, MemObject *mobj, SegmentId segId) :
SegInterface(segmgr, mobj, segId, MEM_OBJ_CLONES) {}
void freeAtAddress(reg_t addr);
void listAllDeallocatable(void *param, NoteCallback note);
void listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note);
};
void SegInterfaceClones::listAllDeallocatable(void *param, NoteCallback note) {
CloneTable *table = (CloneTable *)_mobj;
for (int i = 0; i < table->max_entry; i++)
if (ENTRY_IS_VALID(table, i))
(*note)(param, make_reg(_segId, i));
template<typename T, int INITIAL, int INCREMENT>
void Table<T, INITIAL, INCREMENT>::listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) {
for (int i = 0; i < max_entry; i++)
if (isValidEntry(i))
(*note)(param, make_reg(segId, i));
}
void SegInterfaceClones::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
CloneTable *clone_table = (CloneTable *)_mobj;
void CloneTable::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
CloneTable *clone_table = this;
Clone *clone;
int i;
assert(addr.segment == _segId);
// assert(addr.segment == _segId);
if (!(ENTRY_IS_VALID(clone_table, addr.offset))) {
fprintf(stderr, "Unexpected request for outgoing references from clone at "PREG"\n", PRINT_REG(addr));
@ -1344,7 +1336,6 @@ public:
SegInterface(segmgr, mobj, segId, MEM_OBJ_LOCALS) {}
reg_t findCanonicAddress(reg_t addr);
void freeAtAddress(reg_t addr);
void listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note);
};
reg_t SegInterfaceLocals::findCanonicAddress(reg_t addr) {
@ -1362,13 +1353,11 @@ void SegInterfaceLocals::freeAtAddress(reg_t sub_addr) {
// STUB
}
void SegInterfaceLocals::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
LocalVariables *locals = (LocalVariables *)_mobj;
void LocalVariables::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
// assert(addr.segment == _segId);
assert(addr.segment == _segId);
for (int i = 0; i < locals->nr; i++)
(*note)(param, locals->locals[i]);
for (int i = 0; i < nr; i++)
(*note)(param, locals[i]);
}
@ -1378,7 +1367,6 @@ public:
SegInterfaceStack(SegManager *segmgr, MemObject *mobj, SegmentId segId) :
SegInterface(segmgr, mobj, segId, MEM_OBJ_STACK) {}
reg_t findCanonicAddress(reg_t addr);
void listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note);
};
reg_t SegInterfaceStack::findCanonicAddress(reg_t addr) {
@ -1386,12 +1374,10 @@ reg_t SegInterfaceStack::findCanonicAddress(reg_t addr) {
return addr;
}
void SegInterfaceStack::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
int i;
dstack_t &d = *(dstack_t *)_mobj;
fprintf(stderr, "Emitting %d stack entries\n", d.nr);
for (i = 0; i < d.nr; i++)
(*note)(param, d.entries[i]);
void dstack_t::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
fprintf(stderr, "Emitting %d stack entries\n", nr);
for (int i = 0; i < nr; i++)
(*note)(param, entries[i]);
fprintf(stderr, "DONE");
}
@ -1417,8 +1403,6 @@ public:
SegInterfaceLists(SegManager *segmgr, MemObject *mobj, SegmentId segId) :
SegInterface(segmgr, mobj, segId, MEM_OBJ_LISTS) {}
void freeAtAddress(reg_t addr);
void listAllDeallocatable(void *param, NoteCallback note);
void listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note);
};
void SegInterfaceLists::freeAtAddress(reg_t sub_addr) {
@ -1426,22 +1410,14 @@ void SegInterfaceLists::freeAtAddress(reg_t sub_addr) {
table->freeEntry(sub_addr.offset);
}
void SegInterfaceLists::listAllDeallocatable(void *param, NoteCallback note) {
ListTable *table = (ListTable *)_mobj;
for (int i = 0; i < table->max_entry; i++)
if (ENTRY_IS_VALID(table, i))
(*note) (param, make_reg(_segId, i));
}
void SegInterfaceLists::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
ListTable *table = (ListTable *)_mobj;
List *list = &(table->table[addr.offset]);
if (!ENTRY_IS_VALID(table, addr.offset)) {
fprintf(stderr, "Invalid list referenced for outgoing references: "PREG"\n", PRINT_REG(addr));
void ListTable::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
if (!isValidEntry(addr.offset)) {
warning("Invalid list referenced for outgoing references: "PREG"", PRINT_REG(addr));
return;
}
List *list = &(table[addr.offset]);
note(param, list->first);
note(param, list->last);
// We could probably get away with just one of them, but
@ -1455,8 +1431,6 @@ public:
SegInterfaceNodes(SegManager *segmgr, MemObject *mobj, SegmentId segId) :
SegInterface(segmgr, mobj, segId, MEM_OBJ_NODES) {}
void freeAtAddress(reg_t addr);
void listAllDeallocatable(void *param, NoteCallback note);
void listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note);
};
void SegInterfaceNodes::freeAtAddress(reg_t sub_addr) {
@ -1464,21 +1438,12 @@ void SegInterfaceNodes::freeAtAddress(reg_t sub_addr) {
table->freeEntry(sub_addr.offset);
}
void SegInterfaceNodes::listAllDeallocatable(void *param, NoteCallback note) {
NodeTable *table = (NodeTable *)_mobj;
for (int i = 0; i < table->max_entry; i++)
if (ENTRY_IS_VALID(table, i))
(*note) (param, make_reg(_segId, i));
}
void SegInterfaceNodes::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
NodeTable *table = (NodeTable *)_mobj;
Node *node = &(table->table[addr.offset]);
if (!ENTRY_IS_VALID(table, addr.offset)) {
fprintf(stderr, "Invalid node referenced for outgoing references: "PREG"\n", PRINT_REG(addr));
void NodeTable::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
if (!isValidEntry(addr.offset)) {
warning("Invalid node referenced for outgoing references: "PREG"", PRINT_REG(addr));
return;
}
Node *node = &(table[addr.offset]);
// We need all four here. Can't just stick with 'pred' OR 'succ' because node operations allow us
// to walk around from any given node
@ -1495,7 +1460,6 @@ public:
SegInterfaceHunk(SegManager *segmgr, MemObject *mobj, SegmentId segId) :
SegInterface(segmgr, mobj, segId, MEM_OBJ_HUNK) {}
void freeAtAddress(reg_t addr);
void listAllDeallocatable(void *param, NoteCallback note);
};
void SegInterfaceHunk::freeAtAddress(reg_t sub_addr) {
@ -1503,14 +1467,6 @@ void SegInterfaceHunk::freeAtAddress(reg_t sub_addr) {
// STUB
}
void SegInterfaceHunk::listAllDeallocatable(void *param, NoteCallback note) {
HunkTable *table = (HunkTable *)_mobj;
for (int i = 0; i < table->max_entry; i++)
if (ENTRY_IS_VALID(table, i))
(*note) (param, make_reg(_segId, i));
}
//-------------------- dynamic memory --------------------
class SegInterfaceDynMem : public SegInterfaceBase {
public:

View File

@ -462,19 +462,6 @@ public:
// Parameters: (reg_t) sub_addr: The address (within the given segment) to deallocate
virtual void freeAtAddress(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
// (void *) param: Parameter passed to 'note'
virtual void listAllDeallocatable(void *param, NoteCallback note);
// Iterates over all references reachable from the specified object
// Parameters: (reg_t) object: The object (within the current segment) to analyse
// (void *) param: Parameter passed to 'note'
// note : (voidptr * addr) -> (): Invoked for each outgoing reference within the object
// Note: This function may also choose to report numbers (segment 0) as adresses
virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
// Get the memory object
MemObject *getMobj() { return _mobj; }

View File

@ -56,6 +56,8 @@ struct MemObject /* : public Common::Serializable */ {
MemObjectType _type;
int _segmgrId; /**< Internal value used by the seg_manager's hash map */
typedef void (*NoteCallback)(void *param, reg_t addr); // FIXME: Bad choice of name
public:
static MemObject *createMemObject(MemObjectType type);
@ -72,6 +74,19 @@ public:
inline MemObjectType getType() const { return _type; }
inline int getSegMgrId() const { return _segmgrId; }
// 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
// (void *) param: Parameter passed to 'note'
virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) {}
// Iterates over all references reachable from the specified object
// Parameters: (reg_t) object: The object (within the current segment) to analyse
// (void *) param: Parameter passed to 'note'
// note : (voidptr * addr) -> (): Invoked for each outgoing reference within the object
// Note: This function may also choose to report numbers (segment 0) as adresses
virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note) {}
};
@ -230,6 +245,7 @@ public:
}
virtual byte *dereference(reg_t pointer, int *size);
virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
// virtual void saveLoadWithSerializer(Common::Serializer &ser);
};
@ -343,11 +359,13 @@ public:
freeScript();
}
void freeScript();
virtual byte *dereference(reg_t pointer, int *size);
virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note);
virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
// virtual void saveLoadWithSerializer(Common::Serializer &ser);
void freeScript();
};
/** Data stack */
@ -366,6 +384,7 @@ public:
}
virtual byte *dereference(reg_t pointer, int *size);
virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
// virtual void saveLoadWithSerializer(Common::Serializer &ser);
};
@ -467,6 +486,8 @@ public:
entries_used--;
}
virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note);
// virtual void saveLoadWithSerializer(Common::Serializer &ser);
};
@ -481,16 +502,20 @@ struct CloneTable : public Table<Clone, 16, 4> {
free(table[idx].variables); // Free the dynamically allocated memory part
}
virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
};
/* NodeTable */
struct NodeTable : public Table<Node, 32, 16> {
virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
};
/* ListTable */
struct ListTable : public Table<List, 8, 4> {
virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
};
@ -520,6 +545,7 @@ public:
}
virtual byte *dereference(reg_t pointer, int *size);
virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note);
// virtual void saveLoadWithSerializer(Common::Serializer &ser);
};