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 |