Index: src/arm/full-codegen-arm.cc |
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc |
index 50ed8b1da738e9cedba1e69e98b56c4b5e05d5b0..07efc8b1206729c1c4f6fc24e56129b3d621f98c 100644 |
--- a/src/arm/full-codegen-arm.cc |
+++ b/src/arm/full-codegen-arm.cc |
@@ -2662,20 +2662,24 @@ void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) { |
// Check that the object is a JS object but take special care of JS |
// functions to make sure they have 'Function' as their class. |
+ // Assume that there are only two callable types, and one of them is at |
+ // either end of the type range for JS object types. Saves extra comparisons. |
+ STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |
__ CompareObjectType(r0, r0, r1, FIRST_SPEC_OBJECT_TYPE); |
// Map is now in r0. |
__ b(lt, &null); |
- |
- // As long as LAST_CALLABLE_SPEC_OBJECT_TYPE is the last instance type, and |
- // FIRST_CALLABLE_SPEC_OBJECT_TYPE comes right after |
- // LAST_NONCALLABLE_SPEC_OBJECT_TYPE, we can avoid checking for the latter. |
- STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE); |
- STATIC_ASSERT(FIRST_CALLABLE_SPEC_OBJECT_TYPE == |
- LAST_NONCALLABLE_SPEC_OBJECT_TYPE + 1); |
- __ cmp(r1, Operand(FIRST_CALLABLE_SPEC_OBJECT_TYPE)); |
- __ b(ge, &function); |
- |
- // Check if the constructor in the map is a function. |
+ STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == |
+ FIRST_SPEC_OBJECT_TYPE + 1); |
+ __ b(eq, &function); |
+ |
+ __ cmp(r1, Operand(LAST_SPEC_OBJECT_TYPE)); |
+ STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == |
+ LAST_SPEC_OBJECT_TYPE - 1); |
+ __ b(eq, &function); |
+ // Assume that there is no larger type. |
+ STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == LAST_TYPE - 1); |
+ |
+ // Check if the constructor in the map is a JS function. |
__ ldr(r0, FieldMemOperand(r0, Map::kConstructorOffset)); |
__ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE); |
__ b(ne, &non_function_constructor); |
@@ -3942,9 +3946,11 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, |
} else if (check->Equals(isolate()->heap()->function_symbol())) { |
__ JumpIfSmi(r0, if_false); |
- __ CompareObjectType(r0, r1, r0, FIRST_CALLABLE_SPEC_OBJECT_TYPE); |
- Split(ge, if_true, if_false, fall_through); |
- |
+ STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |
+ __ CompareObjectType(r0, r0, r1, JS_FUNCTION_TYPE); |
+ __ b(eq, if_true); |
+ __ cmp(r1, Operand(JS_FUNCTION_PROXY_TYPE)); |
+ Split(eq, if_true, if_false, fall_through); |
} else if (check->Equals(isolate()->heap()->object_symbol())) { |
__ JumpIfSmi(r0, if_false); |
if (!FLAG_harmony_typeof) { |