Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(346)

Unified Diff: src/heap.cc

Issue 2762008: Track ascii-ness of data in externalized strings. (Closed)
Patch Set: Extended tests. Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/heap.h ('k') | src/ia32/codegen-ia32.cc » ('j') | src/objects-inl.h » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
« no previous file with comments | « src/heap.h ('k') | src/ia32/codegen-ia32.cc » ('j') | src/objects-inl.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698