[Vm-dev] Objects may move while reading a file
eliot.miranda at gmail.com
Mon May 13 21:09:40 UTC 2013
On Mon, May 13, 2013 at 3:04 AM, Guillermo Polito <guillermopolito at gmail.com
> 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?
> <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