void MemoryManager::imageRead(FILE* fp) { long i, size; fr(fp, (char *) &symbols, sizeof(object)); i = 0; while(fr(fp, (char *) &dummyObject, sizeof(dummyObject))) { i = dummyObject.di; if ((i < 0) || (i >= objectTable.size())) { // Grow enough, plus a bit. growObjectStore(i - objectTable.size() + 500); } objectTable[i]._class = dummyObject.cl; if ((objectTable[i]._class < 0) || ((objectTable[i]._class) >= objectTable.size())) { // Grow enough, plus a bit. growObjectStore(objectTable[i]._class - objectTable.size() + 500); } objectTable[i].size = size = dummyObject.ds; if (size < 0) size = ((- size) + 1) / 2; if (size != 0) { objectTable[i].memory = mBlockAlloc((int) size); fr(fp, (char *) objectTable[i].memory, sizeof(object) * (int) size); } else objectTable[i].memory = (object *) 0; objectTable[i].referenceCount = 666; } setFreeLists(); }
object MemoryManager::allocObject(size_t memorySize) { int i; size_t position; bool done; TObjectFreeListIterator tpos; /* first try the free lists, this is fastest */ if((tpos = objectFreeList.find(memorySize)) != objectFreeList.end() && tpos->second != nilobj) { position = tpos->second; objectFreeList.erase(tpos); objectFreeListInv.erase(position); } /* if not there, next try making a size zero object and making it bigger */ else if ((tpos = objectFreeList.find(0)) != objectFreeList.end() && tpos->second != nilobj) { position = tpos->second; objectFreeList.erase(tpos); objectFreeListInv.erase(position); objectTable[position].size = memorySize; objectTable[position].memory = mBlockAlloc(memorySize); } else { /* not found, must work a bit harder */ done = false; /* first try making a bigger object smaller */ TObjectFreeListIterator tbigger = objectFreeList.upper_bound(memorySize); if(tbigger != objectFreeList.end() && tbigger->second != nilobj) { position = tbigger->second; objectFreeList.erase(tbigger); objectFreeListInv.erase(position); /* just trim it a bit */ objectTable[position].size = memorySize; done = true; } /* next try making a smaller object bigger */ if (! done) { TObjectFreeListIterator tsmaller = objectFreeList.lower_bound(memorySize); if(tsmaller != objectFreeList.begin() && (--tsmaller != objectFreeList.begin()) && tsmaller->second != nilobj) { position = tsmaller->second; objectFreeList.erase(tsmaller); objectFreeListInv.erase(position); objectTable[position].size = memorySize; free(objectTable[position].memory); objectTable[position].memory = mBlockAlloc(memorySize); done = true; } } /* if we STILL don't have it then there is nothing */ /* more we can do */ if (! done) { if(debugging) fprintf(stderr, "Failed to find an available object, trying GC\n"); if(garbageCollect() > 0) { return allocObject(memorySize); } else { if(debugging) fprintf(stderr, "No suitable objects available after GC, growing store.\n"); growObjectStore(growAmount); return allocObject(memorySize); } } } /* set class and type */ objectTable[position].referenceCount = 0; objectTable[position]._class = nilobj; objectTable[position].size = memorySize; return(position << 1); }
/* allocate a new memory object */ object allocObject(int memorySize) { int i; register int position; boolean done; if (memorySize >= FREELISTMAX) { fprintf(stderr, "size %d\n", memorySize); sysError("allocation bigger than permitted", "allocObject"); } /* first try the free lists, this is fastest */ if ((position = objectFreeList[memorySize]) != 0) { objectFreeList[memorySize] = objectTable[position].STclass; } /* if not there, next try making a size zero object and making it bigger */ else if ((position = objectFreeList[0]) != 0) { objectFreeList[0] = objectTable[position].STclass; objectTable[position].size = memorySize; objectTable[position].memory = mBlockAlloc(memorySize); } else /* not found, must work a bit harder */ { done = false; /* first try making a bigger object smaller */ for (i = memorySize + 1; i < FREELISTMAX; i++) if ((position = objectFreeList[i]) != 0) { objectFreeList[i] = objectTable[position].STclass; /* just trim it a bit */ objectTable[position].size = memorySize; done = true; break; } /* next try making a smaller object bigger */ if (!done) for (i = 1; i < memorySize; i++) if ((position = objectFreeList[i]) != 0) { objectFreeList[i] = objectTable[position].STclass; objectTable[position].size = memorySize; # ifdef mBlockAlloc free(objectTable[position].memory); # endif objectTable[position].memory = mBlockAlloc(memorySize); done = true; break; } /* if we STILL don't have it then there is nothing */ /* more we can do */ if (!done) sysError("out of objects", "alloc"); } /* set class and type */ objectTable[position].referenceCount = 0; objectTable[position].STclass = nilobj; objectTable[position].size = memorySize; return (position << 1); }