Bug 1626297 - Part 6: Check for string indices in MacroAssembler::convertValueToInt. r=jandem

Ion doesn't use ICs for bit-not `~` with String inputs, which resulted in
`+int32AsString` being noticeably faster than `~~int32AsString`. Handling
string indices makes `~~int32AsString` faster than the IC code, which is what
we'd normally expect.

Drive-by change:
- Reuse `SimpleBitOpOperand()` for `bitnotTrySpecialized()`.

Differential Revision: https://phabricator.services.mozilla.com/D69519

--HG--
extra : moz-landing-system : lando
This commit is contained in:
André Bargull 2020-04-07 08:35:25 +00:00
parent 2d35373468
commit 1c9bdaae93
2 changed files with 28 additions and 13 deletions

View File

@ -3406,6 +3406,11 @@ AbortReasonOr<Ok> IonBuilder::visitTableSwitch() {
void IonBuilder::pushConstant(const Value& v) { current->push(constant(v)); } void IonBuilder::pushConstant(const Value& v) { current->push(constant(v)); }
static inline bool SimpleBitOpOperand(MDefinition* op) {
return !op->mightBeType(MIRType::Object) &&
!op->mightBeType(MIRType::Symbol) && !op->mightBeType(MIRType::BigInt);
}
AbortReasonOr<Ok> IonBuilder::bitnotTrySpecialized(bool* emitted, AbortReasonOr<Ok> IonBuilder::bitnotTrySpecialized(bool* emitted,
MDefinition* input) { MDefinition* input) {
MOZ_ASSERT(*emitted == false); MOZ_ASSERT(*emitted == false);
@ -3413,9 +3418,7 @@ AbortReasonOr<Ok> IonBuilder::bitnotTrySpecialized(bool* emitted,
// Try to emit a specialized bitnot instruction based on the input type // Try to emit a specialized bitnot instruction based on the input type
// of the operand. // of the operand.
if (input->mightBeType(MIRType::Object) || if (!SimpleBitOpOperand(input)) {
input->mightBeType(MIRType::Symbol) ||
input->mightBeType(MIRType::BigInt)) {
return Ok(); return Ok();
} }
@ -3498,11 +3501,6 @@ AbortReasonOr<MBinaryBitwiseInstruction*> IonBuilder::binaryBitOpEmit(
return ins; return ins;
} }
static inline bool SimpleBitOpOperand(MDefinition* op) {
return !op->mightBeType(MIRType::Object) &&
!op->mightBeType(MIRType::Symbol) && !op->mightBeType(MIRType::BigInt);
}
AbortReasonOr<Ok> IonBuilder::binaryBitOpTrySpecialized(bool* emitted, JSOp op, AbortReasonOr<Ok> IonBuilder::binaryBitOpTrySpecialized(bool* emitted, JSOp op,
MDefinition* left, MDefinition* left,
MDefinition* right) { MDefinition* right) {

View File

@ -2273,11 +2273,21 @@ void MacroAssembler::convertValueToInt(
mov(ImmWord(0), output); mov(ImmWord(0), output);
jump(&done); jump(&done);
// Try converting a string into a double, then jump to the double case. // |output| needs to be different from |stringReg| to load string indices.
bool handleStringIndices = handleStrings && output != stringReg;
// First try loading a string index. If that fails, try converting a string
// into a double, then jump to the double case.
Label handleStringIndex;
if (handleStrings) { if (handleStrings) {
bind(&isString); bind(&isString);
unboxString(value, stringReg); unboxString(value, stringReg);
jump(handleStringEntry); if (handleStringIndices) {
loadStringIndexValue(stringReg, output, handleStringEntry);
jump(&handleStringIndex);
} else {
jump(handleStringEntry);
}
} }
// Try converting double into integer. // Try converting double into integer.
@ -2303,9 +2313,16 @@ void MacroAssembler::convertValueToInt(
} }
// Integers can be unboxed. // Integers can be unboxed.
if (isInt32.used()) { if (isInt32.used() || handleStringIndices) {
bind(&isInt32); if (isInt32.used()) {
unboxInt32(value, output); bind(&isInt32);
unboxInt32(value, output);
}
if (handleStringIndices) {
bind(&handleStringIndex);
}
if (behavior == IntConversionBehavior::ClampToUint8) { if (behavior == IntConversionBehavior::ClampToUint8) {
clampIntToUint8(output); clampIntToUint8(output);
} }