Non-extensibility of Typed Arrays

Filip Pizlo fpizlo at apple.com
Fri Aug 30 16:20:18 PDT 2013


On Aug 30, 2013, at 4:03 PM, David Herman <dherman at mozilla.com> wrote:

> On Aug 30, 2013, at 3:54 PM, Filip Pizlo <fpizlo at apple.com> wrote:
> 
>> Yup, that's what I was concerned about.  And reading over the spec I agree.  But just for sanity, we're guaranteeing this because you cannot create a struct type instance by pointing into an arbitrary offset of a buffer - you can only instantiate new ones, or alias structs nested as fields in other structs.  Right?
> 
> Hm, I must be missing something obvious, but I don't see why you'd need that restriction to guarantee this. A struct type with two different fields guarantees they're at different offsets from the base:
> 
>    var T = new StructType({
>        a: int32, // offset 0
>        b: int32  // offset 4
>    });
> 
> so even if I point an instance of T into the middle of a struct, x.a and x.b must be at different offsets.

Sorry, that's not the issue.  Consider this.  In one part of the program I say:

var Point2D = new StructType({x:uint32, y:uint32});

And in another part of the program I encounter a function like this:

function foo(a, b) {
    var blah = a.x;
    b.y = 53;
    return blah + a.x; // does this return a.x * 2 or could it return a.x + 53?
}

Lets say that I've proven that a, b both refer to instances of Point2D.  Can I be sure that this returns a.x * 2 or could it alternatively return a.x + 53?

A closely related case is:

var Point2D = new StructType({x:uint32, y:uint32});
var Vector = new StructType({x:uint32, y:uint32});

function foo(a, b) {
    var blah = a.x;
    b.x = 53;
    return blah + a.x; // does this return a.x * 2 or could it return a.x + 53?
}

Let's say that I've proven that a refers to a Point2D and b refers to a Vector.  Can I be sure that this returns a.x * 2 or could it alternatively return a.x + 53?

The analogue in typed arrays is:

function foo(a, b) {
    var blah = a[0];
    b[1] = 53;
    return blah + b[0]; // does this return a[0] * 2 or could it return a[0] + 53, or something even weirder?
}

Even if I've proven that a, b are typed arrays - of either same or different type - this function could still return a[0] + 53 because the buffers may be weirdly aliased.  In fact for anything other than 1-byte element typed arrays, the above function has endianness-dependent results, so it may return something other than either a[0] * 2 or a[0] + 53.

This is the kind of weirdness that I hope struct types *don't* have, if their alleged purpose is to help people optimize their code.

Now, I don't object to typed arrays having this behavior - it is what it is, and it's certainly useful for doing graphics type stuff.  It's also indispensable for emscripten.  And I'm OK with struct types also having this behavior; in fact I would *expect them to have such behavior* if they're supposed by help C-to-JS code generators or the like.  But if we have such behavior then we ought not also claim that struct types are meant for optimization and helping JITs.  It's particularly intriguing to me that if struct types are specified to allow such aliasing, then using struct types means you get less load elimination and hoisting than you would in regular untyped JS code.  That's kind of a big deal considering that load elimination and hoisting are fundamental compiler optimizations.

-Filip


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130830/4bd548f6/attachment-0001.html>


More information about the es-discuss mailing list