Beginning on October 25th, 2016, Persona will no longer be an option for authentication on BMO. For more details see Persona Deprecated.
Last Comment Bug 651451 - TI: dense array initializedLength can be > length
: TI: dense array initializedLength can be > length
Product: Core
Classification: Components
Component: JavaScript Engine (show other bugs)
: unspecified
: All All
: -- normal (vote)
: ---
Assigned To: Jan de Mooij [:jandem]
: Jason Orendorff [:jorendorff]
Depends on:
Blocks: infer-regress
  Show dependency treegraph
Reported: 2011-04-20 03:20 PDT by Jan de Mooij [:jandem]
Modified: 2011-04-20 10:58 PDT (History)
3 users (show)
See Also:
Crash Signature:
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---

Patch (1.13 KB, patch)
2011-04-20 07:07 PDT, Jan de Mooij [:jandem]
bhackett1024: review+
Details | Diff | Splinter Review

Description Jan de Mooij [:jandem] 2011-04-20 03:20:02 PDT
Reduced from a failing Mochitest-2 test:
var arr = [2];

arr[0] = 2;
assertEq(arr.length, 1);
$ ./js -n -a -m test.js
test.js:5: Error: Assertion failed: got 0, expected 1

The problem is that jsop_setelem_dense does not update the array length if index < initializedLength.
Comment 1 Jan de Mooij [:jandem] 2011-04-20 06:00:49 PDT
Ah, just read some code and I think initializedLength should never be smaller than length when TI is enabled (so we only have to check initializedLength). 

Comment 2 Jan de Mooij [:jandem] 2011-04-20 07:07:53 PDT
Created attachment 527258 [details] [diff] [review]

Update initialized length in array_pop_dense. Also checked array_shift and other callers of setDenseArrayLength but this seems to be the only problem.
Comment 3 Jan de Mooij [:jandem] 2011-04-20 09:14:28 PDT
Comment 4 Mike Shaver (:shaver -- probably not reading bugmail closely) 2011-04-20 09:59:33 PDT
What happens if I do:
a = [1, 2, 3];
a.length = 0xffff;

I would expect initializedLength to be 3 (plus whatever round-up) and length to be materially larger.  Does this just disable TI?
Comment 5 Brian Hackett (:bhackett) 2011-04-20 10:16:14 PDT
Yes, the initialized length will still be three here, it can be less than the length property.  If the assignment to a.length shrinks below the initialized length, the initialized length should be adjusted so it is <= the length property (effectively marking later slots as holes).  That is similar to the bug here, where pop() (which shrinks the array) did not ensure the initialized length is <= the length.

When inference is enabled in a compartment, the invariants we want to preserve are:

initializedLength <= length   (property of the object)
initializedLength <= capacity (allocated space for slots)

It can be less than either though (not a MINLENCAP retread).  This is designed to handle patterns like:

x = Array(1000);
for (i = 0; i < 1000; i++)
  x[i] = 0;

At the head of the loop, the initialized length will be 'i', though the length and capacity are generally larger, and we can determine there are no holes below the initialized length.  This doesn't handle patterns like:

x = Array(1000);
for (i = 999; i >= 0; i--)
  x[i] = 0;

This is similar to the array usage pattern seen in v8-crypto, and if we could dynamically determine the array is packed afterwards, that would help this benchmark.
Comment 6 Jan de Mooij [:jandem] 2011-04-20 10:58:00 PDT
Follow-up fix as discussed on IRC:

If initializedLength < length we should not change it.

Note You need to log in before you can comment on or make changes to this bug.