aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorMax Horn2009-04-28 16:00:59 +0000
committerMax Horn2009-04-28 16:00:59 +0000
commit6ca348c9d0154ca52e2371fd62ae425c1e0a5572 (patch)
treee1d04da226d57904bf1efc97959777bccaf1797d /engines/sci
parent36fcc55c06042a2b35b93f8bb4b2f73fbb19a223 (diff)
downloadscummvm-rg350-6ca348c9d0154ca52e2371fd62ae425c1e0a5572.tar.gz
scummvm-rg350-6ca348c9d0154ca52e2371fd62ae425c1e0a5572.tar.bz2
scummvm-rg350-6ca348c9d0154ca52e2371fd62ae425c1e0a5572.zip
SCI: Further restructured the SegManager heap tables
svn-id: r40184
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/engine/seg_manager.cpp209
-rw-r--r--engines/sci/engine/vm.h62
2 files changed, 115 insertions, 156 deletions
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index b71e3a8e52..84f670091b 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -1282,23 +1282,13 @@ Hunk *SegManager::alloc_hunk_entry(const char *hunk_type, int size, reg_t *reg)
return h;
}
-void _clone_cleanup(Clone *clone) {
- if (clone->variables)
- free(clone->variables); // Free the dynamically allocated memory part
-}
-
-void _hunk_cleanup(Hunk *hunk) {
- if (hunk->mem)
- free(hunk->mem);
-}
-
void init_List_table(ListTable *table) {
table->entries_nr = 8;
table->max_entry = 0;
table->entries_used = 0;
table->first_free = HEAPENTRY_INVALID;
- table->table = (ListEntry *)sci_malloc(sizeof(ListEntry) * 8);\
+ table->table = (ListEntry *)sci_malloc(sizeof(ListEntry) * 8);
memset(table->table, 0, sizeof(ListEntry) * 8);
}
@@ -1306,9 +1296,7 @@ void free_List_entry(ListTable *table, int index) {
ListEntry *e = table->table + index;
if (index < 0 || index >= table->max_entry) {
- fprintf(stderr, "heapmgr: Attempt to release"
- " invalid table index %d!\n", index);
- BREAKPOINT();
+ error("heapmgr: Attempt to release invalid table index %d", index);
}
e->next_free = table->first_free;
@@ -1316,26 +1304,6 @@ void free_List_entry(ListTable *table, int index) {
table->entries_used--;
}
-int alloc_List_entry(ListTable *table) {
- table->entries_used++;
- if (table->first_free != HEAPENTRY_INVALID) {
- int oldff = table->first_free;
- table->first_free = table->table[oldff].next_free;
-
- table->table[oldff].next_free = oldff;
- return oldff;
- } else {
- if (table->max_entry == table->entries_nr) {
- table->entries_nr += 4;
-
- table->table = (ListEntry *)sci_realloc(table->table,\
- sizeof(ListEntry) * table->entries_nr);\
- memset(&table->table[table->entries_nr-4], 0, 4 * sizeof(ListEntry));\
- }
- table->table[table->max_entry].next_free = table->max_entry; /* Tag as 'valid' */\
- return table->max_entry++;
- }
-}
void init_Node_table(NodeTable *table) {
@@ -1343,7 +1311,7 @@ void init_Node_table(NodeTable *table) {
table->max_entry = 0;
table->entries_used = 0;
table->first_free = HEAPENTRY_INVALID;
- table->table = (NodeEntry *)sci_malloc(sizeof(NodeEntry) * 32);\
+ table->table = (NodeEntry *)sci_malloc(sizeof(NodeEntry) * 32);
memset(table->table, 0, sizeof(NodeEntry) * 32);
}
@@ -1351,9 +1319,7 @@ void free_Node_entry(NodeTable *table, int index) {
NodeEntry *e = table->table + index;
if (index < 0 || index >= table->max_entry) {
- fprintf(stderr, "heapmgr: Attempt to release"
- " invalid table index %d!\n", index);
- BREAKPOINT();
+ error("heapmgr: Attempt to release invalid table index %d", index);
}
e->next_free = table->first_free;
@@ -1361,26 +1327,6 @@ void free_Node_entry(NodeTable *table, int index) {
table->entries_used--;
}
-int alloc_Node_entry(NodeTable *table) {
- table->entries_used++;
- if (table->first_free != HEAPENTRY_INVALID) {
- int oldff = table->first_free;
- table->first_free = table->table[oldff].next_free;
-
- table->table[oldff].next_free = oldff;
- return oldff;
- } else {
- if (table->max_entry == table->entries_nr) {
- table->entries_nr += 16;
-
- table->table = (NodeEntry *)sci_realloc(table->table,\
- sizeof(NodeEntry) * table->entries_nr);\
- memset(&table->table[table->entries_nr-16], 0, 16 * sizeof(NodeEntry));\
- }
- table->table[table->max_entry].next_free = table->max_entry; /* Tag as 'valid' */\
- return table->max_entry++;
- }
-}
void init_Clone_table(CloneTable *table) {
@@ -1388,7 +1334,7 @@ void init_Clone_table(CloneTable *table) {
table->max_entry = 0;
table->entries_used = 0;
table->first_free = HEAPENTRY_INVALID;
- table->table = (CloneEntry *)sci_malloc(sizeof(CloneEntry) * 16);\
+ table->table = (CloneEntry *)sci_malloc(sizeof(CloneEntry) * 16);
memset(table->table, 0, sizeof(CloneEntry) * 16);
}
@@ -1396,37 +1342,16 @@ void free_Clone_entry(CloneTable *table, int index) {
CloneEntry *e = table->table + index;
if (index < 0 || index >= table->max_entry) {
- fprintf(stderr, "heapmgr: Attempt to release"
- " invalid table index %d!\n", index);
- BREAKPOINT();
+ error("heapmgr: Attempt to release invalid table index %d", index);
}
- _clone_cleanup(&(e->entry));
+
+ free(e->entry.variables); // Free the dynamically allocated memory part
e->next_free = table->first_free;
table->first_free = index;
table->entries_used--;
}
-int alloc_Clone_entry(CloneTable *table) {
- table->entries_used++;
- if (table->first_free != HEAPENTRY_INVALID) {
- int oldff = table->first_free;
- table->first_free = table->table[oldff].next_free;
-
- table->table[oldff].next_free = oldff;
- return oldff;
- } else {
- if (table->max_entry == table->entries_nr) {
- table->entries_nr += 4;
-
- table->table = (CloneEntry *)sci_realloc(table->table,\
- sizeof(CloneEntry) * table->entries_nr);\
- memset(&table->table[table->entries_nr-4], 0, 4 * sizeof(CloneEntry));\
- }
- table->table[table->max_entry].next_free = table->max_entry; /* Tag as 'valid' */\
- return table->max_entry++;
- }
-}
void init_Hunk_table(HunkTable *table) {
@@ -1434,7 +1359,7 @@ void init_Hunk_table(HunkTable *table) {
table->max_entry = 0;
table->entries_used = 0;
table->first_free = HEAPENTRY_INVALID;
- table->table = (HunkEntry *)sci_malloc(sizeof(HunkEntry) * 4);\
+ table->table = (HunkEntry *)sci_malloc(sizeof(HunkEntry) * 4);
memset(table->table, 0, sizeof(HunkEntry) * 4);
}
@@ -1442,62 +1367,90 @@ void free_Hunk_entry(HunkTable *table, int index) {
HunkEntry *e = table->table + index;
if (index < 0 || index >= table->max_entry) {
- fprintf(stderr, "heapmgr: Attempt to release"
- " invalid table index %d!\n", index);
- BREAKPOINT();
+ error("heapmgr: Attempt to release invalid table index %d", index);
}
- _hunk_cleanup(&(e->entry));
+
+ free(e->entry.mem);
e->next_free = table->first_free;
table->first_free = index;
table->entries_used--;
}
-int alloc_Hunk_entry(HunkTable *table) {
- table->entries_used++;
- if (table->first_free != HEAPENTRY_INVALID) {
- int oldff = table->first_free;
- table->first_free = table->table[oldff].next_free;
- table->table[oldff].next_free = oldff;
- return oldff;
- } else {
- if (table->max_entry == table->entries_nr) {
- table->entries_nr += 4;
- table->table = (HunkEntry *)sci_realloc(table->table,\
- sizeof(HunkEntry) * table->entries_nr);\
- memset(&table->table[table->entries_nr-4], 0, 4 * sizeof(HunkEntry));\
- }
- table->table[table->max_entry].next_free = table->max_entry; /* Tag as 'valid' */\
- return table->max_entry++;
- }
+Clone *SegManager::alloc_Clone(reg_t *addr) {
+ MemObject *mobj;
+ CloneTable *table;
+ int offset;
+
+ if (!Clones_seg_id) {
+ mobj = allocNonscriptSegment(MEM_OBJ_CLONES, &(Clones_seg_id));
+ init_Clone_table(&(mobj->data.clones));
+ } else
+ mobj = heap[Clones_seg_id];
+
+ table = &(mobj->data.clones);
+ offset = table->allocEntry();
+
+ *addr = make_reg(Clones_seg_id, offset);
+ return &(mobj->data.clones.table[offset].entry);
+}
+
+List *SegManager::alloc_List(reg_t *addr) {
+ MemObject *mobj;
+ ListTable *table;
+ int offset;
+
+ if (!Lists_seg_id) {
+ mobj = allocNonscriptSegment(MEM_OBJ_LISTS, &(Lists_seg_id));
+ init_List_table(&(mobj->data.lists));
+ } else
+ mobj = heap[Lists_seg_id];
+
+ table = &(mobj->data.lists);
+ offset = table->allocEntry();
+
+ *addr = make_reg(Lists_seg_id, offset);
+ return &(mobj->data.lists.table[offset].entry);
}
+Node *SegManager::alloc_Node(reg_t *addr) {
+ MemObject *mobj;
+ NodeTable *table;
+ int offset;
+
+ if (!Nodes_seg_id) {
+ mobj = allocNonscriptSegment(MEM_OBJ_NODES, &(Nodes_seg_id));
+ init_Node_table(&(mobj->data.nodes));
+ } else
+ mobj = heap[Nodes_seg_id];
+
+ table = &(mobj->data.nodes);
+ offset = table->allocEntry();
+
+ *addr = make_reg(Nodes_seg_id, offset);
+ return &(mobj->data.nodes.table[offset].entry);
+}
+
+Hunk *SegManager::alloc_Hunk(reg_t *addr) {
+ MemObject *mobj;
+ HunkTable *table;
+ int offset;
+
+ if (!Hunks_seg_id) {
+ mobj = allocNonscriptSegment(MEM_OBJ_HUNK, &(Hunks_seg_id));
+ init_Hunk_table(&(mobj->data.hunks));
+ } else
+ mobj = heap[Hunks_seg_id];
+
+ table = &(mobj->data.hunks);
+ offset = table->allocEntry();
+
+ *addr = make_reg(Hunks_seg_id, offset);
+ return &(mobj->data.hunks.table[offset].entry);
+}
-#define DEFINE_ALLOC(TYPE, SEGTYPE, PLURAL) \
-TYPE *SegManager::alloc_##TYPE(reg_t *addr) { \
- MemObject *mobj; \
- TYPE##Table *table; \
- int offset; \
- \
- if (!TYPE##s_seg_id) { \
- mobj = allocNonscriptSegment(SEGTYPE, &(TYPE##s_seg_id)); \
- init_##TYPE##_table(&(mobj->data.PLURAL)); \
- } else \
- mobj = heap[TYPE##s_seg_id]; \
- \
- table = &(mobj->data.PLURAL); \
- offset = Sci::alloc_##TYPE##_entry(table); \
- \
- *addr = make_reg(TYPE##s_seg_id, offset); \
- return &(mobj->data.PLURAL.table[offset].entry); \
-}
-
-DEFINE_ALLOC(Clone, MEM_OBJ_CLONES, clones)
-DEFINE_ALLOC(List, MEM_OBJ_LISTS, lists)
-DEFINE_ALLOC(Node, MEM_OBJ_NODES, nodes)
-DEFINE_ALLOC(Hunk, MEM_OBJ_HUNK, hunks)
byte *SegManager::dereference(reg_t pointer, int *size) {
diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h
index 861075c887..614ffe56ec 100644
--- a/engines/sci/engine/vm.h
+++ b/engines/sci/engine/vm.h
@@ -257,19 +257,43 @@ struct Hunk {
const char *type;
};
+template<typename T, int INITIAL, int INCREMENT>
+struct Table {
+ int entries_nr; /* Number of entries allocated */
+ int first_free; /* Beginning of a singly linked list for entries */
+ int entries_used; /* Statistical information */
+ int max_entry; /* Highest entry used */
+
+ T *table;
+
+ int allocEntry() {
+ entries_used++;
+ if (first_free != HEAPENTRY_INVALID) {
+ int oldff = first_free;
+ first_free = table[oldff].next_free;
+
+ table[oldff].next_free = oldff;
+ return oldff;
+ } else {
+ if (max_entry == entries_nr) {
+ entries_nr += INCREMENT;
+
+ table = (T *)sci_realloc(table,
+ sizeof(T) * entries_nr);
+ memset(&table[entries_nr-INCREMENT], 0, INCREMENT * sizeof(T));
+ }
+ table[max_entry].next_free = max_entry; /* Tag as 'valid' */
+ return max_entry++;
+ }
+ }
+};
/* CloneTable */
struct CloneEntry {
int next_free; /* Only used for free entries */
Clone entry;
};
-struct CloneTable {
- int entries_nr; /* Number of entries allocated */
- int first_free; /* Beginning of a singly linked list for entries */
- int entries_used; /* Statistical information */
- int max_entry; /* Highest entry used */
- CloneEntry *table;
-};
+typedef Table<CloneEntry, 16, 4> CloneTable;
void init_Clone_table(CloneTable *table);
int alloc_Clone_entry(CloneTable *table);
void free_Clone_entry(CloneTable *table, int index);
@@ -280,13 +304,7 @@ struct NodeEntry {
int next_free; /* Only used for free entries */
Node entry;
};
-struct NodeTable {
- int entries_nr; /* Number of entries allocated */
- int first_free; /* Beginning of a singly linked list for entries */
- int entries_used; /* Statistical information */
- int max_entry; /* Highest entry used */
- NodeEntry *table;
-};
+typedef Table<NodeEntry, 32, 16> NodeTable;
void init_Node_table(NodeTable *table);
int alloc_Node_entry(NodeTable *table);
void free_Node_entry(NodeTable *table, int index);
@@ -297,13 +315,7 @@ struct ListEntry {
int next_free; /* Only used for free entries */
List entry;
};
-struct ListTable {
- int entries_nr; /* Number of entries allocated */
- int first_free; /* Beginning of a singly linked list for entries */
- int entries_used; /* Statistical information */
- int max_entry; /* Highest entry used */
- ListEntry *table;
-};
+typedef Table<ListEntry, 8, 4> ListTable;
void init_List_table(ListTable *table);
int alloc_List_entry(ListTable *table);
void free_List_entry(ListTable *table, int index);
@@ -314,13 +326,7 @@ struct HunkEntry {
int next_free; /* Only used for free entries */
Hunk entry;
};
-struct HunkTable {
- int entries_nr; /* Number of entries allocated */
- int first_free; /* Beginning of a singly linked list for entries */
- int entries_used; /* Statistical information */
- int max_entry; /* Highest entry used */
- HunkEntry *table;
-};
+typedef Table<HunkEntry, 4, 4> HunkTable;
void init_Hunk_table(HunkTable *table);
int alloc_Hunk_entry(HunkTable *table);
void free_Hunk_entry(HunkTable *table, int index);