Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index 939cd92605191d70782d882765df9e7e56d7fdcd..33c90c238775fcffff7bc242fd0e5d51a4bd2e2e 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -2411,55 +2411,65 @@ HValue* HGraphBuilder::BuildUncheckedStringAdd( |
STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0); |
HValue* size = BuildObjectSizeAlignment(Pop(), SeqString::kHeaderSize); |
- // Allocate the string object. HAllocate does not care whether we pass |
- // STRING_TYPE or ONE_BYTE_STRING_TYPE here, so we just use STRING_TYPE. |
- HAllocate* result = BuildAllocate( |
- size, HType::String(), STRING_TYPE, allocation_mode); |
- Add<HStoreNamedField>(result, HObjectAccess::ForMap(), map); |
- |
- // Initialize the string fields. |
- Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(), |
- Add<HConstant>(String::kEmptyHashField)); |
- Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length); |
- |
- // Copy characters to the result string. |
- IfBuilder if_twobyte(this); |
- if_twobyte.If<HCompareObjectEqAndBranch>(map, string_map); |
- if_twobyte.Then(); |
+ IfBuilder if_size(this); |
+ if_size.If<HCompareNumericAndBranch>( |
+ size, Add<HConstant>(Page::kMaxRegularHeapObjectSize), Token::LT); |
+ if_size.Then(); |
{ |
- // Copy characters from the left string. |
- BuildCopySeqStringChars( |
- left, graph()->GetConstant0(), String::TWO_BYTE_ENCODING, |
- result, graph()->GetConstant0(), String::TWO_BYTE_ENCODING, |
- left_length); |
- |
- // Copy characters from the right string. |
- BuildCopySeqStringChars( |
- right, graph()->GetConstant0(), String::TWO_BYTE_ENCODING, |
- result, left_length, String::TWO_BYTE_ENCODING, |
- right_length); |
- } |
- if_twobyte.Else(); |
- { |
- // Copy characters from the left string. |
- BuildCopySeqStringChars( |
- left, graph()->GetConstant0(), String::ONE_BYTE_ENCODING, |
- result, graph()->GetConstant0(), String::ONE_BYTE_ENCODING, |
- left_length); |
+ // Allocate the string object. HAllocate does not care whether we pass |
+ // STRING_TYPE or ONE_BYTE_STRING_TYPE here, so we just use STRING_TYPE. |
+ HAllocate* result = |
+ BuildAllocate(size, HType::String(), STRING_TYPE, allocation_mode); |
+ Add<HStoreNamedField>(result, HObjectAccess::ForMap(), map); |
+ |
+ // Initialize the string fields. |
+ Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(), |
+ Add<HConstant>(String::kEmptyHashField)); |
+ Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length); |
+ |
+ // Copy characters to the result string. |
+ IfBuilder if_twobyte(this); |
+ if_twobyte.If<HCompareObjectEqAndBranch>(map, string_map); |
+ if_twobyte.Then(); |
+ { |
+ // Copy characters from the left string. |
+ BuildCopySeqStringChars( |
+ left, graph()->GetConstant0(), String::TWO_BYTE_ENCODING, result, |
+ graph()->GetConstant0(), String::TWO_BYTE_ENCODING, left_length); |
+ |
+ // Copy characters from the right string. |
+ BuildCopySeqStringChars( |
+ right, graph()->GetConstant0(), String::TWO_BYTE_ENCODING, result, |
+ left_length, String::TWO_BYTE_ENCODING, right_length); |
+ } |
+ if_twobyte.Else(); |
+ { |
+ // Copy characters from the left string. |
+ BuildCopySeqStringChars( |
+ left, graph()->GetConstant0(), String::ONE_BYTE_ENCODING, result, |
+ graph()->GetConstant0(), String::ONE_BYTE_ENCODING, left_length); |
+ |
+ // Copy characters from the right string. |
+ BuildCopySeqStringChars( |
+ right, graph()->GetConstant0(), String::ONE_BYTE_ENCODING, result, |
+ left_length, String::ONE_BYTE_ENCODING, right_length); |
+ } |
+ if_twobyte.End(); |
- // Copy characters from the right string. |
- BuildCopySeqStringChars( |
- right, graph()->GetConstant0(), String::ONE_BYTE_ENCODING, |
- result, left_length, String::ONE_BYTE_ENCODING, |
- right_length); |
- } |
- if_twobyte.End(); |
+ // Count the native string addition. |
+ AddIncrementCounter(isolate()->counters()->string_add_native()); |
- // Count the native string addition. |
- AddIncrementCounter(isolate()->counters()->string_add_native()); |
- |
- // Return the sequential string. |
- Push(result); |
+ // Return the sequential string. |
+ Push(result); |
+ } |
+ if_size.Else(); |
+ { |
+ // Fallback to the runtime to add the two strings. The string has to be |
+ // allocated in LO space. |
+ Add<HPushArguments>(left, right); |
+ Push(Add<HCallRuntime>(Runtime::FunctionForId(Runtime::kStringAdd), 2)); |
+ } |
+ if_size.End(); |
} |
if_sameencodingandsequential.Else(); |
{ |