On Fri, Jul 24, 2009 at 4:59 PM, Eliot Miranda <eliot.miranda@gmail.com> wrote:
Hi John,


so much for that.  gmail seems hopelessly inconsistent form day to day as to whether Reply does reply to all or reply to sender.  Or is it my advancing years??

On Fri, Jul 24, 2009 at 4:02 PM, John M McIntosh <johnmci@smalltalkconsulting.com> wrote:

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


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)

Yes, but that's beside the point.  The basic issue still remains.  I'd still like your opinion on the question asked.  Would you be willing to answer again?  Don't assume that all platforms will reserve the entire memory. Yes, all the platforms we use here do but a bare metal port might still use malloc.


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@smalltalkconsulting.com>   Twitter:  squeaker68882
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com