[Vm-dev] the initial memory allocation interface...

John M McIntosh johnmci at smalltalkconsulting.com
Fri Jul 24 23:02:14 UTC 2009

On 24-Jul-09, at 3:42 PM, Eliot Miranda wrote:

> ...stinks.
> I'm talking about sqAllocateMemory.  Here's the base definition from  
> platforms/Cross/vm/sq.h:
> #define sqAllocateMemory(minHeapSize, desiredHeapSize)   
> malloc(desiredHeapSize)
> The problem here is that there's no obvious way for the client to  
> know how much memory is returned.  The signature implies it is  
> somewhere between minHeapSize & desiredHeapSize inclusive (or null,  
> if allocation failed).  But how do you tell?  Well, one could always  
> ask to grow memory by 0 and see what you get back, except for the  
> small chicken-and-egg problem that sqGrowMemory:By: and  
> sqShrinkMemory:By: require the ammount of memory allocated as an  
> argument:
> #define sqGrowMemoryBy(oldLimit, delta)         oldLimit
> #define sqShrinkMemoryBy(oldLimit, delta)       oldLimit
> So one has to go to extraordinary lengths that are completely non- 
> obvious in the client code to actually pass-back the ammount  
> allocated.  Here's a client in readImageFromFile:
>         "allocate a contiguous block of memory for the Squeak heap"
>         memory := self cCode: 'sqAllocateMemory(minimumMemory,  
> heapSize)'.
>         memory = nil ifTrue: [self insufficientMemoryAvailableError].
>         memStart := self startOfMemory.
>         self setMemoryLimit: (memStart + heapSize) - 24. "decrease  
> memoryLimit a tad for safety"
>         self setEndOfMemory: memStart + dataSize.

Somehow that looks dated? Since it now reads

	"allocate a contiguous block of memory for the Squeak heap"
	memory := self
		allocateMemory: heapSize
		minimum: minimumMemory
		imageFile: f
		headerSize: headerSize.
	memory = nil ifTrue: [self insufficientMemoryAvailableError].

which turns into

	memory = allocateMemoryMinimumImageFileHeaderSize(heapSize,  
minimumMemory, f, headerSize);
	if (memory == null) {

which is
  #define allocateMemoryMinimumImageFileHeaderSize(heapSize,  
minimumMemory, fileStream, headerSize) \
     sqAllocateMemory(minimumMemory, heapSize)

but on iPhone and mac is

#define allocateMemoryMinimumImageFileHeaderSize(heapSize,  
minimumMemory, fileStream, headerSize) \
	sqAllocateMemoryMac(heapSize, minimumMemory, fileStream, headerSize)



On the iPhone let's you vmap in the image from offset  500*1024*1024  
plus header size  to the size of the image file rounded up 4K pages.
After that the free space is mmap anonymous upto the total  heapsize,  
we ignore minimumMemory.
For WikiServer a 10MB image, then  6MB gets paged in from flash, 4MB  
is not touched.
The sqImageFileReadEntireImage does nothing.

On the macintosh the total heap size is mmapped anonymously  at the   
500*1024*1024 boundary plus header size, the sqImageFileReadEntireImage
then reads the image file into the mmap region.  I note that I had the  
same code here from the iPhone but it was discovered there is a bug  
with mmapped
files being read from NFS disks so the feature was made optional. It  
does btw save a few 100 ms at startup time on slower machines (500 Mhz)
But the macintosh virtual memory system does read all the pages from  
the file into RAM, versus the iPhone which does not.
John M. McIntosh <johnmci at smalltalkconsulting.com>   Twitter:   
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com

More information about the Vm-dev mailing list