| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 6121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6132 #endif | 6132 #endif |
| 6133 Comment cmnt(masm_, "[ CompareOperation"); | 6133 Comment cmnt(masm_, "[ CompareOperation"); |
| 6134 | 6134 |
| 6135 VirtualFrame::RegisterAllocationScope nonspilled_scope(this); | 6135 VirtualFrame::RegisterAllocationScope nonspilled_scope(this); |
| 6136 | 6136 |
| 6137 // Get the expressions from the node. | 6137 // Get the expressions from the node. |
| 6138 Expression* left = node->left(); | 6138 Expression* left = node->left(); |
| 6139 Expression* right = node->right(); | 6139 Expression* right = node->right(); |
| 6140 Token::Value op = node->op(); | 6140 Token::Value op = node->op(); |
| 6141 | 6141 |
| 6142 // To make null checks efficient, we check if either left or right is the | |
| 6143 // literal 'null'. If so, we optimize the code by inlining a null check | |
| 6144 // instead of calling the (very) general runtime routine for checking | |
| 6145 // equality. | |
| 6146 if (op == Token::EQ || op == Token::EQ_STRICT) { | |
| 6147 bool left_is_null = | |
| 6148 left->AsLiteral() != NULL && left->AsLiteral()->IsNull(); | |
| 6149 bool right_is_null = | |
| 6150 right->AsLiteral() != NULL && right->AsLiteral()->IsNull(); | |
| 6151 // The 'null' value can only be equal to 'null' or 'undefined'. | |
| 6152 if (left_is_null || right_is_null) { | |
| 6153 Load(left_is_null ? right : left); | |
| 6154 Register tos = frame_->PopToRegister(); | |
| 6155 __ LoadRoot(ip, Heap::kNullValueRootIndex); | |
| 6156 __ cmp(tos, ip); | |
| 6157 | |
| 6158 // The 'null' value is only equal to 'undefined' if using non-strict | |
| 6159 // comparisons. | |
| 6160 if (op != Token::EQ_STRICT) { | |
| 6161 true_target()->Branch(eq); | |
| 6162 | |
| 6163 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | |
| 6164 __ cmp(tos, Operand(ip)); | |
| 6165 true_target()->Branch(eq); | |
| 6166 | |
| 6167 __ tst(tos, Operand(kSmiTagMask)); | |
| 6168 false_target()->Branch(eq); | |
| 6169 | |
| 6170 // It can be an undetectable object. | |
| 6171 __ ldr(tos, FieldMemOperand(tos, HeapObject::kMapOffset)); | |
| 6172 __ ldrb(tos, FieldMemOperand(tos, Map::kBitFieldOffset)); | |
| 6173 __ and_(tos, tos, Operand(1 << Map::kIsUndetectable)); | |
| 6174 __ cmp(tos, Operand(1 << Map::kIsUndetectable)); | |
| 6175 } | |
| 6176 | |
| 6177 cc_reg_ = eq; | |
| 6178 ASSERT(has_cc() && frame_->height() == original_height); | |
| 6179 return; | |
| 6180 } | |
| 6181 } | |
| 6182 | |
| 6183 // To make typeof testing for natives implemented in JavaScript really | 6142 // To make typeof testing for natives implemented in JavaScript really |
| 6184 // efficient, we generate special code for expressions of the form: | 6143 // efficient, we generate special code for expressions of the form: |
| 6185 // 'typeof <expression> == <string>'. | 6144 // 'typeof <expression> == <string>'. |
| 6186 UnaryOperation* operation = left->AsUnaryOperation(); | 6145 UnaryOperation* operation = left->AsUnaryOperation(); |
| 6187 if ((op == Token::EQ || op == Token::EQ_STRICT) && | 6146 if ((op == Token::EQ || op == Token::EQ_STRICT) && |
| 6188 (operation != NULL && operation->op() == Token::TYPEOF) && | 6147 (operation != NULL && operation->op() == Token::TYPEOF) && |
| 6189 (right->AsLiteral() != NULL && | 6148 (right->AsLiteral() != NULL && |
| 6190 right->AsLiteral()->handle()->IsString())) { | 6149 right->AsLiteral()->handle()->IsString())) { |
| 6191 Handle<String> check(String::cast(*right->AsLiteral()->handle())); | 6150 Handle<String> check(String::cast(*right->AsLiteral()->handle())); |
| 6192 | 6151 |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6333 } | 6292 } |
| 6334 | 6293 |
| 6335 default: | 6294 default: |
| 6336 UNREACHABLE(); | 6295 UNREACHABLE(); |
| 6337 } | 6296 } |
| 6338 ASSERT((has_cc() && frame_->height() == original_height) || | 6297 ASSERT((has_cc() && frame_->height() == original_height) || |
| 6339 (!has_cc() && frame_->height() == original_height + 1)); | 6298 (!has_cc() && frame_->height() == original_height + 1)); |
| 6340 } | 6299 } |
| 6341 | 6300 |
| 6342 | 6301 |
| 6302 void CodeGenerator::VisitCompareToNull(CompareToNull* node) { |
| 6303 #ifdef DEBUG |
| 6304 int original_height = frame_->height(); |
| 6305 #endif |
| 6306 Comment cmnt(masm_, "[ CompareToNull"); |
| 6307 |
| 6308 Load(node->expression()); |
| 6309 Register tos = frame_->PopToRegister(); |
| 6310 __ LoadRoot(ip, Heap::kNullValueRootIndex); |
| 6311 __ cmp(tos, ip); |
| 6312 |
| 6313 // The 'null' value is only equal to 'undefined' if using non-strict |
| 6314 // comparisons. |
| 6315 if (!node->is_strict()) { |
| 6316 true_target()->Branch(eq); |
| 6317 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 6318 __ cmp(tos, Operand(ip)); |
| 6319 true_target()->Branch(eq); |
| 6320 |
| 6321 __ tst(tos, Operand(kSmiTagMask)); |
| 6322 false_target()->Branch(eq); |
| 6323 |
| 6324 // It can be an undetectable object. |
| 6325 __ ldr(tos, FieldMemOperand(tos, HeapObject::kMapOffset)); |
| 6326 __ ldrb(tos, FieldMemOperand(tos, Map::kBitFieldOffset)); |
| 6327 __ and_(tos, tos, Operand(1 << Map::kIsUndetectable)); |
| 6328 __ cmp(tos, Operand(1 << Map::kIsUndetectable)); |
| 6329 } |
| 6330 |
| 6331 cc_reg_ = eq; |
| 6332 ASSERT(has_cc() && frame_->height() == original_height); |
| 6333 } |
| 6334 |
| 6335 |
| 6343 class DeferredReferenceGetNamedValue: public DeferredCode { | 6336 class DeferredReferenceGetNamedValue: public DeferredCode { |
| 6344 public: | 6337 public: |
| 6345 explicit DeferredReferenceGetNamedValue(Register receiver, | 6338 explicit DeferredReferenceGetNamedValue(Register receiver, |
| 6346 Handle<String> name) | 6339 Handle<String> name) |
| 6347 : receiver_(receiver), name_(name) { | 6340 : receiver_(receiver), name_(name) { |
| 6348 set_comment("[ DeferredReferenceGetNamedValue"); | 6341 set_comment("[ DeferredReferenceGetNamedValue"); |
| 6349 } | 6342 } |
| 6350 | 6343 |
| 6351 virtual void Generate(); | 6344 virtual void Generate(); |
| 6352 | 6345 |
| (...skipping 5419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11772 __ bind(&string_add_runtime); | 11765 __ bind(&string_add_runtime); |
| 11773 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 11766 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
| 11774 } | 11767 } |
| 11775 | 11768 |
| 11776 | 11769 |
| 11777 #undef __ | 11770 #undef __ |
| 11778 | 11771 |
| 11779 } } // namespace v8::internal | 11772 } } // namespace v8::internal |
| 11780 | 11773 |
| 11781 #endif // V8_TARGET_ARCH_ARM | 11774 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |