forked from mirrors/gecko-dev
Bug 1062893: Add recover support for MCompare. r=iain
Differential Revision: https://phabricator.services.mozilla.com/D153484
This commit is contained in:
parent
1064b24933
commit
7e937f10b1
4 changed files with 324 additions and 1 deletions
|
|
@ -416,6 +416,222 @@ function rnot_object(i) {
|
||||||
return 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'));
|
var uceFault_concat_string = eval(`(${uceFault})`.replace('uceFault', 'uceFault_concat_string'));
|
||||||
function rconcat_string(i) {
|
function rconcat_string(i) {
|
||||||
var x = "s" + i.toString();
|
var x = "s" + i.toString();
|
||||||
|
|
@ -1186,7 +1402,7 @@ function rtodouble_value(i) {
|
||||||
|
|
||||||
if (uceFault_todouble_value(i) || uceFault_todouble_value(i))
|
if (uceFault_todouble_value(i) || uceFault_todouble_value(i))
|
||||||
assertEq(x, true);
|
assertEq(x, true);
|
||||||
assertRecoveredOnBailout(x, false);
|
assertRecoveredOnBailout(x, true);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1605,6 +1821,30 @@ for (j = 100 - max; j < 100; j++) {
|
||||||
rmod_object(i);
|
rmod_object(i);
|
||||||
rnot_number(i);
|
rnot_number(i);
|
||||||
rnot_object(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_string(i);
|
||||||
rconcat_number(i);
|
rconcat_number(i);
|
||||||
rstring_length(i);
|
rstring_length(i);
|
||||||
|
|
|
||||||
|
|
@ -2737,6 +2737,10 @@ class MCompare : public MBinaryInstruction, public ComparePolicy::Data {
|
||||||
return compareType() == ins->toCompare()->compareType() &&
|
return compareType() == ins->toCompare()->compareType() &&
|
||||||
jsop() == ins->toCompare()->jsop();
|
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.
|
// Takes a typed value and returns an untyped value.
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include "jit/MIRGraph.h"
|
#include "jit/MIRGraph.h"
|
||||||
#include "jit/VMFunctions.h"
|
#include "jit/VMFunctions.h"
|
||||||
#include "vm/BigIntType.h"
|
#include "vm/BigIntType.h"
|
||||||
|
#include "vm/EqualityOperations.h"
|
||||||
#include "vm/Interpreter.h"
|
#include "vm/Interpreter.h"
|
||||||
#include "vm/Iteration.h"
|
#include "vm/Iteration.h"
|
||||||
#include "vm/JSContext.h"
|
#include "vm/JSContext.h"
|
||||||
|
|
@ -814,6 +815,73 @@ bool RBigIntBitNot::recover(JSContext* cx, SnapshotIterator& iter) const {
|
||||||
return true;
|
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 {
|
bool MConcat::writeRecoverData(CompactBufferWriter& writer) const {
|
||||||
MOZ_ASSERT(canRecoverOnBailout());
|
MOZ_ASSERT(canRecoverOnBailout());
|
||||||
writer.writeUnsigned(uint32_t(RInstruction::Recover_Concat));
|
writer.writeUnsigned(uint32_t(RInstruction::Recover_Concat));
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ namespace jit {
|
||||||
_(BigIntDecrement) \
|
_(BigIntDecrement) \
|
||||||
_(BigIntNegate) \
|
_(BigIntNegate) \
|
||||||
_(BigIntBitNot) \
|
_(BigIntBitNot) \
|
||||||
|
_(Compare) \
|
||||||
_(Concat) \
|
_(Concat) \
|
||||||
_(StringLength) \
|
_(StringLength) \
|
||||||
_(ArgumentsLength) \
|
_(ArgumentsLength) \
|
||||||
|
|
@ -475,6 +476,16 @@ class RBigIntBitNot final : public RInstruction {
|
||||||
SnapshotIterator& iter) const override;
|
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 {
|
class RConcat final : public RInstruction {
|
||||||
public:
|
public:
|
||||||
RINSTRUCTION_HEADER_NUM_OP_(Concat, 2)
|
RINSTRUCTION_HEADER_NUM_OP_(Concat, 2)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue