| 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/allocation-site-scopes.h" | 9 #include "src/allocation-site-scopes.h" |
| 10 #include "src/ast-numbering.h" | 10 #include "src/ast-numbering.h" |
| (...skipping 10996 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11007 if (right_type->Is(Type::String())) { | 11007 if (right_type->Is(Type::String())) { |
| 11008 right = BuildCheckString(right); | 11008 right = BuildCheckString(right); |
| 11009 } | 11009 } |
| 11010 | 11010 |
| 11011 // Convert left argument as necessary. | 11011 // Convert left argument as necessary. |
| 11012 if (left_type->Is(Type::Number())) { | 11012 if (left_type->Is(Type::Number())) { |
| 11013 DCHECK(right_type->Is(Type::String())); | 11013 DCHECK(right_type->Is(Type::String())); |
| 11014 left = BuildNumberToString(left, left_type); | 11014 left = BuildNumberToString(left, left_type); |
| 11015 } else if (!left_type->Is(Type::String())) { | 11015 } else if (!left_type->Is(Type::String())) { |
| 11016 DCHECK(right_type->Is(Type::String())); | 11016 DCHECK(right_type->Is(Type::String())); |
| 11017 // TODO(bmeurer): We might want to optimize this, because we already | 11017 return AddUncasted<HStringAdd>( |
| 11018 // know that the right hand side is a string. | 11018 left, right, allocation_mode.GetPretenureMode(), |
| 11019 Add<HPushArguments>(left, right); | 11019 STRING_ADD_CONVERT_LEFT, allocation_mode.feedback_site()); |
| 11020 return AddUncasted<HCallRuntime>(Runtime::FunctionForId(Runtime::kAdd), | |
| 11021 2); | |
| 11022 } | 11020 } |
| 11023 | 11021 |
| 11024 // Convert right argument as necessary. | 11022 // Convert right argument as necessary. |
| 11025 if (right_type->Is(Type::Number())) { | 11023 if (right_type->Is(Type::Number())) { |
| 11026 DCHECK(left_type->Is(Type::String())); | 11024 DCHECK(left_type->Is(Type::String())); |
| 11027 right = BuildNumberToString(right, right_type); | 11025 right = BuildNumberToString(right, right_type); |
| 11028 } else if (!right_type->Is(Type::String())) { | 11026 } else if (!right_type->Is(Type::String())) { |
| 11029 DCHECK(left_type->Is(Type::String())); | 11027 DCHECK(left_type->Is(Type::String())); |
| 11030 // TODO(bmeurer): We might want to optimize this, because we already | 11028 return AddUncasted<HStringAdd>( |
| 11031 // know that the left hand side is a string. | 11029 left, right, allocation_mode.GetPretenureMode(), |
| 11032 Add<HPushArguments>(left, right); | 11030 STRING_ADD_CONVERT_RIGHT, allocation_mode.feedback_site()); |
| 11033 return AddUncasted<HCallRuntime>(Runtime::FunctionForId(Runtime::kAdd), | |
| 11034 2); | |
| 11035 } | 11031 } |
| 11036 } | 11032 } |
| 11037 | 11033 |
| 11038 // Fast paths for empty constant strings. | 11034 // Fast paths for empty constant strings. |
| 11039 Handle<String> left_string = | 11035 Handle<String> left_string = |
| 11040 left->IsConstant() && HConstant::cast(left)->HasStringValue() | 11036 left->IsConstant() && HConstant::cast(left)->HasStringValue() |
| 11041 ? HConstant::cast(left)->StringValue() | 11037 ? HConstant::cast(left)->StringValue() |
| 11042 : Handle<String>(); | 11038 : Handle<String>(); |
| 11043 Handle<String> right_string = | 11039 Handle<String> right_string = |
| 11044 right->IsConstant() && HConstant::cast(right)->HasStringValue() | 11040 right->IsConstant() && HConstant::cast(right)->HasStringValue() |
| 11045 ? HConstant::cast(right)->StringValue() | 11041 ? HConstant::cast(right)->StringValue() |
| 11046 : Handle<String>(); | 11042 : Handle<String>(); |
| 11047 if (!left_string.is_null() && left_string->length() == 0) return right; | 11043 if (!left_string.is_null() && left_string->length() == 0) return right; |
| 11048 if (!right_string.is_null() && right_string->length() == 0) return left; | 11044 if (!right_string.is_null() && right_string->length() == 0) return left; |
| 11049 if (!left_string.is_null() && !right_string.is_null()) { | 11045 if (!left_string.is_null() && !right_string.is_null()) { |
| 11050 return AddUncasted<HStringAdd>( | 11046 return AddUncasted<HStringAdd>( |
| 11051 left, right, strength, allocation_mode.GetPretenureMode(), | 11047 left, right, allocation_mode.GetPretenureMode(), |
| 11052 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site()); | 11048 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site()); |
| 11053 } | 11049 } |
| 11054 | 11050 |
| 11055 // Register the dependent code with the allocation site. | 11051 // Register the dependent code with the allocation site. |
| 11056 if (!allocation_mode.feedback_site().is_null()) { | 11052 if (!allocation_mode.feedback_site().is_null()) { |
| 11057 DCHECK(!graph()->info()->IsStub()); | 11053 DCHECK(!graph()->info()->IsStub()); |
| 11058 Handle<AllocationSite> site(allocation_mode.feedback_site()); | 11054 Handle<AllocationSite> site(allocation_mode.feedback_site()); |
| 11059 top_info()->dependencies()->AssumeTenuringDecision(site); | 11055 top_info()->dependencies()->AssumeTenuringDecision(site); |
| 11060 } | 11056 } |
| 11061 | 11057 |
| 11062 // Inline the string addition into the stub when creating allocation | 11058 // Inline the string addition into the stub when creating allocation |
| 11063 // mementos to gather allocation site feedback, or if we can statically | 11059 // mementos to gather allocation site feedback, or if we can statically |
| 11064 // infer that we're going to create a cons string. | 11060 // infer that we're going to create a cons string. |
| 11065 if ((graph()->info()->IsStub() && | 11061 if ((graph()->info()->IsStub() && |
| 11066 allocation_mode.CreateAllocationMementos()) || | 11062 allocation_mode.CreateAllocationMementos()) || |
| 11067 (left->IsConstant() && | 11063 (left->IsConstant() && |
| 11068 HConstant::cast(left)->HasStringValue() && | 11064 HConstant::cast(left)->HasStringValue() && |
| 11069 HConstant::cast(left)->StringValue()->length() + 1 >= | 11065 HConstant::cast(left)->StringValue()->length() + 1 >= |
| 11070 ConsString::kMinLength) || | 11066 ConsString::kMinLength) || |
| 11071 (right->IsConstant() && | 11067 (right->IsConstant() && |
| 11072 HConstant::cast(right)->HasStringValue() && | 11068 HConstant::cast(right)->HasStringValue() && |
| 11073 HConstant::cast(right)->StringValue()->length() + 1 >= | 11069 HConstant::cast(right)->StringValue()->length() + 1 >= |
| 11074 ConsString::kMinLength)) { | 11070 ConsString::kMinLength)) { |
| 11075 return BuildStringAdd(left, right, allocation_mode); | 11071 return BuildStringAdd(left, right, allocation_mode); |
| 11076 } | 11072 } |
| 11077 | 11073 |
| 11078 // Fallback to using the string add stub. | 11074 // Fallback to using the string add stub. |
| 11079 return AddUncasted<HStringAdd>( | 11075 return AddUncasted<HStringAdd>( |
| 11080 left, right, strength, allocation_mode.GetPretenureMode(), | 11076 left, right, allocation_mode.GetPretenureMode(), STRING_ADD_CHECK_NONE, |
| 11081 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site()); | 11077 allocation_mode.feedback_site()); |
| 11082 } | 11078 } |
| 11083 | 11079 |
| 11084 if (graph()->info()->IsStub()) { | 11080 if (graph()->info()->IsStub()) { |
| 11085 left = EnforceNumberType(left, left_type); | 11081 left = EnforceNumberType(left, left_type); |
| 11086 right = EnforceNumberType(right, right_type); | 11082 right = EnforceNumberType(right, right_type); |
| 11087 } | 11083 } |
| 11088 | 11084 |
| 11089 Representation result_rep = RepresentationFor(result_type); | 11085 Representation result_rep = RepresentationFor(result_type); |
| 11090 | 11086 |
| 11091 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || | 11087 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || |
| (...skipping 1437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12529 } | 12525 } |
| 12530 | 12526 |
| 12531 | 12527 |
| 12532 // Fast support for StringAdd. | 12528 // Fast support for StringAdd. |
| 12533 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { | 12529 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { |
| 12534 DCHECK_EQ(2, call->arguments()->length()); | 12530 DCHECK_EQ(2, call->arguments()->length()); |
| 12535 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12531 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 12536 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 12532 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
| 12537 HValue* right = Pop(); | 12533 HValue* right = Pop(); |
| 12538 HValue* left = Pop(); | 12534 HValue* left = Pop(); |
| 12539 HInstruction* result = | 12535 HInstruction* result = NewUncasted<HStringAdd>(left, right); |
| 12540 NewUncasted<HStringAdd>(left, right, strength(function_language_mode())); | |
| 12541 return ast_context()->ReturnInstruction(result, call->id()); | 12536 return ast_context()->ReturnInstruction(result, call->id()); |
| 12542 } | 12537 } |
| 12543 | 12538 |
| 12544 | 12539 |
| 12545 // Fast support for SubString. | 12540 // Fast support for SubString. |
| 12546 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { | 12541 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { |
| 12547 DCHECK_EQ(3, call->arguments()->length()); | 12542 DCHECK_EQ(3, call->arguments()->length()); |
| 12548 CHECK_ALIVE(VisitExpressions(call->arguments())); | 12543 CHECK_ALIVE(VisitExpressions(call->arguments())); |
| 12549 PushArgumentsFromEnvironment(call->arguments()->length()); | 12544 PushArgumentsFromEnvironment(call->arguments()->length()); |
| 12550 HCallStub* result = New<HCallStub>(CodeStub::SubString, 3); | 12545 HCallStub* result = New<HCallStub>(CodeStub::SubString, 3); |
| (...skipping 1057 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13608 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13603 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13609 } | 13604 } |
| 13610 | 13605 |
| 13611 #ifdef DEBUG | 13606 #ifdef DEBUG |
| 13612 graph_->Verify(false); // No full verify. | 13607 graph_->Verify(false); // No full verify. |
| 13613 #endif | 13608 #endif |
| 13614 } | 13609 } |
| 13615 | 13610 |
| 13616 } // namespace internal | 13611 } // namespace internal |
| 13617 } // namespace v8 | 13612 } // namespace v8 |
| OLD | NEW |