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 10410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10421 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); | 10421 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); |
10422 Handle<AllocationSite> allocation_site = expr->allocation_site(); | 10422 Handle<AllocationSite> allocation_site = expr->allocation_site(); |
10423 | 10423 |
10424 HAllocationMode allocation_mode; | 10424 HAllocationMode allocation_mode; |
10425 if (FLAG_allocation_site_pretenuring && !allocation_site.is_null()) { | 10425 if (FLAG_allocation_site_pretenuring && !allocation_site.is_null()) { |
10426 allocation_mode = HAllocationMode(allocation_site); | 10426 allocation_mode = HAllocationMode(allocation_site); |
10427 } | 10427 } |
10428 | 10428 |
10429 HValue* result = HGraphBuilder::BuildBinaryOperation( | 10429 HValue* result = HGraphBuilder::BuildBinaryOperation( |
10430 expr->op(), left, right, left_type, right_type, result_type, | 10430 expr->op(), left, right, left_type, right_type, result_type, |
10431 fixed_right_arg, allocation_mode); | 10431 fixed_right_arg, allocation_mode, function_language_mode()); |
10432 // Add a simulate after instructions with observable side effects, and | 10432 // Add a simulate after instructions with observable side effects, and |
10433 // after phis, which are the result of BuildBinaryOperation when we | 10433 // after phis, which are the result of BuildBinaryOperation when we |
10434 // inlined some complex subgraph. | 10434 // inlined some complex subgraph. |
10435 if (result->HasObservableSideEffects() || result->IsPhi()) { | 10435 if (result->HasObservableSideEffects() || result->IsPhi()) { |
10436 if (push_sim_result == PUSH_BEFORE_SIMULATE) { | 10436 if (push_sim_result == PUSH_BEFORE_SIMULATE) { |
10437 Push(result); | 10437 Push(result); |
10438 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | 10438 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
10439 Drop(1); | 10439 Drop(1); |
10440 } else { | 10440 } else { |
10441 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | 10441 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
10442 } | 10442 } |
10443 } | 10443 } |
10444 return result; | 10444 return result; |
10445 } | 10445 } |
10446 | 10446 |
10447 | 10447 |
10448 HValue* HGraphBuilder::BuildBinaryOperation( | 10448 HValue* HGraphBuilder::BuildBinaryOperation( |
10449 Token::Value op, | 10449 Token::Value op, |
10450 HValue* left, | 10450 HValue* left, |
10451 HValue* right, | 10451 HValue* right, |
10452 Type* left_type, | 10452 Type* left_type, |
10453 Type* right_type, | 10453 Type* right_type, |
10454 Type* result_type, | 10454 Type* result_type, |
10455 Maybe<int> fixed_right_arg, | 10455 Maybe<int> fixed_right_arg, |
10456 HAllocationMode allocation_mode) { | 10456 HAllocationMode allocation_mode, |
| 10457 LanguageMode language_mode) { |
10457 Representation left_rep = RepresentationFor(left_type); | 10458 Representation left_rep = RepresentationFor(left_type); |
10458 Representation right_rep = RepresentationFor(right_type); | 10459 Representation right_rep = RepresentationFor(right_type); |
10459 | 10460 |
10460 bool maybe_string_add = op == Token::ADD && | 10461 bool maybe_string_add = op == Token::ADD && |
10461 (left_type->Maybe(Type::String()) || | 10462 (left_type->Maybe(Type::String()) || |
10462 left_type->Maybe(Type::Receiver()) || | 10463 left_type->Maybe(Type::Receiver()) || |
10463 right_type->Maybe(Type::String()) || | 10464 right_type->Maybe(Type::String()) || |
10464 right_type->Maybe(Type::Receiver())); | 10465 right_type->Maybe(Type::Receiver())); |
10465 | 10466 |
10466 if (!left_type->IsInhabited()) { | 10467 if (!left_type->IsInhabited()) { |
10467 Add<HDeoptimize>( | 10468 Add<HDeoptimize>( |
10468 Deoptimizer::kInsufficientTypeFeedbackForLHSOfBinaryOperation, | 10469 Deoptimizer::kInsufficientTypeFeedbackForLHSOfBinaryOperation, |
10469 Deoptimizer::SOFT); | 10470 is_strong(language_mode) ? Deoptimizer::EAGER : Deoptimizer::SOFT); |
10470 left_type = Type::Any(zone()); | 10471 left_type = Type::Any(zone()); |
10471 left_rep = RepresentationFor(left_type); | 10472 left_rep = RepresentationFor(left_type); |
10472 maybe_string_add = op == Token::ADD; | 10473 maybe_string_add = op == Token::ADD; |
10473 } | 10474 } |
10474 | 10475 |
10475 if (!right_type->IsInhabited()) { | 10476 if (!right_type->IsInhabited()) { |
10476 Add<HDeoptimize>( | 10477 Add<HDeoptimize>( |
10477 Deoptimizer::kInsufficientTypeFeedbackForRHSOfBinaryOperation, | 10478 Deoptimizer::kInsufficientTypeFeedbackForRHSOfBinaryOperation, |
10478 Deoptimizer::SOFT); | 10479 is_strong(language_mode) ? Deoptimizer::EAGER : Deoptimizer::SOFT); |
10479 right_type = Type::Any(zone()); | 10480 right_type = Type::Any(zone()); |
10480 right_rep = RepresentationFor(right_type); | 10481 right_rep = RepresentationFor(right_type); |
10481 maybe_string_add = op == Token::ADD; | 10482 maybe_string_add = op == Token::ADD; |
10482 } | 10483 } |
10483 | 10484 |
10484 if (!maybe_string_add) { | 10485 if (!maybe_string_add) { |
10485 left = TruncateToNumber(left, &left_type); | 10486 left = TruncateToNumber(left, &left_type); |
10486 right = TruncateToNumber(right, &right_type); | 10487 right = TruncateToNumber(right, &right_type); |
10487 } | 10488 } |
10488 | 10489 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10575 Representation result_rep = RepresentationFor(result_type); | 10576 Representation result_rep = RepresentationFor(result_type); |
10576 | 10577 |
10577 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || | 10578 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || |
10578 (right_rep.IsTagged() && !right_rep.IsSmi()); | 10579 (right_rep.IsTagged() && !right_rep.IsSmi()); |
10579 | 10580 |
10580 HInstruction* instr = NULL; | 10581 HInstruction* instr = NULL; |
10581 // Only the stub is allowed to call into the runtime, since otherwise we would | 10582 // Only the stub is allowed to call into the runtime, since otherwise we would |
10582 // inline several instructions (including the two pushes) for every tagged | 10583 // inline several instructions (including the two pushes) for every tagged |
10583 // operation in optimized code, which is more expensive, than a stub call. | 10584 // operation in optimized code, which is more expensive, than a stub call. |
10584 if (graph()->info()->IsStub() && is_non_primitive) { | 10585 if (graph()->info()->IsStub() && is_non_primitive) { |
10585 HValue* function = AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op)); | 10586 HValue* function = AddLoadJSBuiltin( |
| 10587 BinaryOpIC::TokenToJSBuiltin(op, language_mode)); |
10586 Add<HPushArguments>(left, right); | 10588 Add<HPushArguments>(left, right); |
10587 instr = AddUncasted<HInvokeFunction>(function, 2); | 10589 instr = AddUncasted<HInvokeFunction>(function, 2); |
10588 } else { | 10590 } else { |
10589 switch (op) { | 10591 switch (op) { |
10590 case Token::ADD: | 10592 case Token::ADD: |
10591 instr = AddUncasted<HAdd>(left, right); | 10593 instr = AddUncasted<HAdd>(left, right); |
10592 break; | 10594 break; |
10593 case Token::SUB: | 10595 case Token::SUB: |
10594 instr = AddUncasted<HSub>(left, right); | 10596 instr = AddUncasted<HSub>(left, right); |
10595 break; | 10597 break; |
(...skipping 2398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12994 if (ShouldProduceTraceOutput()) { | 12996 if (ShouldProduceTraceOutput()) { |
12995 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12997 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
12996 } | 12998 } |
12997 | 12999 |
12998 #ifdef DEBUG | 13000 #ifdef DEBUG |
12999 graph_->Verify(false); // No full verify. | 13001 graph_->Verify(false); // No full verify. |
13000 #endif | 13002 #endif |
13001 } | 13003 } |
13002 | 13004 |
13003 } } // namespace v8::internal | 13005 } } // namespace v8::internal |
OLD | NEW |