Issue #2308 & #1240 Follow-up - Introduce new increment and decrement operations. https://bugzilla.mozilla.org/show_bug.cgi?id=1508521

This commit is contained in:
Brian Smith 2023-09-16 05:38:42 -05:00 committed by roytam1
commit 5c8a6c5bb8
13 changed files with 157 additions and 30 deletions

View file

@ -1939,6 +1939,18 @@ BaselineCompiler::emit_JSOP_NEG()
return emitUnaryArith();
}
bool
BaselineCompiler::emit_JSOP_INC()
{
return emitUnaryArith();
}
bool
BaselineCompiler::emit_JSOP_DEC()
{
return emitUnaryArith();
}
bool
BaselineCompiler::emit_JSOP_LT()
{

View file

@ -242,8 +242,10 @@ namespace jit {
_(JSOP_JUMPTARGET) \
_(JSOP_IS_CONSTRUCTING) \
_(JSOP_TRY_DESTRUCTURING_ITERCLOSE) \
_(JSOP_IMPORTMETA) \
_(JSOP_DYNAMIC_IMPORT)
_(JSOP_IMPORTMETA) \
_(JSOP_DYNAMIC_IMPORT) \
_(JSOP_INC) \
_(JSOP_DEC)
class BaselineCompiler : public BaselineCompilerSpecific
{
@ -327,7 +329,7 @@ class BaselineCompiler : public BaselineCompilerSpecific
OPCODE_LIST(EMIT_OP)
#undef EMIT_OP
// JSOP_NEG, JSOP_BITNOT
// JSOP_NEG, JSOP_BITNOT, JSOP_INC, JSOP_DEC
MOZ_MUST_USE bool emitUnaryArith();
// JSOP_BITXOR, JSOP_LSH, JSOP_ADD etc.

View file

@ -719,6 +719,8 @@ IonBuilder::analyzeNewLoopTypes(MBasicBlock* entry, jsbytecode* start, jsbytecod
case JSOP_DIV:
case JSOP_MOD:
case JSOP_NEG:
case JSOP_INC:
case JSOP_DEC:
type = inspector->expectedResultType(last);
break;
case JSOP_BIGINT:
@ -1740,6 +1742,10 @@ IonBuilder::inspectOpcode(JSOp op)
case JSOP_NEG:
return jsop_neg();
case JSOP_INC:
case JSOP_DEC:
return jsop_inc_or_dec(op);
case JSOP_TOSTRING:
return jsop_tostring();
@ -5070,6 +5076,14 @@ IonBuilder::arithTrySharedStub(bool* emitted, JSOp op,
stub = MUnarySharedStub::New(alloc(), right);
break;
case JSOP_INC:
MOZ_ASSERT(op == JSOP_ADD && right->toConstant()->toInt32() == 1);
stub = MUnarySharedStub::New(alloc(), left);
break;
case JSOP_DEC:
MOZ_ASSERT(op == JSOP_SUB && right->toConstant()->toInt32() == 1);
stub = MUnarySharedStub::New(alloc(), left);
break;
case JSOP_ADD:
case JSOP_SUB:
case JSOP_MUL:
@ -5202,6 +5216,29 @@ IonBuilder::jsop_neg()
return jsop_binary_arith(JSOP_MUL, negator, right);
}
bool
IonBuilder::jsop_inc_or_dec(JSOp op)
{
// As above, pass constant without slot traffic.
MConstant* one = MConstant::New(alloc(), Int32Value(1));
current->add(one);
MDefinition* value = current->pop();
switch (op) {
case JSOP_INC:
op = JSOP_ADD;
break;
case JSOP_DEC:
op = JSOP_SUB;
break;
default:
MOZ_CRASH("jsop_inc_or_dec with bad op");
}
return jsop_binary_arith(op, value, one);
}
bool
IonBuilder::jsop_tostring()
{

View file

@ -692,6 +692,7 @@ class IonBuilder
MOZ_MUST_USE bool jsop_pow();
MOZ_MUST_USE bool jsop_pos();
MOZ_MUST_USE bool jsop_neg();
MOZ_MUST_USE bool jsop_inc_or_dec(JSOp op);
MOZ_MUST_USE bool jsop_tostring();
MOZ_MUST_USE bool jsop_setarg(uint32_t arg);
MOZ_MUST_USE bool jsop_defvar(uint32_t index);

View file

@ -1469,21 +1469,33 @@ DoUnaryArithFallback(JSContext* cx, void* payload, ICUnaryArith_Fallback* stub_,
JSOp op = JSOp(*pc);
FallbackICSpew(cx, stub, "UnaryArith(%s)", CodeName[op]);
// The unary operations take a copied val because the original value is needed
// below.
RootedValue valCopy(cx, val);
switch (op) {
case JSOP_BITNOT: {
RootedValue valCopy(cx, val);
if (!BitNot(cx, &valCopy, res)) {
return false;
}
break;
}
case JSOP_NEG: {
// We copy val here because the original value is needed below.
RootedValue valCopy(cx, val);
if (!NegOperation(cx, script, pc, &valCopy, res))
if (!NegOperation(cx, script, pc, &valCopy, res))
return false;
break;
}
case JSOP_INC: {
if (!IncOperation(cx, &valCopy, res)) {
return false;
}
break;
}
case JSOP_DEC: {
if (!DecOperation(cx, &valCopy, res)) {
return false;
}
break;
}
default:
MOZ_CRASH("Unexpected op");
}

View file

@ -1855,6 +1855,8 @@ class ICBinaryArith_DoubleWithInt32 : public ICStub
// UnaryArith
// JSOP_BITNOT
// JSOP_NEG
// JSOP_INC
// JSOP_DEC
class ICUnaryArith_Fallback : public ICFallbackStub
{

View file

@ -4958,7 +4958,7 @@ threeByteOpImmSimd("vblendps", VEX_PD, OP3_BLENDPS_VpsWpsIb, ESCAPE_3A, imm, off
void twoByteOp8(TwoByteOpcodeID opcode, RegisterID rm, RegisterID reg)
{
m_buffer.ensureSpace(MaxInstructionSize);
emitRexIf(byteRegRequiresRex(reg)|byteRegRequiresRex(rm), reg, 0, rm);
emitRexIf(byteRegRequiresRex(reg)||byteRegRequiresRex(rm), reg, 0, rm);
m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
m_buffer.putByteUnchecked(opcode);
registerModRM(rm, reg);
@ -4967,7 +4967,7 @@ threeByteOpImmSimd("vblendps", VEX_PD, OP3_BLENDPS_VpsWpsIb, ESCAPE_3A, imm, off
void twoByteOp8(TwoByteOpcodeID opcode, int32_t offset, RegisterID base, RegisterID reg)
{
m_buffer.ensureSpace(MaxInstructionSize);
emitRexIf(byteRegRequiresRex(reg)|regRequiresRex(base), reg, 0, base);
emitRexIf(byteRegRequiresRex(reg)||regRequiresRex(base), reg, 0, base);
m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
m_buffer.putByteUnchecked(opcode);
memoryModRM(offset, base, reg);
@ -4977,7 +4977,7 @@ threeByteOpImmSimd("vblendps", VEX_PD, OP3_BLENDPS_VpsWpsIb, ESCAPE_3A, imm, off
int scale, RegisterID reg)
{
m_buffer.ensureSpace(MaxInstructionSize);
emitRexIf(byteRegRequiresRex(reg)|regRequiresRex(base)|regRequiresRex(index),
emitRexIf(byteRegRequiresRex(reg)||regRequiresRex(base)||regRequiresRex(index),
reg, index, base);
m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
m_buffer.putByteUnchecked(opcode);
@ -4991,7 +4991,7 @@ threeByteOpImmSimd("vblendps", VEX_PD, OP3_BLENDPS_VpsWpsIb, ESCAPE_3A, imm, off
void twoByteOp8_movx(TwoByteOpcodeID opcode, RegisterID rm, RegisterID reg)
{
m_buffer.ensureSpace(MaxInstructionSize);
emitRexIf(regRequiresRex(reg)|byteRegRequiresRex(rm), reg, 0, rm);
emitRexIf(regRequiresRex(reg)||byteRegRequiresRex(rm), reg, 0, rm);
m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
m_buffer.putByteUnchecked(opcode);
registerModRM(rm, reg);