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

Side by Side Diff: runtime/vm/symbols.cc

Issue 1323063004: Fix Dartium by supporting external strings as well in Symbols::FromConcatAll (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Formatting Created 5 years, 3 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 unified diff | Download patch
« no previous file with comments | « runtime/vm/object_test.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/symbols.h" 5 #include "vm/symbols.h"
6 6
7 #include "vm/handles.h" 7 #include "vm/handles.h"
8 #include "vm/handles_impl.h" 8 #include "vm/handles_impl.h"
9 #include "vm/hash_table.h" 9 #include "vm/hash_table.h"
10 #include "vm/isolate.h" 10 #include "vm/isolate.h"
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 return New(str2); 387 return New(str2);
388 } else if (str2.Length() == 0) { 388 } else if (str2.Length() == 0) {
389 return New(str1); 389 return New(str1);
390 } else { 390 } else {
391 return NewSymbol(ConcatString(str1, str2)); 391 return NewSymbol(ConcatString(str1, str2));
392 } 392 }
393 } 393 }
394 394
395 395
396 // TODO(srdjan): If this becomes performance critical code, consider looking 396 // TODO(srdjan): If this becomes performance critical code, consider looking
397 // up symbol from pieces instead of concatenating them first into a big string. 397 // up symbol from hash of pieces instead of concatenating them first into
398 // a string.
398 RawString* Symbols::FromConcatAll( 399 RawString* Symbols::FromConcatAll(
399 const GrowableHandlePtrArray<const String>& strs) { 400 const GrowableHandlePtrArray<const String>& strs) {
400 const intptr_t strs_length = strs.length(); 401 const intptr_t strs_length = strs.length();
401 GrowableArray<intptr_t> lengths(strs_length); 402 GrowableArray<intptr_t> lengths(strs_length);
402 403
403 intptr_t len_sum = 0; 404 intptr_t len_sum = 0;
404 bool is_one_byte_string = true; 405 const intptr_t kOneByteChar = 1;
406 intptr_t char_size = kOneByteChar;
407
405 for (intptr_t i = 0; i < strs_length; i++) { 408 for (intptr_t i = 0; i < strs_length; i++) {
406 const String& str = strs[i]; 409 const String& str = strs[i];
407 const intptr_t str_len = str.Length(); 410 const intptr_t str_len = str.Length();
408 if ((String::kMaxElements - len_sum) < str_len) { 411 if ((String::kMaxElements - len_sum) < str_len) {
409 Exceptions::ThrowOOM(); 412 Exceptions::ThrowOOM();
410 UNREACHABLE(); 413 UNREACHABLE();
411 } 414 }
412 len_sum += str_len; 415 len_sum += str_len;
413 lengths.Add(str_len); 416 lengths.Add(str_len);
414 if (!str.IsOneByteString()) { 417 char_size = Utils::Maximum(char_size, str.CharSize());
415 is_one_byte_string = false;
416 }
417 } 418 }
419 const bool is_one_byte_string = char_size == kOneByteChar;
418 420
419 Zone* zone = Thread::Current()->zone(); 421 Zone* zone = Thread::Current()->zone();
420
421 if (is_one_byte_string) { 422 if (is_one_byte_string) {
422 uint8_t* buffer = zone->Alloc<uint8_t>(len_sum); 423 uint8_t* buffer = zone->Alloc<uint8_t>(len_sum);
423 const uint8_t* const orig_buffer = buffer; 424 const uint8_t* const orig_buffer = buffer;
424 for (intptr_t i = 0; i < strs_length; i++) { 425 for (intptr_t i = 0; i < strs_length; i++) {
425 NoSafepointScope no_safepoint; 426 NoSafepointScope no_safepoint;
426 intptr_t str_len = lengths[i]; 427 intptr_t str_len = lengths[i];
427 const String& str = strs[i]; 428 const String& str = strs[i];
siva 2015/09/02 18:06:44 ASSERT(str.IsOneByteString() || str.IsExternalOneB
srdjan 2015/09/02 18:24:37 Done.
428 memmove(buffer, OneByteString::CharAddr(str, 0), str_len); 429 const uint8_t* src_p = str.IsOneByteString() ?
430 OneByteString::CharAddr(str, 0) :
431 ExternalOneByteString::CharAddr(str, 0);
432 memmove(buffer, src_p, str_len);
429 buffer += str_len; 433 buffer += str_len;
430 } 434 }
431 ASSERT(len_sum == buffer - orig_buffer); 435 ASSERT(len_sum == buffer - orig_buffer);
432 return Symbols::FromLatin1(orig_buffer, len_sum); 436 return Symbols::FromLatin1(orig_buffer, len_sum);
433 } else { 437 } else {
434 uint16_t* buffer = zone->Alloc<uint16_t>(len_sum); 438 uint16_t* buffer = zone->Alloc<uint16_t>(len_sum);
435 const uint16_t* const orig_buffer = buffer; 439 const uint16_t* const orig_buffer = buffer;
436 for (intptr_t i = 0; i < strs_length; i++) { 440 for (intptr_t i = 0; i < strs_length; i++) {
437 NoSafepointScope no_safepoint; 441 NoSafepointScope no_safepoint;
438 intptr_t str_len = lengths[i]; 442 intptr_t str_len = lengths[i];
439 const String& str = strs[i]; 443 const String& str = strs[i];
440 if (str.IsTwoByteString()) { 444 if (str.IsTwoByteString()) {
441 memmove(buffer, TwoByteString::CharAddr(str, 0), str_len * 2); 445 memmove(buffer, TwoByteString::CharAddr(str, 0), str_len * 2);
446 } else if (str.IsExternalTwoByteString()) {
447 memmove(buffer, ExternalTwoByteString::CharAddr(str, 0), str_len * 2);
442 } else { 448 } else {
443 uint8_t* src_p = OneByteString::CharAddr(str, 0); 449 // One-byte to two-byte string copy.
450 ASSERT(str.IsOneByteString() || str.IsExternalOneByteString());
451 const uint8_t* src_p = str.IsOneByteString() ?
452 OneByteString::CharAddr(str, 0) :
453 ExternalOneByteString::CharAddr(str, 0);
siva 2015/09/02 18:06:44 It might make sense to add a String::CharAddr(...)
srdjan 2015/09/02 18:24:37 String::CharAddr was removed because it caused con
444 for (int n = 0; n < str_len; n++) { 454 for (int n = 0; n < str_len; n++) {
445 buffer[n] = src_p[n]; 455 buffer[n] = src_p[n];
446 } 456 }
447 } 457 }
448 buffer += str_len; 458 buffer += str_len;
449 } 459 }
450 ASSERT(len_sum == buffer - orig_buffer); 460 ASSERT(len_sum == buffer - orig_buffer);
451 return Symbols::FromUTF16(orig_buffer, len_sum); 461 return Symbols::FromUTF16(orig_buffer, len_sum);
452 } 462 }
453 } 463 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 RawObject* Symbols::GetVMSymbol(intptr_t object_id) { 539 RawObject* Symbols::GetVMSymbol(intptr_t object_id) {
530 ASSERT(IsVMSymbolId(object_id)); 540 ASSERT(IsVMSymbolId(object_id));
531 intptr_t i = (object_id - kMaxPredefinedObjectIds); 541 intptr_t i = (object_id - kMaxPredefinedObjectIds);
532 if ((i > kIllegal) && (i < Symbols::kMaxPredefinedId)) { 542 if ((i > kIllegal) && (i < Symbols::kMaxPredefinedId)) {
533 return symbol_handles_[i]->raw(); 543 return symbol_handles_[i]->raw();
534 } 544 }
535 return Object::null(); 545 return Object::null();
536 } 546 }
537 547
538 } // namespace dart 548 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object_test.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698