| 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 951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 ElementsKind kind, | 962 ElementsKind kind, |
| 963 HValue* capacity) { | 963 HValue* capacity) { |
| 964 Zone* zone = this->zone(); | 964 Zone* zone = this->zone(); |
| 965 | 965 |
| 966 int elements_size = IsFastDoubleElementsKind(kind) | 966 int elements_size = IsFastDoubleElementsKind(kind) |
| 967 ? kDoubleSize : kPointerSize; | 967 ? kDoubleSize : kPointerSize; |
| 968 HConstant* elements_size_value = | 968 HConstant* elements_size_value = |
| 969 new(zone) HConstant(elements_size, Representation::Integer32()); | 969 new(zone) HConstant(elements_size, Representation::Integer32()); |
| 970 AddInstruction(elements_size_value); | 970 AddInstruction(elements_size_value); |
| 971 HValue* mul = AddInstruction( | 971 HValue* mul = AddInstruction( |
| 972 new(zone) HMul(context, capacity, elements_size_value)); | 972 HMul::New(zone, context, capacity, elements_size_value)); |
| 973 mul->ChangeRepresentation(Representation::Integer32()); | 973 mul->ChangeRepresentation(Representation::Integer32()); |
| 974 mul->ClearFlag(HValue::kCanOverflow); | 974 mul->ClearFlag(HValue::kCanOverflow); |
| 975 | 975 |
| 976 HConstant* header_size = | 976 HConstant* header_size = |
| 977 new(zone) HConstant(FixedArray::kHeaderSize, Representation::Integer32()); | 977 new(zone) HConstant(FixedArray::kHeaderSize, Representation::Integer32()); |
| 978 AddInstruction(header_size); | 978 AddInstruction(header_size); |
| 979 HValue* total_size = AddInstruction( | 979 HValue* total_size = AddInstruction( |
| 980 new(zone) HAdd(context, mul, header_size)); | 980 HAdd::New(zone, context, mul, header_size)); |
| 981 total_size->ChangeRepresentation(Representation::Integer32()); | 981 total_size->ChangeRepresentation(Representation::Integer32()); |
| 982 total_size->ClearFlag(HValue::kCanOverflow); | 982 total_size->ClearFlag(HValue::kCanOverflow); |
| 983 | 983 |
| 984 HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE; | 984 HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE; |
| 985 if (IsFastDoubleElementsKind(kind)) { | 985 if (IsFastDoubleElementsKind(kind)) { |
| 986 flags = static_cast<HAllocate::Flags>( | 986 flags = static_cast<HAllocate::Flags>( |
| 987 flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED); | 987 flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED); |
| 988 } | 988 } |
| 989 | 989 |
| 990 HValue* elements = | 990 HValue* elements = |
| (...skipping 6114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7105 if (expr->AsProperty()->IsArrayLength()) { | 7105 if (expr->AsProperty()->IsArrayLength()) { |
| 7106 HValue* array = Pop(); | 7106 HValue* array = Pop(); |
| 7107 AddInstruction(new(zone()) HCheckNonSmi(array)); | 7107 AddInstruction(new(zone()) HCheckNonSmi(array)); |
| 7108 HInstruction* mapcheck = | 7108 HInstruction* mapcheck = |
| 7109 AddInstruction(HCheckInstanceType::NewIsJSArray(array, zone())); | 7109 AddInstruction(HCheckInstanceType::NewIsJSArray(array, zone())); |
| 7110 instr = new(zone()) HJSArrayLength(array, mapcheck); | 7110 instr = new(zone()) HJSArrayLength(array, mapcheck); |
| 7111 } else if (expr->IsStringLength()) { | 7111 } else if (expr->IsStringLength()) { |
| 7112 HValue* string = Pop(); | 7112 HValue* string = Pop(); |
| 7113 AddInstruction(new(zone()) HCheckNonSmi(string)); | 7113 AddInstruction(new(zone()) HCheckNonSmi(string)); |
| 7114 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); | 7114 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
| 7115 instr = new(zone()) HStringLength(string); | 7115 instr = HStringLength::New(zone(), string); |
| 7116 } else if (expr->IsStringAccess()) { | 7116 } else if (expr->IsStringAccess()) { |
| 7117 CHECK_ALIVE(VisitForValue(expr->key())); | 7117 CHECK_ALIVE(VisitForValue(expr->key())); |
| 7118 HValue* index = Pop(); | 7118 HValue* index = Pop(); |
| 7119 HValue* string = Pop(); | 7119 HValue* string = Pop(); |
| 7120 HValue* context = environment()->LookupContext(); | 7120 HValue* context = environment()->LookupContext(); |
| 7121 HStringCharCodeAt* char_code = | 7121 HInstruction* char_code = |
| 7122 BuildStringCharCodeAt(context, string, index); | 7122 BuildStringCharCodeAt(context, string, index); |
| 7123 AddInstruction(char_code); | 7123 AddInstruction(char_code); |
| 7124 instr = new(zone()) HStringCharFromCode(context, char_code); | 7124 instr = HStringCharFromCode::New(zone(), context, char_code); |
| 7125 | 7125 |
| 7126 } else if (expr->IsFunctionPrototype()) { | 7126 } else if (expr->IsFunctionPrototype()) { |
| 7127 HValue* function = Pop(); | 7127 HValue* function = Pop(); |
| 7128 AddInstruction(new(zone()) HCheckNonSmi(function)); | 7128 AddInstruction(new(zone()) HCheckNonSmi(function)); |
| 7129 instr = new(zone()) HLoadFunctionPrototype(function); | 7129 instr = new(zone()) HLoadFunctionPrototype(function); |
| 7130 | 7130 |
| 7131 } else if (expr->key()->IsPropertyName()) { | 7131 } else if (expr->key()->IsPropertyName()) { |
| 7132 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); | 7132 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
| 7133 SmallMapList* types = expr->GetReceiverTypes(); | 7133 SmallMapList* types = expr->GetReceiverTypes(); |
| 7134 HValue* object = Top(); | 7134 HValue* object = Top(); |
| (...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7784 | 7784 |
| 7785 bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, | 7785 bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, |
| 7786 bool drop_extra) { | 7786 bool drop_extra) { |
| 7787 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; | 7787 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; |
| 7788 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); | 7788 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); |
| 7789 switch (id) { | 7789 switch (id) { |
| 7790 case kMathExp: | 7790 case kMathExp: |
| 7791 if (!FLAG_fast_math) break; | 7791 if (!FLAG_fast_math) break; |
| 7792 // Fall through if FLAG_fast_math. | 7792 // Fall through if FLAG_fast_math. |
| 7793 case kMathRound: | 7793 case kMathRound: |
| 7794 case kMathFloor: |
| 7794 case kMathAbs: | 7795 case kMathAbs: |
| 7795 case kMathSqrt: | 7796 case kMathSqrt: |
| 7796 case kMathLog: | 7797 case kMathLog: |
| 7797 case kMathSin: | 7798 case kMathSin: |
| 7798 case kMathCos: | 7799 case kMathCos: |
| 7799 case kMathTan: | 7800 case kMathTan: |
| 7800 if (expr->arguments()->length() == 1) { | 7801 if (expr->arguments()->length() == 1) { |
| 7801 HValue* argument = Pop(); | 7802 HValue* argument = Pop(); |
| 7802 HValue* context = environment()->LookupContext(); | 7803 HValue* context = environment()->LookupContext(); |
| 7803 Drop(1); // Receiver. | 7804 Drop(1); // Receiver. |
| 7804 HUnaryMathOperation* op = | 7805 HInstruction* op = |
| 7805 new(zone()) HUnaryMathOperation(context, argument, id); | 7806 HUnaryMathOperation::New(zone(), context, argument, id); |
| 7806 op->set_position(expr->position()); | 7807 op->set_position(expr->position()); |
| 7807 if (drop_extra) Drop(1); // Optionally drop the function. | 7808 if (drop_extra) Drop(1); // Optionally drop the function. |
| 7808 ast_context()->ReturnInstruction(op, expr->id()); | 7809 ast_context()->ReturnInstruction(op, expr->id()); |
| 7809 return true; | 7810 return true; |
| 7810 } | 7811 } |
| 7811 break; | 7812 break; |
| 7812 default: | 7813 default: |
| 7813 // Not supported for inlining yet. | 7814 // Not supported for inlining yet. |
| 7814 break; | 7815 break; |
| 7815 } | 7816 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 7832 case kStringCharAt: | 7833 case kStringCharAt: |
| 7833 if (argument_count == 2 && check_type == STRING_CHECK) { | 7834 if (argument_count == 2 && check_type == STRING_CHECK) { |
| 7834 HValue* index = Pop(); | 7835 HValue* index = Pop(); |
| 7835 HValue* string = Pop(); | 7836 HValue* string = Pop(); |
| 7836 HValue* context = environment()->LookupContext(); | 7837 HValue* context = environment()->LookupContext(); |
| 7837 ASSERT(!expr->holder().is_null()); | 7838 ASSERT(!expr->holder().is_null()); |
| 7838 AddInstruction(new(zone()) HCheckPrototypeMaps( | 7839 AddInstruction(new(zone()) HCheckPrototypeMaps( |
| 7839 oracle()->GetPrototypeForPrimitiveCheck(STRING_CHECK), | 7840 oracle()->GetPrototypeForPrimitiveCheck(STRING_CHECK), |
| 7840 expr->holder(), | 7841 expr->holder(), |
| 7841 zone())); | 7842 zone())); |
| 7842 HStringCharCodeAt* char_code = | 7843 HInstruction* char_code = |
| 7843 BuildStringCharCodeAt(context, string, index); | 7844 BuildStringCharCodeAt(context, string, index); |
| 7844 if (id == kStringCharCodeAt) { | 7845 if (id == kStringCharCodeAt) { |
| 7845 ast_context()->ReturnInstruction(char_code, expr->id()); | 7846 ast_context()->ReturnInstruction(char_code, expr->id()); |
| 7846 return true; | 7847 return true; |
| 7847 } | 7848 } |
| 7848 AddInstruction(char_code); | 7849 AddInstruction(char_code); |
| 7849 HStringCharFromCode* result = | 7850 HInstruction* result = |
| 7850 new(zone()) HStringCharFromCode(context, char_code); | 7851 HStringCharFromCode::New(zone(), context, char_code); |
| 7851 ast_context()->ReturnInstruction(result, expr->id()); | 7852 ast_context()->ReturnInstruction(result, expr->id()); |
| 7852 return true; | 7853 return true; |
| 7853 } | 7854 } |
| 7854 break; | 7855 break; |
| 7855 case kMathExp: | 7856 case kMathExp: |
| 7856 if (!FLAG_fast_math) break; | 7857 if (!FLAG_fast_math) break; |
| 7857 // Fall through if FLAG_fast_math. | 7858 // Fall through if FLAG_fast_math. |
| 7858 case kMathRound: | 7859 case kMathRound: |
| 7859 case kMathFloor: | 7860 case kMathFloor: |
| 7860 case kMathAbs: | 7861 case kMathAbs: |
| 7861 case kMathSqrt: | 7862 case kMathSqrt: |
| 7862 case kMathLog: | 7863 case kMathLog: |
| 7863 case kMathSin: | 7864 case kMathSin: |
| 7864 case kMathCos: | 7865 case kMathCos: |
| 7865 case kMathTan: | 7866 case kMathTan: |
| 7866 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { | 7867 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { |
| 7867 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); | 7868 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
| 7868 HValue* argument = Pop(); | 7869 HValue* argument = Pop(); |
| 7869 HValue* context = environment()->LookupContext(); | 7870 HValue* context = environment()->LookupContext(); |
| 7870 Drop(1); // Receiver. | 7871 Drop(1); // Receiver. |
| 7871 HUnaryMathOperation* op = | 7872 HInstruction* op = |
| 7872 new(zone()) HUnaryMathOperation(context, argument, id); | 7873 HUnaryMathOperation::New(zone(), context, argument, id); |
| 7873 op->set_position(expr->position()); | 7874 op->set_position(expr->position()); |
| 7874 ast_context()->ReturnInstruction(op, expr->id()); | 7875 ast_context()->ReturnInstruction(op, expr->id()); |
| 7875 return true; | 7876 return true; |
| 7876 } | 7877 } |
| 7877 break; | 7878 break; |
| 7878 case kMathPow: | 7879 case kMathPow: |
| 7879 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { | 7880 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { |
| 7880 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); | 7881 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
| 7881 HValue* right = Pop(); | 7882 HValue* right = Pop(); |
| 7882 HValue* left = Pop(); | 7883 HValue* left = Pop(); |
| 7883 Pop(); // Pop receiver. | 7884 Pop(); // Pop receiver. |
| 7884 HValue* context = environment()->LookupContext(); | 7885 HValue* context = environment()->LookupContext(); |
| 7885 HInstruction* result = NULL; | 7886 HInstruction* result = NULL; |
| 7886 // Use sqrt() if exponent is 0.5 or -0.5. | 7887 // Use sqrt() if exponent is 0.5 or -0.5. |
| 7887 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { | 7888 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { |
| 7888 double exponent = HConstant::cast(right)->DoubleValue(); | 7889 double exponent = HConstant::cast(right)->DoubleValue(); |
| 7889 if (exponent == 0.5) { | 7890 if (exponent == 0.5) { |
| 7890 result = | 7891 result = |
| 7891 new(zone()) HUnaryMathOperation(context, left, kMathPowHalf); | 7892 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf); |
| 7892 } else if (exponent == -0.5) { | 7893 } else if (exponent == -0.5) { |
| 7893 HConstant* double_one = | 7894 HConstant* double_one = |
| 7894 new(zone()) HConstant(Handle<Object>(Smi::FromInt(1)), | 7895 new(zone()) HConstant(Handle<Object>(Smi::FromInt(1)), |
| 7895 Representation::Double()); | 7896 Representation::Double()); |
| 7896 AddInstruction(double_one); | 7897 AddInstruction(double_one); |
| 7897 HUnaryMathOperation* square_root = | 7898 HInstruction* sqrt = |
| 7898 new(zone()) HUnaryMathOperation(context, left, kMathPowHalf); | 7899 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf); |
| 7899 AddInstruction(square_root); | 7900 AddInstruction(sqrt); |
| 7900 // MathPowHalf doesn't have side effects so there's no need for | 7901 // MathPowHalf doesn't have side effects so there's no need for |
| 7901 // an environment simulation here. | 7902 // an environment simulation here. |
| 7902 ASSERT(!square_root->HasObservableSideEffects()); | 7903 ASSERT(!sqrt->HasObservableSideEffects()); |
| 7903 result = new(zone()) HDiv(context, double_one, square_root); | 7904 result = HDiv::New(zone(), context, double_one, sqrt); |
| 7904 } else if (exponent == 2.0) { | 7905 } else if (exponent == 2.0) { |
| 7905 result = new(zone()) HMul(context, left, left); | 7906 result = HMul::New(zone(), context, left, left); |
| 7906 } | 7907 } |
| 7907 } else if (right->IsConstant() && | 7908 } else if (right->IsConstant() && |
| 7908 HConstant::cast(right)->HasInteger32Value() && | 7909 HConstant::cast(right)->HasInteger32Value() && |
| 7909 HConstant::cast(right)->Integer32Value() == 2) { | 7910 HConstant::cast(right)->Integer32Value() == 2) { |
| 7910 result = new(zone()) HMul(context, left, left); | 7911 result = HMul::New(zone(), context, left, left); |
| 7911 } | 7912 } |
| 7912 | 7913 |
| 7913 if (result == NULL) { | 7914 if (result == NULL) { |
| 7914 result = new(zone()) HPower(left, right); | 7915 result = HPower::New(zone(), left, right); |
| 7915 } | 7916 } |
| 7916 ast_context()->ReturnInstruction(result, expr->id()); | 7917 ast_context()->ReturnInstruction(result, expr->id()); |
| 7917 return true; | 7918 return true; |
| 7918 } | 7919 } |
| 7919 break; | 7920 break; |
| 7920 case kMathRandom: | 7921 case kMathRandom: |
| 7921 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) { | 7922 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) { |
| 7922 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); | 7923 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
| 7923 Drop(1); // Receiver. | 7924 Drop(1); // Receiver. |
| 7924 HValue* context = environment()->LookupContext(); | 7925 HValue* context = environment()->LookupContext(); |
| 7925 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 7926 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| 7926 AddInstruction(global_object); | 7927 AddInstruction(global_object); |
| 7927 HRandom* result = new(zone()) HRandom(global_object); | 7928 HRandom* result = new(zone()) HRandom(global_object); |
| 7928 ast_context()->ReturnInstruction(result, expr->id()); | 7929 ast_context()->ReturnInstruction(result, expr->id()); |
| 7929 return true; | 7930 return true; |
| 7930 } | 7931 } |
| 7931 break; | 7932 break; |
| 7932 case kMathMax: | 7933 case kMathMax: |
| 7933 case kMathMin: | 7934 case kMathMin: |
| 7934 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { | 7935 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { |
| 7935 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); | 7936 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
| 7936 HValue* right = Pop(); | 7937 HValue* right = Pop(); |
| 7937 HValue* left = Pop(); | 7938 HValue* left = Pop(); |
| 7938 Drop(1); // Receiver. | 7939 Drop(1); // Receiver. |
| 7939 HValue* context = environment()->LookupContext(); | 7940 HValue* context = environment()->LookupContext(); |
| 7940 HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin | 7941 HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin |
| 7941 : HMathMinMax::kMathMax; | 7942 : HMathMinMax::kMathMax; |
| 7942 HMathMinMax* result = new(zone()) HMathMinMax(context, left, right, op); | 7943 HInstruction* result = |
| 7944 HMathMinMax::New(zone(), context, left, right, op); |
| 7943 ast_context()->ReturnInstruction(result, expr->id()); | 7945 ast_context()->ReturnInstruction(result, expr->id()); |
| 7944 return true; | 7946 return true; |
| 7945 } | 7947 } |
| 7946 break; | 7948 break; |
| 7947 default: | 7949 default: |
| 7948 // Not yet supported for inlining. | 7950 // Not yet supported for inlining. |
| 7949 break; | 7951 break; |
| 7950 } | 7952 } |
| 7951 return false; | 7953 return false; |
| 7952 } | 7954 } |
| (...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8506 HInstruction* instr = new(zone()) HTypeof(context, value); | 8508 HInstruction* instr = new(zone()) HTypeof(context, value); |
| 8507 return ast_context()->ReturnInstruction(instr, expr->id()); | 8509 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 8508 } | 8510 } |
| 8509 | 8511 |
| 8510 | 8512 |
| 8511 void HOptimizedGraphBuilder::VisitAdd(UnaryOperation* expr) { | 8513 void HOptimizedGraphBuilder::VisitAdd(UnaryOperation* expr) { |
| 8512 CHECK_ALIVE(VisitForValue(expr->expression())); | 8514 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 8513 HValue* value = Pop(); | 8515 HValue* value = Pop(); |
| 8514 HValue* context = environment()->LookupContext(); | 8516 HValue* context = environment()->LookupContext(); |
| 8515 HInstruction* instr = | 8517 HInstruction* instr = |
| 8516 new(zone()) HMul(context, value, graph()->GetConstant1()); | 8518 HMul::New(zone(), context, value, graph()->GetConstant1()); |
| 8517 return ast_context()->ReturnInstruction(instr, expr->id()); | 8519 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 8518 } | 8520 } |
| 8519 | 8521 |
| 8520 | 8522 |
| 8521 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { | 8523 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { |
| 8522 CHECK_ALIVE(VisitForValue(expr->expression())); | 8524 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 8523 HValue* value = Pop(); | 8525 HValue* value = Pop(); |
| 8524 HValue* context = environment()->LookupContext(); | 8526 HValue* context = environment()->LookupContext(); |
| 8525 HInstruction* instr = | 8527 HInstruction* instr = |
| 8526 new(zone()) HMul(context, value, graph()->GetConstantMinus1()); | 8528 HMul::New(zone(), context, value, graph()->GetConstantMinus1()); |
| 8527 TypeInfo info = oracle()->UnaryType(expr); | 8529 TypeInfo info = oracle()->UnaryType(expr); |
| 8528 Representation rep = ToRepresentation(info); | 8530 Representation rep = ToRepresentation(info); |
| 8529 if (info.IsUninitialized()) { | 8531 if (info.IsUninitialized()) { |
| 8530 AddSoftDeoptimize(); | 8532 AddSoftDeoptimize(); |
| 8531 info = TypeInfo::Unknown(); | 8533 info = TypeInfo::Unknown(); |
| 8532 } | 8534 } |
| 8533 HBinaryOperation::cast(instr)->set_observed_input_representation(rep, rep); | 8535 if (instr->IsBinaryOperation()) { |
| 8536 HBinaryOperation::cast(instr)->set_observed_input_representation(rep, rep); |
| 8537 } |
| 8534 return ast_context()->ReturnInstruction(instr, expr->id()); | 8538 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 8535 } | 8539 } |
| 8536 | 8540 |
| 8537 | 8541 |
| 8538 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { | 8542 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { |
| 8539 CHECK_ALIVE(VisitForValue(expr->expression())); | 8543 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 8540 HValue* value = Pop(); | 8544 HValue* value = Pop(); |
| 8541 TypeInfo info = oracle()->UnaryType(expr); | 8545 TypeInfo info = oracle()->UnaryType(expr); |
| 8542 if (info.IsUninitialized()) { | 8546 if (info.IsUninitialized()) { |
| 8543 AddSoftDeoptimize(); | 8547 AddSoftDeoptimize(); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8611 Push(number_input); | 8615 Push(number_input); |
| 8612 } | 8616 } |
| 8613 | 8617 |
| 8614 // The addition has no side effects, so we do not need | 8618 // The addition has no side effects, so we do not need |
| 8615 // to simulate the expression stack after this instruction. | 8619 // to simulate the expression stack after this instruction. |
| 8616 // Any later failures deopt to the load of the input or earlier. | 8620 // Any later failures deopt to the load of the input or earlier. |
| 8617 HConstant* delta = (expr->op() == Token::INC) | 8621 HConstant* delta = (expr->op() == Token::INC) |
| 8618 ? graph()->GetConstant1() | 8622 ? graph()->GetConstant1() |
| 8619 : graph()->GetConstantMinus1(); | 8623 : graph()->GetConstantMinus1(); |
| 8620 HValue* context = environment()->LookupContext(); | 8624 HValue* context = environment()->LookupContext(); |
| 8621 HInstruction* instr = new(zone()) HAdd(context, Top(), delta); | 8625 HInstruction* instr = HAdd::New(zone(), context, Top(), delta); |
| 8622 // We can't insert a simulate here, because it would break deoptimization, | 8626 // We can't insert a simulate here, because it would break deoptimization, |
| 8623 // so the HAdd must not have side effects, so we must freeze its | 8627 // so the HAdd must not have side effects, so we must freeze its |
| 8624 // representation. | 8628 // representation. |
| 8625 instr->AssumeRepresentation(rep); | 8629 instr->AssumeRepresentation(rep); |
| 8626 instr->ClearAllSideEffects(); | 8630 instr->ClearAllSideEffects(); |
| 8627 AddInstruction(instr); | 8631 AddInstruction(instr); |
| 8628 return instr; | 8632 return instr; |
| 8629 } | 8633 } |
| 8630 | 8634 |
| 8631 | 8635 |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8807 ASSERT(has_side_effects); // Stores always have side effects. | 8811 ASSERT(has_side_effects); // Stores always have side effects. |
| 8808 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 8812 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); |
| 8809 } | 8813 } |
| 8810 } | 8814 } |
| 8811 | 8815 |
| 8812 Drop(returns_original_input ? 2 : 1); | 8816 Drop(returns_original_input ? 2 : 1); |
| 8813 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); | 8817 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); |
| 8814 } | 8818 } |
| 8815 | 8819 |
| 8816 | 8820 |
| 8817 HStringCharCodeAt* HOptimizedGraphBuilder::BuildStringCharCodeAt( | 8821 HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt( |
| 8818 HValue* context, | 8822 HValue* context, |
| 8819 HValue* string, | 8823 HValue* string, |
| 8820 HValue* index) { | 8824 HValue* index) { |
| 8825 if (string->IsConstant() && index->IsConstant()) { |
| 8826 HConstant* c_string = HConstant::cast(string); |
| 8827 HConstant* c_index = HConstant::cast(index); |
| 8828 if (c_string->HasStringValue() && c_index->HasNumberValue()) { |
| 8829 int32_t i = c_index->NumberValueAsInteger32(); |
| 8830 Handle<String> s = c_string->StringValue(); |
| 8831 if (i < 0 || i >= s->length()) { |
| 8832 return new(zone()) HConstant(OS::nan_value(), Representation::Double()); |
| 8833 } |
| 8834 return new(zone()) HConstant(s->Get(i), Representation::Integer32()); |
| 8835 } |
| 8836 } |
| 8821 AddInstruction(new(zone()) HCheckNonSmi(string)); | 8837 AddInstruction(new(zone()) HCheckNonSmi(string)); |
| 8822 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); | 8838 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
| 8823 HStringLength* length = new(zone()) HStringLength(string); | 8839 HStringLength* length = new(zone()) HStringLength(string); |
| 8824 AddInstruction(length); | 8840 AddInstruction(length); |
| 8825 HInstruction* checked_index = AddBoundsCheck(index, length); | 8841 HInstruction* checked_index = AddBoundsCheck(index, length); |
| 8826 return new(zone()) HStringCharCodeAt(context, string, checked_index); | 8842 return new(zone()) HStringCharCodeAt(context, string, checked_index); |
| 8827 } | 8843 } |
| 8828 | 8844 |
| 8829 // Checks if the given shift amounts have form: (sa) and (32 - sa). | 8845 // Checks if the given shift amounts have form: (sa) and (32 - sa). |
| 8830 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, | 8846 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8901 left_info = right_info = TypeInfo::Unknown(); | 8917 left_info = right_info = TypeInfo::Unknown(); |
| 8902 } | 8918 } |
| 8903 HInstruction* instr = NULL; | 8919 HInstruction* instr = NULL; |
| 8904 switch (expr->op()) { | 8920 switch (expr->op()) { |
| 8905 case Token::ADD: | 8921 case Token::ADD: |
| 8906 if (left_info.IsString() && right_info.IsString()) { | 8922 if (left_info.IsString() && right_info.IsString()) { |
| 8907 AddInstruction(new(zone()) HCheckNonSmi(left)); | 8923 AddInstruction(new(zone()) HCheckNonSmi(left)); |
| 8908 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); | 8924 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); |
| 8909 AddInstruction(new(zone()) HCheckNonSmi(right)); | 8925 AddInstruction(new(zone()) HCheckNonSmi(right)); |
| 8910 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); | 8926 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); |
| 8911 instr = new(zone()) HStringAdd(context, left, right); | 8927 instr = HStringAdd::New(zone(), context, left, right); |
| 8912 } else { | 8928 } else { |
| 8913 instr = HAdd::NewHAdd(zone(), context, left, right); | 8929 instr = HAdd::New(zone(), context, left, right); |
| 8914 } | 8930 } |
| 8915 break; | 8931 break; |
| 8916 case Token::SUB: | 8932 case Token::SUB: |
| 8917 instr = HSub::NewHSub(zone(), context, left, right); | 8933 instr = HSub::New(zone(), context, left, right); |
| 8918 break; | 8934 break; |
| 8919 case Token::MUL: | 8935 case Token::MUL: |
| 8920 instr = HMul::NewHMul(zone(), context, left, right); | 8936 instr = HMul::New(zone(), context, left, right); |
| 8921 break; | 8937 break; |
| 8922 case Token::MOD: | 8938 case Token::MOD: |
| 8923 instr = HMod::NewHMod(zone(), context, left, right); | 8939 instr = HMod::New(zone(), context, left, right); |
| 8924 break; | 8940 break; |
| 8925 case Token::DIV: | 8941 case Token::DIV: |
| 8926 instr = HDiv::NewHDiv(zone(), context, left, right); | 8942 instr = HDiv::New(zone(), context, left, right); |
| 8927 break; | 8943 break; |
| 8928 case Token::BIT_XOR: | 8944 case Token::BIT_XOR: |
| 8929 case Token::BIT_AND: | 8945 case Token::BIT_AND: |
| 8930 instr = HBitwise::NewHBitwise(zone(), expr->op(), context, left, right); | 8946 instr = HBitwise::New(zone(), expr->op(), context, left, right); |
| 8931 break; | 8947 break; |
| 8932 case Token::BIT_OR: { | 8948 case Token::BIT_OR: { |
| 8933 HValue* operand, *shift_amount; | 8949 HValue* operand, *shift_amount; |
| 8934 if (left_info.IsInteger32() && right_info.IsInteger32() && | 8950 if (left_info.IsInteger32() && right_info.IsInteger32() && |
| 8935 MatchRotateRight(left, right, &operand, &shift_amount)) { | 8951 MatchRotateRight(left, right, &operand, &shift_amount)) { |
| 8936 instr = new(zone()) HRor(context, operand, shift_amount); | 8952 instr = new(zone()) HRor(context, operand, shift_amount); |
| 8937 } else { | 8953 } else { |
| 8938 instr = HBitwise::NewHBitwise(zone(), expr->op(), context, left, right); | 8954 instr = HBitwise::New(zone(), expr->op(), context, left, right); |
| 8939 } | 8955 } |
| 8940 break; | 8956 break; |
| 8941 } | 8957 } |
| 8942 case Token::SAR: | 8958 case Token::SAR: |
| 8943 instr = HSar::NewHSar(zone(), context, left, right); | 8959 instr = HSar::New(zone(), context, left, right); |
| 8944 break; | 8960 break; |
| 8945 case Token::SHR: | 8961 case Token::SHR: |
| 8946 instr = HShr::NewHShr(zone(), context, left, right); | 8962 instr = HShr::New(zone(), context, left, right); |
| 8947 if (FLAG_opt_safe_uint32_operations && instr->IsShr() && | 8963 if (FLAG_opt_safe_uint32_operations && instr->IsShr() && |
| 8948 CanBeZero(right)) { | 8964 CanBeZero(right)) { |
| 8949 graph()->RecordUint32Instruction(instr); | 8965 graph()->RecordUint32Instruction(instr); |
| 8950 } | 8966 } |
| 8951 break; | 8967 break; |
| 8952 case Token::SHL: | 8968 case Token::SHL: |
| 8953 instr = HShl::NewHShl(zone(), context, left, right); | 8969 instr = HShl::New(zone(), context, left, right); |
| 8954 break; | 8970 break; |
| 8955 default: | 8971 default: |
| 8956 UNREACHABLE(); | 8972 UNREACHABLE(); |
| 8957 } | 8973 } |
| 8958 | 8974 |
| 8959 if (instr->IsBinaryOperation()) { | 8975 if (instr->IsBinaryOperation()) { |
| 8960 HBinaryOperation* binop = HBinaryOperation::cast(instr); | 8976 HBinaryOperation* binop = HBinaryOperation::cast(instr); |
| 8961 binop->set_observed_input_representation(left_rep, right_rep); | 8977 binop->set_observed_input_representation(left_rep, right_rep); |
| 8962 binop->initialize_output_representation(result_rep); | 8978 binop->initialize_output_representation(result_rep); |
| 8963 } | 8979 } |
| (...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9703 void HOptimizedGraphBuilder::GenerateTwoByteSeqStringSetChar( | 9719 void HOptimizedGraphBuilder::GenerateTwoByteSeqStringSetChar( |
| 9704 CallRuntime* call) { | 9720 CallRuntime* call) { |
| 9705 ASSERT(call->arguments()->length() == 3); | 9721 ASSERT(call->arguments()->length() == 3); |
| 9706 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9722 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 9707 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 9723 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
| 9708 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); | 9724 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); |
| 9709 HValue* value = Pop(); | 9725 HValue* value = Pop(); |
| 9710 HValue* index = Pop(); | 9726 HValue* index = Pop(); |
| 9711 HValue* string = Pop(); | 9727 HValue* string = Pop(); |
| 9712 HValue* context = environment()->LookupContext(); | 9728 HValue* context = environment()->LookupContext(); |
| 9713 HStringCharCodeAt* char_code = BuildStringCharCodeAt(context, string, index); | 9729 HInstruction* char_code = BuildStringCharCodeAt(context, string, index); |
| 9714 AddInstruction(char_code); | 9730 AddInstruction(char_code); |
| 9715 HSeqStringSetChar* result = new(zone()) HSeqStringSetChar( | 9731 HSeqStringSetChar* result = new(zone()) HSeqStringSetChar( |
| 9716 String::TWO_BYTE_ENCODING, string, index, value); | 9732 String::TWO_BYTE_ENCODING, string, index, value); |
| 9717 return ast_context()->ReturnInstruction(result, call->id()); | 9733 return ast_context()->ReturnInstruction(result, call->id()); |
| 9718 } | 9734 } |
| 9719 | 9735 |
| 9720 | 9736 |
| 9721 void HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) { | 9737 void HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) { |
| 9722 ASSERT(call->arguments()->length() == 2); | 9738 ASSERT(call->arguments()->length() == 2); |
| 9723 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9739 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9761 | 9777 |
| 9762 | 9778 |
| 9763 // Fast support for charCodeAt(n). | 9779 // Fast support for charCodeAt(n). |
| 9764 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { | 9780 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { |
| 9765 ASSERT(call->arguments()->length() == 2); | 9781 ASSERT(call->arguments()->length() == 2); |
| 9766 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9782 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 9767 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 9783 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
| 9768 HValue* index = Pop(); | 9784 HValue* index = Pop(); |
| 9769 HValue* string = Pop(); | 9785 HValue* string = Pop(); |
| 9770 HValue* context = environment()->LookupContext(); | 9786 HValue* context = environment()->LookupContext(); |
| 9771 HStringCharCodeAt* result = BuildStringCharCodeAt(context, string, index); | 9787 HInstruction* result = BuildStringCharCodeAt(context, string, index); |
| 9772 return ast_context()->ReturnInstruction(result, call->id()); | 9788 return ast_context()->ReturnInstruction(result, call->id()); |
| 9773 } | 9789 } |
| 9774 | 9790 |
| 9775 | 9791 |
| 9776 // Fast support for string.charAt(n) and string[n]. | 9792 // Fast support for string.charAt(n) and string[n]. |
| 9777 void HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { | 9793 void HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { |
| 9778 ASSERT(call->arguments()->length() == 1); | 9794 ASSERT(call->arguments()->length() == 1); |
| 9779 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9795 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 9780 HValue* char_code = Pop(); | 9796 HValue* char_code = Pop(); |
| 9781 HValue* context = environment()->LookupContext(); | 9797 HValue* context = environment()->LookupContext(); |
| 9782 HStringCharFromCode* result = | 9798 HStringCharFromCode* result = |
| 9783 new(zone()) HStringCharFromCode(context, char_code); | 9799 new(zone()) HStringCharFromCode(context, char_code); |
| 9784 return ast_context()->ReturnInstruction(result, call->id()); | 9800 return ast_context()->ReturnInstruction(result, call->id()); |
| 9785 } | 9801 } |
| 9786 | 9802 |
| 9787 | 9803 |
| 9788 // Fast support for string.charAt(n) and string[n]. | 9804 // Fast support for string.charAt(n) and string[n]. |
| 9789 void HOptimizedGraphBuilder::GenerateStringCharAt(CallRuntime* call) { | 9805 void HOptimizedGraphBuilder::GenerateStringCharAt(CallRuntime* call) { |
| 9790 ASSERT(call->arguments()->length() == 2); | 9806 ASSERT(call->arguments()->length() == 2); |
| 9791 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9807 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 9792 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 9808 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
| 9793 HValue* index = Pop(); | 9809 HValue* index = Pop(); |
| 9794 HValue* string = Pop(); | 9810 HValue* string = Pop(); |
| 9795 HValue* context = environment()->LookupContext(); | 9811 HValue* context = environment()->LookupContext(); |
| 9796 HStringCharCodeAt* char_code = BuildStringCharCodeAt(context, string, index); | 9812 HInstruction* char_code = BuildStringCharCodeAt(context, string, index); |
| 9797 AddInstruction(char_code); | 9813 AddInstruction(char_code); |
| 9798 HStringCharFromCode* result = | 9814 HStringCharFromCode* result = |
| 9799 new(zone()) HStringCharFromCode(context, char_code); | 9815 new(zone()) HStringCharFromCode(context, char_code); |
| 9800 return ast_context()->ReturnInstruction(result, call->id()); | 9816 return ast_context()->ReturnInstruction(result, call->id()); |
| 9801 } | 9817 } |
| 9802 | 9818 |
| 9803 | 9819 |
| 9804 // Fast support for object equality testing. | 9820 // Fast support for object equality testing. |
| 9805 void HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) { | 9821 void HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) { |
| 9806 ASSERT(call->arguments()->length() == 2); | 9822 ASSERT(call->arguments()->length() == 2); |
| (...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10672 } | 10688 } |
| 10673 } | 10689 } |
| 10674 | 10690 |
| 10675 #ifdef DEBUG | 10691 #ifdef DEBUG |
| 10676 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 10692 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 10677 if (allocator_ != NULL) allocator_->Verify(); | 10693 if (allocator_ != NULL) allocator_->Verify(); |
| 10678 #endif | 10694 #endif |
| 10679 } | 10695 } |
| 10680 | 10696 |
| 10681 } } // namespace v8::internal | 10697 } } // namespace v8::internal |
| OLD | NEW |