Merge inbound to mozilla-central. a=merge

This commit is contained in:
Gurzau Raul 2018-03-16 19:53:35 +02:00
Родитель 7ff67ddf24 692193e3b5
Коммит 70be85b9cd
26 изменённых файлов: 132 добавлений и 184 удалений

Просмотреть файл

@ -312,8 +312,8 @@ struct WrExternalImage {
size: usize,
}
type LockExternalImageCallback = fn(*mut c_void, WrExternalImageId, u8) -> WrExternalImage;
type UnlockExternalImageCallback = fn(*mut c_void, WrExternalImageId, u8);
type LockExternalImageCallback = unsafe extern "C" fn(*mut c_void, WrExternalImageId, u8) -> WrExternalImage;
type UnlockExternalImageCallback = unsafe extern "C" fn(*mut c_void, WrExternalImageId, u8);
#[repr(C)]
pub struct WrExternalImageHandler {
@ -327,7 +327,8 @@ impl ExternalImageHandler for WrExternalImageHandler {
id: ExternalImageId,
channel_index: u8)
-> ExternalImage {
let image = (self.lock_func)(self.external_image_obj, id.into(), channel_index);
let image = unsafe { (self.lock_func)(self.external_image_obj, id.into(), channel_index) };
ExternalImage {
uv: TexelRect::new(image.u0, image.v0, image.u1, image.v1),
source: match image.image_type {
@ -341,7 +342,9 @@ impl ExternalImageHandler for WrExternalImageHandler {
fn unlock(&mut self,
id: ExternalImageId,
channel_index: u8) {
(self.unlock_func)(self.external_image_obj, id.into(), channel_index);
unsafe {
(self.unlock_func)(self.external_image_obj, id.into(), channel_index);
}
}
}

Просмотреть файл

@ -942,7 +942,7 @@ BaselineCacheIRCompiler::emitLoadFrameArgumentResult()
// Bounds check.
masm.loadPtr(Address(BaselineFrameReg, BaselineFrame::offsetOfNumActualArgs()), scratch1);
masm.boundsCheck32ForLoad(index, scratch1, scratch2, failure->label());
masm.spectreBoundsCheck32(index, scratch1, scratch2, failure->label());
// Load the argument.
masm.loadValue(BaseValueIndex(BaselineFrameReg, index, BaselineFrame::offsetOfArg(0)),

Просмотреть файл

@ -1896,7 +1896,7 @@ CacheIRCompiler::emitLoadStringCharResult()
return false;
// Bounds check, load string char.
masm.boundsCheck32ForLoad(index, Address(str, JSString::offsetOfLength()), scratch1,
masm.spectreBoundsCheck32(index, Address(str, JSString::offsetOfLength()), scratch1,
failure->label());
masm.loadStringChar(str, index, scratch1, scratch2, failure->label());
@ -1934,7 +1934,7 @@ CacheIRCompiler::emitLoadArgumentsObjectArgResult()
// Bounds check.
masm.rshift32(Imm32(ArgumentsObject::PACKED_BITS_COUNT), scratch1);
masm.boundsCheck32ForLoad(index, scratch1, scratch2, failure->label());
masm.spectreBoundsCheck32(index, scratch1, scratch2, failure->label());
// Load ArgumentsData.
masm.loadPrivate(Address(obj, ArgumentsObject::getDataSlotOffset()), scratch1);
@ -1970,7 +1970,7 @@ CacheIRCompiler::emitLoadDenseElementResult()
// Bounds check.
Address initLength(scratch1, ObjectElements::offsetOfInitializedLength());
masm.boundsCheck32ForLoad(index, initLength, scratch2, failure->label());
masm.spectreBoundsCheck32(index, initLength, scratch2, failure->label());
// Hole check.
BaseObjectElementIndex element(scratch1, index);
@ -2041,7 +2041,7 @@ CacheIRCompiler::emitLoadDenseElementHoleResult()
// Guard on the initialized length.
Label hole;
Address initLength(scratch1, ObjectElements::offsetOfInitializedLength());
masm.boundsCheck32ForLoad(index, initLength, scratch2, &hole);
masm.spectreBoundsCheck32(index, initLength, scratch2, &hole);
// Load the value.
Label done;
@ -2225,7 +2225,7 @@ CacheIRCompiler::emitLoadTypedElementResult()
// Bounds check.
LoadTypedThingLength(masm, layout, obj, scratch1);
masm.boundsCheck32ForLoad(index, scratch1, scratch2, failure->label());
masm.spectreBoundsCheck32(index, scratch1, scratch2, failure->label());
// Load the elements vector.
LoadTypedThingData(masm, layout, obj, scratch1);

Просмотреть файл

@ -11170,7 +11170,7 @@ CodeGenerator::visitLoadElementHole(LLoadElementHole* lir)
// If the index is out of bounds, load |undefined|. Otherwise, load the
// value.
Label outOfBounds, done;
masm.boundsCheck32ForLoad(index, initLength, out.scratchReg(), &outOfBounds);
masm.spectreBoundsCheck32(index, initLength, out.scratchReg(), &outOfBounds);
masm.loadValue(BaseObjectElementIndex(elements, index), out);
@ -11309,7 +11309,7 @@ CodeGenerator::visitLoadTypedArrayElementHole(LLoadTypedArrayElementHole* lir)
// Load undefined if index >= length.
Label outOfBounds, done;
masm.boundsCheck32ForLoad(index, scratch, scratch2, &outOfBounds);
masm.spectreBoundsCheck32(index, scratch, scratch2, &outOfBounds);
// Load the elements vector.
masm.loadPtr(Address(object, TypedArrayObject::dataOffset()), scratch);

Просмотреть файл

@ -7893,8 +7893,7 @@ bool
IonBuilder::checkTypedObjectIndexInBounds(uint32_t elemSize,
MDefinition* index,
TypedObjectPrediction objPrediction,
LinearSum* indexAsByteOffset,
BoundsCheckKind kind)
LinearSum* indexAsByteOffset)
{
// Ensure index is an integer.
MInstruction* idInt32 = MToNumberInt32::New(alloc(), index);
@ -7921,7 +7920,7 @@ IonBuilder::checkTypedObjectIndexInBounds(uint32_t elemSize,
return false;
}
index = addBoundsCheck(idInt32, length, kind);
index = addBoundsCheck(idInt32, length);
return indexAsByteOffset->add(index, AssertedCast<int32_t>(elemSize));
}
@ -7941,11 +7940,8 @@ IonBuilder::getElemTryScalarElemOfTypedObject(bool* emitted,
MOZ_ASSERT(elemSize == ScalarTypeDescr::alignment(elemType));
LinearSum indexAsByteOffset(alloc());
if (!checkTypedObjectIndexInBounds(elemSize, index, objPrediction, &indexAsByteOffset,
BoundsCheckKind::IsLoad))
{
if (!checkTypedObjectIndexInBounds(elemSize, index, objPrediction, &indexAsByteOffset))
return Ok();
}
trackOptimizationSuccess();
*emitted = true;
@ -7966,11 +7962,8 @@ IonBuilder::getElemTryReferenceElemOfTypedObject(bool* emitted,
uint32_t elemSize = ReferenceTypeDescr::size(elemType);
LinearSum indexAsByteOffset(alloc());
if (!checkTypedObjectIndexInBounds(elemSize, index, objPrediction, &indexAsByteOffset,
BoundsCheckKind::IsLoad))
{
if (!checkTypedObjectIndexInBounds(elemSize, index, objPrediction, &indexAsByteOffset))
return Ok();
}
trackOptimizationSuccess();
*emitted = true;
@ -8090,11 +8083,8 @@ IonBuilder::getElemTryComplexElemOfTypedObject(bool* emitted,
MDefinition* elemTypeObj = typeObjectForElementFromArrayStructType(type);
LinearSum indexAsByteOffset(alloc());
if (!checkTypedObjectIndexInBounds(elemSize, index, objPrediction, &indexAsByteOffset,
BoundsCheckKind::IsLoad))
{
if (!checkTypedObjectIndexInBounds(elemSize, index, objPrediction, &indexAsByteOffset))
return Ok();
}
return pushDerivedTypedObject(emitted, obj, indexAsByteOffset,
elemPrediction, elemTypeObj);
@ -8385,7 +8375,7 @@ IonBuilder::getElemTryString(bool* emitted, MDefinition* obj, MDefinition* index
MStringLength* length = MStringLength::New(alloc(), obj);
current->add(length);
index = addBoundsCheck(index, length, BoundsCheckKind::IsLoad);
index = addBoundsCheck(index, length);
MCharCodeAt* charCode = MCharCodeAt::New(alloc(), obj, index);
current->add(charCode);
@ -8427,7 +8417,7 @@ IonBuilder::getElemTryArguments(bool* emitted, MDefinition* obj, MDefinition* in
index = idInt32;
// Bailouts if we read more than the number of actual arguments.
index = addBoundsCheck(index, length, BoundsCheckKind::IsLoad);
index = addBoundsCheck(index, length);
// Load the argument from the actual arguments.
bool modifiesArgs = script()->baselineScript()->modifiesArguments();
@ -8515,8 +8505,7 @@ IonBuilder::getElemTryArgumentsInlinedIndex(bool* emitted, MDefinition* obj, MDe
// cannot re-enter because reading out of bounds arguments will disable the
// lazy arguments optimization for this script, when this code would be
// executed in Baseline. (see GetElemOptimizedArguments)
index = addBoundsCheck(index, constantInt(inlineCallInfo_->argc()),
BoundsCheckKind::IsLoad);
index = addBoundsCheck(index, constantInt(inlineCallInfo_->argc()));
// Get an instruction to represent the state of the argument vector.
MInstruction* args = MArgumentState::New(alloc().fallible(), inlineCallInfo_->argv());
@ -8709,7 +8698,7 @@ IonBuilder::jsop_getelem_dense(MDefinition* obj, MDefinition* index)
// in-bounds elements, and the array is packed or its holes are not
// read. This is the best case: we can separate the bounds check for
// hoisting.
index = addBoundsCheck(index, initLength, BoundsCheckKind::IsLoad);
index = addBoundsCheck(index, initLength);
load = MLoadElement::New(alloc(), elements, index, needsHoleCheck, loadDouble);
current->add(load);
@ -8748,8 +8737,7 @@ void
IonBuilder::addTypedArrayLengthAndData(MDefinition* obj,
BoundsChecking checking,
MDefinition** index,
MInstruction** length, MInstruction** elements,
BoundsCheckKind boundsCheckKind)
MInstruction** length, MInstruction** elements)
{
MOZ_ASSERT((index != nullptr) == (elements != nullptr));
@ -8783,7 +8771,7 @@ IonBuilder::addTypedArrayLengthAndData(MDefinition* obj,
if (index) {
if (checking == DoBoundsCheck)
*index = addBoundsCheck(*index, *length, boundsCheckKind);
*index = addBoundsCheck(*index, *length);
*elements = MConstantElements::New(alloc(), data);
current->add(*elements);
@ -8798,7 +8786,7 @@ IonBuilder::addTypedArrayLengthAndData(MDefinition* obj,
if (index) {
if (checking == DoBoundsCheck)
*index = addBoundsCheck(*index, *length, boundsCheckKind);
*index = addBoundsCheck(*index, *length);
*elements = MTypedArrayElements::New(alloc(), obj);
current->add(*elements);
@ -8880,8 +8868,7 @@ IonBuilder::jsop_getelem_typed(MDefinition* obj, MDefinition* index,
// Get length, bounds-check, then get elements, and add all instructions.
MInstruction* length;
MInstruction* elements;
addTypedArrayLengthAndData(obj, DoBoundsCheck, &index, &length, &elements,
BoundsCheckKind::IsLoad);
addTypedArrayLengthAndData(obj, DoBoundsCheck, &index, &length, &elements);
// Load the element.
MLoadUnboxedScalar* load = MLoadUnboxedScalar::New(alloc(), elements, index, arrayType);
@ -9066,11 +9053,8 @@ IonBuilder::setElemTryReferenceElemOfTypedObject(bool* emitted,
uint32_t elemSize = ReferenceTypeDescr::size(elemType);
LinearSum indexAsByteOffset(alloc());
if (!checkTypedObjectIndexInBounds(elemSize, index, objPrediction, &indexAsByteOffset,
BoundsCheckKind::IsStore))
{
if (!checkTypedObjectIndexInBounds(elemSize, index, objPrediction, &indexAsByteOffset))
return Ok();
}
return setPropTryReferenceTypedObjectValue(emitted, obj, indexAsByteOffset,
elemType, value, nullptr);
@ -9090,11 +9074,8 @@ IonBuilder::setElemTryScalarElemOfTypedObject(bool* emitted,
MOZ_ASSERT(elemSize == ScalarTypeDescr::alignment(elemType));
LinearSum indexAsByteOffset(alloc());
if (!checkTypedObjectIndexInBounds(elemSize, index, objPrediction, &indexAsByteOffset,
BoundsCheckKind::IsStore))
{
if (!checkTypedObjectIndexInBounds(elemSize, index, objPrediction, &indexAsByteOffset))
return Ok();
}
return setPropTryScalarTypedObjectValue(emitted, obj, indexAsByteOffset, elemType, value);
}
@ -9389,7 +9370,7 @@ IonBuilder::initOrSetElemDense(TemporaryTypeSet::DoubleConversion conversion,
} else {
MInstruction* initLength = initializedLength(elements);
id = addBoundsCheck(id, initLength, BoundsCheckKind::IsStore);
id = addBoundsCheck(id, initLength);
bool needsHoleCheck = !packed && hasExtraIndexedProperty;
MStoreElement* ins = MStoreElement::New(alloc(), elements, id, newValue, needsHoleCheck);
@ -9437,8 +9418,7 @@ IonBuilder::jsop_setelem_typed(Scalar::Type arrayType,
MInstruction* length;
MInstruction* elements;
BoundsChecking checking = expectOOB ? SkipBoundsCheck : DoBoundsCheck;
addTypedArrayLengthAndData(obj, checking, &id, &length, &elements,
BoundsCheckKind::IsStore);
addTypedArrayLengthAndData(obj, checking, &id, &length, &elements);
// Clamp value to [0, 255] for Uint8ClampedArray.
MDefinition* toWrite = value;
@ -12977,7 +12957,7 @@ IonBuilder::inTryDense(bool* emitted, MDefinition* obj, MDefinition* id)
// If there are no holes, speculate the InArray check will not fail.
if (!needsHoleCheck && !failedBoundsCheck_) {
addBoundsCheck(idInt32, initLength, BoundsCheckKind::UnusedIndex);
addBoundsCheck(idInt32, initLength);
pushConstant(BooleanValue(true));
return Ok();
}
@ -13322,7 +13302,7 @@ IonBuilder::addMaybeCopyElementsForWrite(MDefinition* object, bool checkNative)
}
MInstruction*
IonBuilder::addBoundsCheck(MDefinition* index, MDefinition* length, BoundsCheckKind kind)
IonBuilder::addBoundsCheck(MDefinition* index, MDefinition* length)
{
MInstruction* check = MBoundsCheck::New(alloc(), index, length);
current->add(check);
@ -13331,7 +13311,20 @@ IonBuilder::addBoundsCheck(MDefinition* index, MDefinition* length, BoundsCheckK
if (failedBoundsCheck_)
check->setNotMovable();
if (kind == BoundsCheckKind::IsLoad && JitOptions.spectreIndexMasking) {
if (JitOptions.spectreIndexMasking) {
// Use a separate MIR instruction for the index masking. Doing this as
// part of MBoundsCheck would be unsound because bounds checks can be
// optimized or eliminated completely. Consider this:
//
// for (var i = 0; i < x; i++)
// res = arr[i];
//
// If we can prove |x < arr.length|, we are able to eliminate the bounds
// check, but we should not get rid of the index masking because the
// |i < x| branch could still be mispredicted.
//
// Using a separate instruction lets us eliminate the bounds check
// without affecting the index masking.
check = MSpectreMaskIndex::New(alloc(), check, length);
current->add(check);
}

Просмотреть файл

@ -199,8 +199,7 @@ class IonBuilder
MInstruction* addConvertElementsToDoubles(MDefinition* elements);
MDefinition* addMaybeCopyElementsForWrite(MDefinition* object, bool checkNative);
enum class BoundsCheckKind { IsLoad, IsStore, UnusedIndex };
MInstruction* addBoundsCheck(MDefinition* index, MDefinition* length, BoundsCheckKind kind);
MInstruction* addBoundsCheck(MDefinition* index, MDefinition* length);
MInstruction* addShapeGuard(MDefinition* obj, Shape* const shape, BailoutKind bailoutKind);
MInstruction* addGroupGuard(MDefinition* obj, ObjectGroup* group, BailoutKind bailoutKind);
@ -379,8 +378,7 @@ class IonBuilder
bool checkTypedObjectIndexInBounds(uint32_t elemSize,
MDefinition* index,
TypedObjectPrediction objTypeDescrs,
LinearSum* indexAsByteOffset,
BoundsCheckKind kind);
LinearSum* indexAsByteOffset);
AbortReasonOr<Ok> pushDerivedTypedObject(bool* emitted,
MDefinition* obj,
const LinearSum& byteOffset,
@ -468,16 +466,14 @@ class IonBuilder
void addTypedArrayLengthAndData(MDefinition* obj,
BoundsChecking checking,
MDefinition** index,
MInstruction** length, MInstruction** elements,
BoundsCheckKind boundsCheckKind);
MInstruction** length, MInstruction** elements);
// Add an instruction to compute a typed array's length to the current
// block. If you also need the typed array's data, use the above method
// instead.
MInstruction* addTypedArrayLength(MDefinition* obj) {
MInstruction* length;
addTypedArrayLengthAndData(obj, SkipBoundsCheck, nullptr, &length, nullptr,
BoundsCheckKind::UnusedIndex);
addTypedArrayLengthAndData(obj, SkipBoundsCheck, nullptr, &length, nullptr);
return length;
}
@ -773,7 +769,7 @@ class IonBuilder
bool prepareForSimdLoadStore(CallInfo& callInfo, Scalar::Type simdType,
MInstruction** elements, MDefinition** index,
Scalar::Type* arrayType, BoundsCheckKind boundsCheckKind);
Scalar::Type* arrayType);
InliningResult inlineSimdLoad(CallInfo& callInfo, JSNative native, SimdType type,
unsigned numElems);
InliningResult inlineSimdStore(CallInfo& callInfo, JSNative native, SimdType type,
@ -839,8 +835,7 @@ class IonBuilder
bool atomicsMeetsPreconditions(CallInfo& callInfo, Scalar::Type* arrayElementType,
bool* requiresDynamicCheck,
AtomicCheckResult checkResult=DoCheckAtomicResult);
void atomicsCheckBounds(CallInfo& callInfo, MInstruction** elements, MDefinition** index,
BoundsCheckKind kind);
void atomicsCheckBounds(CallInfo& callInfo, MInstruction** elements, MDefinition** index);
bool testNeedsArgumentCheck(JSFunction* target, CallInfo& callInfo);

Просмотреть файл

@ -1871,7 +1871,7 @@ IonBuilder::inlineStrCharCodeAt(CallInfo& callInfo)
MStringLength* length = MStringLength::New(alloc(), callInfo.thisArg());
current->add(length);
index = addBoundsCheck(index, length, BoundsCheckKind::IsLoad);
index = addBoundsCheck(index, length);
MCharCodeAt* charCode = MCharCodeAt::New(alloc(), callInfo.thisArg(), index);
current->add(charCode);
@ -1981,7 +1981,7 @@ IonBuilder::inlineStrCharAt(CallInfo& callInfo)
MStringLength* length = MStringLength::New(alloc(), callInfo.thisArg());
current->add(length);
index = addBoundsCheck(index, length, BoundsCheckKind::IsLoad);
index = addBoundsCheck(index, length);
// String.charAt(x) = String.fromCharCode(String.charCodeAt(x))
MCharCodeAt* charCode = MCharCodeAt::New(alloc(), callInfo.thisArg(), index);
@ -3324,7 +3324,7 @@ IonBuilder::inlineAtomicsCompareExchange(CallInfo& callInfo)
MInstruction* elements;
MDefinition* index;
atomicsCheckBounds(callInfo, &elements, &index, BoundsCheckKind::IsLoad);
atomicsCheckBounds(callInfo, &elements, &index);
if (requiresCheck)
addSharedTypedArrayGuard(callInfo.getArg(0));
@ -3360,7 +3360,7 @@ IonBuilder::inlineAtomicsExchange(CallInfo& callInfo)
MInstruction* elements;
MDefinition* index;
atomicsCheckBounds(callInfo, &elements, &index, BoundsCheckKind::IsLoad);
atomicsCheckBounds(callInfo, &elements, &index);
if (requiresCheck)
addSharedTypedArrayGuard(callInfo.getArg(0));
@ -3392,7 +3392,7 @@ IonBuilder::inlineAtomicsLoad(CallInfo& callInfo)
MInstruction* elements;
MDefinition* index;
atomicsCheckBounds(callInfo, &elements, &index, BoundsCheckKind::IsLoad);
atomicsCheckBounds(callInfo, &elements, &index);
if (requiresCheck)
addSharedTypedArrayGuard(callInfo.getArg(0));
@ -3444,7 +3444,7 @@ IonBuilder::inlineAtomicsStore(CallInfo& callInfo)
MInstruction* elements;
MDefinition* index;
atomicsCheckBounds(callInfo, &elements, &index, BoundsCheckKind::IsStore);
atomicsCheckBounds(callInfo, &elements, &index);
if (requiresCheck)
addSharedTypedArrayGuard(callInfo.getArg(0));
@ -3488,7 +3488,7 @@ IonBuilder::inlineAtomicsBinop(CallInfo& callInfo, InlinableNative target)
MInstruction* elements;
MDefinition* index;
atomicsCheckBounds(callInfo, &elements, &index, BoundsCheckKind::IsLoad);
atomicsCheckBounds(callInfo, &elements, &index);
AtomicOp k = AtomicFetchAddOp;
switch (target) {
@ -3585,15 +3585,14 @@ IonBuilder::atomicsMeetsPreconditions(CallInfo& callInfo, Scalar::Type* arrayTyp
}
void
IonBuilder::atomicsCheckBounds(CallInfo& callInfo, MInstruction** elements, MDefinition** index,
BoundsCheckKind kind)
IonBuilder::atomicsCheckBounds(CallInfo& callInfo, MInstruction** elements, MDefinition** index)
{
// Perform bounds checking and extract the elements vector.
MDefinition* obj = callInfo.getArg(0);
MInstruction* length = nullptr;
*index = callInfo.getArg(1);
*elements = nullptr;
addTypedArrayLengthAndData(obj, DoBoundsCheck, index, &length, elements, kind);
addTypedArrayLengthAndData(obj, DoBoundsCheck, index, &length, elements);
}
IonBuilder::InliningResult
@ -4308,7 +4307,7 @@ SimdTypeToArrayElementType(SimdType type)
bool
IonBuilder::prepareForSimdLoadStore(CallInfo& callInfo, Scalar::Type simdType,
MInstruction** elements, MDefinition** index,
Scalar::Type* arrayType, BoundsCheckKind boundsCheckKind)
Scalar::Type* arrayType)
{
MDefinition* array = callInfo.getArg(0);
*index = callInfo.getArg(1);
@ -4334,20 +4333,20 @@ IonBuilder::prepareForSimdLoadStore(CallInfo& callInfo, Scalar::Type simdType,
}
MInstruction* length;
addTypedArrayLengthAndData(array, SkipBoundsCheck, index, &length, elements, boundsCheckKind);
addTypedArrayLengthAndData(array, SkipBoundsCheck, index, &length, elements);
// If the index+size addition overflows, then indexLoadEnd might be
// in bounds while the actual index isn't, so we need two bounds checks
// here.
if (byteLoadSize > 1) {
indexLoadEnd = addBoundsCheck(indexLoadEnd, length, BoundsCheckKind::IsLoad);
indexLoadEnd = addBoundsCheck(indexLoadEnd, length);
auto* sub = MSub::New(alloc(), indexLoadEnd, constant(Int32Value(byteLoadSize - 1)));
sub->setInt32Specialization();
current->add(sub);
*index = sub;
}
*index = addBoundsCheck(*index, length, boundsCheckKind);
*index = addBoundsCheck(*index, length);
return true;
}
@ -4364,11 +4363,8 @@ IonBuilder::inlineSimdLoad(CallInfo& callInfo, JSNative native, SimdType type, u
MDefinition* index = nullptr;
MInstruction* elements = nullptr;
Scalar::Type arrayType;
if (!prepareForSimdLoadStore(callInfo, elemType, &elements, &index, &arrayType,
BoundsCheckKind::IsLoad))
{
if (!prepareForSimdLoadStore(callInfo, elemType, &elements, &index, &arrayType))
return InliningStatus_NotInlined;
}
MLoadUnboxedScalar* load = MLoadUnboxedScalar::New(alloc(), elements, index, arrayType);
load->setResultType(SimdTypeToMIRType(type));
@ -4389,11 +4385,8 @@ IonBuilder::inlineSimdStore(CallInfo& callInfo, JSNative native, SimdType type,
MDefinition* index = nullptr;
MInstruction* elements = nullptr;
Scalar::Type arrayType;
if (!prepareForSimdLoadStore(callInfo, elemType, &elements, &index, &arrayType,
BoundsCheckKind::IsStore))
{
if (!prepareForSimdLoadStore(callInfo, elemType, &elements, &index, &arrayType))
return InliningStatus_NotInlined;
}
MDefinition* valueToWrite = unboxSimd(callInfo.getArg(2), type);
MStoreUnboxedScalar* store = MStoreUnboxedScalar::New(alloc(), elements, index,

Просмотреть файл

@ -9705,7 +9705,8 @@ class MSpectreMaskIndex
MSpectreMaskIndex(MDefinition* index, MDefinition* length)
: MBinaryInstruction(classOpcode, index, length)
{
setGuard();
// Note: this instruction does not need setGuard(): if there are no uses
// it's fine for DCE to eliminate this instruction.
setMovable();
MOZ_ASSERT(index->type() == MIRType::Int32);
MOZ_ASSERT(length->type() == MIRType::Int32);

Просмотреть файл

@ -1711,7 +1711,7 @@ MacroAssembler::loadStringChar(Register str, Register index, Register output, Re
// Check if the index is contained in the leftChild.
// Todo: Handle index in the rightChild.
boundsCheck32ForLoad(index, Address(output, JSString::offsetOfLength()), scratch, fail);
spectreBoundsCheck32(index, Address(output, JSString::offsetOfLength()), scratch, fail);
// If the left side is another rope, give up.
branchIfRope(output, fail);

Просмотреть файл

@ -1432,10 +1432,10 @@ class MacroAssembler : public MacroAssemblerSpecific
// Performs a bounds check and zeroes the index register if out-of-bounds
// (to mitigate Spectre).
inline void boundsCheck32ForLoad(Register index, Register length, Register scratch,
inline void spectreBoundsCheck32(Register index, Register length, Register scratch,
Label* failure)
DEFINED_ON(arm, arm64, mips_shared, x86_shared);
inline void boundsCheck32ForLoad(Register index, const Address& length, Register scratch,
inline void spectreBoundsCheck32(Register index, const Address& length, Register scratch,
Label* failure)
DEFINED_ON(arm, arm64, mips_shared, x86_shared);

Просмотреть файл

@ -2194,7 +2194,7 @@ MacroAssembler::spectreZeroRegister(Condition cond, Register, Register dest)
}
void
MacroAssembler::boundsCheck32ForLoad(Register index, Register length, Register scratch,
MacroAssembler::spectreBoundsCheck32(Register index, Register length, Register scratch,
Label* failure)
{
MOZ_ASSERT(index != length);
@ -2211,7 +2211,7 @@ MacroAssembler::boundsCheck32ForLoad(Register index, Register length, Register s
}
void
MacroAssembler::boundsCheck32ForLoad(Register index, const Address& length, Register scratch,
MacroAssembler::spectreBoundsCheck32(Register index, const Address& length, Register scratch,
Label* failure)
{
MOZ_ASSERT(index != length.base);

Просмотреть файл

@ -1874,7 +1874,7 @@ MacroAssembler::spectreZeroRegister(Condition cond, Register, Register dest)
}
void
MacroAssembler::boundsCheck32ForLoad(Register index, Register length, Register scratch,
MacroAssembler::spectreBoundsCheck32(Register index, Register length, Register scratch,
Label* failure)
{
MOZ_ASSERT(index != length);
@ -1888,7 +1888,7 @@ MacroAssembler::boundsCheck32ForLoad(Register index, Register length, Register s
}
void
MacroAssembler::boundsCheck32ForLoad(Register index, const Address& length, Register scratch,
MacroAssembler::spectreBoundsCheck32(Register index, const Address& length, Register scratch,
Label* failure)
{
MOZ_ASSERT(index != length.base);

Просмотреть файл

@ -1016,7 +1016,7 @@ MacroAssembler::test32MovePtr(Condition cond, const Address& addr, Imm32 mask, R
}
void
MacroAssembler::boundsCheck32ForLoad(Register index, Register length, Register scratch,
MacroAssembler::spectreBoundsCheck32(Register index, Register length, Register scratch,
Label* failure)
{
MOZ_RELEASE_ASSERT(!JitOptions.spectreIndexMasking);
@ -1024,7 +1024,7 @@ MacroAssembler::boundsCheck32ForLoad(Register index, Register length, Register s
}
void
MacroAssembler::boundsCheck32ForLoad(Register index, const Address& length, Register scratch,
MacroAssembler::spectreBoundsCheck32(Register index, const Address& length, Register scratch,
Label* failure)
{
MOZ_RELEASE_ASSERT(!JitOptions.spectreIndexMasking);

Просмотреть файл

@ -2831,4 +2831,4 @@ void
MacroAssembler::speculationBarrier()
{
MOZ_CRASH();
}
}

Просмотреть файл

@ -275,4 +275,4 @@ LIRGeneratorMIPS::visitInt64ToFloatingPoint(MInt64ToFloatingPoint* ins)
MOZ_ASSERT(IsFloatingPointType(ins->type()));
defineReturn(new(alloc()) LInt64ToFloatingPoint(useInt64RegisterAtStart(opd)), ins);
}
}

Просмотреть файл

@ -201,4 +201,4 @@ LIRGeneratorMIPS64::visitInt64ToFloatingPoint(MInt64ToFloatingPoint* ins)
MOZ_ASSERT(IsFloatingPointType(ins->type()));
define(new(alloc()) LInt64ToFloatingPoint(useInt64Register(opd)), ins);
}
}

Просмотреть файл

@ -1091,16 +1091,6 @@ class AssemblerX86Shared : public AssemblerShared
X86Encoding::SetInt32(code + offset.offset(), n);
}
CodeOffset twoByteNop() {
return CodeOffset(masm.twoByteNop().offset());
}
static void patchTwoByteNopToJump(uint8_t* jump, uint8_t* target) {
X86Encoding::BaseAssembler::patchTwoByteNopToJump(jump, target);
}
static void patchJumpToTwoByteNop(uint8_t* jump) {
X86Encoding::BaseAssembler::patchJumpToTwoByteNop(jump);
}
static void patchFiveByteNopToCall(uint8_t* callsite, uint8_t* target) {
X86Encoding::BaseAssembler::patchFiveByteNopToCall(callsite, target);
}

Просмотреть файл

@ -71,36 +71,6 @@ public:
spew("; %s", msg);
}
MOZ_MUST_USE JmpSrc
twoByteNop()
{
spew("nop (2 byte)");
JmpSrc r(m_formatter.size());
m_formatter.prefix(PRE_OPERAND_SIZE);
m_formatter.oneByteOp(OP_NOP);
return r;
}
static void patchTwoByteNopToJump(uint8_t* jump, uint8_t* target)
{
// Note: the offset is relative to the address of the instruction after
// the jump which is two bytes.
ptrdiff_t rel8 = target - jump - 2;
MOZ_RELEASE_ASSERT(rel8 >= INT8_MIN && rel8 <= INT8_MAX);
MOZ_RELEASE_ASSERT(jump[0] == PRE_OPERAND_SIZE);
MOZ_RELEASE_ASSERT(jump[1] == OP_NOP);
jump[0] = OP_JMP_rel8;
jump[1] = rel8;
}
static void patchJumpToTwoByteNop(uint8_t* jump)
{
// See twoByteNop.
MOZ_RELEASE_ASSERT(jump[0] == OP_JMP_rel8);
jump[0] = PRE_OPERAND_SIZE;
jump[1] = OP_NOP;
}
static void patchFiveByteNopToCall(uint8_t* callsite, uint8_t* target)
{
// Note: the offset is relative to the address of the instruction after

Просмотреть файл

@ -1119,7 +1119,7 @@ MacroAssembler::spectreZeroRegister(Condition cond, Register scratch, Register d
}
void
MacroAssembler::boundsCheck32ForLoad(Register index, Register length, Register scratch,
MacroAssembler::spectreBoundsCheck32(Register index, Register length, Register scratch,
Label* failure)
{
MOZ_ASSERT(index != length);
@ -1137,7 +1137,7 @@ MacroAssembler::boundsCheck32ForLoad(Register index, Register length, Register s
}
void
MacroAssembler::boundsCheck32ForLoad(Register index, const Address& length, Register scratch,
MacroAssembler::spectreBoundsCheck32(Register index, const Address& length, Register scratch,
Label* failure)
{
MOZ_ASSERT(index != length.base);

Просмотреть файл

@ -15,6 +15,7 @@
#include "mozilla/CSSAlignUtils.h"
#include "mozilla/CSSOrderAwareFrameIterator.h"
#include "mozilla/dom/GridBinding.h"
#include "mozilla/IntegerRange.h"
#include "mozilla/Maybe.h"
#include "mozilla/PodOperations.h" // for PodZero
#include "mozilla/Poison.h"
@ -429,6 +430,12 @@ struct nsGridContainerFrame::LineRange
}
return mEnd - mStart;
}
/**
* Return an object suitable for iterating this range.
*/
auto Range() const { return IntegerRange<uint32_t>(mStart, mEnd); }
/**
* Resolve this auto range to start at aStart, making it definite.
* Precondition: this range IsAuto()
@ -1252,9 +1259,7 @@ struct nsGridContainerFrame::Tracks
{
MOZ_ASSERT(aAvailableSpace > 0, "why call me?");
nscoord space = aAvailableSpace - mGridGap * (aRange.Extent() - 1);
const uint32_t start = aRange.mStart;
const uint32_t end = aRange.mEnd;
for (uint32_t i = start; i < end; ++i) {
for (auto i : aRange.Range()) {
const TrackSize& sz = mSizes[i];
space -= StartSizeInDistribution<phase>(sz);
if (space <= 0) {
@ -3869,9 +3874,7 @@ nsGridContainerFrame::Tracks::StateBitsForRange(const LineRange& aRange) const
{
MOZ_ASSERT(!aRange.IsAuto(), "must have a definite range");
TrackSize::StateBits state = TrackSize::StateBits(0);
const uint32_t start = aRange.mStart;
const uint32_t end = aRange.mEnd;
for (uint32_t i = start; i < end; ++i) {
for (auto i : aRange.Range()) {
state |= mSizes[i].mState;
}
return state;
@ -4270,8 +4273,8 @@ nsGridContainerFrame::Tracks::GrowSizeForSpanningItems(
continue;
}
if (isMaxSizingPhase) {
for (auto j = item.mLineRange.mStart, end = item.mLineRange.mEnd; j < end; ++j) {
aPlan[j].mState |= TrackSize::eModified;
for (auto i : item.mLineRange.Range()) {
aPlan[i].mState |= TrackSize::eModified;
}
}
nscoord space = item.SizeContributionForPhase<phase>();
@ -4309,7 +4312,13 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize(
// http://dev.w3.org/csswg/css-grid/#algo-content
// We're also setting eIsFlexing on the item state here to speed up
// FindUsedFlexFraction later.
AutoTArray<TrackSize::StateBits, 16> stateBitsPerSpan;
struct PerSpanData {
PerSpanData() : mItemCountWithSameSpan(0)
, mStateBits(TrackSize::StateBits(0)) {}
uint32_t mItemCountWithSameSpan;
TrackSize::StateBits mStateBits;
};
AutoTArray<PerSpanData, 16> perSpanData;
nsTArray<Step2ItemData> step2Items;
CSSOrderAwareFrameIterator& iter = aState.mIter;
gfxContext* rc = &aState.mRenderingContext;
@ -4354,14 +4363,11 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize(
!(state & TrackSize::eFlexMaxSizing)) {
// Collect data for Step 2.
maxSpan = std::max(maxSpan, span);
if (span >= stateBitsPerSpan.Length()) {
uint32_t len = 2 * span;
stateBitsPerSpan.SetCapacity(len);
for (uint32_t i = stateBitsPerSpan.Length(); i < len; ++i) {
stateBitsPerSpan.AppendElement(TrackSize::StateBits(0));
}
if (span >= perSpanData.Length()) {
perSpanData.SetLength(2 * span);
}
stateBitsPerSpan[span] |= state;
perSpanData[span].mItemCountWithSameSpan++;
perSpanData[span].mStateBits |= state;
CachedIntrinsicSizes cache;
// Calculate data for "Automatic Minimum Size" clamping, if needed.
bool needed = ((state & TrackSize::eIntrinsicMinSizing) ||
@ -4369,7 +4375,7 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize(
(gridItem.mState[mAxis] & ItemState::eApplyAutoMinSize);
if (needed && TrackSize::IsDefiniteMaxSizing(state)) {
nscoord minSizeClamp = 0;
for (auto i = lineRange.mStart, end = lineRange.mEnd; i < end; ++i) {
for (auto i : lineRange.Range()) {
auto maxCoord = aFunctions.MaxSizingFor(i);
minSizeClamp += maxCoord.ComputeCoordPercentCalc(aPercentageBasis);
}
@ -4441,15 +4447,12 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize(
auto spanGroupEnd = spanGroupStart;
const auto end = step2Items.end();
for (; spanGroupStart != end; spanGroupStart = spanGroupEnd) {
while (spanGroupEnd != end &&
!Step2ItemData::IsSpanLessThan(*spanGroupStart, *spanGroupEnd)) {
++spanGroupEnd;
}
const uint32_t span = spanGroupStart->mSpan;
spanGroupEnd = spanGroupStart + perSpanData[span].mItemCountWithSameSpan;
TrackSize::StateBits stateBitsForSpan = perSpanData[span].mStateBits;
bool updatedBase = false; // Did we update any mBase in step 2.1 - 2.3?
TrackSize::StateBits selector(TrackSize::eIntrinsicMinSizing);
if (stateBitsPerSpan[span] & selector) {
if (stateBitsForSpan & selector) {
// Step 2.1 MinSize to intrinsic min-sizing.
updatedBase =
GrowSizeForSpanningItems<TrackSizingPhase::eIntrinsicMinimums>(
@ -4457,7 +4460,7 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize(
}
selector = contentBasedMinSelector;
if (stateBitsPerSpan[span] & selector) {
if (stateBitsForSpan & selector) {
// Step 2.2 MinContentContribution to min-/max-content (and 'auto' when
// sizing under a min-content constraint) min-sizing.
updatedBase |=
@ -4466,7 +4469,7 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize(
}
selector = maxContentMinSelector;
if (stateBitsPerSpan[span] & selector) {
if (stateBitsForSpan & selector) {
// Step 2.3 MaxContentContribution to max-content (and 'auto' when
// sizing under a max-content constraint) min-sizing.
updatedBase |=
@ -4484,9 +4487,9 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize(
}
selector = TrackSize::eIntrinsicMaxSizing;
if (stateBitsPerSpan[span] & selector) {
if (stateBitsForSpan & selector) {
const bool willRunStep2_6 =
stateBitsPerSpan[span] & TrackSize::eAutoOrMaxContentMaxSizing;
stateBitsForSpan & TrackSize::eAutoOrMaxContentMaxSizing;
// Step 2.5 MinSize to intrinsic max-sizing.
GrowSizeForSpanningItems<TrackSizingPhase::eIntrinsicMaximums>(
spanGroupStart, spanGroupEnd, tracks, plan, itemPlan, selector,
@ -4521,7 +4524,7 @@ nsGridContainerFrame::Tracks::FindFrUnitSize(
MOZ_ASSERT(aSpaceToFill > 0 && !aFlexTracks.IsEmpty());
float flexFactorSum = 0.0f;
nscoord leftOverSpace = aSpaceToFill;
for (uint32_t i = aRange.mStart, end = aRange.mEnd; i < end; ++i) {
for (auto i : aRange.Range()) {
const TrackSize& sz = mSizes[i];
if (sz.mState & TrackSize::eFlexMaxSizing) {
flexFactorSum += aFunctions.MaxSizingFor(i).GetFlexFractionValue();
@ -4613,7 +4616,7 @@ nsGridContainerFrame::Tracks::FindUsedFlexFraction(
}
// ... and all its spanned tracks as input.
nsTArray<uint32_t> itemFlexTracks;
for (uint32_t i = range.mStart, end = range.mEnd; i < end; ++i) {
for (auto i : range.Range()) {
if (mSizes[i].mState & TrackSize::eFlexMaxSizing) {
itemFlexTracks.AppendElement(i);
}

Просмотреть файл

@ -390184,7 +390184,7 @@
"manual"
],
"FileAPI/FileReader/workers.html": [
"d7894a0abb064411d4811d8cfb9c3ce65f99babd",
"b93f6c447184bc20cc59e895ae446ee95ebdb406",
"testharness"
],
"FileAPI/FileReaderSync.worker.js": [
@ -500876,7 +500876,7 @@
"reftest"
],
"css/css-scoping/shadow-fallback-dynamic-004.html": [
"50c12659c9625801c6b4bb25ab76acddd50c8e90",
"fc33527eaaa7711ecb2c7cd9523e793bce2503f2",
"reftest"
],
"css/css-scoping/shadow-fallback-dynamic-005.html": [
@ -538912,7 +538912,7 @@
"testharness"
],
"dom/nodes/Element-classlist.html": [
"10a0336430514dbbe8e837472c4476254ea8f8fc",
"db5f4b3f723db026b90e299b2c7be5e5e4f081f5",
"testharness"
],
"dom/nodes/Element-closest.html": [
@ -542324,7 +542324,7 @@
"testharness"
],
"eventsource/dedicated-worker/eventsource-close2.htm": [
"a3d13b0261b05eba56effb9ca3f6c31e312e777a",
"dc79b53506150f4877a36c6c0d54ccebeecf87ba",
"testharness"
],
"eventsource/dedicated-worker/eventsource-constructor-non-same-origin.htm": [
@ -564076,7 +564076,7 @@
"support"
],
"interfaces/dom.idl": [
"773c449a2f9a6bd9e35d0dd8a4c2e1eaa0266150",
"ff96179e520ad069ec36a0ced2a6f2ceb2e8c5da",
"support"
],
"interfaces/fullscreen.idl": [
@ -593812,7 +593812,7 @@
"testharness"
],
"webmessaging/broadcastchannel/workers.html": [
"ef608ad90a3dfbcdbf3cbb0b51ee8cacfb3a3a65",
"483e03e9528f1e80fc1b250caee46f7f256d63c1",
"testharness"
],
"webmessaging/event.data.sub.htm": [
@ -593864,7 +593864,7 @@
"testharness"
],
"webmessaging/message-channels/worker.html": [
"9c6e11c2a0d5cdbca5682c7be5a23f081f419e0f",
"25778166691434e77f361a609742a170c4f787e8",
"testharness"
],
"webmessaging/messageerror.html": [
@ -594616,7 +594616,7 @@
"testharness"
],
"websockets/Create-on-worker-shutdown.html": [
"e710493c0cd84630a1c853ada23c37908bece9cb",
"75112264efdc3b310f4ba2ab4517b7608aacf2f2",
"testharness"
],
"websockets/Create-protocol-with-space.htm": [

Просмотреть файл

@ -981,7 +981,7 @@
"support"
],
"dom/classList.html": [
"f289334e7b3486259b9aae54b4282a7211b8813e",
"5aa8aa335e998e0033b72dfc259f0fe6608182f5",
"testharness"
],
"dom/throttling/resources/test.html": [
@ -1433,7 +1433,7 @@
"support"
],
"wasm/js/harness/index.js": [
"b1af046bac238e99d0bc73cc89faf3030149340f",
"c1f8ca410de85f15e1d9e57748a2fb9f607be40f",
"support"
],
"wasm/js/harness/wasm-constants.js": [

Просмотреть файл

@ -15,7 +15,7 @@ async_test(t => {
postMessage(true);
}
var workerBlob = new Blob([workerCode.toSource() + ";workerCode();"], {type:"application/javascript"});
var workerBlob = new Blob([workerCode.toString() + ";workerCode();"], {type:"application/javascript"});
var w = new Worker(URL.createObjectURL(workerBlob));
w.onmessage = function(e) {

Просмотреть файл

@ -112,7 +112,7 @@ async_test(t => {
postMessage(true);
}
var workerBlob = new Blob([workerCode.toSource() + ";workerCode();"], {type:"application/javascript"});
var workerBlob = new Blob([workerCode.toString() + ";workerCode();"], {type:"application/javascript"});
var w = new Worker(URL.createObjectURL(workerBlob));
w.onmessage = function(e) {

Просмотреть файл

@ -14,7 +14,7 @@ async_test(t => {
postMessage(true);
}
var workerBlob = new Blob([workerCode.toSource() + ";workerCode();"], {type:"application/javascript"});
var workerBlob = new Blob([workerCode.toString() + ";workerCode();"], {type:"application/javascript"});
var w = new Worker(URL.createObjectURL(workerBlob));
w.onmessage = function(e) {

Просмотреть файл

@ -13,11 +13,11 @@
async_test(t => {
function workerCode() {
close();
var ws = new WebSocket(self.location)
var ws = new WebSocket(self.location.origin.replace('http', 'ws'));
postMessage(ws.readyState == WebSocket.CONNECTING);
}
var workerBlob = new Blob([workerCode.toSource() + ";workerCode();"], {type:"application/javascript"});
var workerBlob = new Blob([workerCode.toString() + ";workerCode();"], {type:"application/javascript"});
var w = new Worker(URL.createObjectURL(workerBlob));
w.onmessage = function(e) {