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 |