sqInt sqAllocateMemory(sqInt minHeapSize, sqInt desiredHeapSize) { sqMemoryBase= uxAllocateMemory(minHeapSize, desiredHeapSize); if (!sqMemoryBase) return 0; sqMemoryBase -= SQ_FAKE_MEMORY_OFFSET; return (sqInt)SQ_FAKE_MEMORY_OFFSET; }
sqInt sqAllocateMemory(sqInt minHeapSize, sqInt desiredHeapSize) { return (sqInt)(long)uxAllocateMemory(minHeapSize, desiredHeapSize); }
void * uxAllocateMemory(usqInt minHeapSize, usqInt desiredHeapSize) { if (heap) { fprintf(stderr, "uxAllocateMemory: already called\n"); exit(1); } pageSize= getpagesize(); pageMask= ~(pageSize - 1); #else /* SPURVM */ void *uxAllocateMemory(usqInt minHeapSize, usqInt desiredHeapSize) { # if !ALWAYS_USE_MMAP if (!useMmap) return malloc(desiredHeapSize); # endif if (heap) { fprintf(stderr, "uxAllocateMemory: already called\n"); exit(1); } pageSize= getpagesize(); pageMask= ~(pageSize - 1); DPRINTF(("uxAllocateMemory: pageSize 0x%x (%d), mask 0x%x\n", pageSize, pageSize, pageMask)); # if (!MAP_ANON) if ((devZero= open("/dev/zero", O_RDWR)) < 0) { perror("uxAllocateMemory: /dev/zero"); return 0; } # endif DPRINTF(("uxAllocateMemory: /dev/zero descriptor %d\n", devZero)); DPRINTF(("uxAllocateMemory: min heap %d, desired %d\n", minHeapSize, desiredHeapSize)); heapLimit= valign(max(desiredHeapSize, useMmap)); while ((!heap) && (heapLimit >= minHeapSize)) { DPRINTF(("uxAllocateMemory: mapping 0x%08x bytes (%d Mbytes)\n", heapLimit, heapLimit >> 20)); if (MAP_FAILED == (heap= mmap(0, heapLimit, MAP_PROT, MAP_FLAGS, devZero, 0))) { heap= 0; heapLimit= valign(heapLimit / 4 * 3); } } if (!heap) { fprintf(stderr, "uxAllocateMemory: failed to allocate at least %lld bytes)\n", (long long)minHeapSize); useMmap= 0; return malloc(desiredHeapSize); } heapSize= heapLimit; if (overallocateMemory) uxShrinkMemoryBy(heap + heapLimit, heapLimit - desiredHeapSize); return heap; } #endif /* SPURVM */ static int log_mem_delta = 0; #define MDPRINTF(foo) if (log_mem_delta) DPRINTF(foo); else 0 /* grow the heap by delta bytes. answer the new end of memory. */ char *uxGrowMemoryBy(char *oldLimit, sqInt delta) { if (useMmap) { int newSize= min(valign(oldLimit - heap + delta), heapLimit); int newDelta= newSize - heapSize; MDPRINTF(("uxGrowMemory: %p By: %d(%d) (%d -> %d)\n", oldLimit, newDelta, delta, heapSize, newSize)); assert(0 == (newDelta & ~pageMask)); assert(0 == (newSize & ~pageMask)); assert(newDelta >= 0); if (newDelta) { MDPRINTF(("was: %p %p %p = 0x%x (%d) bytes\n", heap, heap + heapSize, heap + heapLimit, heapSize, heapSize)); if (overallocateMemory) { char *base= heap + heapSize; MDPRINTF(("remap: %p + 0x%x (%d)\n", base, newDelta, newDelta)); if (MAP_FAILED == mmap(base, newDelta, MAP_PROT, MAP_FLAGS | MAP_FIXED, devZero, heapSize)) { perror("mmap"); return oldLimit; } } heapSize += newDelta; MDPRINTF(("now: %p %p %p = 0x%x (%d) bytes\n", heap, heap + heapSize, heap + heapLimit, heapSize, heapSize)); assert(0 == (heapSize & ~pageMask)); } return heap + heapSize; } return oldLimit; } /* shrink the heap by delta bytes. answer the new end of memory. */ char *uxShrinkMemoryBy(char *oldLimit, sqInt delta) { if (useMmap) { int newSize= max(0, valign((char *)oldLimit - heap - delta)); int newDelta= heapSize - newSize; MDPRINTF(("uxGrowMemory: %p By: %d(%d) (%d -> %d)\n", oldLimit, newDelta, delta, heapSize, newSize)); assert(0 == (newDelta & ~pageMask)); assert(0 == (newSize & ~pageMask)); assert(newDelta >= 0); if (newDelta) { MDPRINTF(("was: %p %p %p = 0x%x (%d) bytes\n", heap, heap + heapSize, heap + heapLimit, heapSize, heapSize)); if (overallocateMemory) { char *base= heap + heapSize - newDelta; MDPRINTF(("unmap: %p + 0x%x (%d)\n", base, newDelta, newDelta)); if (munmap(base, newDelta) < 0) { perror("unmap"); return oldLimit; } } heapSize -= newDelta; MDPRINTF(("now: %p %p %p = 0x%x (%d) bytes\n", heap, heap + heapSize, heap + heapLimit, heapSize, heapSize)); assert(0 == (heapSize & ~pageMask)); } return heap + heapSize; } return oldLimit; } /* answer the number of bytes available for growing the heap. */ sqInt uxMemoryExtraBytesLeft(sqInt includingSwap) { return useMmap ? (heapLimit - heapSize) : 0; } #else /* HAVE_MMAP */ # if COG void * uxAllocateMemory(sqInt minHeapSize, sqInt desiredHeapSize) { if (pageMask) { fprintf(stderr, "uxAllocateMemory: already called\n"); exit(1); } pageSize = getpagesize(); pageMask = ~(pageSize - 1); # if SPURVM return malloc(desiredHeapSize); # else return malloc(desiredHeapSize); # endif } # else /* COG */ void *uxAllocateMemory(sqInt minHeapSize, sqInt desiredHeapSize) { return malloc(desiredHeapSize); } # endif /* COG */ char *uxGrowMemoryBy(char * oldLimit, sqInt delta) { return oldLimit; } char *uxShrinkMemoryBy(char *oldLimit, sqInt delta) { return oldLimit; } sqInt uxMemoryExtraBytesLeft(sqInt includingSwap) { return 0; } #endif /* HAVE_MMAP */ #if defined(SQ_IMAGE32) && defined(SQ_HOST64) usqInt sqAllocateMemory(usqInt minHeapSize, usqInt desiredHeapSize) { sqMemoryBase= uxAllocateMemory(minHeapSize, desiredHeapSize); if (!sqMemoryBase) return 0; sqMemoryBase -= SQ_FAKE_MEMORY_OFFSET; return (sqInt)SQ_FAKE_MEMORY_OFFSET; }