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

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

Issue 2952193002: VM: Speed up output of UTF8 for 1-byte strings.
Patch Set: Add test that would have caught bug pointed out by Slava Created 3 years, 2 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.h ('k') | runtime/vm/raw_object_snapshot.cc » ('j') | 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/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/become.h" 9 #include "vm/become.h"
10 #include "vm/bit_vector.h" 10 #include "vm/bit_vector.h"
(...skipping 19839 matching lines...) Expand 10 before | Expand all | Expand 10 after
19850 RawString* String::FromUTF8(const uint8_t* utf8_array, 19850 RawString* String::FromUTF8(const uint8_t* utf8_array,
19851 intptr_t array_len, 19851 intptr_t array_len,
19852 Heap::Space space) { 19852 Heap::Space space) {
19853 Utf8::Type type; 19853 Utf8::Type type;
19854 intptr_t len = Utf8::CodeUnitCount(utf8_array, array_len, &type); 19854 intptr_t len = Utf8::CodeUnitCount(utf8_array, array_len, &type);
19855 if (type == Utf8::kLatin1) { 19855 if (type == Utf8::kLatin1) {
19856 const String& strobj = String::Handle(OneByteString::New(len, space)); 19856 const String& strobj = String::Handle(OneByteString::New(len, space));
19857 if (len > 0) { 19857 if (len > 0) {
19858 NoSafepointScope no_safepoint; 19858 NoSafepointScope no_safepoint;
19859 Utf8::DecodeToLatin1(utf8_array, array_len, 19859 Utf8::DecodeToLatin1(utf8_array, array_len,
19860 OneByteString::CharAddr(strobj, 0), len); 19860 OneByteString::DataStart(strobj), len);
19861 } 19861 }
19862 return strobj.raw(); 19862 return strobj.raw();
19863 } 19863 }
19864 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSupplementary)); 19864 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSupplementary));
19865 const String& strobj = String::Handle(TwoByteString::New(len, space)); 19865 const String& strobj = String::Handle(TwoByteString::New(len, space));
19866 NoSafepointScope no_safepoint; 19866 NoSafepointScope no_safepoint;
19867 Utf8::DecodeToUTF16(utf8_array, array_len, TwoByteString::CharAddr(strobj, 0), 19867 Utf8::DecodeToUTF16(utf8_array, array_len, TwoByteString::DataStart(strobj),
19868 len); 19868 len);
19869 return strobj.raw(); 19869 return strobj.raw();
19870 } 19870 }
19871 19871
19872 RawString* String::FromLatin1(const uint8_t* latin1_array, 19872 RawString* String::FromLatin1(const uint8_t* latin1_array,
19873 intptr_t array_len, 19873 intptr_t array_len,
19874 Heap::Space space) { 19874 Heap::Space space) {
19875 return OneByteString::New(latin1_array, array_len, space); 19875 return OneByteString::New(latin1_array, array_len, space);
19876 } 19876 }
19877 19877
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
20294 if (is_one_byte_string) { 20294 if (is_one_byte_string) {
20295 result = OneByteString::New(length, space); 20295 result = OneByteString::New(length, space);
20296 } else { 20296 } else {
20297 result = TwoByteString::New(length, space); 20297 result = TwoByteString::New(length, space);
20298 } 20298 }
20299 String::Copy(result, 0, str, begin_index, length); 20299 String::Copy(result, 0, str, begin_index, length);
20300 return result.raw(); 20300 return result.raw();
20301 } 20301 }
20302 20302
20303 const char* String::ToCString() const { 20303 const char* String::ToCString() const {
20304 if (IsOneByteString()) {
20305 // Quick conversion if OneByteString contains only ASCII characters.
20306 intptr_t len = Length();
20307 if (len == 0) {
20308 return "";
20309 }
20310 Zone* zone = Thread::Current()->zone();
20311 uint8_t* result = zone->Alloc<uint8_t>(len + 1);
20312 NoSafepointScope no_safepoint;
20313 const uint8_t* original_str = OneByteString::CharAddr(*this, 0);
20314 for (intptr_t i = 0; i < len; i++) {
20315 if (original_str[i] <= Utf8::kMaxOneByteChar) {
20316 result[i] = original_str[i];
20317 } else {
20318 len = -1;
20319 break;
20320 }
20321 }
20322 if (len > 0) {
20323 result[len] = 0;
20324 return reinterpret_cast<const char*>(result);
20325 }
20326 }
20327 const intptr_t len = Utf8::Length(*this); 20304 const intptr_t len = Utf8::Length(*this);
20328 Zone* zone = Thread::Current()->zone(); 20305 Zone* zone = Thread::Current()->zone();
20329 uint8_t* result = zone->Alloc<uint8_t>(len + 1); 20306 uint8_t* result = zone->Alloc<uint8_t>(len + 1);
20330 ToUTF8(result, len); 20307 ToUTF8(result, len);
20331 result[len] = 0; 20308 result[len] = 0;
20332 return reinterpret_cast<const char*>(result); 20309 return reinterpret_cast<const char*>(result);
20333 } 20310 }
20334 20311
20335 char* String::ToMallocCString() const { 20312 char* String::ToMallocCString() const {
20336 if (IsOneByteString()) {
20337 // Quick conversion if OneByteString contains only ASCII characters.
20338 intptr_t len = Length();
20339 uint8_t* result = reinterpret_cast<uint8_t*>(malloc(len + 1));
20340 NoSafepointScope no_safepoint;
20341 const uint8_t* original_str = OneByteString::CharAddr(*this, 0);
20342 for (intptr_t i = 0; i < len; i++) {
20343 if (original_str[i] <= Utf8::kMaxOneByteChar) {
20344 result[i] = original_str[i];
20345 } else {
20346 len = -1;
20347 break;
20348 }
20349 }
20350 if (len > 0) {
20351 result[len] = 0;
20352 return reinterpret_cast<char*>(result);
20353 }
20354 }
20355 const intptr_t len = Utf8::Length(*this); 20313 const intptr_t len = Utf8::Length(*this);
20356 uint8_t* result = reinterpret_cast<uint8_t*>(malloc(len + 1)); 20314 uint8_t* result = reinterpret_cast<uint8_t*>(malloc(len + 1));
20357 ToUTF8(result, len); 20315 ToUTF8(result, len);
20358 result[len] = 0; 20316 result[len] = 0;
20359 return reinterpret_cast<char*>(result); 20317 return reinterpret_cast<char*>(result);
20360 } 20318 }
20361 20319
20362 void String::ToUTF8(uint8_t* utf8_array, intptr_t array_len) const { 20320 void String::ToUTF8(uint8_t* utf8_array, intptr_t array_len) const {
20363 ASSERT(array_len >= Utf8::Length(*this)); 20321 ASSERT(array_len >= Utf8::Length(*this));
20364 Utf8::Encode(*this, reinterpret_cast<char*>(utf8_array), array_len); 20322 Utf8::Encode(*this, reinterpret_cast<char*>(utf8_array), array_len);
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
20639 return result; 20597 return result;
20640 } 20598 }
20641 } 20599 }
20642 20600
20643 RawOneByteString* OneByteString::New(const uint8_t* characters, 20601 RawOneByteString* OneByteString::New(const uint8_t* characters,
20644 intptr_t len, 20602 intptr_t len,
20645 Heap::Space space) { 20603 Heap::Space space) {
20646 const String& result = String::Handle(OneByteString::New(len, space)); 20604 const String& result = String::Handle(OneByteString::New(len, space));
20647 if (len > 0) { 20605 if (len > 0) {
20648 NoSafepointScope no_safepoint; 20606 NoSafepointScope no_safepoint;
20649 memmove(CharAddr(result, 0), characters, len); 20607 memmove(DataStart(result), characters, len);
20650 } 20608 }
20651 return OneByteString::raw(result); 20609 return OneByteString::raw(result);
20652 } 20610 }
20653 20611
20654 RawOneByteString* OneByteString::New(const uint16_t* characters, 20612 RawOneByteString* OneByteString::New(const uint16_t* characters,
20655 intptr_t len, 20613 intptr_t len,
20656 Heap::Space space) { 20614 Heap::Space space) {
20657 const String& result = String::Handle(OneByteString::New(len, space)); 20615 const String& result = String::Handle(OneByteString::New(len, space));
20658 NoSafepointScope no_safepoint; 20616 NoSafepointScope no_safepoint;
20659 for (intptr_t i = 0; i < len; ++i) { 20617 for (intptr_t i = 0; i < len; ++i) {
(...skipping 23 matching lines...) Expand all
20683 } 20641 }
20684 20642
20685 RawOneByteString* OneByteString::New(const String& other_one_byte_string, 20643 RawOneByteString* OneByteString::New(const String& other_one_byte_string,
20686 intptr_t other_start_index, 20644 intptr_t other_start_index,
20687 intptr_t other_len, 20645 intptr_t other_len,
20688 Heap::Space space) { 20646 Heap::Space space) {
20689 const String& result = String::Handle(OneByteString::New(other_len, space)); 20647 const String& result = String::Handle(OneByteString::New(other_len, space));
20690 ASSERT(other_one_byte_string.IsOneByteString()); 20648 ASSERT(other_one_byte_string.IsOneByteString());
20691 if (other_len > 0) { 20649 if (other_len > 0) {
20692 NoSafepointScope no_safepoint; 20650 NoSafepointScope no_safepoint;
20693 memmove(OneByteString::CharAddr(result, 0), 20651 memmove(OneByteString::DataStart(result),
20694 OneByteString::CharAddr(other_one_byte_string, other_start_index), 20652 OneByteString::CharAddr(other_one_byte_string, other_start_index),
20695 other_len); 20653 other_len);
20696 } 20654 }
20697 return OneByteString::raw(result); 20655 return OneByteString::raw(result);
20698 } 20656 }
20699 20657
20700 RawOneByteString* OneByteString::New(const TypedData& other_typed_data, 20658 RawOneByteString* OneByteString::New(const TypedData& other_typed_data,
20701 intptr_t other_start_index, 20659 intptr_t other_start_index,
20702 intptr_t other_len, 20660 intptr_t other_len,
20703 Heap::Space space) { 20661 Heap::Space space) {
20704 const String& result = String::Handle(OneByteString::New(other_len, space)); 20662 const String& result = String::Handle(OneByteString::New(other_len, space));
20705 ASSERT(other_typed_data.ElementSizeInBytes() == 1); 20663 ASSERT(other_typed_data.ElementSizeInBytes() == 1);
20706 if (other_len > 0) { 20664 if (other_len > 0) {
20707 NoSafepointScope no_safepoint; 20665 NoSafepointScope no_safepoint;
20708 memmove(OneByteString::CharAddr(result, 0), 20666 memmove(OneByteString::DataStart(result),
20709 other_typed_data.DataAddr(other_start_index), other_len); 20667 other_typed_data.DataAddr(other_start_index), other_len);
20710 } 20668 }
20711 return OneByteString::raw(result); 20669 return OneByteString::raw(result);
20712 } 20670 }
20713 20671
20714 RawOneByteString* OneByteString::New(const ExternalTypedData& other_typed_data, 20672 RawOneByteString* OneByteString::New(const ExternalTypedData& other_typed_data,
20715 intptr_t other_start_index, 20673 intptr_t other_start_index,
20716 intptr_t other_len, 20674 intptr_t other_len,
20717 Heap::Space space) { 20675 Heap::Space space) {
20718 const String& result = String::Handle(OneByteString::New(other_len, space)); 20676 const String& result = String::Handle(OneByteString::New(other_len, space));
20719 ASSERT(other_typed_data.ElementSizeInBytes() == 1); 20677 ASSERT(other_typed_data.ElementSizeInBytes() == 1);
20720 if (other_len > 0) { 20678 if (other_len > 0) {
20721 NoSafepointScope no_safepoint; 20679 NoSafepointScope no_safepoint;
20722 memmove(OneByteString::CharAddr(result, 0), 20680 memmove(OneByteString::DataStart(result),
20723 other_typed_data.DataAddr(other_start_index), other_len); 20681 other_typed_data.DataAddr(other_start_index), other_len);
20724 } 20682 }
20725 return OneByteString::raw(result); 20683 return OneByteString::raw(result);
20726 } 20684 }
20727 20685
20728 RawOneByteString* OneByteString::Concat(const String& str1, 20686 RawOneByteString* OneByteString::Concat(const String& str1,
20729 const String& str2, 20687 const String& str2,
20730 Heap::Space space) { 20688 Heap::Space space) {
20731 intptr_t len1 = str1.Length(); 20689 intptr_t len1 = str1.Length();
20732 intptr_t len2 = str2.Length(); 20690 intptr_t len2 = str2.Length();
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
20862 return TwoByteString::raw(result); 20820 return TwoByteString::raw(result);
20863 } 20821 }
20864 20822
20865 RawTwoByteString* TwoByteString::New(const uint16_t* utf16_array, 20823 RawTwoByteString* TwoByteString::New(const uint16_t* utf16_array,
20866 intptr_t array_len, 20824 intptr_t array_len,
20867 Heap::Space space) { 20825 Heap::Space space) {
20868 ASSERT(array_len > 0); 20826 ASSERT(array_len > 0);
20869 const String& result = String::Handle(TwoByteString::New(array_len, space)); 20827 const String& result = String::Handle(TwoByteString::New(array_len, space));
20870 { 20828 {
20871 NoSafepointScope no_safepoint; 20829 NoSafepointScope no_safepoint;
20872 memmove(CharAddr(result, 0), utf16_array, (array_len * 2)); 20830 memmove(DataStart(result), utf16_array, (array_len * 2));
20873 } 20831 }
20874 return TwoByteString::raw(result); 20832 return TwoByteString::raw(result);
20875 } 20833 }
20876 20834
20877 RawTwoByteString* TwoByteString::New(intptr_t utf16_len, 20835 RawTwoByteString* TwoByteString::New(intptr_t utf16_len,
20878 const int32_t* utf32_array, 20836 const int32_t* utf32_array,
20879 intptr_t array_len, 20837 intptr_t array_len,
20880 Heap::Space space) { 20838 Heap::Space space) {
20881 ASSERT((array_len > 0) && (utf16_len >= array_len)); 20839 ASSERT((array_len > 0) && (utf16_len >= array_len));
20882 const String& result = String::Handle(TwoByteString::New(utf16_len, space)); 20840 const String& result = String::Handle(TwoByteString::New(utf16_len, space));
(...skipping 22 matching lines...) Expand all
20905 return TwoByteString::raw(result); 20863 return TwoByteString::raw(result);
20906 } 20864 }
20907 20865
20908 RawTwoByteString* TwoByteString::New(const TypedData& other_typed_data, 20866 RawTwoByteString* TwoByteString::New(const TypedData& other_typed_data,
20909 intptr_t other_start_index, 20867 intptr_t other_start_index,
20910 intptr_t other_len, 20868 intptr_t other_len,
20911 Heap::Space space) { 20869 Heap::Space space) {
20912 const String& result = String::Handle(TwoByteString::New(other_len, space)); 20870 const String& result = String::Handle(TwoByteString::New(other_len, space));
20913 if (other_len > 0) { 20871 if (other_len > 0) {
20914 NoSafepointScope no_safepoint; 20872 NoSafepointScope no_safepoint;
20915 memmove(TwoByteString::CharAddr(result, 0), 20873 memmove(TwoByteString::DataStart(result),
20916 other_typed_data.DataAddr(other_start_index), 20874 other_typed_data.DataAddr(other_start_index),
20917 other_len * sizeof(uint16_t)); 20875 other_len * sizeof(uint16_t));
20918 } 20876 }
20919 return TwoByteString::raw(result); 20877 return TwoByteString::raw(result);
20920 } 20878 }
20921 20879
20922 RawTwoByteString* TwoByteString::New(const ExternalTypedData& other_typed_data, 20880 RawTwoByteString* TwoByteString::New(const ExternalTypedData& other_typed_data,
20923 intptr_t other_start_index, 20881 intptr_t other_start_index,
20924 intptr_t other_len, 20882 intptr_t other_len,
20925 Heap::Space space) { 20883 Heap::Space space) {
20926 const String& result = String::Handle(TwoByteString::New(other_len, space)); 20884 const String& result = String::Handle(TwoByteString::New(other_len, space));
20927 if (other_len > 0) { 20885 if (other_len > 0) {
20928 NoSafepointScope no_safepoint; 20886 NoSafepointScope no_safepoint;
20929 memmove(TwoByteString::CharAddr(result, 0), 20887 memmove(TwoByteString::DataStart(result),
20930 other_typed_data.DataAddr(other_start_index), 20888 other_typed_data.DataAddr(other_start_index),
20931 other_len * sizeof(uint16_t)); 20889 other_len * sizeof(uint16_t));
20932 } 20890 }
20933 return TwoByteString::raw(result); 20891 return TwoByteString::raw(result);
20934 } 20892 }
20935 20893
20936 RawTwoByteString* TwoByteString::Concat(const String& str1, 20894 RawTwoByteString* TwoByteString::Concat(const String& str1,
20937 const String& str2, 20895 const String& str2,
20938 Heap::Space space) { 20896 Heap::Space space) {
20939 intptr_t len1 = str1.Length(); 20897 intptr_t len1 = str1.Length();
(...skipping 1588 matching lines...) Expand 10 before | Expand all | Expand 10 after
22528 } 22486 }
22529 return UserTag::null(); 22487 return UserTag::null();
22530 } 22488 }
22531 22489
22532 const char* UserTag::ToCString() const { 22490 const char* UserTag::ToCString() const {
22533 const String& tag_label = String::Handle(label()); 22491 const String& tag_label = String::Handle(label());
22534 return tag_label.ToCString(); 22492 return tag_label.ToCString();
22535 } 22493 }
22536 22494
22537 } // namespace dart 22495 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/raw_object_snapshot.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698