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><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>