Chromium Code Reviews| 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 901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 912 flags = ((loop_nesting() > 0) && type->IsLikelySmi()) | 912 flags = ((loop_nesting() > 0) && type->IsLikelySmi()) |
| 913 ? SMI_CODE_INLINED | 913 ? SMI_CODE_INLINED |
| 914 : SMI_CODE_IN_STUB; | 914 : SMI_CODE_IN_STUB; |
| 915 break; | 915 break; |
| 916 } | 916 } |
| 917 | 917 |
| 918 Result right = frame_->Pop(); | 918 Result right = frame_->Pop(); |
| 919 Result left = frame_->Pop(); | 919 Result left = frame_->Pop(); |
| 920 | 920 |
| 921 if (op == Token::ADD) { | 921 if (op == Token::ADD) { |
| 922 bool left_is_string = left.static_type().is_jsstring(); | 922 bool left_is_string = left.is_constant() && left.handle()->IsString(); |
| 923 bool right_is_string = right.static_type().is_jsstring(); | 923 bool right_is_string = right.is_constant() && right.handle()->IsString(); |
| 924 if (left_is_string || right_is_string) { | 924 if (left_is_string || right_is_string) { |
| 925 frame_->Push(&left); | 925 frame_->Push(&left); |
| 926 frame_->Push(&right); | 926 frame_->Push(&right); |
| 927 Result answer; | 927 Result answer; |
| 928 if (left_is_string) { | 928 if (left_is_string) { |
| 929 if (right_is_string) { | 929 if (right_is_string) { |
| 930 // TODO(lrn): if (left.is_constant() && right.is_constant()) | 930 // TODO(lrn): if both are constant strings |
| 931 // -- do a compile time cons, if allocation during codegen is allowed. | 931 // -- do a compile time cons, if allocation during codegen is allowed. |
| 932 answer = frame_->CallRuntime(Runtime::kStringAdd, 2); | 932 answer = frame_->CallRuntime(Runtime::kStringAdd, 2); |
| 933 } else { | 933 } else { |
| 934 answer = | 934 answer = |
| 935 frame_->InvokeBuiltin(Builtins::STRING_ADD_LEFT, CALL_FUNCTION, 2); | 935 frame_->InvokeBuiltin(Builtins::STRING_ADD_LEFT, CALL_FUNCTION, 2); |
|
Erik Corry
2009/06/24 11:46:35
I wonder whether the stub is faster here. It does
Lasse Reichstein
2009/06/24 12:33:07
Good idea.
I'll commit this for now, and make a te
| |
| 936 } | 936 } |
| 937 } else if (right_is_string) { | 937 } else if (right_is_string) { |
| 938 answer = | 938 answer = |
| 939 frame_->InvokeBuiltin(Builtins::STRING_ADD_RIGHT, CALL_FUNCTION, 2); | 939 frame_->InvokeBuiltin(Builtins::STRING_ADD_RIGHT, CALL_FUNCTION, 2); |
| 940 } | 940 } |
| 941 answer.set_static_type(StaticType::jsstring()); | |
| 942 frame_->Push(&answer); | 941 frame_->Push(&answer); |
| 943 return; | 942 return; |
| 944 } | 943 } |
| 945 // Neither operand is known to be a string. | 944 // Neither operand is known to be a string. |
| 946 } | 945 } |
| 947 | 946 |
| 948 bool left_is_smi = left.is_constant() && left.handle()->IsSmi(); | 947 bool left_is_smi = left.is_constant() && left.handle()->IsSmi(); |
| 949 bool left_is_non_smi = left.is_constant() && !left.handle()->IsSmi(); | 948 bool left_is_non_smi = left.is_constant() && !left.handle()->IsSmi(); |
| 950 bool right_is_smi = right.is_constant() && right.handle()->IsSmi(); | 949 bool right_is_smi = right.is_constant() && right.handle()->IsSmi(); |
| 951 bool right_is_non_smi = right.is_constant() && !right.handle()->IsSmi(); | 950 bool right_is_non_smi = right.is_constant() && !right.handle()->IsSmi(); |
| (...skipping 5895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6847 __ mov(edx, Operand(esp, 2 * kPointerSize)); | 6846 __ mov(edx, Operand(esp, 2 * kPointerSize)); |
| 6848 break; | 6847 break; |
| 6849 } | 6848 } |
| 6850 default: UNREACHABLE(); break; | 6849 default: UNREACHABLE(); break; |
| 6851 } | 6850 } |
| 6852 | 6851 |
| 6853 // If all else fails, use the runtime system to get the correct | 6852 // If all else fails, use the runtime system to get the correct |
| 6854 // result. | 6853 // result. |
| 6855 __ bind(&call_runtime); | 6854 __ bind(&call_runtime); |
| 6856 switch (op_) { | 6855 switch (op_) { |
| 6857 case Token::ADD: | 6856 case Token::ADD: { |
| 6857 // Test for string arguments before calling runtime. | |
| 6858 Label not_strings, both_strings, not_string1, string1; | |
| 6859 Result answer; | |
| 6860 __ mov(eax, Operand(esp, 2 * kPointerSize)); // First argument. | |
| 6861 __ mov(edx, Operand(esp, 1 * kPointerSize)); // Second argument. | |
| 6862 __ test(eax, Immediate(kSmiTagMask)); | |
| 6863 __ j(zero, ¬_string1); | |
| 6864 __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, eax); | |
| 6865 __ j(above_equal, ¬_string1); | |
| 6866 | |
| 6867 // First argument is a a string, test second. | |
| 6868 __ test(edx, Immediate(kSmiTagMask)); | |
| 6869 __ j(zero, &string1); | |
| 6870 __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, edx); | |
| 6871 __ j(above_equal, &string1); | |
| 6872 | |
| 6873 // First and second argument are strings. | |
| 6874 __ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2); | |
| 6875 | |
| 6876 // Only first argument is a string. | |
| 6877 __ bind(&string1); | |
| 6878 __ InvokeBuiltin(Builtins::STRING_ADD_LEFT, JUMP_FUNCTION); | |
| 6879 | |
| 6880 // First argument was not a string, test second. | |
| 6881 __ bind(¬_string1); | |
| 6882 __ test(edx, Immediate(kSmiTagMask)); | |
| 6883 __ j(zero, ¬_strings); | |
| 6884 __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, edx); | |
| 6885 __ j(above_equal, ¬_strings); | |
| 6886 | |
| 6887 // Only second argument is a string. | |
| 6888 __ InvokeBuiltin(Builtins::STRING_ADD_RIGHT, JUMP_FUNCTION); | |
| 6889 | |
| 6890 __ bind(¬_strings); | |
| 6891 // Neither argument is a string. | |
| 6858 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION); | 6892 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION); |
| 6859 break; | 6893 break; |
| 6894 } | |
| 6860 case Token::SUB: | 6895 case Token::SUB: |
| 6861 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION); | 6896 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION); |
| 6862 break; | 6897 break; |
| 6863 case Token::MUL: | 6898 case Token::MUL: |
| 6864 __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION); | 6899 __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION); |
| 6865 break; | 6900 break; |
| 6866 case Token::DIV: | 6901 case Token::DIV: |
| 6867 __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION); | 6902 __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION); |
| 6868 break; | 6903 break; |
| 6869 case Token::MOD: | 6904 case Token::MOD: |
| (...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7802 | 7837 |
| 7803 // Slow-case: Go through the JavaScript implementation. | 7838 // Slow-case: Go through the JavaScript implementation. |
| 7804 __ bind(&slow); | 7839 __ bind(&slow); |
| 7805 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 7840 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
| 7806 } | 7841 } |
| 7807 | 7842 |
| 7808 | 7843 |
| 7809 #undef __ | 7844 #undef __ |
| 7810 | 7845 |
| 7811 } } // namespace v8::internal | 7846 } } // namespace v8::internal |
| OLD | NEW |