From 8ff91650552af289e9e175da4b8ac6e46afd9fd7 Mon Sep 17 00:00:00 2001 From: "whesse@chromium.org" Date: Thu, 3 Mar 2011 12:16:21 +0000 Subject: [PATCH] Simplify test for typeof x == 'y' on all platforms. Review URL: http://codereview.chromium.org/6606005 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7041 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/full-codegen-arm.cc | 73 +++++++++++++++------------------------- src/arm/lithium-codegen-arm.cc | 55 +++++++++++------------------- src/ia32/full-codegen-ia32.cc | 52 +++++++++++----------------- src/ia32/lithium-codegen-ia32.cc | 35 +++++++------------ src/x64/full-codegen-x64.cc | 43 +++++++++-------------- src/x64/lithium-codegen-x64.cc | 20 +++++------ 6 files changed, 102 insertions(+), 176 deletions(-) diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index 8ad62b0..5f5de3a 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -3977,71 +3977,52 @@ bool FullCodeGenerator::TryLiteralCompare(Token::Value op, PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); if (check->Equals(Heap::number_symbol())) { - __ tst(r0, Operand(kSmiTagMask)); - __ b(eq, if_true); + __ JumpIfSmi(r0, if_true); __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); __ cmp(r0, ip); Split(eq, if_true, if_false, fall_through); } else if (check->Equals(Heap::string_symbol())) { - __ tst(r0, Operand(kSmiTagMask)); - __ b(eq, if_false); + __ JumpIfSmi(r0, if_false); // Check for undetectable objects => false. - __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); + __ CompareObjectType(r0, r0, r1, FIRST_NONSTRING_TYPE); + __ b(ge, if_false); __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); - __ and_(r1, r1, Operand(1 << Map::kIsUndetectable)); - __ cmp(r1, Operand(1 << Map::kIsUndetectable)); - __ b(eq, if_false); - __ ldrb(r1, FieldMemOperand(r0, Map::kInstanceTypeOffset)); - __ cmp(r1, Operand(FIRST_NONSTRING_TYPE)); - Split(lt, if_true, if_false, fall_through); + __ tst(r1, Operand(1 << Map::kIsUndetectable)); + Split(eq, if_true, if_false, fall_through); } else if (check->Equals(Heap::boolean_symbol())) { - __ LoadRoot(ip, Heap::kTrueValueRootIndex); - __ cmp(r0, ip); + __ CompareRoot(r0, Heap::kTrueValueRootIndex); __ b(eq, if_true); - __ LoadRoot(ip, Heap::kFalseValueRootIndex); - __ cmp(r0, ip); + __ CompareRoot(r0, Heap::kFalseValueRootIndex); Split(eq, if_true, if_false, fall_through); } else if (check->Equals(Heap::undefined_symbol())) { - __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); - __ cmp(r0, ip); + __ CompareRoot(r0, Heap::kUndefinedValueRootIndex); __ b(eq, if_true); - __ tst(r0, Operand(kSmiTagMask)); - __ b(eq, if_false); + __ JumpIfSmi(r0, if_false); // Check for undetectable objects => true. __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); - __ and_(r1, r1, Operand(1 << Map::kIsUndetectable)); - __ cmp(r1, Operand(1 << Map::kIsUndetectable)); - Split(eq, if_true, if_false, fall_through); + __ tst(r1, Operand(1 << Map::kIsUndetectable)); + Split(ne, if_true, if_false, fall_through); + } else if (check->Equals(Heap::function_symbol())) { - __ tst(r0, Operand(kSmiTagMask)); - __ b(eq, if_false); - __ CompareObjectType(r0, r1, r0, JS_FUNCTION_TYPE); - __ b(eq, if_true); - // Regular expressions => 'function' (they are callable). - __ CompareInstanceType(r1, r0, JS_REGEXP_TYPE); - Split(eq, if_true, if_false, fall_through); + __ JumpIfSmi(r0, if_false); + __ CompareObjectType(r0, r1, r0, FIRST_FUNCTION_CLASS_TYPE); + Split(ge, if_true, if_false, fall_through); + } else if (check->Equals(Heap::object_symbol())) { - __ tst(r0, Operand(kSmiTagMask)); - __ b(eq, if_false); - __ LoadRoot(ip, Heap::kNullValueRootIndex); - __ cmp(r0, ip); + __ JumpIfSmi(r0, if_false); + __ CompareRoot(r0, Heap::kNullValueRootIndex); __ b(eq, if_true); - // Regular expressions => 'function', not 'object'. - __ CompareObjectType(r0, r1, r0, JS_REGEXP_TYPE); - __ b(eq, if_false); - // Check for undetectable objects => false. - __ ldrb(r0, FieldMemOperand(r1, Map::kBitFieldOffset)); - __ and_(r0, r0, Operand(1 << Map::kIsUndetectable)); - __ cmp(r0, Operand(1 << Map::kIsUndetectable)); - __ b(eq, if_false); // Check for JS objects => true. - __ ldrb(r0, FieldMemOperand(r1, Map::kInstanceTypeOffset)); - __ cmp(r0, Operand(FIRST_JS_OBJECT_TYPE)); - __ b(lt, if_false); - __ cmp(r0, Operand(LAST_JS_OBJECT_TYPE)); - Split(le, if_true, if_false, fall_through); + __ CompareObjectType(r0, r0, r1, FIRST_JS_OBJECT_TYPE); + __ b(lo, if_false); + __ CompareInstanceType(r0, r1, FIRST_FUNCTION_CLASS_TYPE); + __ b(hs, if_false); + // Check for undetectable objects => false. + __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); + __ tst(r1, Operand(1 << Map::kIsUndetectable)); + Split(eq, if_true, if_false, fall_through); } else { if (if_false != fall_through) __ jmp(if_false); } diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index 9e046e7..ab58600 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -3672,37 +3672,30 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, Condition final_branch_condition = kNoCondition; Register scratch = scratch0(); if (type_name->Equals(Heap::number_symbol())) { - __ tst(input, Operand(kSmiTagMask)); - __ b(eq, true_label); + __ JumpIfSmi(input, true_label); __ ldr(input, FieldMemOperand(input, HeapObject::kMapOffset)); __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); __ cmp(input, Operand(ip)); final_branch_condition = eq; } else if (type_name->Equals(Heap::string_symbol())) { - __ tst(input, Operand(kSmiTagMask)); - __ b(eq, false_label); - __ ldr(input, FieldMemOperand(input, HeapObject::kMapOffset)); + __ JumpIfSmi(input, false_label); + __ CompareObjectType(input, input, scratch, FIRST_NONSTRING_TYPE); + __ b(ge, false_label); __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); __ tst(ip, Operand(1 << Map::kIsUndetectable)); - __ b(ne, false_label); - __ CompareInstanceType(input, scratch, FIRST_NONSTRING_TYPE); - final_branch_condition = lo; + final_branch_condition = eq; } else if (type_name->Equals(Heap::boolean_symbol())) { - __ LoadRoot(ip, Heap::kTrueValueRootIndex); - __ cmp(input, ip); + __ CompareRoot(input, Heap::kTrueValueRootIndex); __ b(eq, true_label); - __ LoadRoot(ip, Heap::kFalseValueRootIndex); - __ cmp(input, ip); + __ CompareRoot(input, Heap::kFalseValueRootIndex); final_branch_condition = eq; } else if (type_name->Equals(Heap::undefined_symbol())) { - __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); - __ cmp(input, ip); + __ CompareRoot(input, Heap::kUndefinedValueRootIndex); __ b(eq, true_label); - __ tst(input, Operand(kSmiTagMask)); - __ b(eq, false_label); + __ JumpIfSmi(input, false_label); // Check for undetectable objects => true. __ ldr(input, FieldMemOperand(input, HeapObject::kMapOffset)); __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); @@ -3710,32 +3703,22 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, final_branch_condition = ne; } else if (type_name->Equals(Heap::function_symbol())) { - __ tst(input, Operand(kSmiTagMask)); - __ b(eq, false_label); - __ CompareObjectType(input, input, scratch, JS_FUNCTION_TYPE); - __ b(eq, true_label); - // Regular expressions => 'function' (they are callable). - __ CompareInstanceType(input, scratch, JS_REGEXP_TYPE); - final_branch_condition = eq; + __ JumpIfSmi(input, false_label); + __ CompareObjectType(input, input, scratch, FIRST_FUNCTION_CLASS_TYPE); + final_branch_condition = ge; } else if (type_name->Equals(Heap::object_symbol())) { - __ tst(input, Operand(kSmiTagMask)); - __ b(eq, false_label); - __ LoadRoot(ip, Heap::kNullValueRootIndex); - __ cmp(input, ip); + __ JumpIfSmi(input, false_label); + __ CompareRoot(input, Heap::kNullValueRootIndex); __ b(eq, true_label); - // Regular expressions => 'function', not 'object'. - __ CompareObjectType(input, input, scratch, JS_REGEXP_TYPE); - __ b(eq, false_label); + __ CompareObjectType(input, input, scratch, FIRST_JS_OBJECT_TYPE); + __ b(lo, false_label); + __ CompareInstanceType(input, scratch, FIRST_FUNCTION_CLASS_TYPE); + __ b(hs, false_label); // Check for undetectable objects => false. __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); __ tst(ip, Operand(1 << Map::kIsUndetectable)); - __ b(ne, false_label); - // Check for JS objects => true. - __ CompareInstanceType(input, scratch, FIRST_JS_OBJECT_TYPE); - __ b(lo, false_label); - __ CompareInstanceType(input, scratch, LAST_JS_OBJECT_TYPE); - final_branch_condition = ls; + final_branch_condition = eq; } else { final_branch_condition = ne; diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc index 67e0e8f..9a7d41a 100644 --- a/src/ia32/full-codegen-ia32.cc +++ b/src/ia32/full-codegen-ia32.cc @@ -3936,21 +3936,18 @@ bool FullCodeGenerator::TryLiteralCompare(Token::Value op, PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); if (check->Equals(Heap::number_symbol())) { - __ test(eax, Immediate(kSmiTagMask)); - __ j(zero, if_true); + __ JumpIfSmi(eax, if_true); __ cmp(FieldOperand(eax, HeapObject::kMapOffset), Factory::heap_number_map()); Split(equal, if_true, if_false, fall_through); } else if (check->Equals(Heap::string_symbol())) { - __ test(eax, Immediate(kSmiTagMask)); - __ j(zero, if_false); + __ JumpIfSmi(eax, if_false); + __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edx); + __ j(above_equal, if_false); // Check for undetectable objects => false. - __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); - __ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset)); - __ test(ecx, Immediate(1 << Map::kIsUndetectable)); - __ j(not_zero, if_false); - __ CmpInstanceType(edx, FIRST_NONSTRING_TYPE); - Split(below, if_true, if_false, fall_through); + __ test_b(FieldOperand(edx, Map::kBitFieldOffset), + 1 << Map::kIsUndetectable); + Split(zero, if_true, if_false, fall_through); } else if (check->Equals(Heap::boolean_symbol())) { __ cmp(eax, Factory::true_value()); __ j(equal, if_true); @@ -3959,39 +3956,28 @@ bool FullCodeGenerator::TryLiteralCompare(Token::Value op, } else if (check->Equals(Heap::undefined_symbol())) { __ cmp(eax, Factory::undefined_value()); __ j(equal, if_true); - __ test(eax, Immediate(kSmiTagMask)); - __ j(zero, if_false); + __ JumpIfSmi(eax, if_false); // Check for undetectable objects => true. __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); __ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset)); __ test(ecx, Immediate(1 << Map::kIsUndetectable)); Split(not_zero, if_true, if_false, fall_through); } else if (check->Equals(Heap::function_symbol())) { - __ test(eax, Immediate(kSmiTagMask)); - __ j(zero, if_false); - __ CmpObjectType(eax, JS_FUNCTION_TYPE, edx); - __ j(equal, if_true); - // Regular expressions => 'function' (they are callable). - __ CmpInstanceType(edx, JS_REGEXP_TYPE); - Split(equal, if_true, if_false, fall_through); + __ JumpIfSmi(eax, if_false); + __ CmpObjectType(eax, FIRST_FUNCTION_CLASS_TYPE, edx); + Split(above_equal, if_true, if_false, fall_through); } else if (check->Equals(Heap::object_symbol())) { - __ test(eax, Immediate(kSmiTagMask)); - __ j(zero, if_false); + __ JumpIfSmi(eax, if_false); __ cmp(eax, Factory::null_value()); __ j(equal, if_true); - // Regular expressions => 'function', not 'object'. - __ CmpObjectType(eax, JS_REGEXP_TYPE, edx); - __ j(equal, if_false); + __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, edx); + __ j(below, if_false); + __ CmpInstanceType(edx, FIRST_FUNCTION_CLASS_TYPE); + __ j(above_equal, if_false); // Check for undetectable objects => false. - __ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset)); - __ test(ecx, Immediate(1 << Map::kIsUndetectable)); - __ j(not_zero, if_false); - // Check for JS objects => true. - __ movzx_b(ecx, FieldOperand(edx, Map::kInstanceTypeOffset)); - __ cmp(ecx, FIRST_JS_OBJECT_TYPE); - __ j(less, if_false); - __ cmp(ecx, LAST_JS_OBJECT_TYPE); - Split(less_equal, if_true, if_false, fall_through); + __ test_b(FieldOperand(edx, Map::kBitFieldOffset), + 1 << Map::kIsUndetectable); + Split(zero, if_true, if_false, fall_through); } else { if (if_false != fall_through) __ jmp(if_false); } diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index d84354f..6c34394 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -3702,21 +3702,18 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, Handle type_name) { Condition final_branch_condition = no_condition; if (type_name->Equals(Heap::number_symbol())) { - __ test(input, Immediate(kSmiTagMask)); - __ j(zero, true_label); + __ JumpIfSmi(input, true_label); __ cmp(FieldOperand(input, HeapObject::kMapOffset), Factory::heap_number_map()); final_branch_condition = equal; } else if (type_name->Equals(Heap::string_symbol())) { - __ test(input, Immediate(kSmiTagMask)); - __ j(zero, false_label); - __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); + __ JumpIfSmi(input, false_label); + __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); + __ j(above_equal, false_label); __ test_b(FieldOperand(input, Map::kBitFieldOffset), 1 << Map::kIsUndetectable); - __ j(not_zero, false_label); - __ CmpInstanceType(input, FIRST_NONSTRING_TYPE); - final_branch_condition = below; + final_branch_condition = zero; } else if (type_name->Equals(Heap::boolean_symbol())) { __ cmp(input, Factory::true_value()); @@ -3727,8 +3724,7 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, } else if (type_name->Equals(Heap::undefined_symbol())) { __ cmp(input, Factory::undefined_value()); __ j(equal, true_label); - __ test(input, Immediate(kSmiTagMask)); - __ j(zero, false_label); + __ JumpIfSmi(input, false_label); // Check for undetectable objects => true. __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); __ test_b(FieldOperand(input, Map::kBitFieldOffset), @@ -3736,8 +3732,7 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, final_branch_condition = not_zero; } else if (type_name->Equals(Heap::function_symbol())) { - __ test(input, Immediate(kSmiTagMask)); - __ j(zero, false_label); + __ JumpIfSmi(input, false_label); __ CmpObjectType(input, JS_FUNCTION_TYPE, input); __ j(equal, true_label); // Regular expressions => 'function' (they are callable). @@ -3745,22 +3740,18 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, final_branch_condition = equal; } else if (type_name->Equals(Heap::object_symbol())) { - __ test(input, Immediate(kSmiTagMask)); - __ j(zero, false_label); + __ JumpIfSmi(input, false_label); __ cmp(input, Factory::null_value()); __ j(equal, true_label); // Regular expressions => 'function', not 'object'. - __ CmpObjectType(input, JS_REGEXP_TYPE, input); - __ j(equal, false_label); + __ CmpObjectType(input, FIRST_JS_OBJECT_TYPE, input); + __ j(below, false_label); + __ CmpInstanceType(input, FIRST_FUNCTION_CLASS_TYPE); + __ j(above_equal, false_label); // Check for undetectable objects => false. __ test_b(FieldOperand(input, Map::kBitFieldOffset), 1 << Map::kIsUndetectable); - __ j(not_zero, false_label); - // Check for JS objects => true. - __ CmpInstanceType(input, FIRST_JS_OBJECT_TYPE); - __ j(below, false_label); - __ CmpInstanceType(input, LAST_JS_OBJECT_TYPE); - final_branch_condition = below_equal; + final_branch_condition = zero; } else { final_branch_condition = not_equal; diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index 0ad6ec2..780f4b0 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -3640,21 +3640,18 @@ bool FullCodeGenerator::TryLiteralCompare(Token::Value op, PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); if (check->Equals(Heap::number_symbol())) { - Condition is_smi = masm_->CheckSmi(rax); - __ j(is_smi, if_true); + __ JumpIfSmi(rax, if_true); __ movq(rax, FieldOperand(rax, HeapObject::kMapOffset)); __ CompareRoot(rax, Heap::kHeapNumberMapRootIndex); Split(equal, if_true, if_false, fall_through); } else if (check->Equals(Heap::string_symbol())) { - Condition is_smi = masm_->CheckSmi(rax); - __ j(is_smi, if_false); + __ JumpIfSmi(rax, if_false); // Check for undetectable objects => false. - __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset)); + __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdx); + __ j(above_equal, if_false); __ testb(FieldOperand(rdx, Map::kBitFieldOffset), Immediate(1 << Map::kIsUndetectable)); - __ j(not_zero, if_false); - __ CmpInstanceType(rdx, FIRST_NONSTRING_TYPE); - Split(below, if_true, if_false, fall_through); + Split(zero, if_true, if_false, fall_through); } else if (check->Equals(Heap::boolean_symbol())) { __ CompareRoot(rax, Heap::kTrueValueRootIndex); __ j(equal, if_true); @@ -3663,38 +3660,28 @@ bool FullCodeGenerator::TryLiteralCompare(Token::Value op, } else if (check->Equals(Heap::undefined_symbol())) { __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); __ j(equal, if_true); - Condition is_smi = masm_->CheckSmi(rax); - __ j(is_smi, if_false); + __ JumpIfSmi(rax, if_false); // Check for undetectable objects => true. __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset)); __ testb(FieldOperand(rdx, Map::kBitFieldOffset), Immediate(1 << Map::kIsUndetectable)); Split(not_zero, if_true, if_false, fall_through); } else if (check->Equals(Heap::function_symbol())) { - Condition is_smi = masm_->CheckSmi(rax); - __ j(is_smi, if_false); - __ CmpObjectType(rax, JS_FUNCTION_TYPE, rdx); - __ j(equal, if_true); - // Regular expressions => 'function' (they are callable). - __ CmpInstanceType(rdx, JS_REGEXP_TYPE); - Split(equal, if_true, if_false, fall_through); + __ JumpIfSmi(rax, if_false); + __ CmpObjectType(rax, FIRST_FUNCTION_CLASS_TYPE, rdx); + Split(above_equal, if_true, if_false, fall_through); } else if (check->Equals(Heap::object_symbol())) { - Condition is_smi = masm_->CheckSmi(rax); - __ j(is_smi, if_false); + __ JumpIfSmi(rax, if_false); __ CompareRoot(rax, Heap::kNullValueRootIndex); __ j(equal, if_true); - // Regular expressions => 'function', not 'object'. - __ CmpObjectType(rax, JS_REGEXP_TYPE, rdx); - __ j(equal, if_false); + __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rdx); + __ j(below, if_false); + __ CmpInstanceType(rdx, FIRST_FUNCTION_CLASS_TYPE); + __ j(above_equal, if_false); // Check for undetectable objects => false. __ testb(FieldOperand(rdx, Map::kBitFieldOffset), Immediate(1 << Map::kIsUndetectable)); - __ j(not_zero, if_false); - // Check for JS objects => true. - __ CmpInstanceType(rdx, FIRST_JS_OBJECT_TYPE); - __ j(below, if_false); - __ CmpInstanceType(rdx, LAST_JS_OBJECT_TYPE); - Split(below_equal, if_true, if_false, fall_through); + Split(zero, if_true, if_false, fall_through); } else { if (if_false != fall_through) __ jmp(if_false); } diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 2cbab4b..1007784 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -3480,12 +3480,11 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, } else if (type_name->Equals(Heap::string_symbol())) { __ JumpIfSmi(input, false_label); - __ movq(input, FieldOperand(input, HeapObject::kMapOffset)); + __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); + __ j(above_equal, false_label); __ testb(FieldOperand(input, Map::kBitFieldOffset), Immediate(1 << Map::kIsUndetectable)); - __ j(not_zero, false_label); - __ CmpInstanceType(input, FIRST_NONSTRING_TYPE); - final_branch_condition = below; + final_branch_condition = zero; } else if (type_name->Equals(Heap::boolean_symbol())) { __ CompareRoot(input, Heap::kTrueValueRootIndex); @@ -3510,17 +3509,16 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, } else if (type_name->Equals(Heap::object_symbol())) { __ JumpIfSmi(input, false_label); - __ Cmp(input, Factory::null_value()); + __ CompareRoot(input, Heap::kNullValueRootIndex); __ j(equal, true_label); + __ CmpObjectType(input, FIRST_JS_OBJECT_TYPE, input); + __ j(below, false_label); + __ CmpInstanceType(input, FIRST_FUNCTION_CLASS_TYPE); + __ j(above_equal, false_label); // Check for undetectable objects => false. __ testb(FieldOperand(input, Map::kBitFieldOffset), Immediate(1 << Map::kIsUndetectable)); - __ j(not_zero, false_label); - // Check for JS objects that are not RegExp or Function => true. - __ CmpInstanceType(input, FIRST_JS_OBJECT_TYPE); - __ j(below, false_label); - __ CmpInstanceType(input, FIRST_FUNCTION_CLASS_TYPE); - final_branch_condition = below_equal; + final_branch_condition = zero; } else { final_branch_condition = never; -- 2.7.4