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 3094 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3105 instruction->DeleteAndReplaceWith(instruction->RedefinedOperand()); | 3105 instruction->DeleteAndReplaceWith(instruction->RedefinedOperand()); |
3106 } else { | 3106 } else { |
3107 instruction->ReplaceAllUsesWith(instruction->ActualValue()); | 3107 instruction->ReplaceAllUsesWith(instruction->ActualValue()); |
3108 } | 3108 } |
3109 } | 3109 } |
3110 } | 3110 } |
3111 } | 3111 } |
3112 } | 3112 } |
3113 | 3113 |
3114 | 3114 |
3115 void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { | 3115 void HGraphBuilder::PushAndAdd(HInstruction* instr) { |
3116 Push(instr); | 3116 Push(instr); |
3117 AddInstruction(instr); | 3117 AddInstruction(instr); |
3118 } | 3118 } |
3119 | 3119 |
3120 | 3120 |
3121 template <class Instruction> | 3121 template <class Instruction> |
3122 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { | 3122 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { |
3123 int count = call->argument_count(); | 3123 int count = call->argument_count(); |
3124 ZoneList<HValue*> arguments(count, zone()); | 3124 ZoneList<HValue*> arguments(count, zone()); |
3125 for (int i = 0; i < count; ++i) { | 3125 for (int i = 0; i < count; ++i) { |
(...skipping 4327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7453 CHECK_ALIVE(VisitForTypeOf(expr->expression())); | 7453 CHECK_ALIVE(VisitForTypeOf(expr->expression())); |
7454 HValue* value = Pop(); | 7454 HValue* value = Pop(); |
7455 HValue* context = environment()->LookupContext(); | 7455 HValue* context = environment()->LookupContext(); |
7456 HInstruction* instr = new(zone()) HTypeof(context, value); | 7456 HInstruction* instr = new(zone()) HTypeof(context, value); |
7457 return ast_context()->ReturnInstruction(instr, expr->id()); | 7457 return ast_context()->ReturnInstruction(instr, expr->id()); |
7458 } | 7458 } |
7459 | 7459 |
7460 | 7460 |
7461 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { | 7461 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { |
7462 CHECK_ALIVE(VisitForValue(expr->expression())); | 7462 CHECK_ALIVE(VisitForValue(expr->expression())); |
7463 HValue* value = Pop(); | |
7464 Handle<Type> operand_type = expr->expression()->bounds().lower; | 7463 Handle<Type> operand_type = expr->expression()->bounds().lower; |
| 7464 HValue* value = TruncateToNumber(Pop(), &operand_type); |
7465 HInstruction* instr = BuildUnaryMathOp(value, operand_type, Token::SUB); | 7465 HInstruction* instr = BuildUnaryMathOp(value, operand_type, Token::SUB); |
7466 return ast_context()->ReturnInstruction(instr, expr->id()); | 7466 return ast_context()->ReturnInstruction(instr, expr->id()); |
7467 } | 7467 } |
7468 | 7468 |
7469 | 7469 |
7470 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { | 7470 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { |
7471 CHECK_ALIVE(VisitForValue(expr->expression())); | 7471 CHECK_ALIVE(VisitForValue(expr->expression())); |
7472 HValue* value = Pop(); | |
7473 Handle<Type> operand_type = expr->expression()->bounds().lower; | 7472 Handle<Type> operand_type = expr->expression()->bounds().lower; |
| 7473 HValue* value = TruncateToNumber(Pop(), &operand_type); |
7474 HInstruction* instr = BuildUnaryMathOp(value, operand_type, Token::BIT_NOT); | 7474 HInstruction* instr = BuildUnaryMathOp(value, operand_type, Token::BIT_NOT); |
7475 return ast_context()->ReturnInstruction(instr, expr->id()); | 7475 return ast_context()->ReturnInstruction(instr, expr->id()); |
7476 } | 7476 } |
7477 | 7477 |
7478 | 7478 |
7479 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { | 7479 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { |
7480 if (ast_context()->IsTest()) { | 7480 if (ast_context()->IsTest()) { |
7481 TestContext* context = TestContext::cast(ast_context()); | 7481 TestContext* context = TestContext::cast(ast_context()); |
7482 VisitForControl(expr->expression(), | 7482 VisitForControl(expr->expression(), |
7483 context->if_false(), | 7483 context->if_false(), |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7793 HConstant* right_const = HConstant::cast(right); | 7793 HConstant* right_const = HConstant::cast(right); |
7794 if (right_const->HasInteger32Value() && | 7794 if (right_const->HasInteger32Value() && |
7795 (right_const->Integer32Value() & 0x1f) != 0) { | 7795 (right_const->Integer32Value() & 0x1f) != 0) { |
7796 return false; | 7796 return false; |
7797 } | 7797 } |
7798 } | 7798 } |
7799 return true; | 7799 return true; |
7800 } | 7800 } |
7801 | 7801 |
7802 | 7802 |
| 7803 HValue* HGraphBuilder::TruncateToNumber(HValue* value, Handle<Type>* expected) { |
| 7804 if (value->IsConstant()) { |
| 7805 HConstant* constant = HConstant::cast(value); |
| 7806 Maybe<HConstant*> number = constant->CopyToTruncatedNumber(zone()); |
| 7807 if (number.has_value) { |
| 7808 *expected = handle(Type::Number(), isolate()); |
| 7809 return AddInstruction(number.value); |
| 7810 } |
| 7811 return value; |
| 7812 } |
| 7813 |
| 7814 Handle<Type> expected_type = *expected; |
| 7815 Representation rep = Representation::FromType(expected_type); |
| 7816 if (!rep.IsTagged()) return value; |
| 7817 |
| 7818 // If our type feedback suggests that we can non-observably truncate to number |
| 7819 // we introduce the appropriate check here. This avoids 'value' having a |
| 7820 // tagged representation later on. |
| 7821 if (expected_type->Is(Type::Oddball())) { |
| 7822 // TODO(olivf) The BinaryOpStub only records undefined. It might pay off to |
| 7823 // also record booleans and convert them to 0/1 here. |
| 7824 IfBuilder if_nan(this); |
| 7825 if_nan.If<HCompareObjectEqAndBranch>(value, |
| 7826 graph()->GetConstantUndefined()); |
| 7827 if_nan.Then(); |
| 7828 if_nan.ElseDeopt(); |
| 7829 if_nan.End(); |
| 7830 return Add<HConstant>(OS::nan_value(), Representation::Double()); |
| 7831 } |
| 7832 |
| 7833 return value; |
| 7834 } |
| 7835 |
| 7836 |
7803 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( | 7837 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( |
7804 BinaryOperation* expr, | 7838 BinaryOperation* expr, |
7805 HValue* left, | 7839 HValue* left, |
7806 HValue* right) { | 7840 HValue* right) { |
7807 HValue* context = environment()->LookupContext(); | 7841 HValue* context = environment()->LookupContext(); |
7808 Handle<Type> left_type = expr->left()->bounds().lower; | 7842 Handle<Type> left_type = expr->left()->bounds().lower; |
7809 Handle<Type> right_type = expr->right()->bounds().lower; | 7843 Handle<Type> right_type = expr->right()->bounds().lower; |
7810 Handle<Type> result_type = expr->bounds().lower; | 7844 Handle<Type> result_type = expr->bounds().lower; |
7811 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); | 7845 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); |
7812 Representation left_rep = Representation::FromType(left_type); | 7846 Representation left_rep = Representation::FromType(left_type); |
7813 Representation right_rep = Representation::FromType(right_type); | 7847 Representation right_rep = Representation::FromType(right_type); |
7814 Representation result_rep = Representation::FromType(result_type); | 7848 Representation result_rep = Representation::FromType(result_type); |
7815 | 7849 |
| 7850 if (expr->op() != Token::ADD || |
| 7851 (left->type().IsNonString() && right->type().IsNonString())) { |
| 7852 // For addition we can only truncate the arguments to number if we can |
| 7853 // prove that we will not end up in string concatenation mode. |
| 7854 left = TruncateToNumber(left, &left_type); |
| 7855 right = TruncateToNumber(right, &right_type); |
| 7856 } |
| 7857 |
7816 if (left_type->Is(Type::None())) { | 7858 if (left_type->Is(Type::None())) { |
7817 AddSoftDeoptimize(); | 7859 AddSoftDeoptimize(); |
7818 // TODO(rossberg): we should be able to get rid of non-continuous defaults. | 7860 // TODO(rossberg): we should be able to get rid of non-continuous defaults. |
7819 left_type = handle(Type::Any(), isolate()); | 7861 left_type = handle(Type::Any(), isolate()); |
7820 } | 7862 } |
7821 if (right_type->Is(Type::None())) { | 7863 if (right_type->Is(Type::None())) { |
7822 AddSoftDeoptimize(); | 7864 AddSoftDeoptimize(); |
7823 right_type = handle(Type::Any(), isolate()); | 7865 right_type = handle(Type::Any(), isolate()); |
7824 } | 7866 } |
7825 HInstruction* instr = NULL; | 7867 HInstruction* instr = NULL; |
(...skipping 2078 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9904 if (ShouldProduceTraceOutput()) { | 9946 if (ShouldProduceTraceOutput()) { |
9905 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9947 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
9906 } | 9948 } |
9907 | 9949 |
9908 #ifdef DEBUG | 9950 #ifdef DEBUG |
9909 graph_->Verify(false); // No full verify. | 9951 graph_->Verify(false); // No full verify. |
9910 #endif | 9952 #endif |
9911 } | 9953 } |
9912 | 9954 |
9913 } } // namespace v8::internal | 9955 } } // namespace v8::internal |
OLD | NEW |