Bug 1062893: Add recover support for MCompare. r=iain

Differential Revision: https://phabricator.services.mozilla.com/D153484
This commit is contained in:
André Bargull 2022-08-02 17:55:26 +00:00
parent 1064b24933
commit 7e937f10b1
4 changed files with 324 additions and 1 deletions

View file

@ -416,6 +416,222 @@ function rnot_object(i) {
return i;
}
var uceFault_compare_number_eq = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_number_eq'));
function rcompare_number_eq(i) {
var x = i == 99;
if (uceFault_compare_number_eq(i) || uceFault_compare_number_eq(i))
assertEq(x, true);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_number_stricteq = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_number_stricteq'));
function rcompare_number_stricteq(i) {
var x = i === 99;
if (uceFault_compare_number_stricteq(i) || uceFault_compare_number_stricteq(i))
assertEq(x, true);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_number_ne = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_number_ne'));
function rcompare_number_ne(i) {
var x = i != 99;
if (uceFault_compare_number_ne(i) || uceFault_compare_number_ne(i))
assertEq(x, false);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_number_strictne = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_number_strictne'));
function rcompare_number_strictne(i) {
var x = i !== 99;
if (uceFault_compare_number_strictne(i) || uceFault_compare_number_strictne(i))
assertEq(x, false);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_number_lt = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_number_lt'));
function rcompare_number_lt(i) {
var x = i < 99;
if (uceFault_compare_number_lt(i) || uceFault_compare_number_lt(i))
assertEq(x, false);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_number_le = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_number_le'));
function rcompare_number_le(i) {
var x = i <= 99;
if (uceFault_compare_number_le(i) || uceFault_compare_number_le(i))
assertEq(x, true);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_number_gt = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_number_gt'));
function rcompare_number_gt(i) {
var x = i > 99;
if (uceFault_compare_number_gt(i) || uceFault_compare_number_gt(i))
assertEq(x, false);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_number_ge = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_number_ge'));
function rcompare_number_ge(i) {
var x = i >= 99;
if (uceFault_compare_number_ge(i) || uceFault_compare_number_ge(i))
assertEq(x, true);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_string_eq = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_string_eq'));
function rcompare_string_eq(i) {
var x = String(i) == "99";
if (uceFault_compare_string_eq(i) || uceFault_compare_string_eq(i))
assertEq(x, true);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_string_stricteq = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_string_stricteq'));
function rcompare_string_stricteq(i) {
var x = String(i) === "99";
if (uceFault_compare_string_stricteq(i) || uceFault_compare_string_stricteq(i))
assertEq(x, true);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_string_ne = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_string_ne'));
function rcompare_string_ne(i) {
var x = String(i) != "99";
if (uceFault_compare_string_ne(i) || uceFault_compare_string_ne(i))
assertEq(x, false);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_string_strictne = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_string_strictne'));
function rcompare_string_strictne(i) {
var x = String(i) !== "99";
if (uceFault_compare_string_strictne(i) || uceFault_compare_string_strictne(i))
assertEq(x, false);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_string_lt = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_string_lt'));
function rcompare_string_lt(i) {
var x = String(i) < "99";
if (uceFault_compare_string_lt(i) || uceFault_compare_string_lt(i))
assertEq(x, false);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_string_le = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_string_le'));
function rcompare_string_le(i) {
var x = String(i) <= "99";
if (uceFault_compare_string_le(i) || uceFault_compare_string_le(i))
assertEq(x, true);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_string_gt = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_string_gt'));
function rcompare_string_gt(i) {
var x = String(i) > "99";
if (uceFault_compare_string_gt(i) || uceFault_compare_string_gt(i))
assertEq(x, false);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_string_ge = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_string_ge'));
function rcompare_string_ge(i) {
var x = String(i) >= "99";
if (uceFault_compare_string_ge(i) || uceFault_compare_string_ge(i))
assertEq(x, true);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_bigint_eq = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_bigint_eq'));
function rcompare_bigint_eq(i) {
var x = BigInt(i) == 99n;
if (uceFault_compare_bigint_eq(i) || uceFault_compare_bigint_eq(i))
assertEq(x, true);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_bigint_stricteq = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_bigint_stricteq'));
function rcompare_bigint_stricteq(i) {
var x = BigInt(i) === 99n;
if (uceFault_compare_bigint_stricteq(i) || uceFault_compare_bigint_stricteq(i))
assertEq(x, true);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_bigint_ne = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_bigint_ne'));
function rcompare_bigint_ne(i) {
var x = BigInt(i) != 99n;
if (uceFault_compare_bigint_ne(i) || uceFault_compare_bigint_ne(i))
assertEq(x, false);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_bigint_strictne = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_bigint_strictne'));
function rcompare_bigint_strictne(i) {
var x = BigInt(i) !== 99n;
if (uceFault_compare_bigint_strictne(i) || uceFault_compare_bigint_strictne(i))
assertEq(x, false);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_bigint_lt = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_bigint_lt'));
function rcompare_bigint_lt(i) {
var x = BigInt(i) < 99n;
if (uceFault_compare_bigint_lt(i) || uceFault_compare_bigint_lt(i))
assertEq(x, false);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_bigint_le = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_bigint_le'));
function rcompare_bigint_le(i) {
var x = BigInt(i) <= 99n;
if (uceFault_compare_bigint_le(i) || uceFault_compare_bigint_le(i))
assertEq(x, true);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_bigint_gt = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_bigint_gt'));
function rcompare_bigint_gt(i) {
var x = BigInt(i) > 99n;
if (uceFault_compare_bigint_gt(i) || uceFault_compare_bigint_gt(i))
assertEq(x, false);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_compare_bigint_ge = eval(`(${uceFault})`.replace('uceFault', 'uceFault_compare_bigint_ge'));
function rcompare_bigint_ge(i) {
var x = BigInt(i) >= 99n;
if (uceFault_compare_bigint_ge(i) || uceFault_compare_bigint_ge(i))
assertEq(x, true);
assertRecoveredOnBailout(x, true);
return i;
}
var uceFault_concat_string = eval(`(${uceFault})`.replace('uceFault', 'uceFault_concat_string'));
function rconcat_string(i) {
var x = "s" + i.toString();
@ -1186,7 +1402,7 @@ function rtodouble_value(i) {
if (uceFault_todouble_value(i) || uceFault_todouble_value(i))
assertEq(x, true);
assertRecoveredOnBailout(x, false);
assertRecoveredOnBailout(x, true);
return i;
}
@ -1605,6 +1821,30 @@ for (j = 100 - max; j < 100; j++) {
rmod_object(i);
rnot_number(i);
rnot_object(i);
rcompare_number_eq(i);
rcompare_number_stricteq(i);
rcompare_number_ne(i);
rcompare_number_stricteq(i);
rcompare_number_lt(i);
rcompare_number_le(i);
rcompare_number_gt(i);
rcompare_number_ge(i);
rcompare_string_eq(i);
rcompare_string_stricteq(i);
rcompare_string_ne(i);
rcompare_string_stricteq(i);
rcompare_string_lt(i);
rcompare_string_le(i);
rcompare_string_gt(i);
rcompare_string_ge(i);
rcompare_bigint_eq(i);
rcompare_bigint_stricteq(i);
rcompare_bigint_ne(i);
rcompare_bigint_stricteq(i);
rcompare_bigint_lt(i);
rcompare_bigint_le(i);
rcompare_bigint_gt(i);
rcompare_bigint_ge(i);
rconcat_string(i);
rconcat_number(i);
rstring_length(i);

View file

@ -2737,6 +2737,10 @@ class MCompare : public MBinaryInstruction, public ComparePolicy::Data {
return compareType() == ins->toCompare()->compareType() &&
jsop() == ins->toCompare()->jsop();
}
[[nodiscard]] bool writeRecoverData(
CompactBufferWriter& writer) const override;
bool canRecoverOnBailout() const override { return true; }
};
// Takes a typed value and returns an untyped value.

View file

@ -19,6 +19,7 @@
#include "jit/MIRGraph.h"
#include "jit/VMFunctions.h"
#include "vm/BigIntType.h"
#include "vm/EqualityOperations.h"
#include "vm/Interpreter.h"
#include "vm/Iteration.h"
#include "vm/JSContext.h"
@ -814,6 +815,73 @@ bool RBigIntBitNot::recover(JSContext* cx, SnapshotIterator& iter) const {
return true;
}
bool MCompare::writeRecoverData(CompactBufferWriter& writer) const {
MOZ_ASSERT(canRecoverOnBailout());
writer.writeUnsigned(uint32_t(RInstruction::Recover_Compare));
static_assert(sizeof(JSOp) == sizeof(uint8_t));
writer.writeByte(uint8_t(jsop_));
return true;
}
RCompare::RCompare(CompactBufferReader& reader) {
jsop_ = JSOp(reader.readByte());
MOZ_ASSERT(IsEqualityOp(jsop_) || IsRelationalOp(jsop_));
}
bool RCompare::recover(JSContext* cx, SnapshotIterator& iter) const {
RootedValue lhs(cx, iter.read());
RootedValue rhs(cx, iter.read());
bool result;
switch (jsop_) {
case JSOp::Eq:
case JSOp::Ne:
if (!js::LooselyEqual(cx, lhs, rhs, &result)) {
return false;
}
if (jsop_ == JSOp::Ne) {
result = !result;
}
break;
case JSOp::StrictEq:
case JSOp::StrictNe:
if (!StrictlyEqual(cx, lhs, rhs, &result)) {
return false;
}
if (jsop_ == JSOp::StrictNe) {
result = !result;
}
break;
case JSOp::Lt:
if (!js::LessThan(cx, &lhs, &rhs, &result)) {
return false;
}
break;
case JSOp::Le:
if (!js::LessThanOrEqual(cx, &lhs, &rhs, &result)) {
return false;
}
break;
case JSOp::Gt:
if (!js::GreaterThan(cx, &lhs, &rhs, &result)) {
return false;
}
break;
case JSOp::Ge:
if (!js::GreaterThanOrEqual(cx, &lhs, &rhs, &result)) {
return false;
}
break;
default:
MOZ_CRASH("Unexpected op.");
}
iter.storeInstructionResult(BooleanValue(result));
return true;
}
bool MConcat::writeRecoverData(CompactBufferWriter& writer) const {
MOZ_ASSERT(canRecoverOnBailout());
writer.writeUnsigned(uint32_t(RInstruction::Recover_Concat));

View file

@ -85,6 +85,7 @@ namespace jit {
_(BigIntDecrement) \
_(BigIntNegate) \
_(BigIntBitNot) \
_(Compare) \
_(Concat) \
_(StringLength) \
_(ArgumentsLength) \
@ -475,6 +476,16 @@ class RBigIntBitNot final : public RInstruction {
SnapshotIterator& iter) const override;
};
class RCompare final : public RInstruction {
JSOp jsop_;
public:
RINSTRUCTION_HEADER_NUM_OP_(Compare, 2)
[[nodiscard]] bool recover(JSContext* cx,
SnapshotIterator& iter) const override;
};
class RConcat final : public RInstruction {
public:
RINSTRUCTION_HEADER_NUM_OP_(Concat, 2)