[Vm-dev] Objects may move while reading a file
guillermopolito at gmail.com
Tue May 14 12:30:44 UTC 2013
On Mon, May 13, 2013 at 11:09 PM, Eliot Miranda <eliot.miranda at gmail.com>wrote:
> Hi Guillermo,
> On Mon, May 13, 2013 at 3:04 AM, Guillermo Polito <
> guillermopolito at gmail.com> wrote:
>> 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...).
>> Does someone have a clue?
> 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
> "incremental" 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.
> 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.
> does this help?
Yes, so it is only used in case of a threaded VM, what makes more sense :).
Now I wonder, shouldn't then this check be done in (almost) every primitive?
>> <export: true>
>> | retryCount count startIndex array file elementSize bytesRead |
>> <var: 'file' type: #'SQFile *'>
>> <var: 'count' type: #'size_t'>
>> <var: 'startIndex' type: #'size_t'>
>> <var: 'elementSize' type: #'size_t'>
>> retryCount := 0.
>> count := interpreterProxy positive32BitValueOf: (interpreterProxy
>> stackValue: 0).
>> startIndex := interpreterProxy positive32BitValueOf: (interpreterProxy
>> stackValue: 1).
>> [array := interpreterProxy stackValue: 2.
>> file := self fileValueOf: (interpreterProxy stackValue: 3).
>> (interpreterProxy failed
>> "buffer can be any indexable words or bytes object except CompiledMethod"
>> or: [(interpreterProxy isWordsOrBytes: array) not]) ifTrue:
>> [^interpreterProxy primitiveFailFor: PrimErrBadArgument].
>> elementSize := (interpreterProxy isWords: array) ifTrue:  ifFalse:
>> (startIndex >= 1
>> and: [(startIndex + count - 1) <= (interpreterProxy slotSizeOf:
>> array)]) ifFalse:
>> [^interpreterProxy primitiveFailFor: PrimErrBadIndex].
>> "Note: adjust startIndex for zero-origin indexing"
>> bytesRead := self
>> sqFile: file
>> Read: count * elementSize
>> Into: (self cCoerce: (interpreterProxy firstIndexableField: array) to:
>> #'char *')
>> At: (startIndex - 1) * elementSize.
>> *interpreterProxy primitiveFailureCode = PrimErrObjectMayMove*
>> * and: [(retryCount := retryCount + 1) <= 2] "Two objects, the file and
>> the array can move"*] whileTrue:
>> primitiveFailFor: PrimNoErr].
>> interpreterProxy failed ifFalse:
>> pop: 5 "pop rcvr, file, array, startIndex, count"
>> thenPush:(interpreterProxy integerObjectOf: bytesRead // elementSize)
>> "push # of elements read"]
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Vm-dev