On Fri, Nov 27, 2009 at 9:03 AM, David T. Lewis <lewis@mail.msen.com> wrote:

On Thu, Nov 26, 2009 at 03:10:52PM +0100, Henrik Johansen wrote:
>
> Interpreter >> primitiveNextPut:
>  limit := self fetchInteger: StreamReadLimitIndex ofObject: stream.
>       atIx := (array bitAnd: AtCacheMask) + AtPutBase.
>       (index < limit and: [(atCache at: atIx+AtCacheOop) = array])
>
> so basically, it needs ReadLimit to be > 0. (Which is only true for (Read)WriteStreams if created with on:from:to:).
>
> Changing the first line to
>  limit := self fetchInteger: StreamWriteLimitIndex ofObject: stream.
>
> and the primitive now works.
> ws := WriteStream on: (String new: 500000).
> [1 to: 500000 do: [:ix | ws nextPut: $a]] timeToRun
>
> before: 130
>  after: 33
>
> Inserted a counter after the prim call, for the loop above it was always >= 500000, with fix it's >=1.

Can anyone comment as to whether the above fix is correct? It looks right
to me, but it would be good if someone familiar with #primitiveNextPut
and the AtCache could review it.

The fix is correct.  c.f. the body of WriteStream>>nextPut:.

I note that this primitive has not changed since 1998, so this would
rate as a really excellent bug catch!
Thanks,
Dave