Bug 1642067: Use Baseline inspector to decide if strings can occur in binary arithmetic expressions. r=jandem

Differential Revision: https://phabricator.services.mozilla.com/D78018
This commit is contained in:
André Bargull 2020-06-04 13:28:45 +00:00
Родитель b00311bc4f
Коммит 837b01cad4
2 изменённых файлов: 24 добавлений и 17 удалений

Просмотреть файл

@ -235,19 +235,26 @@ bool BaselineInspector::dimorphicStub(jsbytecode* pc, ICStub** pfirst,
// Process the type guards in the stub in order to reveal the
// underlying operation.
static void SkipBinaryGuards(CacheIRReader& reader) {
static void SkipBinaryGuards(CacheIRReader& reader, bool* sawStringOperand) {
while (true) {
// Two skip opcodes
if (reader.matchOp(CacheOp::GuardToInt32) ||
reader.matchOp(CacheOp::GuardNonDoubleType) ||
reader.matchOp(CacheOp::TruncateDoubleToUInt32) ||
reader.matchOp(CacheOp::GuardToBoolean) ||
reader.matchOp(CacheOp::GuardAndGetNumberFromString) ||
reader.matchOp(CacheOp::GuardAndGetInt32FromString)) {
reader.matchOp(CacheOp::GuardToBoolean)) {
reader.skip(); // Skip over operandId
reader.skip(); // Skip over result/type.
continue;
}
if (reader.matchOp(CacheOp::GuardAndGetNumberFromString) ||
reader.matchOp(CacheOp::GuardAndGetInt32FromString)) {
if (sawStringOperand) {
*sawStringOperand = true;
}
reader.skip(); // Skip over operandId
reader.skip(); // Skip over result.
continue;
}
// One skip
if (reader.matchOp(CacheOp::GuardIsNumber) ||
@ -261,10 +268,11 @@ static void SkipBinaryGuards(CacheIRReader& reader) {
}
}
static MIRType ParseCacheIRStub(ICStub* stub) {
static MIRType ParseCacheIRStub(ICStub* stub,
bool* sawStringOperand = nullptr) {
ICCacheIR_Regular* cacheirStub = stub->toCacheIR_Regular();
CacheIRReader reader(cacheirStub->stubInfo());
SkipBinaryGuards(reader);
SkipBinaryGuards(reader, sawStringOperand);
switch (reader.readOp()) {
case CacheOp::LoadUndefinedResult:
return MIRType::Undefined;
@ -548,11 +556,12 @@ static bool TryToSpecializeBinaryArithOp(ICStub** stubs, uint32_t nstubs,
DebugOnly<bool> sawInt32 = false;
bool sawDouble = false;
bool sawOther = false;
bool sawStringOperand = false;
for (uint32_t i = 0; i < nstubs; i++) {
switch (stubs[i]->kind()) {
case ICStub::CacheIR_Regular:
switch (ParseCacheIRStub(stubs[i])) {
switch (ParseCacheIRStub(stubs[i], &sawStringOperand)) {
case MIRType::Double:
sawDouble = true;
break;
@ -574,6 +583,14 @@ static bool TryToSpecializeBinaryArithOp(ICStub** stubs, uint32_t nstubs,
return false;
}
// Ion doesn't support string operands for binary arithmetic operations, so
// return false when we did see one. We don't test for strings in Ion itself,
// because Ion generally doesn't have sufficient type information when it
// falls back to the baseline inspector.
if (sawStringOperand) {
return false;
}
if (sawDouble) {
*result = MIRType::Double;
return true;

Просмотреть файл

@ -3692,11 +3692,6 @@ AbortReasonOr<Ok> IonBuilder::binaryArithTrySpecializedOnBaselineInspector(
// Try to emit a specialized binary instruction speculating the
// type using the baseline caches.
// Anything complex - strings, symbols, and objects - are not specialized
if (!SimpleArithOperand(left) || !SimpleArithOperand(right)) {
return Ok();
}
MIRType specialization = inspector->expectedBinaryArithSpecialization(pc);
if (specialization == MIRType::None) {
return Ok();
@ -3930,11 +3925,6 @@ AbortReasonOr<Ok> IonBuilder::unaryArithTrySpecializedOnBaselineInspector(
// Try to emit a specialized binary instruction speculating the
// type using the baseline caches.
// Anything complex - strings, symbols, and objects - are not specialized
if (!SimpleArithOperand(value)) {
return Ok();
}
MIRType specialization = inspector->expectedBinaryArithSpecialization(pc);
if (specialization == MIRType::None) {
return Ok();