<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Sep 23, 2013 at 3:10 PM, Nicolas Cellier <span dir="ltr">&lt;<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr">
Isn&#39;t Eliot just implementing this feature, having a segment of non relocatable objects?<br></div></blockquote><div><br></div><div>Sort of.  Spur will allow any object in old space to stay still, and through become can move any object to old space very simply.  So instead of having a special fixed space segment it has a best-bit compaction algorithm that doesn&#39;t slide objects, but moves them into holes.  With this kind of compaction it is very easy to leave objects put.</div>
<div><br></div><div>A further advantage of Spur is that objects have 64-bit alignment so passing arrays to e.g. code using sse instructions, won&#39;t cause potential alignment faults.</div><div><br></div><div>But for NB see below on the hack that the ThreadedFFI uses.</div>
<div><br></div><div><br></div><blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div dir="ltr"></div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/9/23 Igor Stasenko <span dir="ltr">&lt;<a href="mailto:siguctua@gmail.com" target="_blank">siguctua@gmail.com</a>&gt;</span><br>
<blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr">
<br><div class="gmail_extra"><br><br><div class="gmail_quote"><div><div>On 23 September 2013 21:40, Igor Stasenko <span dir="ltr">&lt;<a href="mailto:siguctua@gmail.com" target="_blank">siguctua@gmail.com</a>&gt;</span> wrote:<br>


<blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr">
<br><div class="gmail_extra"><br><br><div class="gmail_quote"><div>On 23 September 2013 16:23, Camillo Bruni <span dir="ltr">&lt;<a href="mailto:camillobruni@gmail.com" target="_blank">camillobruni@gmail.com</a>&gt;</span> wrote:<br>



<blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">Hi Jan,<br>
<br>
I think I will add the ByteArray accessor to NBExternalAddress today<br>
or tomorrow since I need it as well for another project.<br>
<br></blockquote></div><div>hmm, reading from memory into bytearray can be done with memory copy:<br><br></div><div>inputs: address , offset , size to read<br><br></div><div>newAddress := NBExternalAddress value: address value + offset.<br>



</div><div>buffer := ByteArray new: size.<br></div><div>NativeBoost memCopy: newAddress to: buffer size: size.<br></div><div><br></div><div>same way, writing, just swap the source and destination:<br></div><div><br><div>


newAddress := NBExternalAddress value: address value + offset.<br>
</div><div>buffer &quot;is given from somewhere&quot;.<br></div><div>NativeBoost memCopy:  buffer  to: newAddress size: size.<br></div><div><br></div>but as Jan noted, you cannot tell to write starting at specified offset from/to bytearray, e.g.:<br>



<br></div><div>copy from: address to: buffer + someOffset<br></div><div>neither:<br><div>copy from: buffer + someOffset to: someAddress<br></div><br></div><div>this  where we need to introduce special &#39;field address&#39; type, so you can construct it like this:<br>



<br></div><div>offsetAddress := buffer nbAddressAt: offset.<br><br></div><div>so then you can use it to pass to any function, which expects address, like memory copy <br></div><div>or any foreign function.<br><br></div><div>



Since objects are moving in memory, we cannot calculate address of field before hand:<br><br>address := NBExternalAddress value:  someObject address + offset.<br></div><div><br></div><div>because if GC will happen, after computing such address and its actual use,<br>



</div><div>you will read/write to wrong location.<br></div></div></div></div></blockquote><div> </div></div></div><div>** after computing and *before* actual use **<br></div><div><div> </div><blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div></div><div>Thus we should keep oop + offset up to the point of passing it to external function, under<br></div><div>controllable conditions, that guarantee there&#39;s no GC is possible.<br>



</div><div><div><div><br></div><div><br></div></div></div></div></div></div></blockquote></div><div>Things would be much simpler if we could have pinning, isnt? :)<br></div></div></div></div></blockquote></div></div></blockquote>
<div><br></div><div>Yes, but for the moment there is a hack one can use, a neat hack invented by Andreas Raab.  The Squeak GC is a two-space GC, old space (collected by fullGC) and new space (collected by incrementalGC).  An incrementalGC will move objects in new space but leave objects on old space alone.  A tenuringIncrementalGC will compact new space and then make new space part of old space.  Therefore one way of nearly pinning objects is to do a young GC to tenure objects into old space via tenuringIncrementalGC and then lock fullGC, prevent fullGC from running, until the external call is finished.  All arguments to the call become old, and they won&#39;t be moved until the fuuGCLock is released. This doesn&#39;t help passing a buffer that will be used after the call returns, but it does help a buffer being passed to code that might callback.</div>
<div><br></div><div>See uses of PrimErrObjectMayMove, e.g. ThreadedFFIPlugin&gt;&gt;primitiveCallout and platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c&gt;&gt;sqFileReadIntoAt</div><div><br></div><div>HTH</div>
<div>eliot</div></div>
</div></div>