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

-----
~Chris
cmar...@apple.com




_______________________________________________
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev

Reply via email to