Hi Clémewnt,

   sorry for the late reply...

On Sat, Apr 28, 2018 at 1:57 AM, Clément Bera <bera.clement@gmail.com> wrote:
Hi Eliot, Hi all,

On mac and linux, Spur uses mmap to allocate new segments. The V3 memory manager used malloc instead. I've looked into many other VMs (Javascript and Java), and most of them use posix_memalign (basically malloc where you can ask for specific alignment)

And on Windows it uses VirtualAlloc.  So it is consistent in using memory mapping to allocate segments across the platforms, where available.
I am wondering why we are using mmap over posix_memalign / mallocThe only reason I can find is that Spur always allocate new memory segments at a higher address than past segments to guarantee that young objects are on lower addresses than old objects for the write barrier. Is that correct?

Well, I don't like using malloc because one is layering unnecessarily and hence there is wastage.  Many malloc implementations are optimized for small block sizes and allocating a huge block
- may have a segment allocated all to itself
- won't necessarily be on a page boundary (especially on systems with very large pages)

Assuming it is correct, let's say I change Spur to implement the write barrier differently (typically, I change all objects to be aligned on 128 bits instead of 64 and have different allocation alignment for young (128 bits alignment) and old objects(128+64 bits alignment)). Will we be able to use posix_memalign / malloc to allocate new memory segment if I do that ?

Sure, but why?  Given that using mmap/VirtualAlloc gives page alignment, one is going to get alignment up to at least 256 bytes (ancient VAX page size) and more typically 4k bytes (x86/x86_64) .
Or does the VM rely on segments being on higher addresses for other reasons ? For example, does the VM assume CogMethods are on lower addresses than objects on heap and rely on it to check if a stack frame is mframe or iframe ? 

Well indeed being able to reply on ordering makes the boundary checks in the store checks simpler.  I think you wrote a blog post on this so you;ve actually captured this info before.  But to reiterate, the Cog and Stack VM assumes the following memory orderings:

1. all primitive functions are above 1024.  This allows the quick primitives to be stored in the method cache with a primitive function pointer that is their index and for executeNewMethod et al to compare the primitiveFunctionPointer against MaxQuickPrimitiveIndex and dispatch to quickPrimitiveResponse

2. New space is below all old space segments, and is immediately below the first old space segment.  This allows isOldObject:/isYoungObject: et al to compare an oop against newSpaceLimit/oldSpaceStart/nilObj (yes we have three different names for exactly the same value; we only need two; the fact that nilObj = oldSpaceStart is incidental).

3. the code zone is below new space.  This allows isReallyYoungObject: to use two comparisons, instead of three.

So let me ask you the corollary.  Why, if mmap/VirtualAlloc provides memory aligned on a page boundary, with no overhead, and control over placement, why would one use posix_memalign or malloc to allocate memory?



best, Eliot