Index: src/x64/lithium-codegen-x64.cc |
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc |
index 47c77b7e0a812a73d2b40ce04f5e48ef74af38cb..6ca5d893fad490355a39952b9a234c2b6706734c 100644 |
--- a/src/x64/lithium-codegen-x64.cc |
+++ b/src/x64/lithium-codegen-x64.cc |
@@ -3644,30 +3644,42 @@ void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { |
void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { |
Register input = ToRegister(instr->InputAt(0)); |
- InstanceType first = instr->hydrogen()->first(); |
- InstanceType last = instr->hydrogen()->last(); |
__ movq(kScratchRegister, FieldOperand(input, HeapObject::kMapOffset)); |
- // If there is only one type in the interval check for equality. |
- if (first == last) { |
+ if (instr->hydrogen()->is_range()) { |
+ InstanceType first = instr->hydrogen()->first(); |
+ InstanceType last = instr->hydrogen()->last(); |
+ |
__ cmpb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset), |
Immediate(static_cast<int8_t>(first))); |
- DeoptimizeIf(not_equal, instr->environment()); |
- } else if (first == FIRST_STRING_TYPE && last == LAST_STRING_TYPE) { |
- // String has a dedicated bit in instance type. |
- __ testb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset), |
- Immediate(kIsNotStringMask)); |
- DeoptimizeIf(not_zero, instr->environment()); |
+ |
+ // If there is only one type in the interval check for equality. |
+ if (first == last) { |
+ DeoptimizeIf(not_equal, instr->environment()); |
+ } else { |
+ DeoptimizeIf(below, instr->environment()); |
+ // Omit check for the last type. |
+ if (last != LAST_TYPE) { |
+ __ cmpb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset), |
+ Immediate(static_cast<int8_t>(last))); |
+ DeoptimizeIf(above, instr->environment()); |
+ } |
+ } |
} else { |
- __ cmpb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset), |
- Immediate(static_cast<int8_t>(first))); |
- DeoptimizeIf(below, instr->environment()); |
- // Omit check for the last type. |
- if (last != LAST_TYPE) { |
- __ cmpb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset), |
- Immediate(static_cast<int8_t>(last))); |
- DeoptimizeIf(above, instr->environment()); |
+ uint8_t mask = instr->hydrogen()->mask(); |
+ uint8_t tag = instr->hydrogen()->tag(); |
+ if (IsPowerOf2(mask)) { |
+ ASSERT(tag == 0 || IsPowerOf2(tag)); |
+ __ testb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset), |
+ Immediate(mask)); |
+ DeoptimizeIf(tag == 0 ? not_zero : zero, instr->environment()); |
+ } else { |
+ __ movzxbl(kScratchRegister, |
+ FieldOperand(kScratchRegister, Map::kInstanceTypeOffset)); |
+ __ andb(kScratchRegister, Immediate(mask)); |
+ __ cmpb(kScratchRegister, Immediate(tag)); |
+ DeoptimizeIf(not_equal, instr->environment()); |
} |
} |
} |