зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1432479 - MIPS64: Use XOR for Value unboxing on 64-bit to mitigate certain Spectre attacks. r=draganmladjenovic
This commit is contained in:
Родитель
e86055999a
Коммит
5504a4c66c
|
@ -1432,28 +1432,6 @@ MacroAssemblerMIPS64Compat::testUndefinedSet(Condition cond, const ValueOperand&
|
|||
ma_cmp_set(dest, SecondScratchReg, ImmTag(JSVAL_TAG_UNDEFINED), cond);
|
||||
}
|
||||
|
||||
// unboxing code
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::unboxNonDouble(const ValueOperand& operand, Register dest)
|
||||
{
|
||||
ma_dext(dest, operand.valueReg(), Imm32(0), Imm32(JSVAL_TAG_SHIFT));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::unboxNonDouble(const Address& src, Register dest)
|
||||
{
|
||||
loadPtr(Address(src.base, src.offset), dest);
|
||||
ma_dext(dest, dest, Imm32(0), Imm32(JSVAL_TAG_SHIFT));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::unboxNonDouble(const BaseIndex& src, Register dest)
|
||||
{
|
||||
computeScaledAddress(src, SecondScratchReg);
|
||||
loadPtr(Address(SecondScratchReg, src.offset), dest);
|
||||
ma_dext(dest, dest, Imm32(0), Imm32(JSVAL_TAG_SHIFT));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::unboxInt32(const ValueOperand& operand, Register dest)
|
||||
{
|
||||
|
@ -1519,53 +1497,59 @@ MacroAssemblerMIPS64Compat::unboxDouble(const Address& src, FloatRegister dest)
|
|||
void
|
||||
MacroAssemblerMIPS64Compat::unboxString(const ValueOperand& operand, Register dest)
|
||||
{
|
||||
unboxNonDouble(operand, dest);
|
||||
unboxNonDouble(operand, dest, JSVAL_TYPE_STRING);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::unboxString(Register src, Register dest)
|
||||
{
|
||||
ma_dext(dest, src, Imm32(0), Imm32(JSVAL_TAG_SHIFT));
|
||||
unboxNonDouble(src, dest, JSVAL_TYPE_STRING);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::unboxString(const Address& src, Register dest)
|
||||
{
|
||||
unboxNonDouble(src, dest);
|
||||
unboxNonDouble(src, dest, JSVAL_TYPE_STRING);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::unboxSymbol(const ValueOperand& operand, Register dest)
|
||||
{
|
||||
unboxNonDouble(operand, dest, JSVAL_TYPE_SYMBOL);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::unboxSymbol(Register src, Register dest)
|
||||
{
|
||||
ma_dext(dest, src, Imm32(0), Imm32(JSVAL_TAG_SHIFT));
|
||||
unboxNonDouble(src, dest, JSVAL_TYPE_SYMBOL);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::unboxSymbol(const Address& src, Register dest)
|
||||
{
|
||||
unboxNonDouble(src, dest);
|
||||
unboxNonDouble(src, dest, JSVAL_TYPE_SYMBOL);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::unboxObject(const ValueOperand& src, Register dest)
|
||||
{
|
||||
unboxNonDouble(src, dest);
|
||||
unboxNonDouble(src, dest, JSVAL_TYPE_OBJECT);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::unboxObject(Register src, Register dest)
|
||||
{
|
||||
ma_dext(dest, src, Imm32(0), Imm32(JSVAL_TAG_SHIFT));
|
||||
unboxNonDouble(src, dest, JSVAL_TYPE_OBJECT);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::unboxObject(const Address& src, Register dest)
|
||||
{
|
||||
unboxNonDouble(src, dest);
|
||||
unboxNonDouble(src, dest, JSVAL_TYPE_OBJECT);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::unboxValue(const ValueOperand& src, AnyRegister dest)
|
||||
MacroAssemblerMIPS64Compat::unboxValue(const ValueOperand& src, AnyRegister dest, JSValueType type)
|
||||
{
|
||||
if (dest.isFloat()) {
|
||||
Label notInt32, end;
|
||||
|
@ -1576,7 +1560,7 @@ MacroAssemblerMIPS64Compat::unboxValue(const ValueOperand& src, AnyRegister dest
|
|||
unboxDouble(src, dest.fpu());
|
||||
bind(&end);
|
||||
} else {
|
||||
unboxNonDouble(src, dest.gpr());
|
||||
unboxNonDouble(src, dest.gpr(), type);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -362,9 +362,44 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64
|
|||
}
|
||||
|
||||
// unboxing code
|
||||
void unboxNonDouble(const ValueOperand& operand, Register dest);
|
||||
void unboxNonDouble(const Address& src, Register dest);
|
||||
void unboxNonDouble(const BaseIndex& src, Register dest);
|
||||
void unboxNonDouble(const ValueOperand& operand, Register dest, JSValueType type) {
|
||||
unboxNonDouble(operand.valueReg(), dest, type);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void unboxNonDouble(T src, Register dest, JSValueType type) {
|
||||
MOZ_ASSERT(type != JSVAL_TYPE_DOUBLE);
|
||||
if (type == JSVAL_TYPE_INT32 || type == JSVAL_TYPE_BOOLEAN) {
|
||||
load32(src, dest);
|
||||
return;
|
||||
}
|
||||
loadPtr(src, dest);
|
||||
unboxNonDouble(dest, dest, type);
|
||||
}
|
||||
|
||||
void unboxNonDouble(Register src, Register dest, JSValueType type) {
|
||||
MOZ_ASSERT(type != JSVAL_TYPE_DOUBLE);
|
||||
if (type == JSVAL_TYPE_INT32 || type == JSVAL_TYPE_BOOLEAN) {
|
||||
ma_sll(dest, src, Imm32(0));
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(ScratchRegister != src);
|
||||
mov(ImmWord(JSVAL_TYPE_TO_SHIFTED_TAG(type)), ScratchRegister);
|
||||
as_xor(dest, src, ScratchRegister);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void unboxObjectOrNull(const T& src, Register dest) {
|
||||
unboxNonDouble(src, dest, JSVAL_TYPE_OBJECT);
|
||||
JS_STATIC_ASSERT(JSVAL_OBJECT_OR_NULL_BIT == (uint64_t(0x8) << JSVAL_TAG_SHIFT));
|
||||
ma_dins(dest, zero, Imm32(JSVAL_TAG_SHIFT + 3), Imm32(1));
|
||||
}
|
||||
|
||||
void unboxGCThingForPreBarrierTrampoline(const Address& src, Register dest) {
|
||||
loadPtr(src, dest);
|
||||
ma_dext(dest, dest, Imm32(0), Imm32(JSVAL_TAG_SHIFT));
|
||||
}
|
||||
|
||||
void unboxInt32(const ValueOperand& operand, Register dest);
|
||||
void unboxInt32(Register src, Register dest);
|
||||
void unboxInt32(const Address& src, Register dest);
|
||||
|
@ -385,8 +420,8 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64
|
|||
void unboxObject(const ValueOperand& src, Register dest);
|
||||
void unboxObject(Register src, Register dest);
|
||||
void unboxObject(const Address& src, Register dest);
|
||||
void unboxObject(const BaseIndex& src, Register dest) { unboxNonDouble(src, dest); }
|
||||
void unboxValue(const ValueOperand& src, AnyRegister dest);
|
||||
void unboxObject(const BaseIndex& src, Register dest) { unboxNonDouble(src, dest, JSVAL_TYPE_OBJECT); }
|
||||
void unboxValue(const ValueOperand& src, AnyRegister dest, JSValueType type);
|
||||
void unboxPrivate(const ValueOperand& src, Register dest);
|
||||
|
||||
void notBoolean(const ValueOperand& val) {
|
||||
|
@ -405,6 +440,14 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64
|
|||
unboxObject(value, scratch);
|
||||
return scratch;
|
||||
}
|
||||
Register extractString(const ValueOperand& value, Register scratch) {
|
||||
unboxString(value, scratch);
|
||||
return scratch;
|
||||
}
|
||||
Register extractSymbol(const ValueOperand& value, Register scratch) {
|
||||
unboxSymbol(value, scratch);
|
||||
return scratch;
|
||||
}
|
||||
Register extractInt32(const ValueOperand& value, Register scratch) {
|
||||
unboxInt32(value, scratch);
|
||||
return scratch;
|
||||
|
@ -449,20 +492,40 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64
|
|||
void loadUnboxedValue(const T& address, MIRType type, AnyRegister dest) {
|
||||
if (dest.isFloat())
|
||||
loadInt32OrDouble(address, dest.fpu());
|
||||
else if (type == MIRType::Int32)
|
||||
unboxInt32(address, dest.gpr());
|
||||
else if (type == MIRType::Boolean)
|
||||
unboxBoolean(address, dest.gpr());
|
||||
else if (type == MIRType::ObjectOrNull)
|
||||
unboxObjectOrNull(address, dest.gpr());
|
||||
else
|
||||
unboxNonDouble(address, dest.gpr());
|
||||
unboxNonDouble(address, dest.gpr(), ValueTypeFromMIRType(type));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void storeUnboxedPayload(ValueOperand value, T address, size_t nbytes) {
|
||||
void storeUnboxedPayload(ValueOperand value, BaseIndex address, size_t nbytes, JSValueType type) {
|
||||
switch (nbytes) {
|
||||
case 8:
|
||||
unboxNonDouble(value, ScratchRegister);
|
||||
storePtr(ScratchRegister, address);
|
||||
if (type == JSVAL_TYPE_OBJECT)
|
||||
unboxObjectOrNull(value, SecondScratchReg);
|
||||
else
|
||||
unboxNonDouble(value, SecondScratchReg, type);
|
||||
computeEffectiveAddress(address, ScratchRegister);
|
||||
as_sd(SecondScratchReg, ScratchRegister, 0);
|
||||
return;
|
||||
case 4:
|
||||
store32(value.valueReg(), address);
|
||||
return;
|
||||
case 1:
|
||||
store8(value.valueReg(), address);
|
||||
return;
|
||||
default: MOZ_CRASH("Bad payload width");
|
||||
}
|
||||
}
|
||||
|
||||
void storeUnboxedPayload(ValueOperand value, Address address, size_t nbytes, JSValueType type) {
|
||||
switch (nbytes) {
|
||||
case 8:
|
||||
if (type == JSVAL_TYPE_OBJECT)
|
||||
unboxObjectOrNull(value, SecondScratchReg);
|
||||
else
|
||||
unboxNonDouble(value, SecondScratchReg, type);
|
||||
storePtr(SecondScratchReg, address);
|
||||
return;
|
||||
case 4:
|
||||
store32(value.valueReg(), address);
|
||||
|
|
Загрузка…
Ссылка в новой задаче