| 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());
|
| }
|
| }
|
| }
|
|
|