Index: src/heap.cc |
=================================================================== |
--- src/heap.cc (revision 3335) |
+++ src/heap.cc (working copy) |
@@ -1774,6 +1774,38 @@ |
} |
int length = first_length + second_length; |
+ |
+ // Optimization for packer.js. This popular library uses two-character |
+ // strings as keys in a hash. Check whether we already have the string |
+ // in the symbol table to prevent creation of many unneccesary strings. |
+ if (length == 2) { |
+ unsigned c1 = first->Get(0); |
+ unsigned c2 = second->Get(0); |
+ String* symbol; |
Søren Thygesen Gjesse
2009/11/19 21:42:57
Please add a comment on why digits only will not w
|
+ if ((c1 - '0' > '9' - '0' || |
Søren Thygesen Gjesse
2009/11/19 21:42:57
Why c1 - '0' > '9' - '0' instead of c1 > '9'?
Erik Corry
2009/11/20 10:12:46
I moved this to a different function so I could po
|
+ c2 - '0' > '9' - '0') && |
+ symbol_table()->LookupTwoCharsIfExists(c1, c2, &symbol)) { |
+ return symbol; |
+ // Now we know the length is 2, we might as well make use of that fact |
+ // when building the new string. |
+ } else if ((c1 | c2) <= String::kMaxAsciiCharCodeU) { // We can do this |
+ ASSERT(IsPowerOf2(String::kMaxAsciiCharCodeU + 1)); // because of this. |
+ Object* result = AllocateRawAsciiString(2); |
+ if (result->IsFailure()) return result; |
+ char* dest = SeqAsciiString::cast(result)->GetChars(); |
+ dest[0] = c1; |
+ dest[1] = c2; |
+ return result; |
+ } else { |
+ Object* result = AllocateRawTwoByteString(2); |
+ if (result->IsFailure()) return result; |
+ uc16* dest = SeqTwoByteString::cast(result)->GetChars(); |
+ dest[0] = c1; |
+ dest[1] = c2; |
+ return result; |
+ } |
+ } |
+ |
bool is_ascii = first->IsAsciiRepresentation() |
&& second->IsAsciiRepresentation(); |
@@ -1843,6 +1875,35 @@ |
if (length == 1) { |
return Heap::LookupSingleCharacterStringFromCode( |
buffer->Get(start)); |
+ } else if (length == 2) { |
Søren Thygesen Gjesse
2009/11/19 21:42:57
Refactor duplicated code.
Erik Corry
2009/11/20 10:12:46
Done.
|
+ // Optimization for packer.js. This popular library uses two-character |
+ // strings as keys in a hash. Check whether we already have the string |
+ // in the symbol table to prevent creation of many unneccesary strings. |
+ unsigned c1 = buffer->Get(start); |
+ unsigned c2 = buffer->Get(start + 1); |
+ String* symbol; |
+ if ((c1 - '0' > '9' - '0' || |
+ c2 - '0' > '9' - '0') && |
+ symbol_table()->LookupTwoCharsIfExists(c1, c2, &symbol)) { |
+ return symbol; |
+ // Now we know the length is 2, we might as well make use of that fact |
+ // when building the new string. |
+ } else if ((c1 | c2) <= String::kMaxAsciiCharCodeU) { // We can do this |
+ ASSERT(IsPowerOf2(String::kMaxAsciiCharCodeU + 1)); // because of this. |
+ Object* result = AllocateRawAsciiString(2); |
+ if (result->IsFailure()) return result; |
+ char* dest = SeqAsciiString::cast(result)->GetChars(); |
+ dest[0] = c1; |
+ dest[1] = c2; |
+ return result; |
+ } else { |
+ Object* result = AllocateRawTwoByteString(2); |
+ if (result->IsFailure()) return result; |
+ uc16* dest = SeqTwoByteString::cast(result)->GetChars(); |
+ dest[0] = c1; |
+ dest[1] = c2; |
+ return result; |
+ } |
} |
// Make an attempt to flatten the buffer to reduce access time. |