Index: src/heap.cc |
diff --git a/src/heap.cc b/src/heap.cc |
index 3115cb31d60b9af9367379dc5b09b3d52a9d3dc0..1464949559431e478226a24f70fbfe78e8292420 100644 |
--- a/src/heap.cc |
+++ b/src/heap.cc |
@@ -1927,6 +1927,18 @@ Object* Heap::AllocateConsString(String* first, String* second) { |
return Failure::OutOfMemoryException(); |
} |
+ bool is_ascii_data_in_two_byte_string = false; |
+ if (!is_ascii) { |
+ // At least one of the strings uses two-byte representation so we |
+ // can't use the fast case code for short ascii strings below, but |
+ // we can try to save memory if all chars actually fit in ascii. |
+ is_ascii_data_in_two_byte_string = |
+ first->HasAsciiChars() && second->HasAsciiChars(); |
+ if (is_ascii_data_in_two_byte_string) { |
+ Counters::string_add_runtime_ext_to_ascii.Increment(); |
+ } |
+ } |
+ |
// If the resulting string is small make a flat string. |
if (length < String::kMinNonFlatLength) { |
ASSERT(first->IsFlat()); |
@@ -1953,22 +1965,13 @@ Object* Heap::AllocateConsString(String* first, String* second) { |
for (int i = 0; i < second_length; i++) *dest++ = src[i]; |
return result; |
} else { |
- // For short external two-byte strings we check whether they can |
- // be represented using ascii. |
- if (!first_is_ascii) { |
- first_is_ascii = first->IsExternalTwoByteStringWithAsciiChars(); |
- } |
- if (first_is_ascii && !second_is_ascii) { |
- second_is_ascii = second->IsExternalTwoByteStringWithAsciiChars(); |
- } |
- if (first_is_ascii && second_is_ascii) { |
+ if (is_ascii_data_in_two_byte_string) { |
Object* result = AllocateRawAsciiString(length); |
if (result->IsFailure()) return result; |
// Copy the characters into the new object. |
char* dest = SeqAsciiString::cast(result)->GetChars(); |
String::WriteToFlat(first, dest, 0, first_length); |
String::WriteToFlat(second, dest + first_length, 0, second_length); |
- Counters::string_add_runtime_ext_to_ascii.Increment(); |
return result; |
} |
@@ -1982,7 +1985,8 @@ Object* Heap::AllocateConsString(String* first, String* second) { |
} |
} |
- Map* map = is_ascii ? cons_ascii_string_map() : cons_string_map(); |
+ Map* map = (is_ascii || is_ascii_data_in_two_byte_string) ? |
+ cons_ascii_string_map() : cons_string_map(); |
Object* result = Allocate(map, NEW_SPACE); |
if (result->IsFailure()) return result; |
@@ -2068,7 +2072,23 @@ Object* Heap::AllocateExternalStringFromTwoByte( |
return Failure::OutOfMemoryException(); |
} |
- Map* map = Heap::external_string_map(); |
+ // For small strings we check whether the resource contains only |
+ // ascii characters. If yes, we use a different string map. |
+ bool is_ascii = true; |
+ if (length >= static_cast<size_t>(String::kMinNonFlatLength)) { |
+ is_ascii = false; |
+ } else { |
+ const uc16* data = resource->data(); |
+ for (size_t i = 0; i < length; i++) { |
+ if (data[i] > String::kMaxAsciiCharCode) { |
+ is_ascii = false; |
+ break; |
+ } |
+ } |
+ } |
+ |
+ Map* map = is_ascii ? |
+ Heap::external_string_with_ascii_data_map() : Heap::external_string_map(); |
Object* result = Allocate(map, NEW_SPACE); |
if (result->IsFailure()) return result; |
@@ -2851,6 +2871,9 @@ Map* Heap::SymbolMapForString(String* string) { |
if (map == cons_ascii_string_map()) return cons_ascii_symbol_map(); |
if (map == external_string_map()) return external_symbol_map(); |
if (map == external_ascii_string_map()) return external_ascii_symbol_map(); |
+ if (map == external_string_with_ascii_data_map()) { |
+ return external_symbol_with_ascii_data_map(); |
+ } |
// No match found. |
return NULL; |