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::NewHMul(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::NewHAdd(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::NewHStringLength(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 = |
7125 HStringCharFromCode::NewHStringCharFromCode(zone(), context, char_code); | |
7125 | 7126 |
7126 } else if (expr->IsFunctionPrototype()) { | 7127 } else if (expr->IsFunctionPrototype()) { |
7127 HValue* function = Pop(); | 7128 HValue* function = Pop(); |
7128 AddInstruction(new(zone()) HCheckNonSmi(function)); | 7129 AddInstruction(new(zone()) HCheckNonSmi(function)); |
7129 instr = new(zone()) HLoadFunctionPrototype(function); | 7130 instr = new(zone()) HLoadFunctionPrototype(function); |
7130 | 7131 |
7131 } else if (expr->key()->IsPropertyName()) { | 7132 } else if (expr->key()->IsPropertyName()) { |
7132 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); | 7133 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
7133 SmallMapList* types = expr->GetReceiverTypes(); | 7134 SmallMapList* types = expr->GetReceiverTypes(); |
7134 HValue* object = Top(); | 7135 HValue* object = Top(); |
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7784 | 7785 |
7785 bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, | 7786 bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, |
7786 bool drop_extra) { | 7787 bool drop_extra) { |
7787 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; | 7788 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; |
7788 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); | 7789 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); |
7789 switch (id) { | 7790 switch (id) { |
7790 case kMathExp: | 7791 case kMathExp: |
7791 if (!FLAG_fast_math) break; | 7792 if (!FLAG_fast_math) break; |
7792 // Fall through if FLAG_fast_math. | 7793 // Fall through if FLAG_fast_math. |
7793 case kMathRound: | 7794 case kMathRound: |
7795 case kMathFloor: | |
Jakob Kummerow
2013/02/20 15:31:04
good catch!
| |
7794 case kMathAbs: | 7796 case kMathAbs: |
7795 case kMathSqrt: | 7797 case kMathSqrt: |
7796 case kMathLog: | 7798 case kMathLog: |
7797 case kMathSin: | 7799 case kMathSin: |
7798 case kMathCos: | 7800 case kMathCos: |
7799 case kMathTan: | 7801 case kMathTan: |
7800 if (expr->arguments()->length() == 1) { | 7802 if (expr->arguments()->length() == 1) { |
7801 HValue* argument = Pop(); | 7803 HValue* argument = Pop(); |
7802 HValue* context = environment()->LookupContext(); | 7804 HValue* context = environment()->LookupContext(); |
7803 Drop(1); // Receiver. | 7805 Drop(1); // Receiver. |
7804 HUnaryMathOperation* op = | 7806 HInstruction* op = HUnaryMathOperation::NewHUnaryMathOperation( |
7805 new(zone()) HUnaryMathOperation(context, argument, id); | 7807 zone(), context, argument, id); |
Jakob Kummerow
2013/02/20 15:31:04
nit: I'd indent 4 spaces relative to "HInstruction
| |
7806 op->set_position(expr->position()); | 7808 op->set_position(expr->position()); |
7807 if (drop_extra) Drop(1); // Optionally drop the function. | 7809 if (drop_extra) Drop(1); // Optionally drop the function. |
7808 ast_context()->ReturnInstruction(op, expr->id()); | 7810 ast_context()->ReturnInstruction(op, expr->id()); |
7809 return true; | 7811 return true; |
7810 } | 7812 } |
7811 break; | 7813 break; |
7812 default: | 7814 default: |
7813 // Not supported for inlining yet. | 7815 // Not supported for inlining yet. |
7814 break; | 7816 break; |
7815 } | 7817 } |
(...skipping 16 matching lines...) Expand all Loading... | |
7832 case kStringCharAt: | 7834 case kStringCharAt: |
7833 if (argument_count == 2 && check_type == STRING_CHECK) { | 7835 if (argument_count == 2 && check_type == STRING_CHECK) { |
7834 HValue* index = Pop(); | 7836 HValue* index = Pop(); |
7835 HValue* string = Pop(); | 7837 HValue* string = Pop(); |
7836 HValue* context = environment()->LookupContext(); | 7838 HValue* context = environment()->LookupContext(); |
7837 ASSERT(!expr->holder().is_null()); | 7839 ASSERT(!expr->holder().is_null()); |
7838 AddInstruction(new(zone()) HCheckPrototypeMaps( | 7840 AddInstruction(new(zone()) HCheckPrototypeMaps( |
7839 oracle()->GetPrototypeForPrimitiveCheck(STRING_CHECK), | 7841 oracle()->GetPrototypeForPrimitiveCheck(STRING_CHECK), |
7840 expr->holder(), | 7842 expr->holder(), |
7841 zone())); | 7843 zone())); |
7842 HStringCharCodeAt* char_code = | 7844 HInstruction* char_code = |
7843 BuildStringCharCodeAt(context, string, index); | 7845 BuildStringCharCodeAt(context, string, index); |
7844 if (id == kStringCharCodeAt) { | 7846 if (id == kStringCharCodeAt) { |
7845 ast_context()->ReturnInstruction(char_code, expr->id()); | 7847 ast_context()->ReturnInstruction(char_code, expr->id()); |
7846 return true; | 7848 return true; |
7847 } | 7849 } |
7848 AddInstruction(char_code); | 7850 AddInstruction(char_code); |
7849 HStringCharFromCode* result = | 7851 HInstruction* result = HStringCharFromCode::NewHStringCharFromCode( |
7850 new(zone()) HStringCharFromCode(context, char_code); | 7852 zone(), context, char_code); |
7851 ast_context()->ReturnInstruction(result, expr->id()); | 7853 ast_context()->ReturnInstruction(result, expr->id()); |
7852 return true; | 7854 return true; |
7853 } | 7855 } |
7854 break; | 7856 break; |
7855 case kMathExp: | 7857 case kMathExp: |
7856 if (!FLAG_fast_math) break; | 7858 if (!FLAG_fast_math) break; |
7857 // Fall through if FLAG_fast_math. | 7859 // Fall through if FLAG_fast_math. |
7858 case kMathRound: | 7860 case kMathRound: |
7859 case kMathFloor: | 7861 case kMathFloor: |
7860 case kMathAbs: | 7862 case kMathAbs: |
7861 case kMathSqrt: | 7863 case kMathSqrt: |
7862 case kMathLog: | 7864 case kMathLog: |
7863 case kMathSin: | 7865 case kMathSin: |
7864 case kMathCos: | 7866 case kMathCos: |
7865 case kMathTan: | 7867 case kMathTan: |
7866 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { | 7868 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { |
7867 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); | 7869 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
7868 HValue* argument = Pop(); | 7870 HValue* argument = Pop(); |
7869 HValue* context = environment()->LookupContext(); | 7871 HValue* context = environment()->LookupContext(); |
7870 Drop(1); // Receiver. | 7872 Drop(1); // Receiver. |
7871 HUnaryMathOperation* op = | 7873 HInstruction* op = HUnaryMathOperation::NewHUnaryMathOperation( |
7872 new(zone()) HUnaryMathOperation(context, argument, id); | 7874 zone(), context, argument, id); |
7873 op->set_position(expr->position()); | 7875 op->set_position(expr->position()); |
7874 ast_context()->ReturnInstruction(op, expr->id()); | 7876 ast_context()->ReturnInstruction(op, expr->id()); |
7875 return true; | 7877 return true; |
7876 } | 7878 } |
7877 break; | 7879 break; |
7878 case kMathPow: | 7880 case kMathPow: |
7879 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { | 7881 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { |
7880 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); | 7882 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
7881 HValue* right = Pop(); | 7883 HValue* right = Pop(); |
7882 HValue* left = Pop(); | 7884 HValue* left = Pop(); |
7883 Pop(); // Pop receiver. | 7885 Pop(); // Pop receiver. |
7884 HValue* context = environment()->LookupContext(); | 7886 HValue* context = environment()->LookupContext(); |
7885 HInstruction* result = NULL; | 7887 HInstruction* result = NULL; |
7886 // Use sqrt() if exponent is 0.5 or -0.5. | 7888 // Use sqrt() if exponent is 0.5 or -0.5. |
7887 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { | 7889 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { |
7888 double exponent = HConstant::cast(right)->DoubleValue(); | 7890 double exponent = HConstant::cast(right)->DoubleValue(); |
7889 if (exponent == 0.5) { | 7891 if (exponent == 0.5) { |
7890 result = | 7892 result = HUnaryMathOperation::NewHUnaryMathOperation( |
7891 new(zone()) HUnaryMathOperation(context, left, kMathPowHalf); | 7893 zone(), context, left, kMathPowHalf); |
7892 } else if (exponent == -0.5) { | 7894 } else if (exponent == -0.5) { |
7893 HConstant* double_one = | 7895 HConstant* double_one = |
7894 new(zone()) HConstant(Handle<Object>(Smi::FromInt(1)), | 7896 new(zone()) HConstant(Handle<Object>(Smi::FromInt(1)), |
7895 Representation::Double()); | 7897 Representation::Double()); |
7896 AddInstruction(double_one); | 7898 AddInstruction(double_one); |
7897 HUnaryMathOperation* square_root = | 7899 HInstruction* sqrt = HUnaryMathOperation::NewHUnaryMathOperation( |
7898 new(zone()) HUnaryMathOperation(context, left, kMathPowHalf); | 7900 zone(), context, left, kMathPowHalf); |
Jakob Kummerow
2013/02/20 15:31:04
nit: now this indentation is just inconsistent wit
Yang
2013/02/20 17:51:15
Done.
| |
7899 AddInstruction(square_root); | 7901 AddInstruction(sqrt); |
7900 // MathPowHalf doesn't have side effects so there's no need for | 7902 // MathPowHalf doesn't have side effects so there's no need for |
7901 // an environment simulation here. | 7903 // an environment simulation here. |
7902 ASSERT(!square_root->HasObservableSideEffects()); | 7904 ASSERT(!sqrt->HasObservableSideEffects()); |
7903 result = new(zone()) HDiv(context, double_one, square_root); | 7905 result = HDiv::NewHDiv(zone(), context, double_one, sqrt); |
7904 } else if (exponent == 2.0) { | 7906 } else if (exponent == 2.0) { |
7905 result = new(zone()) HMul(context, left, left); | 7907 result = HMul::NewHMul(zone(), context, left, left); |
7906 } | 7908 } |
7907 } else if (right->IsConstant() && | 7909 } else if (right->IsConstant() && |
7908 HConstant::cast(right)->HasInteger32Value() && | 7910 HConstant::cast(right)->HasInteger32Value() && |
7909 HConstant::cast(right)->Integer32Value() == 2) { | 7911 HConstant::cast(right)->Integer32Value() == 2) { |
7910 result = new(zone()) HMul(context, left, left); | 7912 result = HMul::NewHMul(zone(), context, left, left); |
7911 } | 7913 } |
7912 | 7914 |
7913 if (result == NULL) { | 7915 if (result == NULL) { |
7914 result = new(zone()) HPower(left, right); | 7916 result = HPower::NewHPower(zone(), left, right); |
7915 } | 7917 } |
7916 ast_context()->ReturnInstruction(result, expr->id()); | 7918 ast_context()->ReturnInstruction(result, expr->id()); |
7917 return true; | 7919 return true; |
7918 } | 7920 } |
7919 break; | 7921 break; |
7920 case kMathRandom: | 7922 case kMathRandom: |
7921 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) { | 7923 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) { |
7922 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); | 7924 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
7923 Drop(1); // Receiver. | 7925 Drop(1); // Receiver. |
7924 HValue* context = environment()->LookupContext(); | 7926 HValue* context = environment()->LookupContext(); |
7925 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 7927 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
7926 AddInstruction(global_object); | 7928 AddInstruction(global_object); |
7927 HRandom* result = new(zone()) HRandom(global_object); | 7929 HRandom* result = new(zone()) HRandom(global_object); |
7928 ast_context()->ReturnInstruction(result, expr->id()); | 7930 ast_context()->ReturnInstruction(result, expr->id()); |
7929 return true; | 7931 return true; |
7930 } | 7932 } |
7931 break; | 7933 break; |
7932 case kMathMax: | 7934 case kMathMax: |
7933 case kMathMin: | 7935 case kMathMin: |
7934 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { | 7936 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { |
7935 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); | 7937 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
7936 HValue* right = Pop(); | 7938 HValue* right = Pop(); |
7937 HValue* left = Pop(); | 7939 HValue* left = Pop(); |
7938 Drop(1); // Receiver. | 7940 Drop(1); // Receiver. |
7939 HValue* context = environment()->LookupContext(); | 7941 HValue* context = environment()->LookupContext(); |
7940 HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin | 7942 HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin |
7941 : HMathMinMax::kMathMax; | 7943 : HMathMinMax::kMathMax; |
7942 HMathMinMax* result = new(zone()) HMathMinMax(context, left, right, op); | 7944 HInstruction* result = HMathMinMax::NewHMathMinMax( |
7945 zone(), context, left, right, op); | |
7943 ast_context()->ReturnInstruction(result, expr->id()); | 7946 ast_context()->ReturnInstruction(result, expr->id()); |
7944 return true; | 7947 return true; |
7945 } | 7948 } |
7946 break; | 7949 break; |
7947 default: | 7950 default: |
7948 // Not yet supported for inlining. | 7951 // Not yet supported for inlining. |
7949 break; | 7952 break; |
7950 } | 7953 } |
7951 return false; | 7954 return false; |
7952 } | 7955 } |
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8611 Push(number_input); | 8614 Push(number_input); |
8612 } | 8615 } |
8613 | 8616 |
8614 // The addition has no side effects, so we do not need | 8617 // The addition has no side effects, so we do not need |
8615 // to simulate the expression stack after this instruction. | 8618 // to simulate the expression stack after this instruction. |
8616 // Any later failures deopt to the load of the input or earlier. | 8619 // Any later failures deopt to the load of the input or earlier. |
8617 HConstant* delta = (expr->op() == Token::INC) | 8620 HConstant* delta = (expr->op() == Token::INC) |
8618 ? graph()->GetConstant1() | 8621 ? graph()->GetConstant1() |
8619 : graph()->GetConstantMinus1(); | 8622 : graph()->GetConstantMinus1(); |
8620 HValue* context = environment()->LookupContext(); | 8623 HValue* context = environment()->LookupContext(); |
8621 HInstruction* instr = new(zone()) HAdd(context, Top(), delta); | 8624 HInstruction* instr = HAdd::NewHAdd(zone(), context, Top(), delta); |
8622 // We can't insert a simulate here, because it would break deoptimization, | 8625 // 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 | 8626 // so the HAdd must not have side effects, so we must freeze its |
8624 // representation. | 8627 // representation. |
8625 instr->AssumeRepresentation(rep); | 8628 instr->AssumeRepresentation(rep); |
8626 instr->ClearAllSideEffects(); | 8629 instr->ClearAllSideEffects(); |
8627 AddInstruction(instr); | 8630 AddInstruction(instr); |
8628 return instr; | 8631 return instr; |
8629 } | 8632 } |
8630 | 8633 |
8631 | 8634 |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8807 ASSERT(has_side_effects); // Stores always have side effects. | 8810 ASSERT(has_side_effects); // Stores always have side effects. |
8808 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | 8811 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); |
8809 } | 8812 } |
8810 } | 8813 } |
8811 | 8814 |
8812 Drop(returns_original_input ? 2 : 1); | 8815 Drop(returns_original_input ? 2 : 1); |
8813 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); | 8816 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); |
8814 } | 8817 } |
8815 | 8818 |
8816 | 8819 |
8817 HStringCharCodeAt* HOptimizedGraphBuilder::BuildStringCharCodeAt( | 8820 HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt( |
8818 HValue* context, | 8821 HValue* context, |
8819 HValue* string, | 8822 HValue* string, |
8820 HValue* index) { | 8823 HValue* index) { |
8824 if (string->IsConstant() && index->IsConstant()) { | |
8825 HConstant* c_string = HConstant::cast(string); | |
8826 HConstant* c_index = HConstant::cast(index); | |
8827 if (c_string->HasStringValue() && c_index->HasNumberValue()) { | |
8828 int32_t i = c_index->NumberValueAsInteger32(); | |
8829 Handle<String> s = c_string->StringValue(); | |
8830 if (i < 0 || i >= s->length()) { | |
8831 return new(zone()) HConstant(OS::nan_value(), Representation::Double()); | |
8832 } | |
8833 return new(zone()) HConstant(s->Get(i), Representation::Integer32()); | |
8834 } | |
8835 } | |
8821 AddInstruction(new(zone()) HCheckNonSmi(string)); | 8836 AddInstruction(new(zone()) HCheckNonSmi(string)); |
8822 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); | 8837 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
8823 HStringLength* length = new(zone()) HStringLength(string); | 8838 HStringLength* length = new(zone()) HStringLength(string); |
8824 AddInstruction(length); | 8839 AddInstruction(length); |
8825 HInstruction* checked_index = AddBoundsCheck(index, length); | 8840 HInstruction* checked_index = AddBoundsCheck(index, length); |
8826 return new(zone()) HStringCharCodeAt(context, string, checked_index); | 8841 return new(zone()) HStringCharCodeAt(context, string, checked_index); |
8827 } | 8842 } |
8828 | 8843 |
8829 // Checks if the given shift amounts have form: (sa) and (32 - sa). | 8844 // Checks if the given shift amounts have form: (sa) and (32 - sa). |
8830 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, | 8845 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(); | 8916 left_info = right_info = TypeInfo::Unknown(); |
8902 } | 8917 } |
8903 HInstruction* instr = NULL; | 8918 HInstruction* instr = NULL; |
8904 switch (expr->op()) { | 8919 switch (expr->op()) { |
8905 case Token::ADD: | 8920 case Token::ADD: |
8906 if (left_info.IsString() && right_info.IsString()) { | 8921 if (left_info.IsString() && right_info.IsString()) { |
8907 AddInstruction(new(zone()) HCheckNonSmi(left)); | 8922 AddInstruction(new(zone()) HCheckNonSmi(left)); |
8908 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); | 8923 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); |
8909 AddInstruction(new(zone()) HCheckNonSmi(right)); | 8924 AddInstruction(new(zone()) HCheckNonSmi(right)); |
8910 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); | 8925 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); |
8911 instr = new(zone()) HStringAdd(context, left, right); | 8926 instr = HStringAdd::NewHStringAdd(zone(), context, left, right); |
8912 } else { | 8927 } else { |
8913 instr = HAdd::NewHAdd(zone(), context, left, right); | 8928 instr = HAdd::NewHAdd(zone(), context, left, right); |
8914 } | 8929 } |
8915 break; | 8930 break; |
8916 case Token::SUB: | 8931 case Token::SUB: |
8917 instr = HSub::NewHSub(zone(), context, left, right); | 8932 instr = HSub::NewHSub(zone(), context, left, right); |
8918 break; | 8933 break; |
8919 case Token::MUL: | 8934 case Token::MUL: |
8920 instr = HMul::NewHMul(zone(), context, left, right); | 8935 instr = HMul::NewHMul(zone(), context, left, right); |
8921 break; | 8936 break; |
(...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9703 void HOptimizedGraphBuilder::GenerateTwoByteSeqStringSetChar( | 9718 void HOptimizedGraphBuilder::GenerateTwoByteSeqStringSetChar( |
9704 CallRuntime* call) { | 9719 CallRuntime* call) { |
9705 ASSERT(call->arguments()->length() == 3); | 9720 ASSERT(call->arguments()->length() == 3); |
9706 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9721 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9707 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 9722 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
9708 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); | 9723 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); |
9709 HValue* value = Pop(); | 9724 HValue* value = Pop(); |
9710 HValue* index = Pop(); | 9725 HValue* index = Pop(); |
9711 HValue* string = Pop(); | 9726 HValue* string = Pop(); |
9712 HValue* context = environment()->LookupContext(); | 9727 HValue* context = environment()->LookupContext(); |
9713 HStringCharCodeAt* char_code = BuildStringCharCodeAt(context, string, index); | 9728 HInstruction* char_code = BuildStringCharCodeAt(context, string, index); |
9714 AddInstruction(char_code); | 9729 AddInstruction(char_code); |
9715 HSeqStringSetChar* result = new(zone()) HSeqStringSetChar( | 9730 HSeqStringSetChar* result = new(zone()) HSeqStringSetChar( |
9716 String::TWO_BYTE_ENCODING, string, index, value); | 9731 String::TWO_BYTE_ENCODING, string, index, value); |
9717 return ast_context()->ReturnInstruction(result, call->id()); | 9732 return ast_context()->ReturnInstruction(result, call->id()); |
9718 } | 9733 } |
9719 | 9734 |
9720 | 9735 |
9721 void HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) { | 9736 void HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) { |
9722 ASSERT(call->arguments()->length() == 2); | 9737 ASSERT(call->arguments()->length() == 2); |
9723 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9738 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9761 | 9776 |
9762 | 9777 |
9763 // Fast support for charCodeAt(n). | 9778 // Fast support for charCodeAt(n). |
9764 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { | 9779 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { |
9765 ASSERT(call->arguments()->length() == 2); | 9780 ASSERT(call->arguments()->length() == 2); |
9766 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9781 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9767 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 9782 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
9768 HValue* index = Pop(); | 9783 HValue* index = Pop(); |
9769 HValue* string = Pop(); | 9784 HValue* string = Pop(); |
9770 HValue* context = environment()->LookupContext(); | 9785 HValue* context = environment()->LookupContext(); |
9771 HStringCharCodeAt* result = BuildStringCharCodeAt(context, string, index); | 9786 HInstruction* result = BuildStringCharCodeAt(context, string, index); |
9772 return ast_context()->ReturnInstruction(result, call->id()); | 9787 return ast_context()->ReturnInstruction(result, call->id()); |
9773 } | 9788 } |
9774 | 9789 |
9775 | 9790 |
9776 // Fast support for string.charAt(n) and string[n]. | 9791 // Fast support for string.charAt(n) and string[n]. |
9777 void HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { | 9792 void HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { |
9778 ASSERT(call->arguments()->length() == 1); | 9793 ASSERT(call->arguments()->length() == 1); |
9779 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9794 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9780 HValue* char_code = Pop(); | 9795 HValue* char_code = Pop(); |
9781 HValue* context = environment()->LookupContext(); | 9796 HValue* context = environment()->LookupContext(); |
9782 HStringCharFromCode* result = | 9797 HStringCharFromCode* result = |
9783 new(zone()) HStringCharFromCode(context, char_code); | 9798 new(zone()) HStringCharFromCode(context, char_code); |
9784 return ast_context()->ReturnInstruction(result, call->id()); | 9799 return ast_context()->ReturnInstruction(result, call->id()); |
9785 } | 9800 } |
9786 | 9801 |
9787 | 9802 |
9788 // Fast support for string.charAt(n) and string[n]. | 9803 // Fast support for string.charAt(n) and string[n]. |
9789 void HOptimizedGraphBuilder::GenerateStringCharAt(CallRuntime* call) { | 9804 void HOptimizedGraphBuilder::GenerateStringCharAt(CallRuntime* call) { |
9790 ASSERT(call->arguments()->length() == 2); | 9805 ASSERT(call->arguments()->length() == 2); |
9791 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9806 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9792 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 9807 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
9793 HValue* index = Pop(); | 9808 HValue* index = Pop(); |
9794 HValue* string = Pop(); | 9809 HValue* string = Pop(); |
9795 HValue* context = environment()->LookupContext(); | 9810 HValue* context = environment()->LookupContext(); |
9796 HStringCharCodeAt* char_code = BuildStringCharCodeAt(context, string, index); | 9811 HInstruction* char_code = BuildStringCharCodeAt(context, string, index); |
9797 AddInstruction(char_code); | 9812 AddInstruction(char_code); |
9798 HStringCharFromCode* result = | 9813 HStringCharFromCode* result = |
9799 new(zone()) HStringCharFromCode(context, char_code); | 9814 new(zone()) HStringCharFromCode(context, char_code); |
9800 return ast_context()->ReturnInstruction(result, call->id()); | 9815 return ast_context()->ReturnInstruction(result, call->id()); |
9801 } | 9816 } |
9802 | 9817 |
9803 | 9818 |
9804 // Fast support for object equality testing. | 9819 // Fast support for object equality testing. |
9805 void HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) { | 9820 void HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) { |
9806 ASSERT(call->arguments()->length() == 2); | 9821 ASSERT(call->arguments()->length() == 2); |
(...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10672 } | 10687 } |
10673 } | 10688 } |
10674 | 10689 |
10675 #ifdef DEBUG | 10690 #ifdef DEBUG |
10676 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 10691 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
10677 if (allocator_ != NULL) allocator_->Verify(); | 10692 if (allocator_ != NULL) allocator_->Verify(); |
10678 #endif | 10693 #endif |
10679 } | 10694 } |
10680 | 10695 |
10681 } } // namespace v8::internal | 10696 } } // namespace v8::internal |
OLD | NEW |