[webkit-dev] XHR responseArrayBuffer attribute

Kenneth Russell kbr at google.com
Wed Sep 29 14:02:05 PDT 2010


On Tue, Sep 28, 2010 at 11:26 AM, Maciej Stachowiak <mjs at apple.com> wrote:
>
> On Sep 28, 2010, at 11:05 AM, Kenneth Russell wrote:
>
>> On Tue, Sep 28, 2010 at 9:45 AM, Maciej Stachowiak <mjs at apple.com> wrote:
>>>
>>> On Sep 28, 2010, at 7:15 AM, Chris Marrin wrote:
>>>
>>>>
>>>> On Sep 27, 2010, at 6:37 PM, Maciej Stachowiak wrote:
>>>>
>>>>>
>>>>> On Sep 27, 2010, at 3:19 PM, Michael Nordman wrote:
>>>>>
>>>>>> Webkit's XHR currently does not keep two copies of the data that I can see. I think we should avoid that.
>>>>>
>>>>> We could keep the raw data around, which hopefully is directly usable as an ArrayBuffer backing store, and only translate it to text format when/if the client requests responseText.
>>>>
>>>> Yes, the raw data should be usable without translation in an ArrayBuffer. But we'd still need to make a copy of the raw bits when a new ArrayBuffer is created via responseArrayBuffer(), because that object is mutable.
>>>
>>> Is there an immutable variant of ArrayBuffer? If not, we really need one. But even without that, note that you don't necessarily need to make an immediate copy, you can use copy-on-write.
>>>
>>> The immutable variant would be helpful since we could avoid implementing threadsafe copy-on-write just to allow efficient passing of ArrayBuffers to Workers.
>>
>> Chris has raised this issue on the public_webgl list, and we've begun
>> discussion there, but I would like to point out that having an
>> immutable ArrayBuffer and views on it does not help with the situation
>> of passing data to or from a web worker. The side that constructs the
>> data will necessarily have a mutable view, so it will be able to cause
>> changes that can be seen on the other side even if the view on the
>> other side is immutable.
>
> Not if the side that got the data got it in immutable form in the first place. For example, if you get an immutable ArrayBuffer from XHR in a Worker, then you can pass it to another Worker or to the main thread without the need for any copying or copy-on-write.
>
>>
>> We have a design that will allow efficient zero-copy producer/consumer
>> queues to be implemented using TypedArrays while maintaining
>> ECMAScript's shared-nothing semantics. I'll be happy to sketch it out,
>> but it's probably most appropriate for a mailing list like
>> public_webgl.
>
> I'm curious to hear it and I don't follow public_webgl.
>
> I'd specifically like to handle the following case:
> - You obtain a chunk of binary data from the network or filesystem and want to pass it to another thread without copying.

The scenario to which I've given the most thought is that where a
continuous stream of data is sent from a worker to the main thread,
vice versa, or back and forth. I'll describe the solution for this
case first and then discuss how it applies to yours.

In the producer/consumer scenario it is essential to avoid continuous
memory allocation and deallocation. Ideally the main thread and worker
would share a fixed size memory region. Since this would violate the
shared-nothing semantic, a different solution is needed.

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

I don't understand why the ArrayBuffer returned from the XHR needs to
be strictly immutable. Since the application created the XHR object,
it seems to me it should be fine if it mutates the copy of the data
attached to it.

-Ken


More information about the webkit-dev mailing list