- Removed the wrapper kalloc, kmem and kfree functions. Now, the associated Segment manager functions allocateHunkEntry, getHunkPointer and freeHunkEntry are used directly (which are more descriptive, anyway)

- Replaced the GET_SEGMENT macro by a method of the segment manager
- Removed the unused reference to the created hunk in allocateHunkEntry(), only the reg_t reference to it is returned now

svn-id: r49078
This commit is contained in:
Filippos Karapetis 2010-05-18 13:05:09 +00:00
parent e3297ef2ca
commit f3892a506b
8 changed files with 49 additions and 82 deletions

View File

@ -2854,7 +2854,7 @@ void Console::printList(List *l) {
while (!pos.isNull()) {
Node *node;
NodeTable *nt = (NodeTable *)GET_SEGMENT(*_engine->_gamestate->_segMan, pos.segment, SEG_TYPE_NODES);
NodeTable *nt = (NodeTable *)_engine->_gamestate->_segMan->getSegment(pos.segment, SEG_TYPE_NODES);
if (!nt || !nt->isValidEntry(pos.offset)) {
DebugPrintf(" WARNING: %04x:%04x: Doesn't contain list node!\n",
@ -2881,7 +2881,7 @@ void Console::printList(List *l) {
}
int Console::printNode(reg_t addr) {
SegmentObj *mobj = GET_SEGMENT(*_engine->_gamestate->_segMan, addr.segment, SEG_TYPE_LISTS);
SegmentObj *mobj = _engine->_gamestate->_segMan->getSegment(addr.segment, SEG_TYPE_LISTS);
if (mobj) {
ListTable *lt = (ListTable *)mobj;
@ -2898,7 +2898,7 @@ int Console::printNode(reg_t addr) {
} else {
NodeTable *nt;
Node *node;
mobj = GET_SEGMENT(*_engine->_gamestate->_segMan, addr.segment, SEG_TYPE_NODES);
mobj = _engine->_gamestate->_segMan->getSegment(addr.segment, SEG_TYPE_NODES);
if (!mobj) {
DebugPrintf("Segment #%04x is not a list or node segment\n", addr.segment);

View File

@ -477,35 +477,6 @@ void Kernel::loadSelectorNames() {
}
}
// Allocates a set amount of memory for a specified use and returns a handle to it.
reg_t kalloc(SegManager *segMan, const char *type, int space) {
reg_t reg;
segMan->allocateHunkEntry(type, space, &reg);
debugC(2, kDebugLevelMemory, "Allocated %d at hunk %04x:%04x (%s)", space, PRINT_REG(reg), type);
return reg;
}
// Returns a pointer to the memory indicated by the specified handle
byte *kmem(SegManager *segMan, reg_t handle) {
HunkTable *ht = (HunkTable *)GET_SEGMENT(*segMan, handle.segment, SEG_TYPE_HUNK);
if (!ht || !ht->isValidEntry(handle.offset)) {
warning("Error: kmem() with invalid handle");
return NULL;
}
return (byte *)ht->_table[handle.offset].mem;
}
// Frees the specified handle. Returns 0 on success, 1 otherwise.
int kfree(SegManager *segMan, reg_t handle) {
segMan->freeHunkEntry(handle);
return 0;
}
static void kernel_compile_signature(const char **s) {
const char *src = *s;
char *result;

View File

@ -39,7 +39,7 @@ reg_t kLoad(EngineState *s, int argc, reg_t *argv) {
// Request to dynamically allocate hunk memory for later use
if (restype == kResourceTypeMemory)
return kalloc(s->_segMan, "kLoad()", resnr);
return s->_segMan->allocateHunkEntry("kLoad()", resnr);
return make_reg(0, ((restype << 11) | resnr)); // Return the resource identifier as handle
}
@ -78,7 +78,7 @@ reg_t kUnLoad(EngineState *s, int argc, reg_t *argv) {
reg_t resnr = argv[1];
if (restype == kResourceTypeMemory)
kfree(s->_segMan, resnr);
s->_segMan->freeHunkEntry(resnr);
if (argc > 2)
warning("kUnload called with more than 2 parameters (%d)", argc);

View File

@ -100,7 +100,7 @@ int propertyOffsetToId(SegManager *segMan, int prop_ofs, reg_t objp) {
// Disassembles one command from the heap, returns address of next command or 0 if a ret was encountered.
reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecode) {
SegmentObj *mobj = GET_SEGMENT(*s->_segMan, pos.segment, SEG_TYPE_SCRIPT);
SegmentObj *mobj = s->_segMan->getSegment(pos.segment, SEG_TYPE_SCRIPT);
Script *script_entity = NULL;
byte *scr;
int scr_size;
@ -328,7 +328,7 @@ void script_debug(EngineState *s) {
#endif
if (g_debugState.seeking && !g_debugState.breakpointWasHit) { // Are we looking for something special?
SegmentObj *mobj = GET_SEGMENT(*s->_segMan, scriptState.xs->addr.pc.segment, SEG_TYPE_SCRIPT);
SegmentObj *mobj = s->_segMan->getSegment(scriptState.xs->addr.pc.segment, SEG_TYPE_SCRIPT);
if (mobj) {
Script *scr = (Script *)mobj;

View File

@ -207,6 +207,10 @@ SegmentType SegManager::getSegmentType(SegmentId seg) {
return _heap[seg]->getType();
}
SegmentObj *SegManager::getSegment(SegmentId seg, SegmentType type) {
return getSegmentType(seg) == type ? _heap[seg] : NULL;
}
Object *SegManager::getObject(reg_t pos) {
SegmentObj *mobj = getSegmentObj(pos.segment);
Object *obj = NULL;
@ -399,7 +403,12 @@ SystemStrings *SegManager::allocateSysStrings(SegmentId *segid) {
}
void SegManager::freeHunkEntry(reg_t addr) {
HunkTable *ht = (HunkTable *)GET_SEGMENT(*this, addr.segment, SEG_TYPE_HUNK);
if (addr.isNull()) {
warning("Attempt to free a Hunk from a null address");
return;
}
HunkTable *ht = (HunkTable *)getSegment(addr.segment, SEG_TYPE_HUNK);
if (!ht) {
warning("Attempt to free Hunk from address %04x:%04x: Invalid segment type", PRINT_REG(addr));
@ -409,7 +418,7 @@ void SegManager::freeHunkEntry(reg_t addr) {
ht->freeEntry(addr.offset);
}
Hunk *SegManager::allocateHunkEntry(const char *hunk_type, int size, reg_t *addr) {
reg_t SegManager::allocateHunkEntry(const char *hunk_type, int size) {
HunkTable *table;
int offset;
@ -419,17 +428,28 @@ Hunk *SegManager::allocateHunkEntry(const char *hunk_type, int size, reg_t *addr
offset = table->allocEntry();
*addr = make_reg(Hunks_seg_id, offset);
reg_t addr = make_reg(Hunks_seg_id, offset);
Hunk *h = &(table->_table[offset]);
if (!h)
return NULL;
return NULL_REG;
h->mem = malloc(size);
h->size = size;
h->type = hunk_type;
return h;
return addr;
}
byte *SegManager::getHunkPointer(reg_t addr) {
HunkTable *ht = (HunkTable *)getSegment(addr.segment, SEG_TYPE_HUNK);
if (!ht || !ht->isValidEntry(addr.offset)) {
warning("getHunkPointer() with invalid handle");
return NULL;
}
return (byte *)ht->_table[addr.offset].mem;
}
Clone *SegManager::allocateClone(reg_t *addr) {

View File

@ -33,8 +33,6 @@
namespace Sci {
#define GET_SEGMENT(mgr, index, rtype) (((mgr).getSegmentType(index) == (rtype))? (mgr)._heap[index] : NULL)
/**
* Verify the the given condition is true, output the message if condition is false, and exit.
* @param cond condition to be verified
@ -255,11 +253,9 @@ public:
* @param[in] size Number of bytes to allocate for the hunk entry
* @param[in] hunk_type A descriptive string for the hunk entry, for
* debugging purposes
* @param[out] addr The offset of the freshly allocated hunk entry
* @return Reference to the memory allocated for the hunk
* piece
* @return The offset of the freshly allocated hunk entry
*/
Hunk *allocateHunkEntry(const char *hunk_type, int size, reg_t *addr);
reg_t allocateHunkEntry(const char *hunk_type, int size);
/**
* Deallocates a hunk entry
@ -267,6 +263,11 @@ public:
*/
void freeHunkEntry(reg_t addr);
/**
* Gets a pointer to the hunk memory referenced by a specified handle
* @param[in] addr Offset of the hunk entry
*/
byte *getHunkPointer(reg_t addr);
// 9. Dynamic Memory
@ -405,6 +406,9 @@ public:
// TODO: document this
SegmentType getSegmentType(SegmentId seg);
// TODO: document this
SegmentObj *getSegment(SegmentId seg, SegmentType type);
/**
* Retrieves an object from the specified location
* @param[in] offset Location (segment, offset) of the object

View File

@ -490,32 +490,6 @@ int game_exit(EngineState *s);
*/
void quit_vm();
/**
* Allocates "kernel" memory and returns a handle suitable to be passed on
* to SCI scripts
* @param[in] segMan The Segment Manager
* @param[in] type A free-form type description string (static)
* @param[in] space The space to allocate
* @return The handle
*/
reg_t kalloc(SegManager *segMan, const char *type, int space);
/**
* Returns a pointer to "kernel" memory based on the handle
* @param[in] segMan The Segment Manager
* @param[in] handle The handle to use
* @return A pointer to the allocated memory
*/
byte *kmem(SegManager *segMan, reg_t handle);
/**
* Frees all "kernel" memory associated with a handle
* @param[in] segMan The Segment Manager
* @param[in] handle The handle to free
* @return 0 on success, 1 otherwise
*/
int kfree(SegManager *segMan, reg_t handle);
/**
* Shrink execution stack to size.
* Contains an assert it is not already smaller.

View File

@ -135,7 +135,7 @@ void GfxPaint16::drawHiresCelAndShow(GuiResourceId viewId, int16 loopNo, int16 c
// I'm not sure if this is what we are supposed to do or if there is some other bug that actually makes
// coordinates to be 0 in the first place
byte *memoryPtr = NULL;
memoryPtr = kmem(_segMan, upscaledHiresHandle);
memoryPtr = _segMan->getHunkPointer(upscaledHiresHandle);
if (memoryPtr) {
Common::Rect upscaledHiresRect;
_screen->bitsGetRect(memoryPtr, &upscaledHiresRect);
@ -322,8 +322,8 @@ reg_t GfxPaint16::bitsSave(const Common::Rect &rect, byte screenMask) {
// now actually ask _screen how much space it will need for saving
size = _screen->bitsGetDataSize(workerRect, screenMask);
memoryId = kalloc(_segMan, "SaveBits()", size);
memoryPtr = kmem(_segMan, memoryId);
memoryId = _segMan->allocateHunkEntry("SaveBits()", size);
memoryPtr = _segMan->getHunkPointer(memoryId);
_screen->bitsSave(workerRect, screenMask, memoryPtr);
return memoryId;
}
@ -332,7 +332,7 @@ void GfxPaint16::bitsGetRect(reg_t memoryHandle, Common::Rect *destRect) {
byte *memoryPtr = NULL;
if (!memoryHandle.isNull()) {
memoryPtr = kmem(_segMan, memoryHandle);
memoryPtr = _segMan->getHunkPointer(memoryHandle);
if (memoryPtr) {
_screen->bitsGetRect(memoryPtr, destRect);
@ -344,19 +344,17 @@ void GfxPaint16::bitsRestore(reg_t memoryHandle) {
byte *memoryPtr = NULL;
if (!memoryHandle.isNull()) {
memoryPtr = kmem(_segMan, memoryHandle);
memoryPtr = _segMan->getHunkPointer(memoryHandle);
if (memoryPtr) {
_screen->bitsRestore(memoryPtr);
kfree(_segMan, memoryHandle);
_segMan->freeHunkEntry(memoryHandle);
}
}
}
void GfxPaint16::bitsFree(reg_t memoryHandle) {
if (!memoryHandle.isNull()) {
kfree(_segMan, memoryHandle);
}
_segMan->freeHunkEntry(memoryHandle);
}
void GfxPaint16::kernelDrawPicture(GuiResourceId pictureId, int16 animationNr, bool animationBlackoutFlag, bool mirroredFlag, bool addToFlag, int16 EGApaletteNo) {