usqInt sqAllocateMemoryMac(sqInt minHeapSize, sqInt *desiredHeapSize);
#define sqAllocateMemory(x,y) sqAllocateMemoryMac(x,&y);
Ingenious (seriously; John this is a very clever working around of the restriction). Totally non-obvious at the client site, but it still gets the job done without requiring the client to change. So this costs too much to maintain (a.k.a. puts too much strain on my rodent brain).
We could go with an explicit out parameter, as in
"allocate a contiguous block of memory for the Squeak heap"
memory := self cCode: 'sqAllocateMemory(minimumMemory, heapSize, &allocatedSize)'.
memory = nil ifTrue: [self insufficientMemoryAvailableError].
memStart := self startOfMemory.
self setMemoryLimit: (memStart + allocatedSize) - 24. "decrease memoryLimit a tad for safety"
self setEndOfMemory: memStart + dataSize.
but out parameters are not supported by Smalltalk and the VM is a Smalltalk program goddammit.
So I want to canvas opinions on the following simplified proposal, which is to drop the oldLimit parameter from sqGrowMemoryBy, discard sqShrinkMemoryBy (it is superfluous given sqGrowMemoryBy can take a signed argument) and use self sqGrowMemoryBy: 0 to determine how much memory has been allocated:
"allocate a contiguous block of memory for the Squeak heap"
memory := self sqAllocateAtLeast: minimumMemory AtMostMemory: heapSize.
memory = nil ifTrue: [self insufficientMemoryAvailableError].
heapSize := self sqGrowMemoryBy: 0.
memStart := self startOfMemory.
self setMemoryLimit: (memStart + heapSize) - 24. "decrease memoryLimit a tad for safety"
self setEndOfMemory: memStart + dataSize.
with the obvious default implementations in e.g. platforms/Cross/vm/sqMemory.c
void *mem;
if ((mem = malloc(reserved)) ~= 0)
memoryLimit = reserved;
else if ((mem = malloc(committed)) ~= 0)
memoryLimit = committed;
return mem;
}
unsigned long
sqGrowMemoryBy(sqInt delta)
{
return memoryLimit;
}
and everywhere in the VM which expects the old sqGrowMemoryBy to answer a pointer to the limit must instead add the result to the base of allocated memory; i.e.
limit := self sqGrowMemory: memoryLimit By: delta.
limit = memoryLimit ifFalse:
[self setMemoryLimit: limit - 24. "remove a tad for safety"
self initializeMemoryFirstFree: freeBlock]
is rewritten as
limit := memoryLimit + (self sqGrowMemoryBy: delta).
limit = memoryLimit ifFalse:
[self setMemoryLimit: limit - 24. "remove a tad for safety"
self initializeMemoryFirstFree: freeBlock]
Opinions?
best
Eliot