<br><br><div class="gmail_quote">On Tue, May 14, 2013 at 5:30 AM, Guillermo Polito <span dir="ltr">&lt;<a href="mailto:guillermopolito@gmail.com" target="_blank">guillermopolito@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 <br><div dir="ltr">Hi!<br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, May 13, 2013 at 11:09 PM, Eliot Miranda <span dir="ltr">&lt;<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> <br>Hi Guillermo,<br><br><div class="gmail_quote">On Mon, May 13, 2013 at 3:04 AM, Guillermo Polito <span dir="ltr">&lt;<a href="mailto:guillermopolito@gmail.com" target="_blank">guillermopolito@gmail.com</a>&gt;</span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> <br><div dir="ltr"><div>I was looking at the following primitiveFileRead because I wanted to extract some code. I do not see why objects should move during the primitive execution... And I do not see why is this check only made in this primitive (and the threadedFFI ones...).</div>



<div><br></div><div>Does someone have a clue?</div></div></blockquote><div><br></div><div>This is for the threaded VM with the current GC.  Imagine sqFileReadIntoAt blocks and the VM does a thread switch to some other thread.  At that point the other thread could cause the VM to perform a GC.  Andreas came up with the idea of handling this situation by allowing a blocking thread to prevent full GCs that move objects in old space, but not prevent &quot;incremental&quot; GCs which only move objects in young space.  So if the thread executing sqFileReadIntoAt is given only old objects it can safely block if it sets a flag preventing full GCs.</div>


<div><br></div><div>In a GC supporting pinning and/or lazy become the blocking thread would instead either pin its buffer or become its buffer into a pinned space, in which case the error below could never occur.  But the check is harmless.</div>


<div><br></div><div>does this help?</div><div><br></div></div></blockquote><div><br></div><div>Yes, so it is only used in case of a threaded VM, what makes more sense :).</div><div><br></div><div>Now I wonder, shouldn&#39;t then this check be done in (almost) every primitive?</div>
</div></div></div></blockquote><div><br></div><div>I don&#39;t think so. Only in primitives that could block while the VM could do other things.  So for example, DNS lookup.  In fact, the current DNS lookup primitive has its own custom threading scheme sop it can run un the background (not functional on unix).  A threaded VM should eliminate the need for such special-case code.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">
<div> </div><div>Tx!!</div><div>Guille</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="gmail_quote"><div></div><div><br></div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><br></div><div>Thanks,</div>
<div>Guille</div><div><br></div><div>primitiveFileRead</div><div><span style="white-space:pre-wrap">        </span>&lt;export: true&gt;</div>
<div><span style="white-space:pre-wrap">        </span>| retryCount count startIndex array file elementSize bytesRead |</div><div><span style="white-space:pre-wrap">        </span>&lt;var: &#39;file&#39; type: #&#39;SQFile *&#39;&gt;</div>



<div><span style="white-space:pre-wrap">        </span>&lt;var: &#39;count&#39; type: #&#39;size_t&#39;&gt;</div><div><span style="white-space:pre-wrap">        </span>&lt;var: &#39;startIndex&#39; type: #&#39;size_t&#39;&gt;</div>
<div><span style="white-space:pre-wrap">        </span>&lt;var: &#39;elementSize&#39; type: #&#39;size_t&#39;&gt;</div><div><br></div><div><span style="white-space:pre-wrap">        </span>retryCount<span style="white-space:pre-wrap">        </span>:= 0.</div>



<div><span style="white-space:pre-wrap">        </span>count<span style="white-space:pre-wrap">                </span>:= interpreterProxy positive32BitValueOf: (interpreterProxy stackValue: 0).</div><div><span style="white-space:pre-wrap">        </span>startIndex<span style="white-space:pre-wrap">        </span>:= interpreterProxy positive32BitValueOf: (interpreterProxy stackValue: 1).</div>



<div> </div><div><span style="white-space:pre-wrap">        </span>[array<span style="white-space:pre-wrap">                </span>:= interpreterProxy stackValue: 2.</div><div><span style="white-space:pre-wrap">        </span> file<span style="white-space:pre-wrap">                        </span>:= self fileValueOf: (interpreterProxy stackValue: 3).</div>



<div><br></div><div><span style="white-space:pre-wrap">        </span> (interpreterProxy failed</div><div><span style="white-space:pre-wrap">        </span> &quot;buffer can be any indexable words or bytes object except CompiledMethod&quot;</div>



<div><span style="white-space:pre-wrap">        </span> or: [(interpreterProxy isWordsOrBytes: array) not]) ifTrue:</div><div><span style="white-space:pre-wrap">                </span>[^interpreterProxy primitiveFailFor: PrimErrBadArgument].</div>



<div><br></div><div><span style="white-space:pre-wrap">        </span> elementSize := (interpreterProxy isWords: array) ifTrue: [4] ifFalse: [1].</div><div><span style="white-space:pre-wrap">        </span> (startIndex &gt;= 1</div>
<div><span style="white-space:pre-wrap">        </span>  and: [(startIndex + count - 1) &lt;= (interpreterProxy slotSizeOf: array)]) ifFalse:</div><div><span style="white-space:pre-wrap">                </span>[^interpreterProxy primitiveFailFor: PrimErrBadIndex].</div>



<div><br></div><div><span style="white-space:pre-wrap">        </span> &quot;Note: adjust startIndex for zero-origin indexing&quot;</div><div><span style="white-space:pre-wrap">        </span> bytesRead := self</div><div><span style="white-space:pre-wrap">                                        </span>sqFile: file</div>



<div><span style="white-space:pre-wrap">                                        </span>Read: count * elementSize</div><div><span style="white-space:pre-wrap">                                        </span>Into: (self cCoerce: (interpreterProxy firstIndexableField: array) to: #&#39;char *&#39;)</div>



<div><span style="white-space:pre-wrap">                                        </span>At: (startIndex - 1) * elementSize.</div><div><span style="white-space:pre-wrap">        </span> <b>interpreterProxy primitiveFailureCode = PrimErrObjectMayMove</b></div>
<div><b><span style="white-space:pre-wrap">        </span> and: [(retryCount := retryCount + 1) &lt;= 2] &quot;Two objects, the file and the array can move&quot;</b>] whileTrue:</div><div><span style="white-space:pre-wrap">                </span>[interpreterProxy</div>



<div><span style="white-space:pre-wrap">                        </span>tenuringIncrementalGC;</div><div><span style="white-space:pre-wrap">                        </span>primitiveFailFor: PrimNoErr].</div><div><span style="white-space:pre-wrap">        </span>interpreterProxy failed ifFalse:</div>



<div><span style="white-space:pre-wrap">                </span>[interpreterProxy</div><div><span style="white-space:pre-wrap">                        </span>pop: 5 &quot;pop rcvr, file, array, startIndex, count&quot;</div><div><span style="white-space:pre-wrap">                        </span>thenPush:(interpreterProxy integerObjectOf: bytesRead // elementSize)  &quot;push # of elements read&quot;]</div>



</div>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br>best,<div>Eliot</div>
<br></blockquote></div><br></div></div>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br>best,<div>Eliot</div>