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

Unified Diff: runtime/vm/symbols.cc

Issue 1322043002: More elimination of new space allocation, fix bugs in Symbols::FromConcatAll (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: synced Created 5 years, 4 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 | « runtime/vm/parser.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/symbols.cc
diff --git a/runtime/vm/symbols.cc b/runtime/vm/symbols.cc
index be081818ba689bfeff188d4dc054f38f1e4668c5..d8683fe7ab967f99998d6d50db5beeadb3725482 100644
--- a/runtime/vm/symbols.cc
+++ b/runtime/vm/symbols.cc
@@ -397,27 +397,59 @@ RawString* Symbols::FromConcat(const String& str1, const String& str2) {
// up symbol from pieces instead of concatenating them first into a big string.
RawString* Symbols::FromConcatAll(
const GrowableHandlePtrArray<const String>& strs) {
- GrowableArray<const char*> cchars(strs.length());
- GrowableArray<intptr_t> lengths(strs.length());
+ const intptr_t strs_length = strs.length();
+ GrowableArray<intptr_t> lengths(strs_length);
+
intptr_t len_sum = 0;
- for (intptr_t i = 0; i < strs.length(); i++) {
- const char* to_cstr = strs[i].ToCString();
- intptr_t len = strlen(to_cstr);
- cchars.Add(to_cstr);
- lengths.Add(len);
- len_sum += len;
+ bool is_one_byte_string = true;
+ for (intptr_t i = 0; i < strs_length; i++) {
+ const String& str = strs[i];
+ const intptr_t str_len = str.Length();
+ if ((String::kMaxElements - len_sum) < str_len) {
+ Exceptions::ThrowOOM();
+ UNREACHABLE();
+ }
+ len_sum += str_len;
+ lengths.Add(str_len);
+ if (!str.IsOneByteString()) {
+ is_one_byte_string = false;
+ }
}
Zone* zone = Thread::Current()->zone();
- char* buffer = zone->Alloc<char>(len_sum);
- const char* const orig_buffer = buffer;
- for (intptr_t i = 0; i < cchars.length(); i++) {
- intptr_t len = lengths[i];
- strncpy(buffer, cchars[i], len);
- buffer += len;
- }
- ASSERT(len_sum == buffer - orig_buffer);
- return Symbols::New(orig_buffer, len_sum);
+
+ if (is_one_byte_string) {
+ uint8_t* buffer = zone->Alloc<uint8_t>(len_sum);
+ const uint8_t* const orig_buffer = buffer;
+ for (intptr_t i = 0; i < strs_length; i++) {
+ NoSafepointScope no_safepoint;
+ intptr_t str_len = lengths[i];
+ const String& str = strs[i];
+ memmove(buffer, OneByteString::CharAddr(str, 0), str_len);
+ buffer += str_len;
+ }
+ ASSERT(len_sum == buffer - orig_buffer);
+ return Symbols::FromLatin1(orig_buffer, len_sum);
+ } else {
+ uint16_t* buffer = zone->Alloc<uint16_t>(len_sum);
+ const uint16_t* const orig_buffer = buffer;
+ for (intptr_t i = 0; i < strs_length; i++) {
+ NoSafepointScope no_safepoint;
+ intptr_t str_len = lengths[i];
+ const String& str = strs[i];
+ if (str.IsTwoByteString()) {
+ memmove(buffer, TwoByteString::CharAddr(str, 0), str_len * 2);
+ } else {
+ uint8_t* src_p = OneByteString::CharAddr(str, 0);
+ for (int n = 0; n < str_len; n++) {
+ buffer[n] = src_p[n];
+ }
+ }
+ buffer += str_len;
+ }
+ ASSERT(len_sum == buffer - orig_buffer);
+ return Symbols::FromUTF16(orig_buffer, len_sum);
+ }
}
« no previous file with comments | « runtime/vm/parser.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698