| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 904 HValue* right = GetParameter(BinaryOpICStub::kRight); | 904 HValue* right = GetParameter(BinaryOpICStub::kRight); |
| 905 | 905 |
| 906 Handle<Type> left_type = state.GetLeftType(isolate()); | 906 Handle<Type> left_type = state.GetLeftType(isolate()); |
| 907 Handle<Type> right_type = state.GetRightType(isolate()); | 907 Handle<Type> right_type = state.GetRightType(isolate()); |
| 908 Handle<Type> result_type = state.GetResultType(isolate()); | 908 Handle<Type> result_type = state.GetResultType(isolate()); |
| 909 | 909 |
| 910 ASSERT(!left_type->Is(Type::None()) && !right_type->Is(Type::None()) && | 910 ASSERT(!left_type->Is(Type::None()) && !right_type->Is(Type::None()) && |
| 911 (state.HasSideEffects() || !result_type->Is(Type::None()))); | 911 (state.HasSideEffects() || !result_type->Is(Type::None()))); |
| 912 | 912 |
| 913 HValue* result = NULL; | 913 HValue* result = NULL; |
| 914 HAllocationMode allocation_mode(NOT_TENURED); | |
| 915 if (state.op() == Token::ADD && | 914 if (state.op() == Token::ADD && |
| 916 (left_type->Maybe(Type::String()) || right_type->Maybe(Type::String())) && | 915 (left_type->Maybe(Type::String()) || right_type->Maybe(Type::String())) && |
| 917 !left_type->Is(Type::String()) && !right_type->Is(Type::String())) { | 916 !left_type->Is(Type::String()) && !right_type->Is(Type::String())) { |
| 918 // For the generic add stub a fast case for string addition is performance | 917 // For the generic add stub a fast case for string addition is performance |
| 919 // critical. | 918 // critical. |
| 920 if (left_type->Maybe(Type::String())) { | 919 if (left_type->Maybe(Type::String())) { |
| 921 IfBuilder if_leftisstring(this); | 920 IfBuilder if_leftisstring(this); |
| 922 if_leftisstring.If<HIsStringAndBranch>(left); | 921 if_leftisstring.If<HIsStringAndBranch>(left); |
| 923 if_leftisstring.Then(); | 922 if_leftisstring.Then(); |
| 924 { | 923 { |
| 925 Push(BuildBinaryOperation( | 924 Push(BuildBinaryOperation( |
| 926 state.op(), left, right, | 925 state.op(), left, right, |
| 927 handle(Type::String(), isolate()), right_type, | 926 handle(Type::String(), isolate()), right_type, |
| 928 result_type, state.fixed_right_arg(), | 927 result_type, state.fixed_right_arg())); |
| 929 allocation_mode)); | |
| 930 } | 928 } |
| 931 if_leftisstring.Else(); | 929 if_leftisstring.Else(); |
| 932 { | 930 { |
| 933 Push(BuildBinaryOperation( | 931 Push(BuildBinaryOperation( |
| 934 state.op(), left, right, | 932 state.op(), left, right, |
| 935 left_type, right_type, result_type, | 933 left_type, right_type, result_type, |
| 936 state.fixed_right_arg(), allocation_mode)); | 934 state.fixed_right_arg())); |
| 937 } | 935 } |
| 938 if_leftisstring.End(); | 936 if_leftisstring.End(); |
| 939 result = Pop(); | 937 result = Pop(); |
| 940 } else { | 938 } else { |
| 941 IfBuilder if_rightisstring(this); | 939 IfBuilder if_rightisstring(this); |
| 942 if_rightisstring.If<HIsStringAndBranch>(right); | 940 if_rightisstring.If<HIsStringAndBranch>(right); |
| 943 if_rightisstring.Then(); | 941 if_rightisstring.Then(); |
| 944 { | 942 { |
| 945 Push(BuildBinaryOperation( | 943 Push(BuildBinaryOperation( |
| 946 state.op(), left, right, | 944 state.op(), left, right, |
| 947 left_type, handle(Type::String(), isolate()), | 945 left_type, handle(Type::String(), isolate()), |
| 948 result_type, state.fixed_right_arg(), | 946 result_type, state.fixed_right_arg())); |
| 949 allocation_mode)); | |
| 950 } | 947 } |
| 951 if_rightisstring.Else(); | 948 if_rightisstring.Else(); |
| 952 { | 949 { |
| 953 Push(BuildBinaryOperation( | 950 Push(BuildBinaryOperation( |
| 954 state.op(), left, right, | 951 state.op(), left, right, |
| 955 left_type, right_type, result_type, | 952 left_type, right_type, result_type, |
| 956 state.fixed_right_arg(), allocation_mode)); | 953 state.fixed_right_arg())); |
| 957 } | 954 } |
| 958 if_rightisstring.End(); | 955 if_rightisstring.End(); |
| 959 result = Pop(); | 956 result = Pop(); |
| 960 } | 957 } |
| 961 } else { | 958 } else { |
| 962 result = BuildBinaryOperation( | 959 result = BuildBinaryOperation( |
| 963 state.op(), left, right, | 960 state.op(), left, right, |
| 964 left_type, right_type, result_type, | 961 left_type, right_type, result_type, |
| 965 state.fixed_right_arg(), allocation_mode); | 962 state.fixed_right_arg()); |
| 966 } | 963 } |
| 967 | 964 |
| 968 // If we encounter a generic argument, the number conversion is | 965 // If we encounter a generic argument, the number conversion is |
| 969 // observable, thus we cannot afford to bail out after the fact. | 966 // observable, thus we cannot afford to bail out after the fact. |
| 970 if (!state.HasSideEffects()) { | 967 if (!state.HasSideEffects()) { |
| 971 if (result_type->Is(Type::Smi())) { | 968 if (result_type->Is(Type::Smi())) { |
| 972 if (state.op() == Token::SHR) { | 969 if (state.op() == Token::SHR) { |
| 973 // TODO(olivf) Replace this by a SmiTagU Instruction. | 970 // TODO(olivf) Replace this by a SmiTagU Instruction. |
| 974 // 0x40000000: this number would convert to negative when interpreting | 971 // 0x40000000: this number would convert to negative when interpreting |
| 975 // the register as signed value; | 972 // the register as signed value; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1003 return result; | 1000 return result; |
| 1004 } | 1001 } |
| 1005 | 1002 |
| 1006 | 1003 |
| 1007 Handle<Code> BinaryOpICStub::GenerateCode(Isolate* isolate) { | 1004 Handle<Code> BinaryOpICStub::GenerateCode(Isolate* isolate) { |
| 1008 return DoGenerateCode(isolate, this); | 1005 return DoGenerateCode(isolate, this); |
| 1009 } | 1006 } |
| 1010 | 1007 |
| 1011 | 1008 |
| 1012 template <> | 1009 template <> |
| 1013 HValue* CodeStubGraphBuilder<BinaryOpWithAllocationSiteStub>::BuildCodeStub() { | |
| 1014 BinaryOpIC::State state = casted_stub()->state(); | |
| 1015 | |
| 1016 HValue* allocation_site = GetParameter( | |
| 1017 BinaryOpWithAllocationSiteStub::kAllocationSite); | |
| 1018 HValue* left = GetParameter(BinaryOpWithAllocationSiteStub::kLeft); | |
| 1019 HValue* right = GetParameter(BinaryOpWithAllocationSiteStub::kRight); | |
| 1020 | |
| 1021 Handle<Type> left_type = state.GetLeftType(isolate()); | |
| 1022 Handle<Type> right_type = state.GetRightType(isolate()); | |
| 1023 Handle<Type> result_type = state.GetResultType(isolate()); | |
| 1024 HAllocationMode allocation_mode(allocation_site); | |
| 1025 | |
| 1026 return BuildBinaryOperation(state.op(), left, right, | |
| 1027 left_type, right_type, result_type, | |
| 1028 state.fixed_right_arg(), allocation_mode); | |
| 1029 } | |
| 1030 | |
| 1031 | |
| 1032 Handle<Code> BinaryOpWithAllocationSiteStub::GenerateCode(Isolate* isolate) { | |
| 1033 return DoGenerateCode(isolate, this); | |
| 1034 } | |
| 1035 | |
| 1036 | |
| 1037 template <> | |
| 1038 HValue* CodeStubGraphBuilder<NewStringAddStub>::BuildCodeInitializedStub() { | 1010 HValue* CodeStubGraphBuilder<NewStringAddStub>::BuildCodeInitializedStub() { |
| 1039 NewStringAddStub* stub = casted_stub(); | 1011 NewStringAddStub* stub = casted_stub(); |
| 1040 StringAddFlags flags = stub->flags(); | 1012 StringAddFlags flags = stub->flags(); |
| 1041 PretenureFlag pretenure_flag = stub->pretenure_flag(); | 1013 PretenureFlag pretenure_flag = stub->pretenure_flag(); |
| 1042 | 1014 |
| 1043 HValue* left = GetParameter(NewStringAddStub::kLeft); | 1015 HValue* left = GetParameter(NewStringAddStub::kLeft); |
| 1044 HValue* right = GetParameter(NewStringAddStub::kRight); | 1016 HValue* right = GetParameter(NewStringAddStub::kRight); |
| 1045 | 1017 |
| 1046 // Make sure that both arguments are strings if not known in advance. | 1018 // Make sure that both arguments are strings if not known in advance. |
| 1047 if ((flags & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) { | 1019 if ((flags & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) { |
| 1048 left = BuildCheckString(left); | 1020 left = BuildCheckString(left); |
| 1049 } | 1021 } |
| 1050 if ((flags & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) { | 1022 if ((flags & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) { |
| 1051 right = BuildCheckString(right); | 1023 right = BuildCheckString(right); |
| 1052 } | 1024 } |
| 1053 | 1025 |
| 1054 return BuildStringAdd(left, right, HAllocationMode(pretenure_flag)); | 1026 return BuildStringAdd(left, right, pretenure_flag); |
| 1055 } | 1027 } |
| 1056 | 1028 |
| 1057 | 1029 |
| 1058 Handle<Code> NewStringAddStub::GenerateCode(Isolate* isolate) { | 1030 Handle<Code> NewStringAddStub::GenerateCode(Isolate* isolate) { |
| 1059 return DoGenerateCode(isolate, this); | 1031 return DoGenerateCode(isolate, this); |
| 1060 } | 1032 } |
| 1061 | 1033 |
| 1062 | 1034 |
| 1063 template <> | 1035 template <> |
| 1064 HValue* CodeStubGraphBuilder<ToBooleanStub>::BuildCodeInitializedStub() { | 1036 HValue* CodeStubGraphBuilder<ToBooleanStub>::BuildCodeInitializedStub() { |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1374 return BuildUncheckedDictionaryElementLoad(receiver, key); | 1346 return BuildUncheckedDictionaryElementLoad(receiver, key); |
| 1375 } | 1347 } |
| 1376 | 1348 |
| 1377 | 1349 |
| 1378 Handle<Code> KeyedLoadDictionaryElementStub::GenerateCode(Isolate* isolate) { | 1350 Handle<Code> KeyedLoadDictionaryElementStub::GenerateCode(Isolate* isolate) { |
| 1379 return DoGenerateCode(isolate, this); | 1351 return DoGenerateCode(isolate, this); |
| 1380 } | 1352 } |
| 1381 | 1353 |
| 1382 | 1354 |
| 1383 } } // namespace v8::internal | 1355 } } // namespace v8::internal |
| OLD | NEW |