Index: src/ia32/full-codegen-ia32.cc |
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc |
index 81c9ccb12807f6ed0e9abc77fd3db1f2c4336579..6ad20c001231683e59285ece13f07a981c5d183b 100644 |
--- a/src/ia32/full-codegen-ia32.cc |
+++ b/src/ia32/full-codegen-ia32.cc |
@@ -2647,20 +2647,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); |
__ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, eax); |
// Map is now in eax. |
__ j(below, &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); |
- __ CmpInstanceType(eax, FIRST_CALLABLE_SPEC_OBJECT_TYPE); |
- __ j(above_equal, &function); |
- |
- // Check if the constructor in the map is a function. |
+ STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == |
+ FIRST_SPEC_OBJECT_TYPE + 1); |
+ __ j(equal, &function); |
+ |
+ __ CmpInstanceType(eax, LAST_SPEC_OBJECT_TYPE); |
+ STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == |
+ LAST_SPEC_OBJECT_TYPE - 1); |
+ __ j(equal, &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. |
__ mov(eax, FieldOperand(eax, Map::kConstructorOffset)); |
__ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx); |
__ j(not_equal, &non_function_constructor); |
@@ -3998,8 +4002,11 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, |
Split(not_zero, if_true, if_false, fall_through); |
} else if (check->Equals(isolate()->heap()->function_symbol())) { |
__ JumpIfSmi(eax, if_false); |
- __ CmpObjectType(eax, FIRST_CALLABLE_SPEC_OBJECT_TYPE, edx); |
- Split(above_equal, if_true, if_false, fall_through); |
+ STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |
+ __ CmpObjectType(eax, JS_FUNCTION_TYPE, edx); |
+ __ j(equal, if_true); |
+ __ CmpInstanceType(edx, JS_FUNCTION_PROXY_TYPE); |
+ Split(equal, if_true, if_false, fall_through); |
} else if (check->Equals(isolate()->heap()->object_symbol())) { |
__ JumpIfSmi(eax, if_false); |
if (!FLAG_harmony_typeof) { |