OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 3104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3115 instruction->DeleteAndReplaceWith(instruction->RedefinedOperand()); | 3115 instruction->DeleteAndReplaceWith(instruction->RedefinedOperand()); |
3116 } else { | 3116 } else { |
3117 instruction->ReplaceAllUsesWith(instruction->ActualValue()); | 3117 instruction->ReplaceAllUsesWith(instruction->ActualValue()); |
3118 } | 3118 } |
3119 } | 3119 } |
3120 } | 3120 } |
3121 } | 3121 } |
3122 } | 3122 } |
3123 | 3123 |
3124 | 3124 |
3125 void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { | 3125 void HGraphBuilder::PushAndAdd(HInstruction* instr) { |
3126 Push(instr); | 3126 Push(instr); |
3127 AddInstruction(instr); | 3127 AddInstruction(instr); |
3128 } | 3128 } |
3129 | 3129 |
3130 | 3130 |
3131 template <class Instruction> | 3131 template <class Instruction> |
3132 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { | 3132 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { |
3133 int count = call->argument_count(); | 3133 int count = call->argument_count(); |
3134 ZoneList<HValue*> arguments(count, zone()); | 3134 ZoneList<HValue*> arguments(count, zone()); |
3135 for (int i = 0; i < count; ++i) { | 3135 for (int i = 0; i < count; ++i) { |
(...skipping 4345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7481 CHECK_ALIVE(VisitForTypeOf(expr->expression())); | 7481 CHECK_ALIVE(VisitForTypeOf(expr->expression())); |
7482 HValue* value = Pop(); | 7482 HValue* value = Pop(); |
7483 HValue* context = environment()->LookupContext(); | 7483 HValue* context = environment()->LookupContext(); |
7484 HInstruction* instr = new(zone()) HTypeof(context, value); | 7484 HInstruction* instr = new(zone()) HTypeof(context, value); |
7485 return ast_context()->ReturnInstruction(instr, expr->id()); | 7485 return ast_context()->ReturnInstruction(instr, expr->id()); |
7486 } | 7486 } |
7487 | 7487 |
7488 | 7488 |
7489 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { | 7489 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { |
7490 CHECK_ALIVE(VisitForValue(expr->expression())); | 7490 CHECK_ALIVE(VisitForValue(expr->expression())); |
7491 HValue* value = Pop(); | |
7492 Handle<Type> operand_type = expr->expression()->bounds().lower; | 7491 Handle<Type> operand_type = expr->expression()->bounds().lower; |
| 7492 HValue* value = TruncateToNumber(Pop(), &operand_type); |
7493 HInstruction* instr = BuildUnaryMathOp(value, operand_type, Token::SUB); | 7493 HInstruction* instr = BuildUnaryMathOp(value, operand_type, Token::SUB); |
7494 return ast_context()->ReturnInstruction(instr, expr->id()); | 7494 return ast_context()->ReturnInstruction(instr, expr->id()); |
7495 } | 7495 } |
7496 | 7496 |
7497 | 7497 |
7498 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { | 7498 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { |
7499 CHECK_ALIVE(VisitForValue(expr->expression())); | 7499 CHECK_ALIVE(VisitForValue(expr->expression())); |
7500 HValue* value = Pop(); | |
7501 Handle<Type> operand_type = expr->expression()->bounds().lower; | 7500 Handle<Type> operand_type = expr->expression()->bounds().lower; |
| 7501 HValue* value = TruncateToNumber(Pop(), &operand_type); |
7502 HInstruction* instr = BuildUnaryMathOp(value, operand_type, Token::BIT_NOT); | 7502 HInstruction* instr = BuildUnaryMathOp(value, operand_type, Token::BIT_NOT); |
7503 return ast_context()->ReturnInstruction(instr, expr->id()); | 7503 return ast_context()->ReturnInstruction(instr, expr->id()); |
7504 } | 7504 } |
7505 | 7505 |
7506 | 7506 |
7507 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { | 7507 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { |
7508 if (ast_context()->IsTest()) { | 7508 if (ast_context()->IsTest()) { |
7509 TestContext* context = TestContext::cast(ast_context()); | 7509 TestContext* context = TestContext::cast(ast_context()); |
7510 VisitForControl(expr->expression(), | 7510 VisitForControl(expr->expression(), |
7511 context->if_false(), | 7511 context->if_false(), |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7822 HConstant* right_const = HConstant::cast(right); | 7822 HConstant* right_const = HConstant::cast(right); |
7823 if (right_const->HasInteger32Value() && | 7823 if (right_const->HasInteger32Value() && |
7824 (right_const->Integer32Value() & 0x1f) != 0) { | 7824 (right_const->Integer32Value() & 0x1f) != 0) { |
7825 return false; | 7825 return false; |
7826 } | 7826 } |
7827 } | 7827 } |
7828 return true; | 7828 return true; |
7829 } | 7829 } |
7830 | 7830 |
7831 | 7831 |
| 7832 HValue* HGraphBuilder::TruncateToNumber(HValue* value, Handle<Type>* expected) { |
| 7833 if (value->IsConstant()) { |
| 7834 HConstant* constant = HConstant::cast(value); |
| 7835 Maybe<HConstant*> number = constant->CopyToTruncatedNumber(zone()); |
| 7836 if (number.has_value) { |
| 7837 *expected = handle(Type::Number(), isolate()); |
| 7838 return AddInstruction(number.value); |
| 7839 } |
| 7840 return value; |
| 7841 } |
| 7842 |
| 7843 Handle<Type> expected_type = *expected; |
| 7844 Representation rep = Representation::FromType(expected_type); |
| 7845 if (!rep.IsTagged()) return value; |
| 7846 |
| 7847 // If our type feedback suggests that we can non-observably truncate to number |
| 7848 // we introduce the appropriate check here. This avoids 'value' having a |
| 7849 // tagged representation later on. |
| 7850 if (expected_type->Is(Type::Oddball())) { |
| 7851 // TODO(olivf) The BinaryOpStub only records undefined. It might pay off to |
| 7852 // also record booleans and convert them to 0/1 here. |
| 7853 IfBuilder if_nan(this); |
| 7854 if_nan.If<HCompareObjectEqAndBranch>(value, |
| 7855 graph()->GetConstantUndefined()); |
| 7856 if_nan.Then(); |
| 7857 if_nan.ElseDeopt(); |
| 7858 if_nan.End(); |
| 7859 return Add<HConstant>(OS::nan_value(), Representation::Double()); |
| 7860 } |
| 7861 |
| 7862 return value; |
| 7863 } |
| 7864 |
| 7865 |
7832 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( | 7866 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( |
7833 BinaryOperation* expr, | 7867 BinaryOperation* expr, |
7834 HValue* left, | 7868 HValue* left, |
7835 HValue* right) { | 7869 HValue* right) { |
7836 HValue* context = environment()->LookupContext(); | 7870 HValue* context = environment()->LookupContext(); |
7837 Handle<Type> left_type = expr->left()->bounds().lower; | 7871 Handle<Type> left_type = expr->left()->bounds().lower; |
7838 Handle<Type> right_type = expr->right()->bounds().lower; | 7872 Handle<Type> right_type = expr->right()->bounds().lower; |
7839 Handle<Type> result_type = expr->bounds().lower; | 7873 Handle<Type> result_type = expr->bounds().lower; |
7840 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); | 7874 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); |
7841 Representation left_rep = Representation::FromType(left_type); | 7875 Representation left_rep = Representation::FromType(left_type); |
7842 Representation right_rep = Representation::FromType(right_type); | 7876 Representation right_rep = Representation::FromType(right_type); |
7843 Representation result_rep = Representation::FromType(result_type); | 7877 Representation result_rep = Representation::FromType(result_type); |
7844 | 7878 |
| 7879 if (expr->op() != Token::ADD || |
| 7880 (left->type().IsNonString() && right->type().IsNonString())) { |
| 7881 // For addition we can only truncate the arguments to number if we can |
| 7882 // prove that we will not end up in string concatenation mode. |
| 7883 left = TruncateToNumber(left, &left_type); |
| 7884 right = TruncateToNumber(right, &right_type); |
| 7885 } |
| 7886 |
7845 if (left_type->Is(Type::None())) { | 7887 if (left_type->Is(Type::None())) { |
7846 AddSoftDeoptimize(); | 7888 AddSoftDeoptimize(); |
7847 // TODO(rossberg): we should be able to get rid of non-continuous defaults. | 7889 // TODO(rossberg): we should be able to get rid of non-continuous defaults. |
7848 left_type = handle(Type::Any(), isolate()); | 7890 left_type = handle(Type::Any(), isolate()); |
7849 } | 7891 } |
7850 if (right_type->Is(Type::None())) { | 7892 if (right_type->Is(Type::None())) { |
7851 AddSoftDeoptimize(); | 7893 AddSoftDeoptimize(); |
7852 right_type = handle(Type::Any(), isolate()); | 7894 right_type = handle(Type::Any(), isolate()); |
7853 } | 7895 } |
7854 HInstruction* instr = NULL; | 7896 HInstruction* instr = NULL; |
(...skipping 2075 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9930 if (ShouldProduceTraceOutput()) { | 9972 if (ShouldProduceTraceOutput()) { |
9931 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9973 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
9932 } | 9974 } |
9933 | 9975 |
9934 #ifdef DEBUG | 9976 #ifdef DEBUG |
9935 graph_->Verify(false); // No full verify. | 9977 graph_->Verify(false); // No full verify. |
9936 #endif | 9978 #endif |
9937 } | 9979 } |
9938 | 9980 |
9939 } } // namespace v8::internal | 9981 } } // namespace v8::internal |
OLD | NEW |