Bug 1023755 - PJS: Array.prototype.scanPar per-element thunk reads and writes result array; vulnerable to bailout-and-restart. r=nmatsakis

This commit is contained in:
Lars T Hansen 2014-06-11 19:29:34 +02:00
parent af064a29d7
commit 0e57af1dbb

View File

@ -864,7 +864,12 @@ function ArrayScanPar(func, mode) {
if (length === 0) if (length === 0)
ThrowError(JSMSG_EMPTY_ARRAY_REDUCE); ThrowError(JSMSG_EMPTY_ARRAY_REDUCE);
// We need two buffers because phase2() will read an intermediate result and
// write a final result; that is safe against bailout-and-restart only if
// the intermediate and final buffers are distinct. (Bug 1023755)
// Obviously paying for a second buffer is undesirable.
var buffer = NewDenseArray(length); var buffer = NewDenseArray(length);
var buffer2 = NewDenseArray(length);
parallel: for (;;) { // see ArrayMapPar() to explain why for(;;) etc parallel: for (;;) { // see ArrayMapPar() to explain why for(;;) etc
if (ShouldForceSequential()) if (ShouldForceSequential())
@ -889,11 +894,12 @@ function ArrayScanPar(func, mode) {
// Complete each slice using intermediates array (see comment on phase2()). // Complete each slice using intermediates array (see comment on phase2()).
// //
// We start from slice 1 instead of 0 since there is no work to be done // Slice 0 must be handled specially - it's just a copy - since we don't
// for slice 0. // have an identity value for the operation.
if (numSlices > 1) for ( var k=0, limit=finalElement(0) ; k <= limit ; k++ )
ForkJoin(phase2, 1, numSlices, ForkJoinMode(mode), buffer); buffer2[k] = buffer[k];
return buffer; ForkJoin(phase2, 1, numSlices, ForkJoinMode(mode), buffer2);
return buffer2;
} }
// Sequential fallback: // Sequential fallback:
@ -986,7 +992,7 @@ function ArrayScanPar(func, mode) {
var indexEnd = SLICE_END_INDEX(sliceShift, indexPos, length); var indexEnd = SLICE_END_INDEX(sliceShift, indexPos, length);
var intermediate = intermediates[sliceId - 1]; var intermediate = intermediates[sliceId - 1];
for (; indexPos < indexEnd; indexPos++) for (; indexPos < indexEnd; indexPos++)
UnsafePutElements(buffer, indexPos, func(intermediate, buffer[indexPos])); UnsafePutElements(buffer2, indexPos, func(intermediate, buffer[indexPos]));
} }
return sliceId; return sliceId;
} }