SCI: Changed SegManager to store the heap pointers in a Common::Arrray
svn-id: r40293
This commit is contained in:
parent
6a632b51ad
commit
82f2672008
9 changed files with 87 additions and 110 deletions
|
@ -80,9 +80,9 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {
|
||||||
WorklistManager wm;
|
WorklistManager wm;
|
||||||
uint i;
|
uint i;
|
||||||
|
|
||||||
interfaces.resize(sm->heap_size);
|
interfaces.resize(sm->_heap.size());
|
||||||
for (i = 1; i < sm->heap_size; i++)
|
for (i = 1; i < sm->_heap.size(); i++)
|
||||||
if (sm->heap[i] == NULL)
|
if (sm->_heap[i] == NULL)
|
||||||
interfaces[i] = NULL;
|
interfaces[i] = NULL;
|
||||||
else
|
else
|
||||||
interfaces[i] = sm->getSegInterface(i);
|
interfaces[i] = sm->getSegInterface(i);
|
||||||
|
@ -120,7 +120,7 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Init: Explicitly loaded scripts
|
// Init: Explicitly loaded scripts
|
||||||
for (i = 1; i < sm->heap_size; i++)
|
for (i = 1; i < sm->_heap.size(); i++)
|
||||||
if (interfaces[i]
|
if (interfaces[i]
|
||||||
&& interfaces[i]->getType() == MEM_OBJ_SCRIPT) {
|
&& interfaces[i]->getType() == MEM_OBJ_SCRIPT) {
|
||||||
Script *script = &(interfaces[i]->getMobj()->data.script);
|
Script *script = &(interfaces[i]->getMobj()->data.script);
|
||||||
|
@ -150,7 +150,7 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {
|
||||||
#ifdef DEBUG_GC_VERBOSE
|
#ifdef DEBUG_GC_VERBOSE
|
||||||
sciprintf("[GC] Checking "PREG"\n", PRINT_REG(reg));
|
sciprintf("[GC] Checking "PREG"\n", PRINT_REG(reg));
|
||||||
#endif
|
#endif
|
||||||
if (reg.segment < sm->heap_size && interfaces[reg.segment])
|
if (reg.segment < sm->_heap.size() && interfaces[reg.segment])
|
||||||
interfaces[reg.segment]->listAllOutgoingReferences(s, reg, &wm, add_outgoing_refs);
|
interfaces[reg.segment]->listAllOutgoingReferences(s, reg, &wm, add_outgoing_refs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {
|
||||||
normal_map = normalise_hashmap_ptrs(wm._map, interfaces);
|
normal_map = normalise_hashmap_ptrs(wm._map, interfaces);
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
for (i = 1; i < sm->heap_size; i++)
|
for (i = 1; i < sm->_heap.size(); i++)
|
||||||
if (interfaces[i])
|
if (interfaces[i])
|
||||||
delete interfaces[i];
|
delete interfaces[i];
|
||||||
|
|
||||||
|
@ -204,8 +204,8 @@ void run_gc(EngineState *s) {
|
||||||
|
|
||||||
deallocator.use_map = find_all_used_references(s);
|
deallocator.use_map = find_all_used_references(s);
|
||||||
|
|
||||||
for (seg_nr = 1; seg_nr < sm->heap_size; seg_nr++) {
|
for (seg_nr = 1; seg_nr < sm->_heap.size(); seg_nr++) {
|
||||||
if (sm->heap[seg_nr] != NULL) {
|
if (sm->_heap[seg_nr] != NULL) {
|
||||||
deallocator.interfce = sm->getSegInterface(seg_nr);
|
deallocator.interfce = sm->getSegInterface(seg_nr);
|
||||||
#ifdef DEBUG_GC
|
#ifdef DEBUG_GC
|
||||||
deallocator.segnames[deallocator.interfce->getType()] = deallocator.interfce->type;
|
deallocator.segnames[deallocator.interfce->getType()] = deallocator.interfce->type;
|
||||||
|
|
|
@ -454,7 +454,7 @@ reg_t kMemory(EngineState *s, int funct_nr, int argc, reg_t *argv) {
|
||||||
SCIkdebug(SCIkERROR, "Attempt to poke invalid memory at "PREG"!\n", PRINT_REG(argv[1]));
|
SCIkdebug(SCIkERROR, "Attempt to poke invalid memory at "PREG"!\n", PRINT_REG(argv[1]));
|
||||||
return s->r_acc;
|
return s->r_acc;
|
||||||
}
|
}
|
||||||
if (s->seg_manager->heap[argv[1].segment]->getType() == MEM_OBJ_LOCALS)
|
if (s->seg_manager->_heap[argv[1].segment]->getType() == MEM_OBJ_LOCALS)
|
||||||
return *((reg_t *) ref);
|
return *((reg_t *) ref);
|
||||||
else
|
else
|
||||||
return make_reg(0, (int16)READ_LE_UINT16(ref));
|
return make_reg(0, (int16)READ_LE_UINT16(ref));
|
||||||
|
@ -468,7 +468,7 @@ reg_t kMemory(EngineState *s, int funct_nr, int argc, reg_t *argv) {
|
||||||
return s->r_acc;
|
return s->r_acc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->seg_manager->heap[argv[1].segment]->getType() == MEM_OBJ_LOCALS)
|
if (s->seg_manager->_heap[argv[1].segment]->getType() == MEM_OBJ_LOCALS)
|
||||||
*((reg_t *) ref) = argv[2];
|
*((reg_t *) ref) = argv[2];
|
||||||
else {
|
else {
|
||||||
if (argv[2].segment) {
|
if (argv[2].segment) {
|
||||||
|
@ -667,10 +667,10 @@ int determine_reg_type(EngineState *s, reg_t reg, int allow_invalid) {
|
||||||
return KSIG_ARITHMETIC;
|
return KSIG_ARITHMETIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((reg.segment >= s->seg_manager->heap_size) || !s->seg_manager->heap[reg.segment])
|
if ((reg.segment >= s->seg_manager->_heap.size()) || !s->seg_manager->_heap[reg.segment])
|
||||||
return 0; // Invalid
|
return 0; // Invalid
|
||||||
|
|
||||||
mobj = s->seg_manager->heap[reg.segment];
|
mobj = s->seg_manager->_heap[reg.segment];
|
||||||
|
|
||||||
switch (mobj->getType()) {
|
switch (mobj->getType()) {
|
||||||
case MEM_OBJ_SCRIPT:
|
case MEM_OBJ_SCRIPT:
|
||||||
|
|
|
@ -368,7 +368,7 @@ reg_t kStrCpy(EngineState *s, int funct_nr, int argc, reg_t *argv) {
|
||||||
if (length >= 0)
|
if (length >= 0)
|
||||||
strncpy(dest, src, length);
|
strncpy(dest, src, length);
|
||||||
else {
|
else {
|
||||||
if (s->seg_manager->heap[argv[0].segment]->getType() == MEM_OBJ_DYNMEM) {
|
if (s->seg_manager->_heap[argv[0].segment]->getType() == MEM_OBJ_DYNMEM) {
|
||||||
reg_t *srcp = (reg_t *) src;
|
reg_t *srcp = (reg_t *) src;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -172,8 +172,8 @@ void Menubar::saveLoadWithSerializer(Common::Serializer &s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SegManager::saveLoadWithSerializer(Common::Serializer &s) {
|
void SegManager::saveLoadWithSerializer(Common::Serializer &s) {
|
||||||
uint allocated_heap_size = heap_size;
|
uint sync_heap_size = _heap.size();
|
||||||
s.syncAsUint32LE(heap_size);
|
s.syncAsUint32LE(sync_heap_size);
|
||||||
s.syncAsSint32LE(reserved_id);
|
s.syncAsSint32LE(reserved_id);
|
||||||
s.syncAsSint32LE(exports_wide);
|
s.syncAsSint32LE(exports_wide);
|
||||||
s.syncAsSint32LE(gc_mark_bits);
|
s.syncAsSint32LE(gc_mark_bits);
|
||||||
|
@ -181,11 +181,9 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) {
|
||||||
|
|
||||||
id_seg_map->saveLoadWithSerializer(s);
|
id_seg_map->saveLoadWithSerializer(s);
|
||||||
|
|
||||||
assert(heap);
|
_heap.resize(sync_heap_size);
|
||||||
if (allocated_heap_size != heap_size)
|
for (uint i = 0; i < sync_heap_size; ++i)
|
||||||
heap = (MemObject**)sci_realloc((void *)heap, heap_size * sizeof(MemObject *));
|
sync_MemObjPtr(s, _heap[i]);
|
||||||
for (uint i = 0; i < heap_size; ++i)
|
|
||||||
sync_MemObjPtr(s, heap[i]);
|
|
||||||
|
|
||||||
s.syncAsSint32LE(Clones_seg_id);
|
s.syncAsSint32LE(Clones_seg_id);
|
||||||
s.syncAsSint32LE(Lists_seg_id);
|
s.syncAsSint32LE(Lists_seg_id);
|
||||||
|
@ -538,9 +536,9 @@ int gamestate_save(EngineState *s, Common::WriteStream *fh, const char* savename
|
||||||
|
|
||||||
// FIXME: This should probably be turned into a SegManager method
|
// FIXME: This should probably be turned into a SegManager method
|
||||||
static SegmentId find_unique_seg_by_type(SegManager *self, int type) {
|
static SegmentId find_unique_seg_by_type(SegManager *self, int type) {
|
||||||
for (uint i = 0; i < self->heap_size; i++)
|
for (uint i = 0; i < self->_heap.size(); i++)
|
||||||
if (self->heap[i] &&
|
if (self->_heap[i] &&
|
||||||
self->heap[i]->getType() == type)
|
self->_heap[i]->getType() == type)
|
||||||
return i;
|
return i;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -566,7 +564,7 @@ static byte *find_unique_script_block(EngineState *s, byte *buf, int type) {
|
||||||
// FIXME: This should probably be turned into an EngineState method
|
// FIXME: This should probably be turned into an EngineState method
|
||||||
static void reconstruct_stack(EngineState *retval) {
|
static void reconstruct_stack(EngineState *retval) {
|
||||||
SegmentId stack_seg = find_unique_seg_by_type(retval->seg_manager, MEM_OBJ_STACK);
|
SegmentId stack_seg = find_unique_seg_by_type(retval->seg_manager, MEM_OBJ_STACK);
|
||||||
dstack_t *stack = &(retval->seg_manager->heap[stack_seg]->data.stack);
|
dstack_t *stack = &(retval->seg_manager->_heap[stack_seg]->data.stack);
|
||||||
|
|
||||||
retval->stack_segment = stack_seg;
|
retval->stack_segment = stack_seg;
|
||||||
retval->stack_base = stack->entries;
|
retval->stack_base = stack->entries;
|
||||||
|
@ -591,7 +589,7 @@ static int clone_entry_used(CloneTable *table, int n) {
|
||||||
|
|
||||||
static void load_script(EngineState *s, SegmentId seg) {
|
static void load_script(EngineState *s, SegmentId seg) {
|
||||||
Resource *script, *heap = NULL;
|
Resource *script, *heap = NULL;
|
||||||
Script *scr = &(s->seg_manager->heap[seg]->data.script);
|
Script *scr = &(s->seg_manager->_heap[seg]->data.script);
|
||||||
|
|
||||||
scr->buf = (byte *)malloc(scr->buf_size);
|
scr->buf = (byte *)malloc(scr->buf_size);
|
||||||
|
|
||||||
|
@ -614,16 +612,16 @@ static void load_script(EngineState *s, SegmentId seg) {
|
||||||
static void reconstruct_scripts(EngineState *s, SegManager *self) {
|
static void reconstruct_scripts(EngineState *s, SegManager *self) {
|
||||||
uint i;
|
uint i;
|
||||||
MemObject *mobj;
|
MemObject *mobj;
|
||||||
for (i = 0; i < self->heap_size; i++) {
|
for (i = 0; i < self->_heap.size(); i++) {
|
||||||
if (self->heap[i]) {
|
if (self->_heap[i]) {
|
||||||
mobj = self->heap[i];
|
mobj = self->_heap[i];
|
||||||
switch (mobj->getType()) {
|
switch (mobj->getType()) {
|
||||||
case MEM_OBJ_SCRIPT: {
|
case MEM_OBJ_SCRIPT: {
|
||||||
int j;
|
int j;
|
||||||
Script *scr = &mobj->data.script;
|
Script *scr = &mobj->data.script;
|
||||||
|
|
||||||
load_script(s, i);
|
load_script(s, i);
|
||||||
scr->locals_block = scr->locals_segment == 0 ? NULL : &s->seg_manager->heap[scr->locals_segment]->data.locals;
|
scr->locals_block = scr->locals_segment == 0 ? NULL : &s->seg_manager->_heap[scr->locals_segment]->data.locals;
|
||||||
scr->export_table = (uint16 *) find_unique_script_block(s, scr->buf, sci_obj_exports);
|
scr->export_table = (uint16 *) find_unique_script_block(s, scr->buf, sci_obj_exports);
|
||||||
scr->synonyms = find_unique_script_block(s, scr->buf, sci_obj_synonyms);
|
scr->synonyms = find_unique_script_block(s, scr->buf, sci_obj_synonyms);
|
||||||
scr->code = NULL;
|
scr->code = NULL;
|
||||||
|
@ -646,9 +644,9 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < self->heap_size; i++) {
|
for (i = 0; i < self->_heap.size(); i++) {
|
||||||
if (self->heap[i]) {
|
if (self->_heap[i]) {
|
||||||
mobj = self->heap[i];
|
mobj = self->_heap[i];
|
||||||
switch (mobj->getType()) {
|
switch (mobj->getType()) {
|
||||||
case MEM_OBJ_SCRIPT: {
|
case MEM_OBJ_SCRIPT: {
|
||||||
int j;
|
int j;
|
||||||
|
@ -695,9 +693,9 @@ static void reconstruct_clones(EngineState *s, SegManager *self) {
|
||||||
uint i;
|
uint i;
|
||||||
MemObject *mobj;
|
MemObject *mobj;
|
||||||
|
|
||||||
for (i = 0; i < self->heap_size; i++) {
|
for (i = 0; i < self->_heap.size(); i++) {
|
||||||
if (self->heap[i]) {
|
if (self->_heap[i]) {
|
||||||
mobj = self->heap[i];
|
mobj = self->_heap[i];
|
||||||
switch (mobj->getType()) {
|
switch (mobj->getType()) {
|
||||||
case MEM_OBJ_CLONES: {
|
case MEM_OBJ_CLONES: {
|
||||||
int j;
|
int j;
|
||||||
|
@ -860,7 +858,7 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
|
||||||
reconstruct_scripts(retval, retval->seg_manager);
|
reconstruct_scripts(retval, retval->seg_manager);
|
||||||
reconstruct_clones(retval, retval->seg_manager);
|
reconstruct_clones(retval, retval->seg_manager);
|
||||||
retval->game_obj = s->game_obj;
|
retval->game_obj = s->game_obj;
|
||||||
retval->script_000 = &retval->seg_manager->heap[script_get_segment(s, 0, SCRIPT_GET_DONT_LOAD)]->data.script;
|
retval->script_000 = &retval->seg_manager->_heap[script_get_segment(s, 0, SCRIPT_GET_DONT_LOAD)]->data.script;
|
||||||
retval->gc_countdown = GC_INTERVAL - 1;
|
retval->gc_countdown = GC_INTERVAL - 1;
|
||||||
retval->save_dir_copy = make_reg(s->sys_strings_segment, SYS_STRING_SAVEDIR);
|
retval->save_dir_copy = make_reg(s->sys_strings_segment, SYS_STRING_SAVEDIR);
|
||||||
retval->save_dir_edit_offset = 0;
|
retval->save_dir_edit_offset = 0;
|
||||||
|
|
|
@ -305,8 +305,8 @@ int parse_reg_t(EngineState *s, const char *str, reg_t *dest) { // Returns 0 on
|
||||||
str_objname = str + 1;
|
str_objname = str + 1;
|
||||||
|
|
||||||
// Now all values are available; iterate over all objects.
|
// Now all values are available; iterate over all objects.
|
||||||
for (i = 0; i < s->seg_manager->heap_size; i++) {
|
for (i = 0; i < s->seg_manager->_heap.size(); i++) {
|
||||||
MemObject *mobj = s->seg_manager->heap[i];
|
MemObject *mobj = s->seg_manager->_heap[i];
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
int max_index = 0;
|
int max_index = 0;
|
||||||
|
|
||||||
|
|
|
@ -286,8 +286,8 @@ int c_segtable(EngineState *s) {
|
||||||
uint i;
|
uint i;
|
||||||
|
|
||||||
sciprintf(" ---- segment table ----\n");
|
sciprintf(" ---- segment table ----\n");
|
||||||
for (i = 0; i < s->seg_manager->heap_size; i++) {
|
for (i = 0; i < s->seg_manager->_heap.size(); i++) {
|
||||||
MemObject *mobj = s->seg_manager->heap[i];
|
MemObject *mobj = s->seg_manager->_heap[i];
|
||||||
if (mobj && mobj->getType()) {
|
if (mobj && mobj->getType()) {
|
||||||
sciprintf(" [%04x] ", i);
|
sciprintf(" [%04x] ", i);
|
||||||
|
|
||||||
|
@ -673,18 +673,18 @@ int c_seginfo(EngineState *s) {
|
||||||
if (cmd_paramlength) {
|
if (cmd_paramlength) {
|
||||||
while (i < cmd_paramlength) {
|
while (i < cmd_paramlength) {
|
||||||
int nr = cmd_params[i++].val;
|
int nr = cmd_params[i++].val;
|
||||||
if (nr < 0 || (uint)nr >= s->seg_manager->heap_size || !s->seg_manager->heap[nr]) {
|
if (nr < 0 || (uint)nr >= s->seg_manager->_heap.size() || !s->seg_manager->_heap[nr]) {
|
||||||
sciprintf("Segment %04x does not exist\n", nr);
|
sciprintf("Segment %04x does not exist\n", nr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
sciprintf("[%04x] ", nr);
|
sciprintf("[%04x] ", nr);
|
||||||
_c_single_seg_info(s, s->seg_manager->heap[nr]);
|
_c_single_seg_info(s, s->seg_manager->_heap[nr]);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
for (i = 0; i < s->seg_manager->heap_size; i++) {
|
for (i = 0; i < s->seg_manager->_heap.size(); i++) {
|
||||||
if (s->seg_manager->heap[i]) {
|
if (s->seg_manager->_heap[i]) {
|
||||||
sciprintf("[%04x] ", i);
|
sciprintf("[%04x] ", i);
|
||||||
_c_single_seg_info(s, s->seg_manager->heap[i]);
|
_c_single_seg_info(s, s->seg_manager->_heap[i]);
|
||||||
sciprintf("\n");
|
sciprintf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -727,7 +727,7 @@ int c_stepover(EngineState *s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_debugstate_valid = 0;
|
_debugstate_valid = 0;
|
||||||
opcode = s->heap [*p_pc];
|
opcode = s->_heap[*p_pc];
|
||||||
opnumber = opcode >> 1;
|
opnumber = opcode >> 1;
|
||||||
if (opnumber == 0x22 /* callb */ || opnumber == 0x23 /* calle */ ||
|
if (opnumber == 0x22 /* callb */ || opnumber == 0x23 /* calle */ ||
|
||||||
opnumber == 0x25 /* send */ || opnumber == 0x2a /* self */ || opnumber == 0x2b /* super */) {
|
opnumber == 0x25 /* send */ || opnumber == 0x2a /* self */ || opnumber == 0x2b /* super */) {
|
||||||
|
@ -1590,7 +1590,7 @@ static int c_backtrace(EngineState *s) {
|
||||||
|
|
||||||
sciprintf(" argp:"PSTK, PRINT_STK(call.variables_argp));
|
sciprintf(" argp:"PSTK, PRINT_STK(call.variables_argp));
|
||||||
if (call.type == EXEC_STACK_TYPE_CALL)
|
if (call.type == EXEC_STACK_TYPE_CALL)
|
||||||
sciprintf(" script: %d", s->seg_manager->heap[call.addr.pc.segment]->data.script.nr);
|
sciprintf(" script: %d", s->seg_manager->_heap[call.addr.pc.segment]->data.script.nr);
|
||||||
sciprintf("\n");
|
sciprintf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2557,8 +2557,8 @@ int objinfo(EngineState *s, reg_t pos) {
|
||||||
reg_t fptr = VM_OBJECT_READ_FUNCTION(obj, i);
|
reg_t fptr = VM_OBJECT_READ_FUNCTION(obj, i);
|
||||||
sciprintf(" [%03x] %s = "PREG"\n", VM_OBJECT_GET_FUNCSELECTOR(obj, i), selector_name(s, VM_OBJECT_GET_FUNCSELECTOR(obj, i)), PRINT_REG(fptr));
|
sciprintf(" [%03x] %s = "PREG"\n", VM_OBJECT_GET_FUNCSELECTOR(obj, i), selector_name(s, VM_OBJECT_GET_FUNCSELECTOR(obj, i)), PRINT_REG(fptr));
|
||||||
}
|
}
|
||||||
if (s->seg_manager->heap[pos.segment]->getType() == MEM_OBJ_SCRIPT)
|
if (s->seg_manager->_heap[pos.segment]->getType() == MEM_OBJ_SCRIPT)
|
||||||
sciprintf("\nOwner script:\t%d\n", s->seg_manager->heap[pos.segment]->data.script.nr);
|
sciprintf("\nOwner script:\t%d\n", s->seg_manager->_heap[pos.segment]->data.script.nr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,8 +83,7 @@ SegManager::SegManager(bool sci1_1) {
|
||||||
id_seg_map->checkKey(reserved_id, true); // reserve 0 for seg_id
|
id_seg_map->checkKey(reserved_id, true); // reserve 0 for seg_id
|
||||||
reserved_id--; // reserved_id runs in the reversed direction to make sure no one will use it.
|
reserved_id--; // reserved_id runs in the reversed direction to make sure no one will use it.
|
||||||
|
|
||||||
heap_size = DEFAULT_SCRIPTS;
|
_heap.resize(DEFAULT_SCRIPTS);
|
||||||
heap = (MemObject **)sci_calloc(heap_size, sizeof(MemObject *));
|
|
||||||
|
|
||||||
Clones_seg_id = 0;
|
Clones_seg_id = 0;
|
||||||
Lists_seg_id = 0;
|
Lists_seg_id = 0;
|
||||||
|
@ -94,11 +93,6 @@ SegManager::SegManager(bool sci1_1) {
|
||||||
exports_wide = 0;
|
exports_wide = 0;
|
||||||
isSci1_1 = sci1_1;
|
isSci1_1 = sci1_1;
|
||||||
|
|
||||||
// initialize the heap pointers
|
|
||||||
for (uint i = 0; i < heap_size; i++) {
|
|
||||||
heap[i] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// gc initialisation
|
// gc initialisation
|
||||||
gc_mark_bits = 0;
|
gc_mark_bits = 0;
|
||||||
}
|
}
|
||||||
|
@ -106,14 +100,12 @@ SegManager::SegManager(bool sci1_1) {
|
||||||
// Destroy the object, free the memorys if allocated before
|
// Destroy the object, free the memorys if allocated before
|
||||||
SegManager::~SegManager() {
|
SegManager::~SegManager() {
|
||||||
// Free memory
|
// Free memory
|
||||||
for (uint i = 0; i < heap_size; i++) {
|
for (uint i = 0; i < _heap.size(); i++) {
|
||||||
if (heap[i])
|
if (_heap[i])
|
||||||
deallocate(i, false);
|
deallocate(i, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete id_seg_map;
|
delete id_seg_map;
|
||||||
|
|
||||||
free(heap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate a memory for script from heap
|
// allocate a memory for script from heap
|
||||||
|
@ -130,7 +122,7 @@ MemObject *SegManager::allocateScript(EngineState *s, int script_nr, int* seg_id
|
||||||
seg = id_seg_map->checkKey(script_nr, true, &was_added);
|
seg = id_seg_map->checkKey(script_nr, true, &was_added);
|
||||||
if (!was_added) {
|
if (!was_added) {
|
||||||
*seg_id = seg;
|
*seg_id = seg;
|
||||||
return heap[*seg_id];
|
return _heap[*seg_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate the MemObject
|
// allocate the MemObject
|
||||||
|
@ -225,7 +217,7 @@ int SegManager::deallocate(int seg, bool recursive) {
|
||||||
VERIFY(check(seg), "invalid seg id");
|
VERIFY(check(seg), "invalid seg id");
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
mobj = heap[seg];
|
mobj = _heap[seg];
|
||||||
id_seg_map->removeKey(mobj->getSegMgrId());
|
id_seg_map->removeKey(mobj->getSegMgrId());
|
||||||
|
|
||||||
switch (mobj->getType()) {
|
switch (mobj->getType()) {
|
||||||
|
@ -293,7 +285,7 @@ int SegManager::deallocate(int seg, bool recursive) {
|
||||||
}
|
}
|
||||||
|
|
||||||
free(mobj);
|
free(mobj);
|
||||||
heap[seg] = NULL;
|
_heap[seg] = NULL;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -319,10 +311,10 @@ int SegManager::scriptIsMarkedAsDeleted(SegmentId seg) {
|
||||||
if (!check(seg))
|
if (!check(seg))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (heap[seg]->getType() != MEM_OBJ_SCRIPT)
|
if (_heap[seg]->getType() != MEM_OBJ_SCRIPT)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
scr = &(heap[seg]->data.script);
|
scr = &(_heap[seg]->data.script);
|
||||||
|
|
||||||
return scr->marked_as_deleted;
|
return scr->marked_as_deleted;
|
||||||
}
|
}
|
||||||
|
@ -343,31 +335,19 @@ MemObject *SegManager::memObjAllocate(SegmentId segid, int hash_id, memObjType t
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (segid >= (int)heap_size) {
|
if (segid >= (int)_heap.size()) {
|
||||||
void *temp;
|
if (segid >= (int)_heap.size() * 2) {
|
||||||
int oldhs = heap_size;
|
|
||||||
|
|
||||||
if (segid >= (int)heap_size * 2) {
|
|
||||||
sciprintf("SegManager: hash_map error or others??");
|
sciprintf("SegManager: hash_map error or others??");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
heap_size *= 2;
|
_heap.resize(_heap.size() * 2);
|
||||||
temp = sci_realloc((void *)heap, heap_size * sizeof(MemObject *));
|
|
||||||
if (!temp) {
|
|
||||||
sciprintf("SegManager: Not enough memory space for script size");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
heap = (MemObject **)temp;
|
|
||||||
|
|
||||||
// Clear pointers
|
|
||||||
memset(heap + oldhs, 0, sizeof(MemObject *) * (heap_size - oldhs));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mem->data.tmp_dummy._segmgrId = hash_id;
|
mem->data.tmp_dummy._segmgrId = hash_id;
|
||||||
mem->data.tmp_dummy._type = type;
|
mem->data.tmp_dummy._type = type;
|
||||||
|
|
||||||
// hook it to the heap
|
// hook it to the heap
|
||||||
heap[segid] = mem;
|
_heap[segid] = mem;
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,7 +398,7 @@ int16 SegManager::getHeap(reg_t reg) {
|
||||||
MemObject *mem_obj;
|
MemObject *mem_obj;
|
||||||
|
|
||||||
VERIFY(check(reg.segment), "Invalid seg id");
|
VERIFY(check(reg.segment), "Invalid seg id");
|
||||||
mem_obj = heap[reg.segment];
|
mem_obj = _heap[reg.segment];
|
||||||
|
|
||||||
switch (mem_obj->getType()) {
|
switch (mem_obj->getType()) {
|
||||||
case MEM_OBJ_SCRIPT:
|
case MEM_OBJ_SCRIPT:
|
||||||
|
@ -439,16 +419,16 @@ int SegManager::segGet(int script_id) const {
|
||||||
Script *SegManager::getScript(const int id, idFlag flag) {
|
Script *SegManager::getScript(const int id, idFlag flag) {
|
||||||
const int seg = (flag == SCRIPT_ID) ? segGet(id) : id;
|
const int seg = (flag == SCRIPT_ID) ? segGet(id) : id;
|
||||||
|
|
||||||
if (seg < 0 || (uint)seg >= heap_size) {
|
if (seg < 0 || (uint)seg >= _heap.size()) {
|
||||||
error("SegManager::getScript(%d,%d): seg id %x out of bounds", id, flag, seg);
|
error("SegManager::getScript(%d,%d): seg id %x out of bounds", id, flag, seg);
|
||||||
}
|
}
|
||||||
if (!heap[seg]) {
|
if (!_heap[seg]) {
|
||||||
error("SegManager::getScript(%d,%d): seg id %x is not in memory", id, flag, seg);
|
error("SegManager::getScript(%d,%d): seg id %x is not in memory", id, flag, seg);
|
||||||
}
|
}
|
||||||
if (heap[seg]->getType() != MEM_OBJ_SCRIPT) {
|
if (_heap[seg]->getType() != MEM_OBJ_SCRIPT) {
|
||||||
error("SegManager::getScript(%d,%d): seg id %x refers to type %d != MEM_OBJ_SCRIPT", id, flag, seg, heap[seg]->getType());
|
error("SegManager::getScript(%d,%d): seg id %x refers to type %d != MEM_OBJ_SCRIPT", id, flag, seg, _heap[seg]->getType());
|
||||||
}
|
}
|
||||||
return &(heap[seg]->data.script);
|
return &(_heap[seg]->data.script);
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate the seg
|
// validate the seg
|
||||||
|
@ -456,10 +436,10 @@ Script *SegManager::getScript(const int id, idFlag flag) {
|
||||||
// false - invalid seg
|
// false - invalid seg
|
||||||
// true - valid seg
|
// true - valid seg
|
||||||
bool SegManager::check(int seg) {
|
bool SegManager::check(int seg) {
|
||||||
if (seg < 0 || (uint)seg >= heap_size) {
|
if (seg < 0 || (uint)seg >= _heap.size()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!heap[seg]) {
|
if (!_heap[seg]) {
|
||||||
sciprintf("SegManager: seg %x is removed from memory, but not removed from hash_map\n", seg);
|
sciprintf("SegManager: seg %x is removed from memory, but not removed from hash_map\n", seg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -548,7 +528,7 @@ int SegManager::relocateBlock(reg_t *block, int block_location, int block_items,
|
||||||
}
|
}
|
||||||
block[index].segment = segment; // Perform relocation
|
block[index].segment = segment; // Perform relocation
|
||||||
if (isSci1_1)
|
if (isSci1_1)
|
||||||
block[index].offset += heap[segment]->data.script.script_size;
|
block[index].offset += _heap[segment]->data.script.script_size;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -808,7 +788,7 @@ LocalVariables *SegManager::allocLocalsSegment(Script *scr, int count) {
|
||||||
LocalVariables *locals;
|
LocalVariables *locals;
|
||||||
|
|
||||||
if (scr->locals_segment) {
|
if (scr->locals_segment) {
|
||||||
mobj = heap[scr->locals_segment];
|
mobj = _heap[scr->locals_segment];
|
||||||
VERIFY(mobj != NULL, "Re-used locals segment was NULL'd out");
|
VERIFY(mobj != NULL, "Re-used locals segment was NULL'd out");
|
||||||
VERIFY(mobj->getType() == MEM_OBJ_LOCALS, "Re-used locals segment did not consist of local variables");
|
VERIFY(mobj->getType() == MEM_OBJ_LOCALS, "Re-used locals segment did not consist of local variables");
|
||||||
VERIFY(mobj->data.locals.script_id == scr->nr, "Re-used locals segment belonged to other script");
|
VERIFY(mobj->data.locals.script_id == scr->nr, "Re-used locals segment belonged to other script");
|
||||||
|
@ -1074,7 +1054,7 @@ Clone *SegManager::alloc_Clone(reg_t *addr) {
|
||||||
mobj = allocNonscriptSegment(MEM_OBJ_CLONES, &(Clones_seg_id));
|
mobj = allocNonscriptSegment(MEM_OBJ_CLONES, &(Clones_seg_id));
|
||||||
mobj->data.clones.initTable();
|
mobj->data.clones.initTable();
|
||||||
} else
|
} else
|
||||||
mobj = heap[Clones_seg_id];
|
mobj = _heap[Clones_seg_id];
|
||||||
|
|
||||||
table = &(mobj->data.clones);
|
table = &(mobj->data.clones);
|
||||||
offset = table->allocEntry();
|
offset = table->allocEntry();
|
||||||
|
@ -1092,7 +1072,7 @@ List *SegManager::alloc_List(reg_t *addr) {
|
||||||
mobj = allocNonscriptSegment(MEM_OBJ_LISTS, &(Lists_seg_id));
|
mobj = allocNonscriptSegment(MEM_OBJ_LISTS, &(Lists_seg_id));
|
||||||
mobj->data.lists.initTable();
|
mobj->data.lists.initTable();
|
||||||
} else
|
} else
|
||||||
mobj = heap[Lists_seg_id];
|
mobj = _heap[Lists_seg_id];
|
||||||
|
|
||||||
table = &(mobj->data.lists);
|
table = &(mobj->data.lists);
|
||||||
offset = table->allocEntry();
|
offset = table->allocEntry();
|
||||||
|
@ -1110,7 +1090,7 @@ Node *SegManager::alloc_Node(reg_t *addr) {
|
||||||
mobj = allocNonscriptSegment(MEM_OBJ_NODES, &(Nodes_seg_id));
|
mobj = allocNonscriptSegment(MEM_OBJ_NODES, &(Nodes_seg_id));
|
||||||
mobj->data.nodes.initTable();
|
mobj->data.nodes.initTable();
|
||||||
} else
|
} else
|
||||||
mobj = heap[Nodes_seg_id];
|
mobj = _heap[Nodes_seg_id];
|
||||||
|
|
||||||
table = &(mobj->data.nodes);
|
table = &(mobj->data.nodes);
|
||||||
offset = table->allocEntry();
|
offset = table->allocEntry();
|
||||||
|
@ -1128,7 +1108,7 @@ Hunk *SegManager::alloc_Hunk(reg_t *addr) {
|
||||||
mobj = allocNonscriptSegment(MEM_OBJ_HUNK, &(Hunks_seg_id));
|
mobj = allocNonscriptSegment(MEM_OBJ_HUNK, &(Hunks_seg_id));
|
||||||
mobj->data.hunks.initTable();
|
mobj->data.hunks.initTable();
|
||||||
} else
|
} else
|
||||||
mobj = heap[Hunks_seg_id];
|
mobj = _heap[Hunks_seg_id];
|
||||||
|
|
||||||
table = &(mobj->data.hunks);
|
table = &(mobj->data.hunks);
|
||||||
offset = table->allocEntry();
|
offset = table->allocEntry();
|
||||||
|
@ -1144,13 +1124,13 @@ byte *SegManager::dereference(reg_t pointer, int *size) {
|
||||||
byte *base = NULL;
|
byte *base = NULL;
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
if (!pointer.segment || (pointer.segment >= heap_size) || !heap[pointer.segment]) {
|
if (!pointer.segment || (pointer.segment >= _heap.size()) || !_heap[pointer.segment]) {
|
||||||
sciprintf("Error: Attempt to dereference invalid pointer "PREG"!\n",
|
sciprintf("Error: Attempt to dereference invalid pointer "PREG"!\n",
|
||||||
PRINT_REG(pointer));
|
PRINT_REG(pointer));
|
||||||
return NULL; /* Invalid */
|
return NULL; /* Invalid */
|
||||||
}
|
}
|
||||||
|
|
||||||
mobj = heap[pointer.segment];
|
mobj = _heap[pointer.segment];
|
||||||
|
|
||||||
switch (mobj->getType()) {
|
switch (mobj->getType()) {
|
||||||
case MEM_OBJ_SCRIPT:
|
case MEM_OBJ_SCRIPT:
|
||||||
|
@ -1221,9 +1201,9 @@ unsigned char *SegManager::allocDynmem(int size, const char *descr, reg_t *addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *SegManager::getDescription(reg_t addr) {
|
const char *SegManager::getDescription(reg_t addr) {
|
||||||
MemObject *mobj = heap[addr.segment];
|
MemObject *mobj = _heap[addr.segment];
|
||||||
|
|
||||||
if (addr.segment >= heap_size)
|
if (addr.segment >= _heap.size())
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
switch (mobj->getType()) {
|
switch (mobj->getType()) {
|
||||||
|
@ -1235,7 +1215,7 @@ const char *SegManager::getDescription(reg_t addr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int SegManager::freeDynmem(reg_t addr) {
|
int SegManager::freeDynmem(reg_t addr) {
|
||||||
if (addr.segment <= 0 || addr.segment >= heap_size || !heap[addr.segment] || heap[addr.segment]->getType() != MEM_OBJ_DYNMEM)
|
if (addr.segment <= 0 || addr.segment >= _heap.size() || !_heap[addr.segment] || _heap[addr.segment]->getType() != MEM_OBJ_DYNMEM)
|
||||||
return 1; // error
|
return 1; // error
|
||||||
|
|
||||||
deallocate(addr.segment, true);
|
deallocate(addr.segment, true);
|
||||||
|
@ -1603,7 +1583,7 @@ SegInterface *SegManager::getSegInterface(SegmentId segid) {
|
||||||
return NULL; // Invalid segment
|
return NULL; // Invalid segment
|
||||||
|
|
||||||
SegInterface *retval = NULL;
|
SegInterface *retval = NULL;
|
||||||
MemObject *mobj = heap[segid];
|
MemObject *mobj = _heap[segid];
|
||||||
switch (mobj->getType()) {
|
switch (mobj->getType()) {
|
||||||
case MEM_OBJ_SCRIPT:
|
case MEM_OBJ_SCRIPT:
|
||||||
retval = new SegInterfaceScript(this, mobj, segid);
|
retval = new SegInterfaceScript(this, mobj, segid);
|
||||||
|
|
|
@ -38,14 +38,14 @@ enum idFlag {
|
||||||
SEG_ID
|
SEG_ID
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GET_SEGMENT(mgr, index, rtype) (((index) > 0 && (int)(mgr).heap_size > index) ? \
|
#define GET_SEGMENT(mgr, index, rtype) (((index) > 0 && (int)(mgr)._heap.size() > index) ? \
|
||||||
(((mgr).heap[index] && (mgr).heap[index]->getType() == rtype)? (mgr).heap[index] : NULL) : NULL)
|
(((mgr)._heap[index] && (mgr)._heap[index]->getType() == rtype)? (mgr)._heap[index] : NULL) : NULL)
|
||||||
|
|
||||||
#define GET_SEGMENT_ANY(mgr, index) (((index) > 0 && (int)(mgr).heap_size > index) ? \
|
#define GET_SEGMENT_ANY(mgr, index) (((index) > 0 && (int)(mgr)._heap.size() > index) ? \
|
||||||
(((mgr).heap[index])? (mgr).heap[index] : NULL) : NULL)
|
(((mgr)._heap[index])? (mgr)._heap[index] : NULL) : NULL)
|
||||||
|
|
||||||
#define GET_OBJECT_SEGMENT(mgr, index) (((index) > 0 && (int)(mgr).heap_size > index) ? \
|
#define GET_OBJECT_SEGMENT(mgr, index) (((index) > 0 && (int)(mgr)._heap.size() > index) ? \
|
||||||
(((mgr).heap[index] && ((mgr).heap[index]->getType() == MEM_OBJ_SCRIPT || (mgr).heap[index]->getType() == MEM_OBJ_CLONES))? (mgr).heap[index] \
|
(((mgr)._heap[index] && ((mgr)._heap[index]->getType() == MEM_OBJ_SCRIPT || (mgr)._heap[index]->getType() == MEM_OBJ_CLONES))? (mgr)._heap[index] \
|
||||||
: NULL): NULL)
|
: NULL): NULL)
|
||||||
|
|
||||||
class SegInterface;
|
class SegInterface;
|
||||||
|
@ -388,8 +388,7 @@ public:
|
||||||
private:
|
private:
|
||||||
IntMapper *id_seg_map; // id - script id; seg - index of heap
|
IntMapper *id_seg_map; // id - script id; seg - index of heap
|
||||||
public: // TODO: make private
|
public: // TODO: make private
|
||||||
MemObject **heap;
|
Common::Array<MemObject *> _heap;
|
||||||
uint heap_size; // size of the heap
|
|
||||||
int reserved_id;
|
int reserved_id;
|
||||||
int exports_wide;
|
int exports_wide;
|
||||||
bool isSci1_1;
|
bool isSci1_1;
|
||||||
|
|
|
@ -1701,7 +1701,7 @@ int script_instantiate_common(EngineState *s, int script_nr, Resource **script,
|
||||||
return seg;
|
return seg;
|
||||||
} else {
|
} else {
|
||||||
seg_id = seg;
|
seg_id = seg;
|
||||||
mem = s->seg_manager->heap[seg];
|
mem = s->seg_manager->_heap[seg];
|
||||||
assert(mem);
|
assert(mem);
|
||||||
s->seg_manager->freeScript(*(Script *)mem);
|
s->seg_manager->freeScript(*(Script *)mem);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue