| OLD | NEW | 
|---|
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without | 
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are | 
| 4 // met: | 4 // met: | 
| 5 // | 5 // | 
| 6 //     * Redistributions of source code must retain the above copyright | 6 //     * Redistributions of source code must retain the above copyright | 
| 7 //       notice, this list of conditions and the following disclaimer. | 7 //       notice, this list of conditions and the following disclaimer. | 
| 8 //     * Redistributions in binary form must reproduce the above | 8 //     * Redistributions in binary form must reproduce the above | 
| 9 //       copyright notice, this list of conditions and the following | 9 //       copyright notice, this list of conditions and the following | 
| 10 //       disclaimer in the documentation and/or other materials provided | 10 //       disclaimer in the documentation and/or other materials provided | 
| (...skipping 2967 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2978 | 2978 | 
| 2979 | 2979 | 
| 2980 void CodeGenerator::VisitCompareOperation(CompareOperation* node) { | 2980 void CodeGenerator::VisitCompareOperation(CompareOperation* node) { | 
| 2981   Comment cmnt(masm_, "[ CompareOperation"); | 2981   Comment cmnt(masm_, "[ CompareOperation"); | 
| 2982 | 2982 | 
| 2983   // Get the expressions from the node. | 2983   // Get the expressions from the node. | 
| 2984   Expression* left = node->left(); | 2984   Expression* left = node->left(); | 
| 2985   Expression* right = node->right(); | 2985   Expression* right = node->right(); | 
| 2986   Token::Value op = node->op(); | 2986   Token::Value op = node->op(); | 
| 2987 | 2987 | 
| 2988   // NOTE: To make null checks efficient, we check if either left or | 2988   // To make null checks efficient, we check if either left or right is the | 
| 2989   // right is the literal 'null'. If so, we optimize the code by | 2989   // literal 'null'. If so, we optimize the code by inlining a null check | 
| 2990   // inlining a null check instead of calling the (very) general | 2990   // instead of calling the (very) general runtime routine for checking | 
| 2991   // runtime routine for checking equality. | 2991   // equality. | 
| 2992 |  | 
| 2993   if (op == Token::EQ || op == Token::EQ_STRICT) { | 2992   if (op == Token::EQ || op == Token::EQ_STRICT) { | 
| 2994     bool left_is_null = | 2993     bool left_is_null = | 
| 2995       left->AsLiteral() != NULL && left->AsLiteral()->IsNull(); | 2994         left->AsLiteral() != NULL && left->AsLiteral()->IsNull(); | 
| 2996     bool right_is_null = | 2995     bool right_is_null = | 
| 2997       right->AsLiteral() != NULL && right->AsLiteral()->IsNull(); | 2996         right->AsLiteral() != NULL && right->AsLiteral()->IsNull(); | 
| 2998     // The 'null' value is only equal to 'null' or 'undefined'. | 2997     // The 'null' value can only be equal to 'null' or 'undefined'. | 
| 2999     if (left_is_null || right_is_null) { | 2998     if (left_is_null || right_is_null) { | 
| 3000       Load(left_is_null ? right : left); | 2999       Load(left_is_null ? right : left); | 
| 3001       Label exit, undetectable; |  | 
| 3002       frame_->Pop(r0); | 3000       frame_->Pop(r0); | 
| 3003       __ cmp(r0, Operand(Factory::null_value())); | 3001       __ cmp(r0, Operand(Factory::null_value())); | 
| 3004 | 3002 | 
| 3005       // The 'null' value is only equal to 'undefined' if using | 3003       // The 'null' value is only equal to 'undefined' if using non-strict | 
| 3006       // non-strict comparisons. | 3004       // comparisons. | 
| 3007       if (op != Token::EQ_STRICT) { | 3005       if (op != Token::EQ_STRICT) { | 
| 3008         __ b(eq, &exit); | 3006         __ b(eq, true_target()); | 
|  | 3007 | 
| 3009         __ cmp(r0, Operand(Factory::undefined_value())); | 3008         __ cmp(r0, Operand(Factory::undefined_value())); | 
|  | 3009         __ b(eq, true_target()); | 
| 3010 | 3010 | 
| 3011         // NOTE: it can be undetectable object. |  | 
| 3012         __ b(eq, &exit); |  | 
| 3013         __ tst(r0, Operand(kSmiTagMask)); | 3011         __ tst(r0, Operand(kSmiTagMask)); | 
|  | 3012         __ b(eq, false_target()); | 
| 3014 | 3013 | 
| 3015         __ b(ne, &undetectable); | 3014         // It can be an undetectable object. | 
| 3016         __ b(false_target()); | 3015         __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); | 
| 3017 | 3016         __ ldrb(r0, FieldMemOperand(r0, Map::kBitFieldOffset)); | 
| 3018         __ bind(&undetectable); | 3017         __ and_(r0, r0, Operand(1 << Map::kIsUndetectable)); | 
| 3019         __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); | 3018         __ cmp(r0, Operand(1 << Map::kIsUndetectable)); | 
| 3020         __ ldrb(r2, FieldMemOperand(r1, Map::kBitFieldOffset)); |  | 
| 3021         __ and_(r2, r2, Operand(1 << Map::kIsUndetectable)); |  | 
| 3022         __ cmp(r2, Operand(1 << Map::kIsUndetectable)); |  | 
| 3023       } | 3019       } | 
| 3024 | 3020 | 
| 3025       __ bind(&exit); |  | 
| 3026 |  | 
| 3027       cc_reg_ = eq; | 3021       cc_reg_ = eq; | 
| 3028       return; | 3022       return; | 
| 3029     } | 3023     } | 
| 3030   } | 3024   } | 
| 3031 | 3025 | 
| 3032 | 3026   // To make typeof testing for natives implemented in JavaScript really | 
| 3033   // NOTE: To make typeof testing for natives implemented in | 3027   // efficient, we generate special code for expressions of the form: | 
| 3034   // JavaScript really efficient, we generate special code for | 3028   // 'typeof <expression> == <string>'. | 
| 3035   // expressions of the form: 'typeof <expression> == <string>'. |  | 
| 3036 |  | 
| 3037   UnaryOperation* operation = left->AsUnaryOperation(); | 3029   UnaryOperation* operation = left->AsUnaryOperation(); | 
| 3038   if ((op == Token::EQ || op == Token::EQ_STRICT) && | 3030   if ((op == Token::EQ || op == Token::EQ_STRICT) && | 
| 3039       (operation != NULL && operation->op() == Token::TYPEOF) && | 3031       (operation != NULL && operation->op() == Token::TYPEOF) && | 
| 3040       (right->AsLiteral() != NULL && | 3032       (right->AsLiteral() != NULL && | 
| 3041        right->AsLiteral()->handle()->IsString())) { | 3033        right->AsLiteral()->handle()->IsString())) { | 
| 3042     Handle<String> check(String::cast(*right->AsLiteral()->handle())); | 3034     Handle<String> check(String::cast(*right->AsLiteral()->handle())); | 
| 3043 | 3035 | 
| 3044     // Load the operand, move it to register r1. | 3036     // Load the operand, move it to register r1. | 
| 3045     LoadTypeofExpression(operation->expression()); | 3037     LoadTypeofExpression(operation->expression()); | 
| 3046     frame_->Pop(r1); | 3038     frame_->Pop(r1); | 
| 3047 | 3039 | 
| 3048     if (check->Equals(Heap::number_symbol())) { | 3040     if (check->Equals(Heap::number_symbol())) { | 
| 3049       __ tst(r1, Operand(kSmiTagMask)); | 3041       __ tst(r1, Operand(kSmiTagMask)); | 
| 3050       __ b(eq, true_target()); | 3042       __ b(eq, true_target()); | 
| 3051       __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset)); | 3043       __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset)); | 
| 3052       __ cmp(r1, Operand(Factory::heap_number_map())); | 3044       __ cmp(r1, Operand(Factory::heap_number_map())); | 
| 3053       cc_reg_ = eq; | 3045       cc_reg_ = eq; | 
| 3054 | 3046 | 
| 3055     } else if (check->Equals(Heap::string_symbol())) { | 3047     } else if (check->Equals(Heap::string_symbol())) { | 
| 3056       __ tst(r1, Operand(kSmiTagMask)); | 3048       __ tst(r1, Operand(kSmiTagMask)); | 
| 3057       __ b(eq, false_target()); | 3049       __ b(eq, false_target()); | 
| 3058 | 3050 | 
| 3059       __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset)); | 3051       __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset)); | 
| 3060 | 3052 | 
| 3061       // NOTE: it might be an undetectable string object | 3053       // It can be an undetectable string object. | 
| 3062       __ ldrb(r2, FieldMemOperand(r1, Map::kBitFieldOffset)); | 3054       __ ldrb(r2, FieldMemOperand(r1, Map::kBitFieldOffset)); | 
| 3063       __ and_(r2, r2, Operand(1 << Map::kIsUndetectable)); | 3055       __ and_(r2, r2, Operand(1 << Map::kIsUndetectable)); | 
| 3064       __ cmp(r2, Operand(1 << Map::kIsUndetectable)); | 3056       __ cmp(r2, Operand(1 << Map::kIsUndetectable)); | 
| 3065       __ b(eq, false_target()); | 3057       __ b(eq, false_target()); | 
| 3066 | 3058 | 
| 3067       __ ldrb(r2, FieldMemOperand(r1, Map::kInstanceTypeOffset)); | 3059       __ ldrb(r2, FieldMemOperand(r1, Map::kInstanceTypeOffset)); | 
| 3068       __ cmp(r2, Operand(FIRST_NONSTRING_TYPE)); | 3060       __ cmp(r2, Operand(FIRST_NONSTRING_TYPE)); | 
| 3069       cc_reg_ = lt; | 3061       cc_reg_ = lt; | 
| 3070 | 3062 | 
| 3071     } else if (check->Equals(Heap::boolean_symbol())) { | 3063     } else if (check->Equals(Heap::boolean_symbol())) { | 
| 3072       __ cmp(r1, Operand(Factory::true_value())); | 3064       __ cmp(r1, Operand(Factory::true_value())); | 
| 3073       __ b(eq, true_target()); | 3065       __ b(eq, true_target()); | 
| 3074       __ cmp(r1, Operand(Factory::false_value())); | 3066       __ cmp(r1, Operand(Factory::false_value())); | 
| 3075       cc_reg_ = eq; | 3067       cc_reg_ = eq; | 
| 3076 | 3068 | 
| 3077     } else if (check->Equals(Heap::undefined_symbol())) { | 3069     } else if (check->Equals(Heap::undefined_symbol())) { | 
| 3078       __ cmp(r1, Operand(Factory::undefined_value())); | 3070       __ cmp(r1, Operand(Factory::undefined_value())); | 
| 3079       __ b(eq, true_target()); | 3071       __ b(eq, true_target()); | 
| 3080 | 3072 | 
| 3081       __ tst(r1, Operand(kSmiTagMask)); | 3073       __ tst(r1, Operand(kSmiTagMask)); | 
| 3082       __ b(eq, false_target()); | 3074       __ b(eq, false_target()); | 
| 3083 | 3075 | 
| 3084       // NOTE: it can be undetectable object. | 3076       // It can be an undetectable object. | 
| 3085       __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset)); | 3077       __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset)); | 
| 3086       __ ldrb(r2, FieldMemOperand(r1, Map::kBitFieldOffset)); | 3078       __ ldrb(r2, FieldMemOperand(r1, Map::kBitFieldOffset)); | 
| 3087       __ and_(r2, r2, Operand(1 << Map::kIsUndetectable)); | 3079       __ and_(r2, r2, Operand(1 << Map::kIsUndetectable)); | 
| 3088       __ cmp(r2, Operand(1 << Map::kIsUndetectable)); | 3080       __ cmp(r2, Operand(1 << Map::kIsUndetectable)); | 
| 3089 | 3081 | 
| 3090       cc_reg_ = eq; | 3082       cc_reg_ = eq; | 
| 3091 | 3083 | 
| 3092     } else if (check->Equals(Heap::function_symbol())) { | 3084     } else if (check->Equals(Heap::function_symbol())) { | 
| 3093       __ tst(r1, Operand(kSmiTagMask)); | 3085       __ tst(r1, Operand(kSmiTagMask)); | 
| 3094       __ b(eq, false_target()); | 3086       __ b(eq, false_target()); | 
| 3095       __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset)); | 3087       __ ldr(r1, FieldMemOperand(r1, HeapObject::kMapOffset)); | 
| 3096       __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset)); | 3088       __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset)); | 
| 3097       __ cmp(r1, Operand(JS_FUNCTION_TYPE)); | 3089       __ cmp(r1, Operand(JS_FUNCTION_TYPE)); | 
| 3098       cc_reg_ = eq; | 3090       cc_reg_ = eq; | 
| 3099 | 3091 | 
| 3100     } else if (check->Equals(Heap::object_symbol())) { | 3092     } else if (check->Equals(Heap::object_symbol())) { | 
| 3101       __ tst(r1, Operand(kSmiTagMask)); | 3093       __ tst(r1, Operand(kSmiTagMask)); | 
| 3102       __ b(eq, false_target()); | 3094       __ b(eq, false_target()); | 
| 3103 | 3095 | 
| 3104       __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); | 3096       __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); | 
| 3105       __ cmp(r1, Operand(Factory::null_value())); | 3097       __ cmp(r1, Operand(Factory::null_value())); | 
| 3106       __ b(eq, true_target()); | 3098       __ b(eq, true_target()); | 
| 3107 | 3099 | 
| 3108       // NOTE: it might be an undetectable object. | 3100       // It can be an undetectable object. | 
| 3109       __ ldrb(r1, FieldMemOperand(r2, Map::kBitFieldOffset)); | 3101       __ ldrb(r1, FieldMemOperand(r2, Map::kBitFieldOffset)); | 
| 3110       __ and_(r1, r1, Operand(1 << Map::kIsUndetectable)); | 3102       __ and_(r1, r1, Operand(1 << Map::kIsUndetectable)); | 
| 3111       __ cmp(r1, Operand(1 << Map::kIsUndetectable)); | 3103       __ cmp(r1, Operand(1 << Map::kIsUndetectable)); | 
| 3112       __ b(eq, false_target()); | 3104       __ b(eq, false_target()); | 
| 3113 | 3105 | 
| 3114       __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); | 3106       __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); | 
| 3115       __ cmp(r2, Operand(FIRST_JS_OBJECT_TYPE)); | 3107       __ cmp(r2, Operand(FIRST_JS_OBJECT_TYPE)); | 
| 3116       __ b(lt, false_target()); | 3108       __ b(lt, false_target()); | 
| 3117       __ cmp(r2, Operand(LAST_JS_OBJECT_TYPE)); | 3109       __ cmp(r2, Operand(LAST_JS_OBJECT_TYPE)); | 
| 3118       cc_reg_ = le; | 3110       cc_reg_ = le; | 
| 3119 | 3111 | 
| 3120     } else { | 3112     } else { | 
| 3121       // Uncommon case: Typeof testing against a string literal that | 3113       // Uncommon case: typeof testing against a string literal that is | 
| 3122       // is never returned from the typeof operator. | 3114       // never returned from the typeof operator. | 
| 3123       __ b(false_target()); | 3115       __ b(false_target()); | 
| 3124     } | 3116     } | 
| 3125     return; | 3117     return; | 
| 3126   } | 3118   } | 
| 3127 | 3119 | 
| 3128   Load(left); | 3120   Load(left); | 
| 3129   Load(right); | 3121   Load(right); | 
| 3130   switch (op) { | 3122   switch (op) { | 
| 3131     case Token::EQ: | 3123     case Token::EQ: | 
| 3132       Comparison(eq, false); | 3124       Comparison(eq, false); | 
| (...skipping 1153 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4286   __ mov(r2, Operand(0)); | 4278   __ mov(r2, Operand(0)); | 
| 4287   __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); | 4279   __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); | 
| 4288   __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), | 4280   __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), | 
| 4289           RelocInfo::CODE_TARGET); | 4281           RelocInfo::CODE_TARGET); | 
| 4290 } | 4282 } | 
| 4291 | 4283 | 
| 4292 | 4284 | 
| 4293 #undef __ | 4285 #undef __ | 
| 4294 | 4286 | 
| 4295 } }  // namespace v8::internal | 4287 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|