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/crankshaft/hydrogen.h" | 5 #include "src/crankshaft/hydrogen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/allocation-site-scopes.h" | 9 #include "src/allocation-site-scopes.h" |
10 #include "src/ast/ast-numbering.h" | 10 #include "src/ast/ast-numbering.h" |
(...skipping 10888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10899 return number; | 10899 return number; |
10900 } | 10900 } |
10901 | 10901 |
10902 | 10902 |
10903 HValue* HGraphBuilder::TruncateToNumber(HValue* value, Type** expected) { | 10903 HValue* HGraphBuilder::TruncateToNumber(HValue* value, Type** expected) { |
10904 if (value->IsConstant()) { | 10904 if (value->IsConstant()) { |
10905 HConstant* constant = HConstant::cast(value); | 10905 HConstant* constant = HConstant::cast(value); |
10906 Maybe<HConstant*> number = | 10906 Maybe<HConstant*> number = |
10907 constant->CopyToTruncatedNumber(isolate(), zone()); | 10907 constant->CopyToTruncatedNumber(isolate(), zone()); |
10908 if (number.IsJust()) { | 10908 if (number.IsJust()) { |
10909 *expected = Type::Number(zone()); | 10909 *expected = Type::Number(); |
10910 return AddInstruction(number.FromJust()); | 10910 return AddInstruction(number.FromJust()); |
10911 } | 10911 } |
10912 } | 10912 } |
10913 | 10913 |
10914 // We put temporary values on the stack, which don't correspond to anything | 10914 // We put temporary values on the stack, which don't correspond to anything |
10915 // in baseline code. Since nothing is observable we avoid recording those | 10915 // in baseline code. Since nothing is observable we avoid recording those |
10916 // pushes with a NoObservableSideEffectsScope. | 10916 // pushes with a NoObservableSideEffectsScope. |
10917 NoObservableSideEffectsScope no_effects(this); | 10917 NoObservableSideEffectsScope no_effects(this); |
10918 | 10918 |
10919 Type* expected_type = *expected; | 10919 Type* expected_type = *expected; |
10920 | 10920 |
10921 // Separate the number type from the rest. | 10921 // Separate the number type from the rest. |
10922 Type* expected_obj = | 10922 Type* expected_obj = |
10923 Type::Intersect(expected_type, Type::NonNumber(zone()), zone()); | 10923 Type::Intersect(expected_type, Type::NonNumber(), zone()); |
10924 Type* expected_number = | 10924 Type* expected_number = |
10925 Type::Intersect(expected_type, Type::Number(zone()), zone()); | 10925 Type::Intersect(expected_type, Type::Number(), zone()); |
10926 | 10926 |
10927 // We expect to get a number. | 10927 // We expect to get a number. |
10928 // (We need to check first, since Type::None->Is(Type::Any()) == true. | 10928 // (We need to check first, since Type::None->Is(Type::Any()) == true. |
10929 if (expected_obj->Is(Type::None())) { | 10929 if (expected_obj->Is(Type::None())) { |
10930 DCHECK(!expected_number->Is(Type::None(zone()))); | 10930 DCHECK(!expected_number->Is(Type::None())); |
10931 return value; | 10931 return value; |
10932 } | 10932 } |
10933 | 10933 |
10934 if (expected_obj->Is(Type::Undefined(zone()))) { | 10934 if (expected_obj->Is(Type::Undefined())) { |
10935 // This is already done by HChange. | 10935 // This is already done by HChange. |
10936 *expected = Type::Union(expected_number, Type::Number(zone()), zone()); | 10936 *expected = Type::Union(expected_number, Type::Number(), zone()); |
10937 return value; | 10937 return value; |
10938 } | 10938 } |
10939 | 10939 |
10940 return value; | 10940 return value; |
10941 } | 10941 } |
10942 | 10942 |
10943 | 10943 |
10944 HValue* HOptimizedGraphBuilder::BuildBinaryOperation( | 10944 HValue* HOptimizedGraphBuilder::BuildBinaryOperation( |
10945 BinaryOperation* expr, | 10945 BinaryOperation* expr, |
10946 HValue* left, | 10946 HValue* left, |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11001 right_type->Maybe(Type::Receiver())); | 11001 right_type->Maybe(Type::Receiver())); |
11002 } | 11002 } |
11003 | 11003 |
11004 Representation left_rep = RepresentationFor(left_type); | 11004 Representation left_rep = RepresentationFor(left_type); |
11005 Representation right_rep = RepresentationFor(right_type); | 11005 Representation right_rep = RepresentationFor(right_type); |
11006 | 11006 |
11007 if (!left_type->IsInhabited()) { | 11007 if (!left_type->IsInhabited()) { |
11008 Add<HDeoptimize>( | 11008 Add<HDeoptimize>( |
11009 Deoptimizer::kInsufficientTypeFeedbackForLHSOfBinaryOperation, | 11009 Deoptimizer::kInsufficientTypeFeedbackForLHSOfBinaryOperation, |
11010 Deoptimizer::SOFT); | 11010 Deoptimizer::SOFT); |
11011 left_type = Type::Any(zone()); | 11011 left_type = Type::Any(); |
11012 left_rep = RepresentationFor(left_type); | 11012 left_rep = RepresentationFor(left_type); |
11013 maybe_string_add = op == Token::ADD; | 11013 maybe_string_add = op == Token::ADD; |
11014 } | 11014 } |
11015 | 11015 |
11016 if (!right_type->IsInhabited()) { | 11016 if (!right_type->IsInhabited()) { |
11017 Add<HDeoptimize>( | 11017 Add<HDeoptimize>( |
11018 Deoptimizer::kInsufficientTypeFeedbackForRHSOfBinaryOperation, | 11018 Deoptimizer::kInsufficientTypeFeedbackForRHSOfBinaryOperation, |
11019 Deoptimizer::SOFT); | 11019 Deoptimizer::SOFT); |
11020 right_type = Type::Any(zone()); | 11020 right_type = Type::Any(); |
11021 right_rep = RepresentationFor(right_type); | 11021 right_rep = RepresentationFor(right_type); |
11022 maybe_string_add = op == Token::ADD; | 11022 maybe_string_add = op == Token::ADD; |
11023 } | 11023 } |
11024 | 11024 |
11025 if (!maybe_string_add && !is_strong(strength)) { | 11025 if (!maybe_string_add && !is_strong(strength)) { |
11026 left = TruncateToNumber(left, &left_type); | 11026 left = TruncateToNumber(left, &left_type); |
11027 right = TruncateToNumber(right, &right_type); | 11027 right = TruncateToNumber(right, &right_type); |
11028 } | 11028 } |
11029 | 11029 |
11030 // Special case for string addition here. | 11030 // Special case for string addition here. |
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11564 Token::Value op, HValue* left, HValue* right, Type* left_type, | 11564 Token::Value op, HValue* left, HValue* right, Type* left_type, |
11565 Type* right_type, Type* combined_type, SourcePosition left_position, | 11565 Type* right_type, Type* combined_type, SourcePosition left_position, |
11566 SourcePosition right_position, PushBeforeSimulateBehavior push_sim_result, | 11566 SourcePosition right_position, PushBeforeSimulateBehavior push_sim_result, |
11567 BailoutId bailout_id) { | 11567 BailoutId bailout_id) { |
11568 // Cases handled below depend on collected type feedback. They should | 11568 // Cases handled below depend on collected type feedback. They should |
11569 // soft deoptimize when there is no type feedback. | 11569 // soft deoptimize when there is no type feedback. |
11570 if (!combined_type->IsInhabited()) { | 11570 if (!combined_type->IsInhabited()) { |
11571 Add<HDeoptimize>( | 11571 Add<HDeoptimize>( |
11572 Deoptimizer::kInsufficientTypeFeedbackForCombinedTypeOfBinaryOperation, | 11572 Deoptimizer::kInsufficientTypeFeedbackForCombinedTypeOfBinaryOperation, |
11573 Deoptimizer::SOFT); | 11573 Deoptimizer::SOFT); |
11574 combined_type = left_type = right_type = Type::Any(zone()); | 11574 combined_type = left_type = right_type = Type::Any(); |
11575 } | 11575 } |
11576 | 11576 |
11577 Representation left_rep = RepresentationFor(left_type); | 11577 Representation left_rep = RepresentationFor(left_type); |
11578 Representation right_rep = RepresentationFor(right_type); | 11578 Representation right_rep = RepresentationFor(right_type); |
11579 Representation combined_rep = RepresentationFor(combined_type); | 11579 Representation combined_rep = RepresentationFor(combined_type); |
11580 | 11580 |
11581 if (combined_type->Is(Type::Receiver())) { | 11581 if (combined_type->Is(Type::Receiver())) { |
11582 if (Token::IsEqualityOp(op)) { | 11582 if (Token::IsEqualityOp(op)) { |
11583 // HCompareObjectEqAndBranch can only deal with object, so | 11583 // HCompareObjectEqAndBranch can only deal with object, so |
11584 // exclude numbers. | 11584 // exclude numbers. |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11750 if (expr->op() == Token::EQ_STRICT) { | 11750 if (expr->op() == Token::EQ_STRICT) { |
11751 HConstant* nil_constant = nil == kNullValue | 11751 HConstant* nil_constant = nil == kNullValue |
11752 ? graph()->GetConstantNull() | 11752 ? graph()->GetConstantNull() |
11753 : graph()->GetConstantUndefined(); | 11753 : graph()->GetConstantUndefined(); |
11754 HCompareObjectEqAndBranch* instr = | 11754 HCompareObjectEqAndBranch* instr = |
11755 New<HCompareObjectEqAndBranch>(value, nil_constant); | 11755 New<HCompareObjectEqAndBranch>(value, nil_constant); |
11756 return ast_context()->ReturnControl(instr, expr->id()); | 11756 return ast_context()->ReturnControl(instr, expr->id()); |
11757 } else { | 11757 } else { |
11758 DCHECK_EQ(Token::EQ, expr->op()); | 11758 DCHECK_EQ(Token::EQ, expr->op()); |
11759 Type* type = expr->combined_type()->Is(Type::None()) | 11759 Type* type = expr->combined_type()->Is(Type::None()) |
11760 ? Type::Any(zone()) : expr->combined_type(); | 11760 ? Type::Any() |
| 11761 : expr->combined_type(); |
11761 HIfContinuation continuation; | 11762 HIfContinuation continuation; |
11762 BuildCompareNil(value, type, &continuation); | 11763 BuildCompareNil(value, type, &continuation); |
11763 return ast_context()->ReturnContinuation(&continuation, expr->id()); | 11764 return ast_context()->ReturnContinuation(&continuation, expr->id()); |
11764 } | 11765 } |
11765 } | 11766 } |
11766 | 11767 |
11767 | 11768 |
11768 void HOptimizedGraphBuilder::VisitSpread(Spread* expr) { UNREACHABLE(); } | 11769 void HOptimizedGraphBuilder::VisitSpread(Spread* expr) { UNREACHABLE(); } |
11769 | 11770 |
11770 | 11771 |
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12313 return ast_context()->ReturnValue(Pop()); | 12314 return ast_context()->ReturnValue(Pop()); |
12314 } | 12315 } |
12315 } | 12316 } |
12316 | 12317 |
12317 | 12318 |
12318 void HOptimizedGraphBuilder::GenerateToName(CallRuntime* call) { | 12319 void HOptimizedGraphBuilder::GenerateToName(CallRuntime* call) { |
12319 DCHECK_EQ(1, call->arguments()->length()); | 12320 DCHECK_EQ(1, call->arguments()->length()); |
12320 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12321 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
12321 HValue* input = Pop(); | 12322 HValue* input = Pop(); |
12322 if (input->type().IsSmi()) { | 12323 if (input->type().IsSmi()) { |
12323 HValue* result = BuildNumberToString(input, Type::SignedSmall(zone())); | 12324 HValue* result = BuildNumberToString(input, Type::SignedSmall()); |
12324 return ast_context()->ReturnValue(result); | 12325 return ast_context()->ReturnValue(result); |
12325 } else if (input->type().IsTaggedNumber()) { | 12326 } else if (input->type().IsTaggedNumber()) { |
12326 HValue* result = BuildNumberToString(input, Type::Number(zone())); | 12327 HValue* result = BuildNumberToString(input, Type::Number()); |
12327 return ast_context()->ReturnValue(result); | 12328 return ast_context()->ReturnValue(result); |
12328 } else if (input->type().IsString()) { | 12329 } else if (input->type().IsString()) { |
12329 return ast_context()->ReturnValue(input); | 12330 return ast_context()->ReturnValue(input); |
12330 } else { | 12331 } else { |
12331 Callable callable = CodeFactory::ToName(isolate()); | 12332 Callable callable = CodeFactory::ToName(isolate()); |
12332 HValue* stub = Add<HConstant>(callable.code()); | 12333 HValue* stub = Add<HConstant>(callable.code()); |
12333 HValue* values[] = {context(), input}; | 12334 HValue* values[] = {context(), input}; |
12334 HInstruction* result = | 12335 HInstruction* result = |
12335 New<HCallWithDescriptor>(stub, 0, callable.descriptor(), | 12336 New<HCallWithDescriptor>(stub, 0, callable.descriptor(), |
12336 Vector<HValue*>(values, arraysize(values))); | 12337 Vector<HValue*>(values, arraysize(values))); |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12737 HValue* result = BuildRegExpConstructResult(length, index, input); | 12738 HValue* result = BuildRegExpConstructResult(length, index, input); |
12738 return ast_context()->ReturnValue(result); | 12739 return ast_context()->ReturnValue(result); |
12739 } | 12740 } |
12740 | 12741 |
12741 | 12742 |
12742 // Fast support for number to string. | 12743 // Fast support for number to string. |
12743 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { | 12744 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { |
12744 DCHECK_EQ(1, call->arguments()->length()); | 12745 DCHECK_EQ(1, call->arguments()->length()); |
12745 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12746 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
12746 HValue* number = Pop(); | 12747 HValue* number = Pop(); |
12747 HValue* result = BuildNumberToString(number, Type::Any(zone())); | 12748 HValue* result = BuildNumberToString(number, Type::Any()); |
12748 return ast_context()->ReturnValue(result); | 12749 return ast_context()->ReturnValue(result); |
12749 } | 12750 } |
12750 | 12751 |
12751 | 12752 |
12752 // Fast support for calls. | 12753 // Fast support for calls. |
12753 void HOptimizedGraphBuilder::GenerateCall(CallRuntime* call) { | 12754 void HOptimizedGraphBuilder::GenerateCall(CallRuntime* call) { |
12754 DCHECK_LE(2, call->arguments()->length()); | 12755 DCHECK_LE(2, call->arguments()->length()); |
12755 CHECK_ALIVE(VisitExpressions(call->arguments())); | 12756 CHECK_ALIVE(VisitExpressions(call->arguments())); |
12756 CallTrampolineDescriptor descriptor(isolate()); | 12757 CallTrampolineDescriptor descriptor(isolate()); |
12757 PushArgumentsFromEnvironment(call->arguments()->length() - 1); | 12758 PushArgumentsFromEnvironment(call->arguments()->length() - 1); |
(...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13664 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13665 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13665 } | 13666 } |
13666 | 13667 |
13667 #ifdef DEBUG | 13668 #ifdef DEBUG |
13668 graph_->Verify(false); // No full verify. | 13669 graph_->Verify(false); // No full verify. |
13669 #endif | 13670 #endif |
13670 } | 13671 } |
13671 | 13672 |
13672 } // namespace internal | 13673 } // namespace internal |
13673 } // namespace v8 | 13674 } // namespace v8 |
OLD | NEW |