| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/hydrogen.h" | 5 #include "src/hydrogen.h" |
| 6 | 6 |
| 7 #include <sstream> | 7 #include <sstream> |
| 8 | 8 |
| 9 #include "src/v8.h" | 9 #include "src/v8.h" |
| 10 | 10 |
| (...skipping 10062 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10073 materialize_true = NULL; | 10073 materialize_true = NULL; |
| 10074 } | 10074 } |
| 10075 | 10075 |
| 10076 HBasicBlock* join = | 10076 HBasicBlock* join = |
| 10077 CreateJoin(materialize_false, materialize_true, expr->id()); | 10077 CreateJoin(materialize_false, materialize_true, expr->id()); |
| 10078 set_current_block(join); | 10078 set_current_block(join); |
| 10079 if (join != NULL) return ast_context()->ReturnValue(Pop()); | 10079 if (join != NULL) return ast_context()->ReturnValue(Pop()); |
| 10080 } | 10080 } |
| 10081 | 10081 |
| 10082 | 10082 |
| 10083 static Representation RepresentationFor(Type* type) { |
| 10084 DisallowHeapAllocation no_allocation; |
| 10085 if (type->Is(Type::None())) return Representation::None(); |
| 10086 if (type->Is(Type::SignedSmall())) return Representation::Smi(); |
| 10087 if (type->Is(Type::Signed32())) return Representation::Integer32(); |
| 10088 if (type->Is(Type::Number())) return Representation::Double(); |
| 10089 return Representation::Tagged(); |
| 10090 } |
| 10091 |
| 10092 |
| 10083 HInstruction* HOptimizedGraphBuilder::BuildIncrement( | 10093 HInstruction* HOptimizedGraphBuilder::BuildIncrement( |
| 10084 bool returns_original_input, | 10094 bool returns_original_input, |
| 10085 CountOperation* expr) { | 10095 CountOperation* expr) { |
| 10086 // The input to the count operation is on top of the expression stack. | 10096 // The input to the count operation is on top of the expression stack. |
| 10087 Representation rep = Representation::FromType(expr->type()); | 10097 Representation rep = RepresentationFor(expr->type()); |
| 10088 if (rep.IsNone() || rep.IsTagged()) { | 10098 if (rep.IsNone() || rep.IsTagged()) { |
| 10089 rep = Representation::Smi(); | 10099 rep = Representation::Smi(); |
| 10090 } | 10100 } |
| 10091 | 10101 |
| 10092 if (returns_original_input) { | 10102 if (returns_original_input) { |
| 10093 // We need an explicit HValue representing ToNumber(input). The | 10103 // We need an explicit HValue representing ToNumber(input). The |
| 10094 // actual HChange instruction we need is (sometimes) added in a later | 10104 // actual HChange instruction we need is (sometimes) added in a later |
| 10095 // phase, so it is not available now to be used as an input to HAdd and | 10105 // phase, so it is not available now to be used as an input to HAdd and |
| 10096 // as the return value. | 10106 // as the return value. |
| 10097 HInstruction* number_input = AddUncasted<HForceRepresentation>(Pop(), rep); | 10107 HInstruction* number_input = AddUncasted<HForceRepresentation>(Pop(), rep); |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10421 | 10431 |
| 10422 HValue* HGraphBuilder::BuildBinaryOperation( | 10432 HValue* HGraphBuilder::BuildBinaryOperation( |
| 10423 Token::Value op, | 10433 Token::Value op, |
| 10424 HValue* left, | 10434 HValue* left, |
| 10425 HValue* right, | 10435 HValue* right, |
| 10426 Type* left_type, | 10436 Type* left_type, |
| 10427 Type* right_type, | 10437 Type* right_type, |
| 10428 Type* result_type, | 10438 Type* result_type, |
| 10429 Maybe<int> fixed_right_arg, | 10439 Maybe<int> fixed_right_arg, |
| 10430 HAllocationMode allocation_mode) { | 10440 HAllocationMode allocation_mode) { |
| 10431 | 10441 Representation left_rep = RepresentationFor(left_type); |
| 10432 Representation left_rep = Representation::FromType(left_type); | 10442 Representation right_rep = RepresentationFor(right_type); |
| 10433 Representation right_rep = Representation::FromType(right_type); | |
| 10434 | 10443 |
| 10435 bool maybe_string_add = op == Token::ADD && | 10444 bool maybe_string_add = op == Token::ADD && |
| 10436 (left_type->Maybe(Type::String()) || | 10445 (left_type->Maybe(Type::String()) || |
| 10437 left_type->Maybe(Type::Receiver()) || | 10446 left_type->Maybe(Type::Receiver()) || |
| 10438 right_type->Maybe(Type::String()) || | 10447 right_type->Maybe(Type::String()) || |
| 10439 right_type->Maybe(Type::Receiver())); | 10448 right_type->Maybe(Type::Receiver())); |
| 10440 | 10449 |
| 10441 if (!left_type->IsInhabited()) { | 10450 if (!left_type->IsInhabited()) { |
| 10442 Add<HDeoptimize>( | 10451 Add<HDeoptimize>( |
| 10443 Deoptimizer::kInsufficientTypeFeedbackForLHSOfBinaryOperation, | 10452 Deoptimizer::kInsufficientTypeFeedbackForLHSOfBinaryOperation, |
| 10444 Deoptimizer::SOFT); | 10453 Deoptimizer::SOFT); |
| 10445 left_type = Type::Any(zone()); | 10454 left_type = Type::Any(zone()); |
| 10446 left_rep = Representation::FromType(left_type); | 10455 left_rep = RepresentationFor(left_type); |
| 10447 maybe_string_add = op == Token::ADD; | 10456 maybe_string_add = op == Token::ADD; |
| 10448 } | 10457 } |
| 10449 | 10458 |
| 10450 if (!right_type->IsInhabited()) { | 10459 if (!right_type->IsInhabited()) { |
| 10451 Add<HDeoptimize>( | 10460 Add<HDeoptimize>( |
| 10452 Deoptimizer::kInsufficientTypeFeedbackForRHSOfBinaryOperation, | 10461 Deoptimizer::kInsufficientTypeFeedbackForRHSOfBinaryOperation, |
| 10453 Deoptimizer::SOFT); | 10462 Deoptimizer::SOFT); |
| 10454 right_type = Type::Any(zone()); | 10463 right_type = Type::Any(zone()); |
| 10455 right_rep = Representation::FromType(right_type); | 10464 right_rep = RepresentationFor(right_type); |
| 10456 maybe_string_add = op == Token::ADD; | 10465 maybe_string_add = op == Token::ADD; |
| 10457 } | 10466 } |
| 10458 | 10467 |
| 10459 if (!maybe_string_add) { | 10468 if (!maybe_string_add) { |
| 10460 left = TruncateToNumber(left, &left_type); | 10469 left = TruncateToNumber(left, &left_type); |
| 10461 right = TruncateToNumber(right, &right_type); | 10470 right = TruncateToNumber(right, &right_type); |
| 10462 } | 10471 } |
| 10463 | 10472 |
| 10464 // Special case for string addition here. | 10473 // Special case for string addition here. |
| 10465 if (op == Token::ADD && | 10474 if (op == Token::ADD && |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10540 return AddUncasted<HStringAdd>( | 10549 return AddUncasted<HStringAdd>( |
| 10541 left, right, allocation_mode.GetPretenureMode(), | 10550 left, right, allocation_mode.GetPretenureMode(), |
| 10542 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site()); | 10551 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site()); |
| 10543 } | 10552 } |
| 10544 | 10553 |
| 10545 if (graph()->info()->IsStub()) { | 10554 if (graph()->info()->IsStub()) { |
| 10546 left = EnforceNumberType(left, left_type); | 10555 left = EnforceNumberType(left, left_type); |
| 10547 right = EnforceNumberType(right, right_type); | 10556 right = EnforceNumberType(right, right_type); |
| 10548 } | 10557 } |
| 10549 | 10558 |
| 10550 Representation result_rep = Representation::FromType(result_type); | 10559 Representation result_rep = RepresentationFor(result_type); |
| 10551 | 10560 |
| 10552 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || | 10561 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || |
| 10553 (right_rep.IsTagged() && !right_rep.IsSmi()); | 10562 (right_rep.IsTagged() && !right_rep.IsSmi()); |
| 10554 | 10563 |
| 10555 HInstruction* instr = NULL; | 10564 HInstruction* instr = NULL; |
| 10556 // Only the stub is allowed to call into the runtime, since otherwise we would | 10565 // Only the stub is allowed to call into the runtime, since otherwise we would |
| 10557 // inline several instructions (including the two pushes) for every tagged | 10566 // inline several instructions (including the two pushes) for every tagged |
| 10558 // operation in optimized code, which is more expensive, than a stub call. | 10567 // operation in optimized code, which is more expensive, than a stub call. |
| 10559 if (graph()->info()->IsStub() && is_non_primitive) { | 10568 if (graph()->info()->IsStub() && is_non_primitive) { |
| 10560 HValue* function = AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op)); | 10569 HValue* function = AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op)); |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10922 BailoutId bailout_id) { | 10931 BailoutId bailout_id) { |
| 10923 // Cases handled below depend on collected type feedback. They should | 10932 // Cases handled below depend on collected type feedback. They should |
| 10924 // soft deoptimize when there is no type feedback. | 10933 // soft deoptimize when there is no type feedback. |
| 10925 if (!combined_type->IsInhabited()) { | 10934 if (!combined_type->IsInhabited()) { |
| 10926 Add<HDeoptimize>( | 10935 Add<HDeoptimize>( |
| 10927 Deoptimizer::kInsufficientTypeFeedbackForCombinedTypeOfBinaryOperation, | 10936 Deoptimizer::kInsufficientTypeFeedbackForCombinedTypeOfBinaryOperation, |
| 10928 Deoptimizer::SOFT); | 10937 Deoptimizer::SOFT); |
| 10929 combined_type = left_type = right_type = Type::Any(zone()); | 10938 combined_type = left_type = right_type = Type::Any(zone()); |
| 10930 } | 10939 } |
| 10931 | 10940 |
| 10932 Representation left_rep = Representation::FromType(left_type); | 10941 Representation left_rep = RepresentationFor(left_type); |
| 10933 Representation right_rep = Representation::FromType(right_type); | 10942 Representation right_rep = RepresentationFor(right_type); |
| 10934 Representation combined_rep = Representation::FromType(combined_type); | 10943 Representation combined_rep = RepresentationFor(combined_type); |
| 10935 | 10944 |
| 10936 if (combined_type->Is(Type::Receiver())) { | 10945 if (combined_type->Is(Type::Receiver())) { |
| 10937 if (Token::IsEqualityOp(op)) { | 10946 if (Token::IsEqualityOp(op)) { |
| 10938 // HCompareObjectEqAndBranch can only deal with object, so | 10947 // HCompareObjectEqAndBranch can only deal with object, so |
| 10939 // exclude numbers. | 10948 // exclude numbers. |
| 10940 if ((left->IsConstant() && | 10949 if ((left->IsConstant() && |
| 10941 HConstant::cast(left)->HasNumberValue()) || | 10950 HConstant::cast(left)->HasNumberValue()) || |
| 10942 (right->IsConstant() && | 10951 (right->IsConstant() && |
| 10943 HConstant::cast(right)->HasNumberValue())) { | 10952 HConstant::cast(right)->HasNumberValue())) { |
| 10944 Add<HDeoptimize>(Deoptimizer::kTypeMismatchBetweenFeedbackAndConstant, | 10953 Add<HDeoptimize>(Deoptimizer::kTypeMismatchBetweenFeedbackAndConstant, |
| (...skipping 2024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12969 if (ShouldProduceTraceOutput()) { | 12978 if (ShouldProduceTraceOutput()) { |
| 12970 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12979 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 12971 } | 12980 } |
| 12972 | 12981 |
| 12973 #ifdef DEBUG | 12982 #ifdef DEBUG |
| 12974 graph_->Verify(false); // No full verify. | 12983 graph_->Verify(false); // No full verify. |
| 12975 #endif | 12984 #endif |
| 12976 } | 12985 } |
| 12977 | 12986 |
| 12978 } } // namespace v8::internal | 12987 } } // namespace v8::internal |
| OLD | NEW |