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 |