[webkit-dev] XHR responseArrayBuffer attribute
cmarrin at apple.com
Thu Sep 30 07:09:19 PDT 2010
On Sep 29, 2010, at 6:34 PM, Maciej Stachowiak wrote:
>> ...The idea is that when an ArrayBuffer is sent via postMessage, it is
>> atomically "closed" on this side; its publicly visible length goes to
>> 0, as do the lengths of any views referring to it. On the other side,
>> a new ArrayBuffer wrapper object is synthesized, pointing to the same
>> storage and with the original length.
>> To be able to reuse the same memory region over and over again, the
>> other side would simply send the ArrayBuffer back for re-filling via
>> postMessage. Ping-ponging ArrayBuffers back and forth achieves
>> zero-copy transfer of large amounts of data while still maintaining
>> the shared-nothing semantic. The only allocations are for the (tiny)
>> ArrayBuffer wrapper objects, but the underlying storage is stable.
>> Implementing this idea will require a couple of minor additions to the
>> TypedArray specification (in particular, the addition of a "close"
>> method on ArrayBuffer) as well as defining the semantics of sending an
>> ArrayBuffer via postMessage. I hope to prototype it soon.
>> Regarding your scenario, I would simply post the ArrayBuffer from the
>> XHR object to the worker with the above semantics. The main thread
>> would then not be able to access the data in the ArrayBuffer, but
>> sending it to the worker for processing would not involve any data
> Sure, transfer semantics avoid shared mutable state, though it would be inconsistent with most other "pure data" types. But what if you have some data that doesn't need mutating but you'd like to share with multiple other Workers? Now you'd be forced to explicitly copy. The availability of an immutable variant would let you avoid that. At most, you'd need to copy once if your ArrayBuffer started immutable; or you could have the ability to convert mutable to immutable at runtime (it would have to be a one-way conversion, of course).
I'm thinking about how this would be implemented. Ken talks about a "close" function to make it possible to pass an ArrayBuffer to a worker. If I have it right, this would detach the contents of the ArrayBuffer from it's owning object, replacing it with a 0 length buffer. Then the worker attaches the contents to a new ArrayBuffer owned by the worker. To do that we'd need to figure out the "magic" of passing this bare buffer to the worker. An ImmutableArrayBuffer would not need any such magic. But without any additional functionality, you'd always need an additional copy (even it's a copy-on-write) for Maciej's example.
In Maciej's example, he wants to take an incoming buffer and pass it to a worker, presumably so it can be mutated into something else. So you'd pass the ImmutableArrayBuffer to the worker (no copy) and it would create a new ArrayBuffer with one or more views which it would fill with the mutated data. But to pass this buffer back to the main thread, you'd need to convert this ArrayBuffer to an ImmutableArrayBuffer, which would require some sort of copy.
What's needed is a way to pass that ArrayBuffer back to the main thread without a copy. So maybe we just need a function like Ken's "close" but without the magic. A makeImmutable() function could be called on the ArrayBuffer, which would create a new ImmutableArrayBuffer, attach the contents of the ArrayBuffer to it and set the contents of the ArrayBuffer to a 0 length buffer, as in Ken's design.
So now you'd pass the incoming ImmutableArrayBuffer to the worker, create a new ArrayBuffer for the mutated data, fill it, call makeImmutable on it and return the result. No copies would be needed. Once the process starts, the old buffers can be recycled to avoid memory allocations as well.
Would something like that work?
cmarrin at apple.com
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the webkit-dev