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

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

Issue 8383029: Implement external strings. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address final review comments Created 9 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_store.h » ('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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 "vm/assembler.h" 7 #include "vm/assembler.h"
8 #include "vm/assert.h" 8 #include "vm/assert.h"
9 #include "vm/bigint_operations.h" 9 #include "vm/bigint_operations.h"
10 #include "vm/bootstrap.h" 10 #include "vm/bootstrap.h"
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 cls = Class::New<TwoByteString>(); 458 cls = Class::New<TwoByteString>();
459 object_store->set_two_byte_string_class(cls); 459 object_store->set_two_byte_string_class(cls);
460 RegisterClass(cls, "TwoByteString", impl_script, core_impl_lib); 460 RegisterClass(cls, "TwoByteString", impl_script, core_impl_lib);
461 pending_classes.Add(&Class::ZoneHandle(cls.raw())); 461 pending_classes.Add(&Class::ZoneHandle(cls.raw()));
462 462
463 cls = Class::New<FourByteString>(); 463 cls = Class::New<FourByteString>();
464 object_store->set_four_byte_string_class(cls); 464 object_store->set_four_byte_string_class(cls);
465 RegisterClass(cls, "FourByteString", impl_script, core_impl_lib); 465 RegisterClass(cls, "FourByteString", impl_script, core_impl_lib);
466 pending_classes.Add(&Class::ZoneHandle(cls.raw())); 466 pending_classes.Add(&Class::ZoneHandle(cls.raw()));
467 467
468 cls = Class::New<ExternalOneByteString>();
469 object_store->set_external_one_byte_string_class(cls);
470 RegisterClass(cls, "ExternalOneByteString", impl_script, core_impl_lib);
471 pending_classes.Add(&Class::ZoneHandle(cls.raw()));
472
473 cls = Class::New<ExternalTwoByteString>();
474 object_store->set_external_two_byte_string_class(cls);
475 RegisterClass(cls, "ExternalTwoByteString", impl_script, core_impl_lib);
476 pending_classes.Add(&Class::ZoneHandle(cls.raw()));
477
478 cls = Class::New<ExternalFourByteString>();
479 object_store->set_external_four_byte_string_class(cls);
480 RegisterClass(cls, "ExternalFourByteString", impl_script, core_impl_lib);
481 pending_classes.Add(&Class::ZoneHandle(cls.raw()));
482
468 cls = Class::New<UnhandledException>(); 483 cls = Class::New<UnhandledException>();
469 object_store->set_unhandled_exception_class(cls); 484 object_store->set_unhandled_exception_class(cls);
470 RegisterClass(cls, "UnhandledException", impl_script, core_impl_lib); 485 RegisterClass(cls, "UnhandledException", impl_script, core_impl_lib);
471 pending_classes.Add(&Class::ZoneHandle(cls.raw())); 486 pending_classes.Add(&Class::ZoneHandle(cls.raw()));
472 487
473 cls = Class::New<Stacktrace>(); 488 cls = Class::New<Stacktrace>();
474 object_store->set_stacktrace_class(cls); 489 object_store->set_stacktrace_class(cls);
475 RegisterClass(cls, "Stacktrace", impl_script, core_impl_lib); 490 RegisterClass(cls, "Stacktrace", impl_script, core_impl_lib);
476 pending_classes.Add(&Class::ZoneHandle(cls.raw())); 491 pending_classes.Add(&Class::ZoneHandle(cls.raw()));
477 // Super type set below, after Object is allocated. 492 // Super type set below, after Object is allocated.
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 648
634 cls = Class::New<OneByteString>(); 649 cls = Class::New<OneByteString>();
635 object_store->set_one_byte_string_class(cls); 650 object_store->set_one_byte_string_class(cls);
636 651
637 cls = Class::New<TwoByteString>(); 652 cls = Class::New<TwoByteString>();
638 object_store->set_two_byte_string_class(cls); 653 object_store->set_two_byte_string_class(cls);
639 654
640 cls = Class::New<FourByteString>(); 655 cls = Class::New<FourByteString>();
641 object_store->set_four_byte_string_class(cls); 656 object_store->set_four_byte_string_class(cls);
642 657
658 cls = Class::New<ExternalOneByteString>();
659 object_store->set_external_one_byte_string_class(cls);
660
661 cls = Class::New<ExternalTwoByteString>();
662 object_store->set_external_two_byte_string_class(cls);
663
664 cls = Class::New<ExternalFourByteString>();
665 object_store->set_external_four_byte_string_class(cls);
666
643 cls = Class::New<Bool>(); 667 cls = Class::New<Bool>();
644 object_store->set_bool_class(cls); 668 object_store->set_bool_class(cls);
645 669
646 cls = Class::New<UnhandledException>(); 670 cls = Class::New<UnhandledException>();
647 object_store->set_unhandled_exception_class(cls); 671 object_store->set_unhandled_exception_class(cls);
648 672
649 cls = Class::New<Stacktrace>(); 673 cls = Class::New<Stacktrace>();
650 object_store->set_stacktrace_class(cls); 674 object_store->set_stacktrace_class(cls);
651 675
652 cls = Class::New<JSRegExp>(); 676 cls = Class::New<JSRegExp>();
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
1131 return object_store->double_class(); 1155 return object_store->double_class();
1132 case kOneByteString: 1156 case kOneByteString:
1133 ASSERT(object_store->one_byte_string_class() != Class::null()); 1157 ASSERT(object_store->one_byte_string_class() != Class::null());
1134 return object_store->one_byte_string_class(); 1158 return object_store->one_byte_string_class();
1135 case kTwoByteString: 1159 case kTwoByteString:
1136 ASSERT(object_store->two_byte_string_class() != Class::null()); 1160 ASSERT(object_store->two_byte_string_class() != Class::null());
1137 return object_store->two_byte_string_class(); 1161 return object_store->two_byte_string_class();
1138 case kFourByteString: 1162 case kFourByteString:
1139 ASSERT(object_store->four_byte_string_class() != Class::null()); 1163 ASSERT(object_store->four_byte_string_class() != Class::null());
1140 return object_store->four_byte_string_class(); 1164 return object_store->four_byte_string_class();
1165 case kExternalOneByteString:
1166 ASSERT(object_store->external_one_byte_string_class() != Class::null());
1167 return object_store->external_one_byte_string_class();
1168 case kExternalTwoByteString:
1169 ASSERT(object_store->external_two_byte_string_class() != Class::null());
1170 return object_store->external_two_byte_string_class();
1171 case kExternalFourByteString:
1172 ASSERT(object_store->external_four_byte_string_class() != Class::null());
1173 return object_store->external_four_byte_string_class();
1141 case kBool: 1174 case kBool:
1142 ASSERT(object_store->bool_class() != Class::null()); 1175 ASSERT(object_store->bool_class() != Class::null());
1143 return object_store->bool_class(); 1176 return object_store->bool_class();
1144 case kArray: 1177 case kArray:
1145 ASSERT(object_store->array_class() != Class::null()); 1178 ASSERT(object_store->array_class() != Class::null());
1146 return object_store->array_class(); 1179 return object_store->array_class();
1147 case kImmutableArray: 1180 case kImmutableArray:
1148 ASSERT(object_store->immutable_array_class() != Class::null()); 1181 ASSERT(object_store->immutable_array_class() != Class::null());
1149 return object_store->immutable_array_class(); 1182 return object_store->immutable_array_class();
1150 case kByteBuffer: 1183 case kByteBuffer:
(...skipping 4433 matching lines...) Expand 10 before | Expand all | Expand 10 after
5584 } 5617 }
5585 5618
5586 5619
5587 int32_t String::CharAt(intptr_t index) const { 5620 int32_t String::CharAt(intptr_t index) const {
5588 // String is an abstract class. 5621 // String is an abstract class.
5589 UNREACHABLE(); 5622 UNREACHABLE();
5590 return 0; 5623 return 0;
5591 } 5624 }
5592 5625
5593 5626
5627 intptr_t String::CharSize() const {
5628 // String is an abstract class.
5629 UNREACHABLE();
5630 return 0;
5631 }
5632
5633
5594 bool String::Equals(const Instance& other) const { 5634 bool String::Equals(const Instance& other) const {
5595 if (this->raw() == other.raw()) { 5635 if (this->raw() == other.raw()) {
5596 // Both handles point to the same raw instance. 5636 // Both handles point to the same raw instance.
5597 return true; 5637 return true;
5598 } 5638 }
5599 5639
5600 if (!other.IsString() || other.IsNull()) { 5640 if (!other.IsString() || other.IsNull()) {
5601 return false; 5641 return false;
5602 } 5642 }
5603 5643
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
5847 } 5887 }
5848 return FourByteString::New(characters, len, space); 5888 return FourByteString::New(characters, len, space);
5849 } 5889 }
5850 5890
5851 5891
5852 RawString* String::New(const String& str, Heap::Space space) { 5892 RawString* String::New(const String& str, Heap::Space space) {
5853 // Currently this just creates a copy of the string in the correct space. 5893 // Currently this just creates a copy of the string in the correct space.
5854 // Once we have external string support, this will also create a heap copy of 5894 // Once we have external string support, this will also create a heap copy of
5855 // the string if necessary. Some optimizations are possible, such as not 5895 // the string if necessary. Some optimizations are possible, such as not
5856 // copying internal strings into the same space. 5896 // copying internal strings into the same space.
5857 if (str.IsOneByteString()) { 5897 intptr_t len = str.Length();
5858 OneByteString& one_byte_str = OneByteString::Handle(); 5898 String& result = String::Handle();
5859 one_byte_str ^= str.raw(); 5899 intptr_t char_size = str.CharSize();
5860 return OneByteString::New(one_byte_str, space); 5900 if (char_size == kOneByteChar) {
5861 } else if (str.IsTwoByteString()) { 5901 result ^= OneByteString::New(len, space);
5862 TwoByteString& two_byte_str = TwoByteString::Handle(); 5902 } else if (char_size == kTwoByteChar) {
5863 two_byte_str ^= str.raw(); 5903 result ^= TwoByteString::New(len, space);
5864 return TwoByteString::New(two_byte_str, space); 5904 } else {
5905 ASSERT(char_size == kFourByteChar);
5906 result ^= FourByteString::New(len, space);
5865 } 5907 }
5866 ASSERT(str.IsFourByteString()); 5908 String::Copy(result, 0, str, 0, len);
5867 FourByteString& four_byte_str = FourByteString::Handle(); 5909 return result.raw();
5868 four_byte_str ^= str.raw();
5869 return FourByteString::New(four_byte_str, space);
5870 } 5910 }
5871 5911
5872 5912
5913 RawString* String::NewExternal(const uint8_t* characters,
5914 intptr_t len,
5915 void* peer,
5916 PeerFinalizer callback,
5917 Heap::Space space) {
5918 return ExternalOneByteString::New(characters, len, peer, callback, space);
5919 }
5920
5921
5922 RawString* String::NewExternal(const uint16_t* characters,
5923 intptr_t len,
5924 void* peer,
5925 PeerFinalizer callback,
5926 Heap::Space space) {
5927 return ExternalTwoByteString::New(characters, len, peer, callback, space);
5928 }
5929
5930
5931 RawString* String::NewExternal(const uint32_t* characters,
5932 intptr_t len,
5933 void* peer,
5934 PeerFinalizer callback,
5935 Heap::Space space) {
5936 return ExternalFourByteString::New(characters, len, peer, callback, space);
5937 }
5938
5939
5873 void String::Copy(const String& dst, intptr_t dst_offset, 5940 void String::Copy(const String& dst, intptr_t dst_offset,
5874 const uint8_t* characters, 5941 const uint8_t* characters,
5875 intptr_t len) { 5942 intptr_t len) {
5876 ASSERT(dst_offset >= 0); 5943 ASSERT(dst_offset >= 0);
5877 ASSERT(len >= 0); 5944 ASSERT(len >= 0);
5878 ASSERT(len <= (dst.Length() - dst_offset)); 5945 ASSERT(len <= (dst.Length() - dst_offset));
5879 if (dst.IsOneByteString()) { 5946 if (dst.IsOneByteString()) {
5880 OneByteString& onestr = OneByteString::Handle(); 5947 OneByteString& onestr = OneByteString::Handle();
5881 onestr ^= dst.raw(); 5948 onestr ^= dst.raw();
5882 NoGCScope no_gc; 5949 NoGCScope no_gc;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
5971 6038
5972 void String::Copy(const String& dst, intptr_t dst_offset, 6039 void String::Copy(const String& dst, intptr_t dst_offset,
5973 const String& src, intptr_t src_offset, 6040 const String& src, intptr_t src_offset,
5974 intptr_t len) { 6041 intptr_t len) {
5975 ASSERT(dst_offset >= 0); 6042 ASSERT(dst_offset >= 0);
5976 ASSERT(src_offset >= 0); 6043 ASSERT(src_offset >= 0);
5977 ASSERT(len >= 0); 6044 ASSERT(len >= 0);
5978 ASSERT(len <= (dst.Length() - dst_offset)); 6045 ASSERT(len <= (dst.Length() - dst_offset));
5979 ASSERT(len <= (src.Length() - src_offset)); 6046 ASSERT(len <= (src.Length() - src_offset));
5980 if (len > 0) { 6047 if (len > 0) {
5981 if (src.IsOneByteString()) { 6048 intptr_t char_size = src.CharSize();
5982 OneByteString& onestr = OneByteString::Handle(); 6049 if (char_size == kOneByteChar) {
5983 onestr ^= src.raw(); 6050 if (src.IsOneByteString()) {
5984 NoGCScope no_gc; 6051 OneByteString& onestr = OneByteString::Handle();
5985 String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len); 6052 onestr ^= src.raw();
5986 } else if (src.IsTwoByteString()) { 6053 NoGCScope no_gc;
5987 TwoByteString& twostr = TwoByteString::Handle(); 6054 String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len);
5988 twostr ^= src.raw(); 6055 } else {
5989 NoGCScope no_gc; 6056 ASSERT(src.IsExternalOneByteString());
5990 String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len); 6057 ExternalOneByteString& onestr = ExternalOneByteString::Handle();
6058 onestr ^= src.raw();
6059 NoGCScope no_gc;
6060 String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len);
6061 }
6062 } else if (char_size == kTwoByteChar) {
6063 if (src.IsTwoByteString()) {
6064 TwoByteString& twostr = TwoByteString::Handle();
6065 twostr ^= src.raw();
6066 NoGCScope no_gc;
6067 String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len);
6068 } else {
6069 ASSERT(src.IsExternalTwoByteString());
6070 ExternalTwoByteString& twostr = ExternalTwoByteString::Handle();
6071 twostr ^= src.raw();
6072 NoGCScope no_gc;
6073 String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len);
6074 }
5991 } else { 6075 } else {
5992 ASSERT(src.IsFourByteString()); 6076 ASSERT(char_size == kFourByteChar);
5993 FourByteString& fourstr = FourByteString::Handle(); 6077 if (src.IsFourByteString()) {
5994 fourstr ^= src.raw(); 6078 FourByteString& fourstr = FourByteString::Handle();
5995 NoGCScope no_gc; 6079 fourstr ^= src.raw();
5996 String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len); 6080 NoGCScope no_gc;
6081 String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len);
6082 } else {
6083 ASSERT(src.IsExternalFourByteString());
6084 ExternalFourByteString& fourstr = ExternalFourByteString::Handle();
6085 fourstr ^= src.raw();
6086 NoGCScope no_gc;
6087 String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len);
6088 }
5997 } 6089 }
5998 } 6090 }
5999 } 6091 }
6000 6092
6001 6093
6002 static void GrowSymbolTable(const Array& symbol_table, intptr_t table_size) { 6094 static void GrowSymbolTable(const Array& symbol_table, intptr_t table_size) {
6003 // TODO(iposva): Avoid exponential growth. 6095 // TODO(iposva): Avoid exponential growth.
6004 intptr_t new_table_size = table_size * 2; 6096 intptr_t new_table_size = table_size * 2;
6005 Array& new_symbol_table = Array::Handle(Array::New(new_table_size + 1)); 6097 Array& new_symbol_table = Array::Handle(Array::New(new_table_size + 1));
6006 // Copy all elements from the original symbol table to the newly allocated 6098 // Copy all elements from the original symbol table to the newly allocated
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
6148 } 6240 }
6149 ASSERT(symbol.IsSymbol()); 6241 ASSERT(symbol.IsSymbol());
6150 return symbol.raw(); 6242 return symbol.raw();
6151 } 6243 }
6152 6244
6153 6245
6154 RawString* String::Concat(const String& str1, 6246 RawString* String::Concat(const String& str1,
6155 const String& str2, 6247 const String& str2,
6156 Heap::Space space) { 6248 Heap::Space space) {
6157 ASSERT(!str1.IsNull() && !str2.IsNull()); 6249 ASSERT(!str1.IsNull() && !str2.IsNull());
6158 if (str1.IsFourByteString() || str2.IsFourByteString()) { 6250 intptr_t char_size = Utils::Maximum(str1.CharSize(), str2.CharSize());
6251 if (char_size == kFourByteChar) {
6159 return FourByteString::Concat(str1, str2, space); 6252 return FourByteString::Concat(str1, str2, space);
6160 } 6253 }
6161 if (str1.IsTwoByteString() || str2.IsTwoByteString()) { 6254 if (char_size == kTwoByteChar) {
6162 return TwoByteString::Concat(str1, str2, space); 6255 return TwoByteString::Concat(str1, str2, space);
6163 } 6256 }
6164 ASSERT(str1.IsOneByteString() && str2.IsOneByteString());
6165 return OneByteString::Concat(str1, str2, space); 6257 return OneByteString::Concat(str1, str2, space);
6166 } 6258 }
6167 6259
6168 6260
6169 RawString* String::ConcatAll(const Array& strings, 6261 RawString* String::ConcatAll(const Array& strings,
6170 Heap::Space space) { 6262 Heap::Space space) {
6171 ASSERT(!strings.IsNull()); 6263 ASSERT(!strings.IsNull());
6172 bool is_one_byte_string = true;
6173 bool is_two_byte_string = true;
6174 intptr_t result_len = 0; 6264 intptr_t result_len = 0;
6175 intptr_t strings_len = strings.Length(); 6265 intptr_t strings_len = strings.Length();
6176 String& str = String::Handle(); 6266 String& str = String::Handle();
6267 intptr_t char_size = kOneByteChar;
6177 for (intptr_t i = 0; i < strings_len; i++) { 6268 for (intptr_t i = 0; i < strings_len; i++) {
6178 str ^= strings.At(i); 6269 str ^= strings.At(i);
6179 result_len += str.Length(); 6270 result_len += str.Length();
6180 if (str.IsFourByteString()) { 6271 char_size = Utils::Maximum(char_size, str.CharSize());
6181 is_one_byte_string = false;
6182 is_two_byte_string = false;
6183 } else if (str.IsTwoByteString()) {
6184 is_one_byte_string = false;
6185 }
6186 } 6272 }
6187 if (is_one_byte_string) { 6273 if (char_size == kOneByteChar) {
6188 return OneByteString::ConcatAll(strings, result_len, space); 6274 return OneByteString::ConcatAll(strings, result_len, space);
6189 } else if (is_two_byte_string) { 6275 } else if (char_size == kTwoByteChar) {
6190 return TwoByteString::ConcatAll(strings, result_len, space); 6276 return TwoByteString::ConcatAll(strings, result_len, space);
6191 } 6277 }
6278 ASSERT(char_size == kFourByteChar);
6192 return FourByteString::ConcatAll(strings, result_len, space); 6279 return FourByteString::ConcatAll(strings, result_len, space);
6193 } 6280 }
6194 6281
6195 6282
6196 RawString* String::SubString(const String& str, 6283 RawString* String::SubString(const String& str,
6197 intptr_t begin_index, 6284 intptr_t begin_index,
6198 Heap::Space space) { 6285 Heap::Space space) {
6199 ASSERT(!str.IsNull()); 6286 ASSERT(!str.IsNull());
6200 if (begin_index >= str.Length()) { 6287 if (begin_index >= str.Length()) {
6201 return String::null(); 6288 return String::null();
6202 } 6289 }
6203 return String::SubString(str, begin_index, (str.Length() - begin_index)); 6290 return String::SubString(str, begin_index, (str.Length() - begin_index));
6204 } 6291 }
6205 6292
6206 6293
6207 RawString* String::SubString(const String& str, 6294 RawString* String::SubString(const String& str,
6208 intptr_t begin_index, 6295 intptr_t begin_index,
6209 intptr_t length, 6296 intptr_t length,
6210 Heap::Space space) { 6297 Heap::Space space) {
6211 ASSERT(!str.IsNull()); 6298 ASSERT(!str.IsNull());
6212 ASSERT(begin_index >= 0); 6299 ASSERT(begin_index >= 0);
6213 ASSERT(length >= 0); 6300 ASSERT(length >= 0);
6214 if (begin_index >= str.Length()) { 6301 if (begin_index >= str.Length()) {
6215 return String::null(); 6302 return String::null();
6216 } 6303 }
6217 if (str.IsOneByteString()) { 6304 String& result = String::Handle();
6218 OneByteString& obstr = OneByteString::Handle(); 6305 bool is_one_byte_string = true;
6219 obstr ^= str.raw(); 6306 bool is_two_byte_string = true;
6220 return OneByteString::SubString(obstr, begin_index, length, space); 6307 intptr_t char_size = str.CharSize();
6221 } else if (str.IsTwoByteString()) { 6308 if (char_size == kTwoByteChar) {
6222 TwoByteString& twostr = TwoByteString::Handle(); 6309 for (intptr_t i = begin_index; i < begin_index + length; ++i) {
6223 twostr ^= str.raw(); 6310 if (str.CharAt(i) > 0xFF) {
6224 return TwoByteString::SubString(twostr, begin_index, length, space); 6311 is_one_byte_string = false;
6312 break;
6313 }
6314 }
6315 } else if (char_size == kFourByteChar) {
6316 for (intptr_t i = begin_index; i < begin_index + length; ++i) {
6317 if (str.CharAt(i) > 0xFFFF) {
6318 is_one_byte_string = false;
6319 is_two_byte_string = false;
6320 break;
6321 } else if (str.CharAt(i) > 0xFF) {
6322 is_one_byte_string = false;
6323 }
6324 }
6225 } 6325 }
6226 ASSERT(str.IsFourByteString()); 6326 if (is_one_byte_string) {
6227 FourByteString& fourstr = FourByteString::Handle(); 6327 result ^= OneByteString::New(length, space);
6228 fourstr ^= str.raw(); 6328 } else if (is_two_byte_string) {
6229 return FourByteString::SubString(fourstr, begin_index, length, space); 6329 result ^= TwoByteString::New(length, space);
6330 } else {
6331 result ^= FourByteString::New(length, space);
6332 }
6333 String::Copy(result, 0, str, begin_index, length);
6334 return result.raw();
6230 } 6335 }
6231 6336
6232 6337
6233 const char* String::ToCString() const { 6338 const char* String::ToCString() const {
6234 intptr_t len = Utf8::Length(*this); 6339 intptr_t len = Utf8::Length(*this);
6235 Zone* zone = Isolate::Current()->current_zone(); 6340 Zone* zone = Isolate::Current()->current_zone();
6236 char* result = reinterpret_cast<char*>(zone->Allocate(len + 1)); 6341 char* result = reinterpret_cast<char*>(zone->Allocate(len + 1));
6237 Utf8::Encode(*this, result, len); 6342 Utf8::Encode(*this, result, len);
6238 result[len] = 0; 6343 result[len] = 0;
6239 return result; 6344 return result;
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
6367 for (intptr_t i = 0; i < strings_len; i++) { 6472 for (intptr_t i = 0; i < strings_len; i++) {
6368 str ^= strings.At(i); 6473 str ^= strings.At(i);
6369 intptr_t str_len = str.Length(); 6474 intptr_t str_len = str.Length();
6370 String::Copy(result, pos, str, 0, str_len); 6475 String::Copy(result, pos, str, 0, str_len);
6371 pos += str_len; 6476 pos += str_len;
6372 } 6477 }
6373 return result.raw(); 6478 return result.raw();
6374 } 6479 }
6375 6480
6376 6481
6377 RawString* OneByteString::SubString(const OneByteString& str,
6378 intptr_t begin_index,
6379 intptr_t length,
6380 Heap::Space space) {
6381 ASSERT(!str.IsNull());
6382 ASSERT(begin_index < str.Length());
6383 OneByteString& result = OneByteString::Handle();
6384 if (length <= (str.Length() - begin_index)) {
6385 result ^= OneByteString::New(length, space);
6386 String::Copy(result, 0, str, begin_index, length);
6387 }
6388 // TODO(5418937): return a non-null object on error.
6389 return result.raw();
6390 }
6391
6392
6393 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), 6482 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch),
6394 const String& str, 6483 const String& str,
6395 Heap::Space space) { 6484 Heap::Space space) {
6396 ASSERT(!str.IsNull()); 6485 ASSERT(!str.IsNull());
6397 intptr_t len = str.Length(); 6486 intptr_t len = str.Length();
6398 const OneByteString& result = 6487 const OneByteString& result =
6399 OneByteString::Handle(OneByteString::New(len, space)); 6488 OneByteString::Handle(OneByteString::New(len, space));
6400 for (intptr_t i = 0; i < len; ++i) { 6489 for (intptr_t i = 0; i < len; ++i) {
6401 int32_t ch = mapping(str.CharAt(i)); 6490 int32_t ch = mapping(str.CharAt(i));
6402 ASSERT(ch >= 0 && ch <= 0xFF); 6491 ASSERT(ch >= 0 && ch <= 0xFF);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
6486 for (intptr_t i = 0; i < strings_len; i++) { 6575 for (intptr_t i = 0; i < strings_len; i++) {
6487 str ^= strings.At(i); 6576 str ^= strings.At(i);
6488 intptr_t str_len = str.Length(); 6577 intptr_t str_len = str.Length();
6489 String::Copy(result, pos, str, 0, str_len); 6578 String::Copy(result, pos, str, 0, str_len);
6490 pos += str_len; 6579 pos += str_len;
6491 } 6580 }
6492 return result.raw(); 6581 return result.raw();
6493 } 6582 }
6494 6583
6495 6584
6496 RawString* TwoByteString::SubString(const TwoByteString& str,
6497 intptr_t begin_index,
6498 intptr_t length,
6499 Heap::Space space) {
6500 ASSERT(!str.IsNull());
6501 ASSERT(begin_index < str.Length());
6502 String& result = String::Handle();
6503 if (length <= (str.Length() - begin_index)) {
6504 bool is_one_byte_string = true;
6505 for (intptr_t i = begin_index; i < begin_index + length; ++i) {
6506 if (str.CharAt(i) > 0xFF) {
6507 is_one_byte_string = false;
6508 break;
6509 }
6510 }
6511 if (is_one_byte_string) {
6512 result ^= OneByteString::New(length, space);
6513 } else {
6514 result ^= TwoByteString::New(length, space);
6515 }
6516 String::Copy(result, 0, str, begin_index, length);
6517 }
6518 // TODO(5418937): return a non-null object on error.
6519 return result.raw();
6520 }
6521
6522
6523 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch), 6585 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch),
6524 const String& str, 6586 const String& str,
6525 Heap::Space space) { 6587 Heap::Space space) {
6526 ASSERT(!str.IsNull()); 6588 ASSERT(!str.IsNull());
6527 intptr_t len = str.Length(); 6589 intptr_t len = str.Length();
6528 const TwoByteString& result = 6590 const TwoByteString& result =
6529 TwoByteString::Handle(TwoByteString::New(len, space)); 6591 TwoByteString::Handle(TwoByteString::New(len, space));
6530 for (intptr_t i = 0; i < len; ++i) { 6592 for (intptr_t i = 0; i < len; ++i) {
6531 int32_t ch = mapping(str.CharAt(i)); 6593 int32_t ch = mapping(str.CharAt(i));
6532 ASSERT(ch >= 0 && ch <= 0xFFFF); 6594 ASSERT(ch >= 0 && ch <= 0xFFFF);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
6604 str ^= strings.At(i); 6666 str ^= strings.At(i);
6605 intptr_t str_len = str.Length(); 6667 intptr_t str_len = str.Length();
6606 String::Copy(result, pos, str, 0, str_len); 6668 String::Copy(result, pos, str, 0, str_len);
6607 pos += str_len; 6669 pos += str_len;
6608 } 6670 }
6609 } 6671 }
6610 return result.raw(); 6672 return result.raw();
6611 } 6673 }
6612 6674
6613 6675
6614 RawString* FourByteString::SubString(const FourByteString& str,
6615 intptr_t begin_index,
6616 intptr_t length,
6617 Heap::Space space) {
6618 ASSERT(!str.IsNull());
6619 ASSERT(begin_index < str.Length());
6620 String& result = String::Handle();
6621 if (length <= (str.Length() - begin_index)) {
6622 bool is_one_byte_string = true;
6623 bool is_two_byte_string = true;
6624 for (intptr_t i = begin_index; i < begin_index + length; ++i) {
6625 if (str.CharAt(i) > 0xFFFF) {
6626 is_one_byte_string = false;
6627 is_two_byte_string = false;
6628 break;
6629 } else if (str.CharAt(i) > 0xFF) {
6630 is_one_byte_string = false;
6631 }
6632 }
6633 if (is_one_byte_string) {
6634 result ^= OneByteString::New(length, space);
6635 } else if (is_two_byte_string) {
6636 result ^= TwoByteString::New(length, space);
6637 } else {
6638 result ^= FourByteString::New(length, space);
6639 }
6640 String::Copy(result, 0, str, begin_index, length);
6641 }
6642 // TODO(5418937): return a non-null object on error.
6643 return result.raw();
6644 }
6645
6646
6647 RawFourByteString* FourByteString::Transform(int32_t (*mapping)(int32_t ch), 6676 RawFourByteString* FourByteString::Transform(int32_t (*mapping)(int32_t ch),
6648 const String& str, 6677 const String& str,
6649 Heap::Space space) { 6678 Heap::Space space) {
6650 ASSERT(!str.IsNull()); 6679 ASSERT(!str.IsNull());
6651 intptr_t len = str.Length(); 6680 intptr_t len = str.Length();
6652 const FourByteString& result = 6681 const FourByteString& result =
6653 FourByteString::Handle(FourByteString::New(len, space)); 6682 FourByteString::Handle(FourByteString::New(len, space));
6654 for (intptr_t i = 0; i < len; ++i) { 6683 for (intptr_t i = 0; i < len; ++i) {
6655 int32_t ch = mapping(str.CharAt(i)); 6684 int32_t ch = mapping(str.CharAt(i));
6656 ASSERT(ch >= 0 && ch <= 0x10FFFF); 6685 ASSERT(ch >= 0 && ch <= 0x10FFFF);
6657 *result.CharAddr(i) = ch; 6686 *result.CharAddr(i) = ch;
6658 } 6687 }
6659 return result.raw(); 6688 return result.raw();
6660 } 6689 }
6661 6690
6662 6691
6663 const char* FourByteString::ToCString() const { 6692 const char* FourByteString::ToCString() const {
6664 return String::ToCString(); 6693 return String::ToCString();
6665 } 6694 }
6666 6695
6667 6696
6697 RawExternalOneByteString* ExternalOneByteString::New(const uint8_t* data,
6698 intptr_t len,
6699 void* peer,
6700 PeerFinalizer callback,
6701 Heap::Space space) {
6702 Isolate* isolate = Isolate::Current();
6703
6704 const Class& cls =
6705 Class::Handle(isolate->object_store()->external_one_byte_string_class());
6706 ExternalOneByteString& result = ExternalOneByteString::Handle();
6707 {
6708 ExternalStringData<uint8_t>* external_data =
6709 new ExternalStringData<uint8_t>(data, peer, callback);
6710 RawObject* raw = Object::Allocate(cls,
6711 ExternalOneByteString::InstanceSize(),
6712 space);
6713 NoGCScope no_gc;
6714 result ^= raw;
6715 result.SetLength(len);
6716 result.SetHash(0);
6717 result.SetExternalData(external_data);
6718 }
6719 return result.raw();
6720 }
6721
6722
6723 const char* ExternalOneByteString::ToCString() const {
6724 return String::ToCString();
6725 }
6726
6727
6728 RawExternalTwoByteString* ExternalTwoByteString::New(const uint16_t* data,
6729 intptr_t len,
6730 void* peer,
6731 PeerFinalizer callback,
6732 Heap::Space space) {
6733 Isolate* isolate = Isolate::Current();
6734
6735 const Class& cls =
6736 Class::Handle(isolate->object_store()->external_two_byte_string_class());
6737 ExternalTwoByteString& result = ExternalTwoByteString::Handle();
6738 {
6739 ExternalStringData<uint16_t>* external_data =
6740 new ExternalStringData<uint16_t>(data, peer, callback);
6741 RawObject* raw = Object::Allocate(cls,
6742 ExternalTwoByteString::InstanceSize(),
6743 space);
6744 NoGCScope no_gc;
6745 result ^= raw;
6746 result.SetLength(len);
6747 result.SetHash(0);
6748 result.SetExternalData(external_data);
6749 }
6750 return result.raw();
6751 }
6752
6753
6754 const char* ExternalTwoByteString::ToCString() const {
6755 return String::ToCString();
6756 }
6757
6758
6759 RawExternalFourByteString* ExternalFourByteString::New(const uint32_t* data,
6760 intptr_t len,
6761 void* peer,
6762 PeerFinalizer callback,
6763 Heap::Space space) {
6764 Isolate* isolate = Isolate::Current();
6765
6766 const Class& cls =
6767 Class::Handle(isolate->object_store()->external_four_byte_string_class());
6768 ExternalFourByteString& result = ExternalFourByteString::Handle();
6769 {
6770 ExternalStringData<uint32_t>* external_data =
6771 new ExternalStringData<uint32_t>(data, peer, callback);
6772 RawObject* raw = Object::Allocate(cls,
6773 ExternalFourByteString::InstanceSize(),
6774 space);
6775 NoGCScope no_gc;
6776 result ^= raw;
6777 result.SetLength(len);
6778 result.SetHash(0);
6779 result.SetExternalData(external_data);
6780 }
6781 return result.raw();
6782 }
6783
6784
6785 const char* ExternalFourByteString::ToCString() const {
6786 return String::ToCString();
6787 }
6788
6789
6668 RawBool* Bool::True() { 6790 RawBool* Bool::True() {
6669 return Isolate::Current()->object_store()->true_value(); 6791 return Isolate::Current()->object_store()->true_value();
6670 } 6792 }
6671 6793
6672 6794
6673 RawBool* Bool::False() { 6795 RawBool* Bool::False() {
6674 return Isolate::Current()->object_store()->false_value(); 6796 return Isolate::Current()->object_store()->false_value();
6675 } 6797 }
6676 6798
6677 6799
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
7145 const String& str = String::Handle(pattern()); 7267 const String& str = String::Handle(pattern());
7146 const char* format = "JSRegExp: pattern=%s flags=%s"; 7268 const char* format = "JSRegExp: pattern=%s flags=%s";
7147 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); 7269 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags());
7148 char* chars = reinterpret_cast<char*>( 7270 char* chars = reinterpret_cast<char*>(
7149 Isolate::Current()->current_zone()->Allocate(len + 1)); 7271 Isolate::Current()->current_zone()->Allocate(len + 1));
7150 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); 7272 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags());
7151 return chars; 7273 return chars;
7152 } 7274 }
7153 7275
7154 } // namespace dart 7276 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_store.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698