<div dir="ltr">Hi Clément,<div class="gmail_extra"><br><div class="gmail_quote">On Wed, May 2, 2018 at 11:42 PM, Clément Bera <span dir="ltr"><<a href="mailto:bera.clement@gmail.com" target="_blank">bera.clement@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="auto"><div>Hi Eliot,</div><div><br></div><div>I am more annoyed about using mmap to get memory at higher addresses and segment positioning than using mmap itself.</div><div><br></div><div>Allocating memory at higher addresses:</div><div>- is impossible in some platforms such as rumpkernel</div><div>- is annoying since it relies on API such as sbrk, which is deprecated in SUSv2 and not present at all in <span style="color:rgb(64,64,64);font-family:verdana,arial,helvetica,geneva,sans-serif;font-size:12.8px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);float:none;display:inline">POSIX.</span></div><div><br></div><div>Malloc is not amazing, but it's much more portable. I would rather have something like:</div><div><br></div><div>#ifdef mmap</div><div>  mmap(...)</div><div>#else </div><div>  posix_memalign{...)</div><div>#endif</div></div></div></blockquote><div><br></div><div>I think the thing to do is something like</div><div>- a cross platform define, USE_MALLOC (see e.g. USE_MMAP in the Unix sources)</div><div>- either files that implement each interface, e.g.</div><div>    sqUnixSpurMMapMemory.c, sqUnixSpurMallocMemory.c</div><div>  and a small file that includes one or the other</div><div>- or each function implemented twice3, surrounded by #if USE_MALLOC ... #else ... #endif /* USE_MALLOC */</div><div><br></div><div>But before you go there, how do you hope to get posix_memalign to answer memory where you need it?  It seems to me that if you go with malloc then you're forced to allocate memory at start-up, because there's no guarantee that memory will appear at higher or lower addresses than the initial alloc.  This was the situation with the original V3 allocator; it did a large allocation, defaulting to 512Mb, and allocated the heap from that.  One couldn't release memory back to the OS, one couldn't have a small footprint and be allowed to grow afterwards, etc.  And the only interface I know that allows address hints is the memory mapping one.</div><div><br></div><div>I get that there are platforms for which mmap doesn't work.  But I would suggest that on these platforms one has to do something very different than what makes sense for desktop OSs, and so one has to accommodate their limitations somehow.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="auto"><span class="gmail-"><div><br></div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);float:none;display:inline"><i>1. all primitive functions are above 1024</i></span></div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);float:none;display:inline"><i><br></i></span></div></span><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);float:none;display:inline">That's not a problem whatsoever.</span></div></div></div></blockquote><div><br></div><div>I know.  I was just being precise.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="auto"><span class="gmail-"><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);float:none;display:inline"><i><br></i></span></div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);float:none;display:inline"><i><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);float:none;display:inline">2. New space is below all old space segments</span><br></i></span></div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);float:none;display:inline"><i><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);float:none;display:inline"><br></span></i></span></div></span><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);float:none;display:inline"><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);float:none;display:inline">Here there's the alignment solution, which improves performance and removes the constraint.</span></span></div></div></div></blockquote><div><br></div><div>What, that objects are allocated on a 0 modulo 16 byte boundary or an 8 modulo 16 byte boundary?  That's fine, but it wastes 5% of the heap.  And don't we encounter more problems using the alignment solution if we want to do shared segments?  (I guess not; we simply choose the 0 modulo 16 alignment for old space segments).  Have you implemented the alignment solution?</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="auto"><span class="gmail-"><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);float:none;display:inline"><i><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);float:none;display:inline">3. the code zone is below new space.<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);float:none;display:inline"> This allows isReallyYoungObject: to use two comparisons, instead of three.</span></span><br></i></span></div><div><br></div></span><div><div><font face="monospace, monospace">isReallyYoungObject: objOop</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap"> </span><api></font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">       </span>"Answer if obj is young. Require that obj is non-immediate. Override to filter-out Cog methods"</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap"> </span>self assert: (self isNonImmediate: objOop).</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">       </span>^(self oop: objOop isLessThan: newSpaceLimit)</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">     </span>  and: [self oop: objOop isGreaterThanOrEqualTo: newSpaceStart]</font></div></div><div><br></div><div>I don't think that method would change.</div></div></div></blockquote><div><br></div><div>Right.  Sorry.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="auto"><div>I think the method <font face="monospace, monospace">isMachineCodeFrame:</font> would change (2 comparisons instead of one).<br></div><div><br></div><div>I dream of a world where young space, code zone and old space segments are in different segments which do not have any position requirement. That way:</div><div>- no constraints for platforms like rumpkernel</div><div>- no reliance on API such as sbrk.</div><div>- quicker segment alloc since 0 can be used as the address (OS allocates segment wherever it wants)</div><div>- quicker write barrier with bit check instead of cmp with constant</div><div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255)">- growing code zone at runtime is fairly easy (divorce allFrames, alloc new segment and free old one)</div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255)">- growing new space at runtime is fairly easy (do a tenureAll, alloc new segment and free the old new space segment)</div></div></div></div></blockquote><div><br></div><div>Sure.  Some things to consider:</div><div>- boundary checks are frequent.  The ParcPlace code (written by David Ungar and Frank Jackson) was very careful to have as many single boundary checks as possible.</div><div><br></div><div>And my own complaint.</div><div>- sbrk is regrettable, but an interface like mmap that allows for one to supply a position hint and then doesn't provide a convenient of finding out what the emory map seems to me to be broken without sbrk.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="auto"><div>It's just details all right. I will see if I can try that someday.<br></div></div></div></blockquote><div><br></div><div>Right.  And implementing things using subclasses (e.g. of SpurMemoryManager) means we can mix and match and experiment.</div><div><br></div><div><br></div><div>P.S.  sorry to have replied so slowly...</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="auto"><div><div class="gmail-h5"><div><br><div class="gmail_quote"><div dir="ltr">On Wed, May 2, 2018, 02:19 Eliot Miranda <<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hi Clémewnt,<div><br></div><div>   sorry for the late reply...</div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Apr 28, 2018 at 1:57 AM, Clément Bera <span dir="ltr"><<a href="mailto:bera.clement@gmail.com" rel="noreferrer" target="_blank">bera.clement@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hi Eliot, Hi all,<div><div><br></div><div>On mac and linux, Spur uses <font face="monospace, monospace">mmap</font> to allocate new segments. The V3 memory manager used <font face="monospace, monospace">malloc</font> instead. I've looked into many other VMs (Javascript and Java), and most of them use <font face="monospace, monospace">posix_memalign </font><font face="arial, helvetica, sans-serif">(basically malloc where you can ask for specific alignment)</font><font face="monospace, monospace">. </font></div></div></div></blockquote><div><br></div><div>And on Windows it uses VirtualAlloc.  So it is consistent in using memory mapping to allocate segments across the platforms, where available.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>I am wondering why we are using <font face="monospace, monospace">mmap</font> over <span style="font-family:monospace,monospace;font-variant-ligatures:normal">posix_memalign / malloc</span><span style="font-family:monospace,monospace;font-variant-ligatures:normal"><span style="font-variant-ligatures:normal">. </span></span><span style="font-family:arial,helvetica,sans-serif">The 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?</span><br></div></div></blockquote><div><br></div><div>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</div><div>- may have a segment allocated all to itself</div><div>- won't necessarily be on a page boundary (especially on systems with very large pages)</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>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 <span style="font-family:monospace,monospace;font-variant-ligatures:normal">posix_memalign / malloc </span><span style="font-variant-ligatures:normal"><font face="arial, helvetica, sans-serif">to allocate new memory segment if I do that ?</font></span></div></div></blockquote><div><br></div><div>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) .</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><span style="font-variant-ligatures:normal"><font face="arial, helvetica, sans-serif"> Or d</font></span>oes 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 ? <br></div></div></blockquote><div><br></div><div>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:</div><div><br></div><div>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</div><div><br></div><div>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/ni<wbr>lObj (yes we have three different names for exactly the same value; we only need two; the fact that nilObj = oldSpaceStart is incidental).</div><div><br></div><div>3. the code zone is below new space.  This allows isReallyYoungObject: to use two comparisons, instead of three.</div><div><br></div><div>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?</div></div></div></div></blockquote></div></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div></div><div><br></div><div>Thanks,</div><span class="gmail-m_3755183701180637087gmail-m_-8552730535794020473m_-1104729415784352467gmail-HOEnZb"><font color="#888888"><div><br></div>-- <br><div class="gmail-m_3755183701180637087gmail-m_-8552730535794020473m_-1104729415784352467gmail-m_3718303252889089252gmail_signature"><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><span style="font-size:12.8px">Clément Béra<br></span><span style="color:rgb(0,0,238)"><a href="https://clementbera.github.io/" rel="noreferrer" target="_blank">https://clementbera.github.io/</a></span><div style="font-size:12.8px"><a href="https://clementbera.wordpress.com/" rel="noreferrer" target="_blank">https://clementbera.wordpress.<wbr>com/</a></div></div></div></div></div></div>
</font></span></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail-m_3755183701180637087gmail-m_-8552730535794020473m_-1104729415784352467gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>
</blockquote></div></div></div></div></div></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>