Index: src/x64/lithium-codegen-x64.cc |
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc |
index 887282b2eb20278d74be7ffc801049836778e10e..f26db274575686f9c9ea81d9e19ebacd1e6bd6ed 100644 |
--- a/src/x64/lithium-codegen-x64.cc |
+++ b/src/x64/lithium-codegen-x64.cc |
@@ -3650,30 +3650,45 @@ 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_interval_check()) { |
+ InstanceType first; |
+ InstanceType last; |
+ instr->hydrogen()->GetCheckInterval(&first, &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; |
+ uint8_t tag; |
+ instr->hydrogen()->GetCheckMaskAndTag(&mask, &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()); |
} |
} |
} |