Should assigning to out-of-bounds elements of a typed array throw in strict mode code?
And expanding scope slightly: IntegerIndexedElementGet -- get -- throws a TypeError if the relevant typed array is detached, rather than just returning |undefined| as the computed value. I understand there are also significant complaints about this, for similar reasons.
Somewhere there's obviously got to be a bounds check, in order to not overwrite memory outside the array. Why does the requirement that the failure of this bounds check cause a TypeError make the inbounds case any more expensive? The specified difference in behavior is only what happens following the failure of the bounds check.
Again, I don't understand this. Why would it make the normal case more expensive. The underlying detachment test must be there regardless, and the only difference in behavior is what happens after that test fails.
In the past 'throw' statements have caused a deopt for the enclosing function in v8 and spidermonkey. I think they still do in some scenarios. I would assume that if a statement is able to throw the enclosing function must have unwind logic and it could potentially suppress inlining as well depending on how smart the VM is?
Jeff?
On Thu, Feb 26, 2015 at 6:48 PM, Katelyn Gadd <kg at luminance.org> wrote:
In the past 'throw' statements have caused a deopt for the enclosing function in v8 and spidermonkey. I think they still do in some scenarios. I would assume that if a statement is able to throw the enclosing function must have unwind logic and it could potentially suppress inlining as well depending on how smart the VM is?
At least in SpiderMonkey, they don't cause a deopt anymore; only finally does (and exceptions that actually occur).
More importantly, I would argue that performance concerns, even if they turn out to be real, shouldn't be the basis of a decision here.
At least in strict mode, I can't think of any operations that would just silently let data fall under the table. E.g., setting a property on a frozen object throws. Silently swallowing the value on out-of-bounds writes to typed arrays would be an outlier here, and a dangerous one.
Seems like a bug. You can just profile whether the exceptional path was ever taken; if it wasn't then speculate that accesses are in-bounds. Boom, you have a fast in-bounds check and the optimizing JIT doesn't have to know anything about what happens on out-of-bounds (i.e. it could throw exceptions, call functions, or activate toaster ovens - it don't matter).
I think that throwing on out-of-bounds assignment makes sense in strict mode. I'm in favor of that behavior.
On 02/26/2015 09:54 AM, Mark S. Miller wrote:
Jeff?
To be completely honest, I can't answer this. My message was merely to pass along the sentiments of others, observed elsewhere, not previously communicated to this list. I personally don't understand what we're doing at a low level sufficient to intelligently discuss this. (In isolation of all other concerns, just purely on "aesthetic" grounds, the current semantics seem like the ones I'd want, tho.)
Right now I'm hoping some of the people I CC'd (including the ones whose CC was dropt by mailman) on the initial email can chime in to elaborate at some point. Luke? Brian? You particularly were the ones whose comments were the most recent ones I was relying on in conveying the sentiments here.
Sorry if there was any confusion earlier, but throw-on-OOB semantics is easier from an AOT/asm.js-compilation POV. Ideally, typed arrays would throw on all OOB, but I realize that isn't web compatible at this point.
Currently, the behavior of IntegerIndexedElementSet is to return false if the index being set is outside the array bounds. This return-false directly feeds into the result of [[Set]] on a typed array. The result is that in strict mode code, setting an out-of-bounds array element throws a TypeError.
I've heard claims from other SpiderMonkey implementers that this requirement makes it difficult to implement high-performance JIT optimizations for code that assigns into typed arrays, except in the case that the array length is observable in context, the typed array never escapes anywhere, its backing ArrayBuffer never escapes anywhere, etc. Restrictions that generally aren't very easy to determine with local information observable by a JIT. And while quite often such high-performance code isn't strict mode code, it's doubtful that will be true far into the future.