зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
282eef67d2
Коммит
8972e438d0
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче