| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 789 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 800 Result right(generator()); | 800 Result right(generator()); |
| 801 enter()->Bind(&left, &right); | 801 enter()->Bind(&left, &right); |
| 802 generator()->frame()->Push(&left); | 802 generator()->frame()->Push(&left); |
| 803 generator()->frame()->Push(&right); | 803 generator()->frame()->Push(&right); |
| 804 Result answer = generator()->frame()->CallStub(&stub_, 2); | 804 Result answer = generator()->frame()->CallStub(&stub_, 2); |
| 805 exit_.Jump(&answer); | 805 exit_.Jump(&answer); |
| 806 } | 806 } |
| 807 | 807 |
| 808 | 808 |
| 809 void CodeGenerator::GenericBinaryOperation(Token::Value op, | 809 void CodeGenerator::GenericBinaryOperation(Token::Value op, |
| 810 StaticType* type, | 810 SmiAnalysis* type, |
| 811 OverwriteMode overwrite_mode) { | 811 OverwriteMode overwrite_mode) { |
| 812 Comment cmnt(masm_, "[ BinaryOperation"); | 812 Comment cmnt(masm_, "[ BinaryOperation"); |
| 813 Comment cmnt_token(masm_, Token::String(op)); | 813 Comment cmnt_token(masm_, Token::String(op)); |
| 814 | 814 |
| 815 if (op == Token::COMMA) { | 815 if (op == Token::COMMA) { |
| 816 // Simply discard left value. | 816 // Simply discard left value. |
| 817 frame_->Nip(1); | 817 frame_->Nip(1); |
| 818 return; | 818 return; |
| 819 } | 819 } |
| 820 | 820 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 838 // By default only inline the Smi check code for likely smis if this | 838 // By default only inline the Smi check code for likely smis if this |
| 839 // operation is part of a loop. | 839 // operation is part of a loop. |
| 840 flags = ((loop_nesting() > 0) && type->IsLikelySmi()) | 840 flags = ((loop_nesting() > 0) && type->IsLikelySmi()) |
| 841 ? SMI_CODE_INLINED | 841 ? SMI_CODE_INLINED |
| 842 : SMI_CODE_IN_STUB; | 842 : SMI_CODE_IN_STUB; |
| 843 break; | 843 break; |
| 844 } | 844 } |
| 845 | 845 |
| 846 Result right = frame_->Pop(); | 846 Result right = frame_->Pop(); |
| 847 Result left = frame_->Pop(); | 847 Result left = frame_->Pop(); |
| 848 |
| 849 if (op == Token::ADD) { |
| 850 bool left_is_string = left.static_type().is_jsstring(); |
| 851 bool right_is_string = right.static_type().is_jsstring(); |
| 852 if (left_is_string || right_is_string) { |
| 853 frame_->Push(&left); |
| 854 frame_->Push(&right); |
| 855 Result answer(this); |
| 856 if (left_is_string) { |
| 857 if (right_is_string) { |
| 858 // TODO(lrn): if (left.is_constant() && right.is_constant()) |
| 859 // -- do a compile time cons, if allocation during codegen is allowed. |
| 860 answer = frame_->CallRuntime(Runtime::kStringAdd, 2); |
| 861 } else { |
| 862 answer = |
| 863 frame_->InvokeBuiltin(Builtins::STRING_ADD_LEFT, CALL_FUNCTION, 2); |
| 864 } |
| 865 } else if (right_is_string) { |
| 866 answer = |
| 867 frame_->InvokeBuiltin(Builtins::STRING_ADD_RIGHT, CALL_FUNCTION, 2); |
| 868 } |
| 869 answer.set_static_type(StaticType::jsstring()); |
| 870 frame_->Push(&answer); |
| 871 return; |
| 872 } |
| 873 // Neither operand is known to be a string. |
| 874 } |
| 875 |
| 848 bool left_is_smi = left.is_constant() && left.handle()->IsSmi(); | 876 bool left_is_smi = left.is_constant() && left.handle()->IsSmi(); |
| 849 bool left_is_non_smi = left.is_constant() && !left.handle()->IsSmi(); | 877 bool left_is_non_smi = left.is_constant() && !left.handle()->IsSmi(); |
| 850 bool right_is_smi = right.is_constant() && right.handle()->IsSmi(); | 878 bool right_is_smi = right.is_constant() && right.handle()->IsSmi(); |
| 851 bool right_is_non_smi = right.is_constant() && !right.handle()->IsSmi(); | 879 bool right_is_non_smi = right.is_constant() && !right.handle()->IsSmi(); |
| 852 bool generate_no_smi_code = false; // No smi code at all, inline or in stub. | 880 bool generate_no_smi_code = false; // No smi code at all, inline or in stub. |
| 853 | 881 |
| 854 if (left_is_smi && right_is_smi) { | 882 if (left_is_smi && right_is_smi) { |
| 855 // Compute the constant result at compile time, and leave it on the frame. | 883 // Compute the constant result at compile time, and leave it on the frame. |
| 856 int left_int = Smi::cast(*left.handle())->value(); | 884 int left_int = Smi::cast(*left.handle())->value(); |
| 857 int right_int = Smi::cast(*right.handle())->value(); | 885 int right_int = Smi::cast(*right.handle())->value(); |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1182 generator()->frame()->Push(&right); | 1210 generator()->frame()->Push(&right); |
| 1183 GenericBinaryOpStub igostub(Token::SUB, overwrite_mode_, SMI_CODE_INLINED); | 1211 GenericBinaryOpStub igostub(Token::SUB, overwrite_mode_, SMI_CODE_INLINED); |
| 1184 Result answer = generator()->frame()->CallStub(&igostub, 2); | 1212 Result answer = generator()->frame()->CallStub(&igostub, 2); |
| 1185 exit_.Jump(&answer); | 1213 exit_.Jump(&answer); |
| 1186 } | 1214 } |
| 1187 | 1215 |
| 1188 | 1216 |
| 1189 void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, | 1217 void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, |
| 1190 Result* operand, | 1218 Result* operand, |
| 1191 Handle<Object> value, | 1219 Handle<Object> value, |
| 1192 StaticType* type, | 1220 SmiAnalysis* type, |
| 1193 bool reversed, | 1221 bool reversed, |
| 1194 OverwriteMode overwrite_mode) { | 1222 OverwriteMode overwrite_mode) { |
| 1195 // NOTE: This is an attempt to inline (a bit) more of the code for | 1223 // NOTE: This is an attempt to inline (a bit) more of the code for |
| 1196 // some possible smi operations (like + and -) when (at least) one | 1224 // some possible smi operations (like + and -) when (at least) one |
| 1197 // of the operands is a constant smi. | 1225 // of the operands is a constant smi. |
| 1198 // Consumes the argument "operand". | 1226 // Consumes the argument "operand". |
| 1199 | 1227 |
| 1200 // TODO(199): Optimize some special cases of operations involving a | 1228 // TODO(199): Optimize some special cases of operations involving a |
| 1201 // smi literal (multiply by 2, shift by 0, etc.). | 1229 // smi literal (multiply by 2, shift by 0, etc.). |
| 1202 if (IsUnsafeSmi(value)) { | 1230 if (IsUnsafeSmi(value)) { |
| (...skipping 2289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3492 } else { | 3520 } else { |
| 3493 ASSERT(var->is_global()); | 3521 ASSERT(var->is_global()); |
| 3494 Reference ref(this, node); | 3522 Reference ref(this, node); |
| 3495 ref.GetValue(typeof_state()); | 3523 ref.GetValue(typeof_state()); |
| 3496 } | 3524 } |
| 3497 } | 3525 } |
| 3498 | 3526 |
| 3499 | 3527 |
| 3500 void CodeGenerator::VisitLiteral(Literal* node) { | 3528 void CodeGenerator::VisitLiteral(Literal* node) { |
| 3501 Comment cmnt(masm_, "[ Literal"); | 3529 Comment cmnt(masm_, "[ Literal"); |
| 3502 frame_->Push(node->handle()); | 3530 frame_->Push(node->handle()); |
| 3503 } | 3531 } |
| 3504 | 3532 |
| 3505 | 3533 |
| 3506 void CodeGenerator::LoadUnsafeSmi(Register target, Handle<Object> value) { | 3534 void CodeGenerator::LoadUnsafeSmi(Register target, Handle<Object> value) { |
| 3507 ASSERT(target.is_valid()); | 3535 ASSERT(target.is_valid()); |
| 3508 ASSERT(value->IsSmi()); | 3536 ASSERT(value->IsSmi()); |
| 3509 int bits = reinterpret_cast<int>(*value); | 3537 int bits = reinterpret_cast<int>(*value); |
| 3510 __ Set(target, Immediate(bits & 0x0000FFFF)); | 3538 __ Set(target, Immediate(bits & 0x0000FFFF)); |
| 3511 __ xor_(target, bits & 0xFFFF0000); | 3539 __ xor_(target, bits & 0xFFFF0000); |
| 3512 } | 3540 } |
| 3513 | 3541 |
| (...skipping 3572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7086 | 7114 |
| 7087 // Slow-case: Go through the JavaScript implementation. | 7115 // Slow-case: Go through the JavaScript implementation. |
| 7088 __ bind(&slow); | 7116 __ bind(&slow); |
| 7089 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 7117 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
| 7090 } | 7118 } |
| 7091 | 7119 |
| 7092 | 7120 |
| 7093 #undef __ | 7121 #undef __ |
| 7094 | 7122 |
| 7095 } } // namespace v8::internal | 7123 } } // namespace v8::internal |
| OLD | NEW |