Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/external/source/byakugan/heapSplay.cpp
Views: 11765
#include "byakugan.h"1#include "heapStructs.h"23void initializeHeapModel(struct HeapState *heapModel) {45memset(heapModel, 0, sizeof (struct HeapState));6heapModel->hPoolListLen = 16;7heapModel->heaps = (struct HPool *) calloc(heapModel->hPoolListLen, sizeof (struct HPool));8}910void heapAllocate(struct HeapState *heapModel, struct AllocateStruct *aStruct) {11struct HPool *myHeap;12struct HeapChunk *myChunk;1314if (aStruct->heapHandle == 0 || aStruct->ret == 0)15return;1617myHeap = getHeap(heapModel, aStruct->heapHandle);18myChunk = getChunk(myHeap, aStruct->ret);1920if (myChunk == NULL)21return;2223myChunk->size = aStruct->size;24myChunk->flags = aStruct->flags;25myChunk->free = FALSE;26}2728void heapReallocate(struct HeapState *heapModel, struct ReallocateStruct *rStruct) {29struct HPool *myHeap;30struct HeapChunk *oChunk, *nChunk;3132if (rStruct->heapHandle == 0 || rStruct->ret == 0)33return;3435myHeap = getHeap(heapModel, rStruct->heapHandle);36nChunk = getChunk(myHeap, rStruct->ret);37if (nChunk == NULL)38return;3940if (rStruct->ret != rStruct->memoryPointer && rStruct->memoryPointer != 0) {41oChunk = getChunk(myHeap, rStruct->memoryPointer);42if (oChunk != NULL)43oChunk->free = TRUE;44}4546nChunk->size = rStruct->size;47nChunk->flags = rStruct->flags;48nChunk->free = FALSE;49}5051void heapFree(struct HeapState *heapModel, struct FreeStruct *fStruct) {52struct HPool *myHeap;53struct HeapChunk *myChunk;5455if (fStruct->heapHandle == 0 || fStruct->memoryPointer == 0x00000000) {56// So many of these that it slows us down :(57//dprintf("[T] Program attempted to free a NULL pointer.\n\n");58return;59}6061myHeap = getHeap(heapModel, fStruct->heapHandle);62myChunk = getChunk(myHeap, fStruct->memoryPointer);63if (myChunk == NULL)64return;6566if (myChunk->free == TRUE)67dprintf("[T] Possible 'double free' of chunk @ 0x%08x:0x%08x\n\n",68myChunk->addr, fStruct->memoryPointer);6970myChunk->flags = fStruct->flags;71myChunk->free = TRUE;72}7374void heapCreate(struct HeapState *heapModel, struct CreateStruct *cStruct) {75struct HPool *newHeap;76ULONG i;7778if (cStruct->base == 0)79return;8081newHeap = getHeap(heapModel, cStruct->base);82newHeap->commit = cStruct->commit;83newHeap->reserve = cStruct->reserve;84newHeap->lock = cStruct->lock;85newHeap->flags = cStruct->flags;86}8788void heapDestroy(struct HeapState *heapModel, struct DestroyStruct *dStruct) {89// Only place we mark heaps as not in use90struct HPool *deadHeap;9192if (dStruct->heapHandle == 0)93return;9495deadHeap = getHeap(heapModel, dStruct->heapHandle);96free(deadHeap->chunks);97memset(deadHeap, 0, sizeof(struct HPool));98heapModel->numHeaps--;99}100101void heapCoalesce(struct HeapState *heapModel, struct CoalesceStruct *cfbStruct) {102// Only place we mark chunks as not in use103}104105struct HPool *getHeap(struct HeapState *heapModel, PVOID heapHandle) {106ULONG i;107struct HPool *newHeap = NULL;108109for (i = 0; i < heapModel->hPoolListLen; i++) {110if ((heapModel->heaps[i]).base == heapHandle)111return (&(heapModel->heaps[i]));112if (heapModel->numHeaps == heapModel->hPoolListLen) // Add some short circuits here113continue;114if (newHeap != NULL)115continue;116if ((heapModel->heaps[i]).inUse == FALSE)117newHeap = &(heapModel->heaps[i]);118}119120// If we get here we haven't found a heap, so lets make one121//dprintf("[T] Creating entry for heap: 0x%08x\n", heapHandle);122123if (newHeap == NULL) {124heapModel->hPoolListLen = heapModel->hPoolListLen * 2;125newHeap = heapModel->heaps;126heapModel->heaps = (struct HPool *) realloc(heapModel->heaps,127heapModel->hPoolListLen * sizeof(struct HPool));128if (heapModel->heaps == NULL) {129heapModel->heaps = newHeap;130//crushModel(heapModel); ADD ME XXX131dprintf("[T] OOM getting new heaps!\n\n");132return (NULL);133}134newHeap = &(heapModel->heaps[heapModel->numHeaps]);135// Clean the newly allocated memory136memset(newHeap, 0, (sizeof (struct HPool) * (heapModel->hPoolListLen - heapModel->numHeaps)));137}138139heapModel->numHeaps++;140newHeap->base = heapHandle;141newHeap->inUse = TRUE;142newHeap->chunkListLen = 0x007fffff/8;143newHeap->chunks = (struct HeapChunk *) calloc(newHeap->chunkListLen,144sizeof (struct HeapChunk));145146return (newHeap);147}148149// CRRRRAAAAZZYYY splay tree action on top of our chunk code...150// Many thanks to Sedgewick and Sleator :)151struct HeapChunk *splay(PVOID addr, struct HeapChunk *t) {152struct HeapChunk N, *l, *r, *y;153154if (t == NULL) {155return (t);156}157memset(&N, 0, sizeof (HeapChunk));158l = r = &N;159160for (;;) {161if (addr < t->addr) {162if (t->left == NULL) break;163if (addr < (t->left)->addr) {164y = t->left;165t->left = y->right;166y->right = t;167t = y;168if (t->left == NULL) break;169}170r->left = t;171r = t;172t = t->left;173} else if (addr > t->addr) {174if (t->right == NULL) break;175if (addr > (t->right)->addr) {176y = t->right;177t->right = y->left;178y->left = t;179t = y;180if (t->right == NULL) break;181}182l->right = t;183l = t;184t = t->right;185} else {186break;187}188}189l->right = t->left;190r->left = t->right;191t->left = N.right;192t->right = N.left;193194return (t);195}196197struct HeapChunk *insert(struct HeapChunk *newC, struct HPool *heap) {198/* Insert i into the tree t, unless it's already there. */199/* Return a pointer to the resulting tree. */200struct HeapChunk *t;201202heap->numChunks++;203newC->inUse = TRUE;204205t = heap->t;206if (t == NULL) {207heap->t = newC;208return (newC);209}210t = splay(newC->addr,t);211if (newC->addr < t->addr) {212newC->left = t->left;213newC->right = t;214t->left = NULL;215heap->t = newC;216return (newC);217} else if (newC->addr > t->addr) {218newC->right = t->right;219newC->left = t;220t->right = NULL;221heap->t = newC;222return (newC);223} else { /* We get here if it's already in the tree */224/* Don't add it again */225dprintf("[XXX] WTF?? Inserting the same address twice!\nBase: 0x%08x\tAddr: 0x%08x:0x%08x\n\n",226heap->base, newC->addr, t->addr);227t->inUse = TRUE;228heap->t = t;229return (t);230}231}232233234struct HeapChunk *getChunk(struct HPool *heap, PVOID memoryPointer) {235ULONG i;236struct HeapChunk *newChunk, *niuChunk = NULL;237238// Old and slow - O(n)239#if 0240for (i = 0; i < heap->chunkListLen; i++) {241newChunk = &(heap->chunks[i]);242if (newChunk->addr == memoryPointer)243return (newChunk);244if (heap->numChunks == heap->chunkListLen)245continue;246if (niuChunk != NULL)247continue;248if (newChunk->inUse == FALSE)249niuChunk = newChunk;250}251252// New splayness - O(log n)253newChunk = heap->t;254i = 0;255while (newChunk != NULL) {256if (newChunk->addr == memoryPointer) {257return (newChunk);258}259260if (newChunk->inUse == FALSE) {261dprintf("[XXX] Unused chunk in the tree!! L%d 0x%08x\n\n",262i, newChunk->addr);263niuChunk = newChunk;264}265266if (memoryPointer < newChunk->addr) {267newChunk = newChunk->left;268i++;269} else {270newChunk = newChunk->right;271i++;272}273}274#endif275heap->t = splay(memoryPointer, heap->t);276if (heap->t != NULL && (heap->t)->addr == memoryPointer)277return (heap->t);278279if (niuChunk == NULL) {280if (heap->numChunks < heap->chunkListLen) {281if ((heap->chunks[heap->numChunks]).inUse == FALSE) {282//dprintf("[XXX] FOUND CHUNK WHERE EXPECTED! :)\n\n");283niuChunk = &(heap->chunks[heap->numChunks]);284niuChunk->addr = memoryPointer;285niuChunk->heapHandle = heap->base;286insert(niuChunk, heap);287return (niuChunk);288}289// Worst muddahfuggin case...290dprintf("[XXX] Unused chunks should be at the END of the list!\n\n");291for (i = 0; i < heap->chunkListLen; i++) {292if ((heap->chunks[i]).inUse == FALSE) {293niuChunk = &(heap->chunks[i]);294niuChunk->addr = memoryPointer;295niuChunk->heapHandle = heap->base;296insert(niuChunk, heap);297return (niuChunk);298}299}300}301302heap->chunkListLen = heap->chunkListLen * 2;303niuChunk = heap->chunks;304heap->chunks = (struct HeapChunk *) realloc(heap->chunks,305heap->chunkListLen * sizeof (struct HeapChunk));306if (heap->chunks == NULL) {307heap->chunks = niuChunk;308//crushHeap(heap);309heap->chunkListLen = heap->chunkListLen/2;310dprintf("[T] OOM getting new chunks! %d -> %d\n\n",311heap->chunkListLen, heap->chunkListLen*2);312return (NULL);313}314niuChunk = &(heap->chunks[heap->numChunks]);315memset(niuChunk, 0, (sizeof (struct HeapChunk) * (heap->chunkListLen - heap->numChunks)));316}317318niuChunk->addr = memoryPointer;319niuChunk->heapHandle = heap->base;320insert(niuChunk, heap);321return (niuChunk);322}323324325