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

Unified Diff: runtime/vm/object.cc

Issue 8383029: Implement external strings. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: pre-review clean-up Created 9 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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/object.cc
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index b5adbd1b34d54de05ba344002f91293159025420..06e15cc99613e77e1958cc987c8b37bdddad4322 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -388,6 +388,15 @@ void Object::Init(Isolate* isolate) {
cls = Class::New<FourByteString>();
object_store->set_four_byte_string_class(cls);
+ cls = Class::New<ExternalOneByteString>();
+ object_store->set_external_one_byte_string_class(cls);
+
+ cls = Class::New<ExternalTwoByteString>();
+ object_store->set_external_two_byte_string_class(cls);
+
+ cls = Class::New<ExternalFourByteString>();
+ object_store->set_external_four_byte_string_class(cls);
+
cls = Class::New<Bool>();
object_store->set_bool_class(cls);
@@ -457,6 +466,24 @@ void Object::Init(Isolate* isolate) {
cls.set_script(impl_script);
core_impl_lib.AddClass(cls);
+ name = String::NewSymbol("ExternalOneByteString");
+ cls = object_store->external_one_byte_string_class();
+ cls.set_name(name);
+ cls.set_script(impl_script);
+ core_impl_lib.AddClass(cls);
+
+ name = String::NewSymbol("ExternalTwoByteString");
+ cls = object_store->external_two_byte_string_class();
+ cls.set_name(name);
+ cls.set_script(impl_script);
+ core_impl_lib.AddClass(cls);
+
+ name = String::NewSymbol("ExternalFourByteString");
+ cls = object_store->external_four_byte_string_class();
+ cls.set_name(name);
+ cls.set_script(impl_script);
+ core_impl_lib.AddClass(cls);
+
name = String::NewSymbol("Mint");
cls = object_store->mint_class();
cls.set_name(name);
@@ -632,6 +659,15 @@ void Object::InitFromSnapshot(Isolate* isolate) {
cls = Class::New<FourByteString>();
object_store->set_four_byte_string_class(cls);
+ cls = Class::New<ExternalOneByteString>();
+ object_store->set_external_one_byte_string_class(cls);
+
+ cls = Class::New<ExternalTwoByteString>();
+ object_store->set_external_two_byte_string_class(cls);
+
+ cls = Class::New<ExternalFourByteString>();
+ object_store->set_external_four_byte_string_class(cls);
+
cls = Class::New<Bool>();
object_store->set_bool_class(cls);
@@ -1082,6 +1118,15 @@ RawClass* Class::GetClass(ObjectKind kind) {
case kFourByteString:
ASSERT(object_store->four_byte_string_class() != Class::null());
return object_store->four_byte_string_class();
+ case kExternalOneByteString:
+ ASSERT(object_store->external_one_byte_string_class() != Class::null());
+ return object_store->external_one_byte_string_class();
+ case kExternalTwoByteString:
+ ASSERT(object_store->external_two_byte_string_class() != Class::null());
+ return object_store->external_two_byte_string_class();
+ case kExternalFourByteString:
+ ASSERT(object_store->external_four_byte_string_class() != Class::null());
+ return object_store->external_four_byte_string_class();
case kBool:
ASSERT(object_store->bool_class() != Class::null());
return object_store->bool_class();
@@ -5569,19 +5614,18 @@ RawString* String::New(const String& str, Heap::Space space) {
// Once we have external string support, this will also create a heap copy of
turnidge 2011/10/25 18:07:20 Update this comment?
cshapiro 2011/10/25 20:42:47 Yes, indeed. Thanks for pointing that out.
// the string if necessary. Some optimizations are possible, such as not
// copying internal strings into the same space.
- if (str.IsOneByteString()) {
- OneByteString& one_byte_str = OneByteString::Handle();
- one_byte_str ^= str.raw();
- return OneByteString::New(one_byte_str, space);
- } else if (str.IsTwoByteString()) {
- TwoByteString& two_byte_str = TwoByteString::Handle();
- two_byte_str ^= str.raw();
- return TwoByteString::New(two_byte_str, space);
+ intptr_t len = str.Length();
+ String& result = String::Handle();
+ if (str.HasOneByteChar()) {
+ result ^= OneByteString::New(len, space);
+ } else if (str.HasTwoByteChar()) {
+ result ^= TwoByteString::New(len, space);
+ } else {
+ ASSERT(str.HasFourByteChar());
+ result ^= FourByteString::New(len, space);
}
- ASSERT(str.IsFourByteString());
- FourByteString& four_byte_str = FourByteString::Handle();
- four_byte_str ^= str.raw();
- return FourByteString::New(four_byte_str, space);
+ String::Copy(result, 0, str, 0, len);
+ return result.raw();
}
@@ -5693,22 +5737,46 @@ void String::Copy(const String& dst, intptr_t dst_offset,
ASSERT(len <= (dst.Length() - dst_offset));
ASSERT(len <= (src.Length() - src_offset));
if (len > 0) {
- if (src.IsOneByteString()) {
- OneByteString& onestr = OneByteString::Handle();
- onestr ^= src.raw();
- NoGCScope no_gc;
- String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len);
- } else if (src.IsTwoByteString()) {
- TwoByteString& twostr = TwoByteString::Handle();
- twostr ^= src.raw();
- NoGCScope no_gc;
- String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len);
+ if (src.HasOneByteChar()) {
+ if (src.IsOneByteString()) {
+ OneByteString& onestr = OneByteString::Handle();
+ onestr ^= src.raw();
+ NoGCScope no_gc;
+ String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len);
+ } else {
+ ASSERT(src.IsExternalOneByteString());
+ ExternalOneByteString& onestr = ExternalOneByteString::Handle();
+ onestr ^= src.raw();
+ NoGCScope no_gc;
+ String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len);
+ }
+ } else if (src.HasTwoByteChar()) {
+ if (src.IsTwoByteString()) {
+ TwoByteString& twostr = TwoByteString::Handle();
+ twostr ^= src.raw();
+ NoGCScope no_gc;
+ String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len);
+ } else {
+ ASSERT(src.IsExternalTwoByteString());
+ ExternalTwoByteString& twostr = ExternalTwoByteString::Handle();
+ twostr ^= src.raw();
+ NoGCScope no_gc;
+ String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len);
+ }
} else {
- ASSERT(src.IsFourByteString());
- FourByteString& fourstr = FourByteString::Handle();
- fourstr ^= src.raw();
- NoGCScope no_gc;
- String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len);
+ ASSERT(src.HasFourByteChar());
+ if (src.IsFourByteString()) {
+ FourByteString& fourstr = FourByteString::Handle();
+ fourstr ^= src.raw();
+ NoGCScope no_gc;
+ String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len);
+ } else {
+ ASSERT(src.IsExternalFourByteString());
+ ExternalFourByteString& fourstr = ExternalFourByteString::Handle();
+ fourstr ^= src.raw();
+ NoGCScope no_gc;
+ String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len);
+ }
}
}
}
@@ -5870,13 +5938,13 @@ RawString* String::Concat(const String& str1,
const String& str2,
Heap::Space space) {
ASSERT(!str1.IsNull() && !str2.IsNull());
- if (str1.IsFourByteString() || str2.IsFourByteString()) {
+ if (str1.HasFourByteChar() || str2.HasFourByteChar()) {
return FourByteString::Concat(str1, str2, space);
}
- if (str1.IsTwoByteString() || str2.IsTwoByteString()) {
+ if (str1.HasTwoByteChar() || str2.HasTwoByteChar()) {
return TwoByteString::Concat(str1, str2, space);
}
- ASSERT(str1.IsOneByteString() && str2.IsOneByteString());
+ ASSERT(str1.HasOneByteChar() && str2.HasOneByteChar());
return OneByteString::Concat(str1, str2, space);
}
@@ -5892,10 +5960,10 @@ RawString* String::ConcatAll(const Array& strings,
for (intptr_t i = 0; i < strings_len; i++) {
str ^= strings.At(i);
result_len += str.Length();
- if (str.IsFourByteString()) {
+ if (str.HasFourByteChar()) {
is_one_byte_string = false;
is_two_byte_string = false;
- } else if (str.IsTwoByteString()) {
+ } else if (str.HasTwoByteChar()) {
is_one_byte_string = false;
}
}
@@ -5929,19 +5997,39 @@ RawString* String::SubString(const String& str,
if (begin_index >= str.Length()) {
return String::null();
}
- if (str.IsOneByteString()) {
- OneByteString& obstr = OneByteString::Handle();
- obstr ^= str.raw();
- return OneByteString::SubString(obstr, begin_index, length, space);
- } else if (str.IsTwoByteString()) {
- TwoByteString& twostr = TwoByteString::Handle();
- twostr ^= str.raw();
- return TwoByteString::SubString(twostr, begin_index, length, space);
+ String& result = String::Handle();
+ bool is_one_byte_string = true;
+ bool is_two_byte_string = true;
+ if (str.HasOneByteChar()) {
+ // do nothing
+ } else if (str.HasTwoByteChar()) {
+ for (intptr_t i = begin_index; i < begin_index + length; ++i) {
+ if (str.CharAt(i) > 0xFF) {
+ is_one_byte_string = false;
+ break;
+ }
+ }
+ } else {
+ ASSERT(str.HasFourByteChar());
+ for (intptr_t i = begin_index; i < begin_index + length; ++i) {
+ if (str.CharAt(i) > 0xFFFF) {
+ is_one_byte_string = false;
+ is_two_byte_string = false;
+ break;
+ } else if (str.CharAt(i) > 0xFF) {
+ is_one_byte_string = false;
+ }
+ }
+ }
+ if (is_one_byte_string) {
+ result ^= OneByteString::New(length, space);
+ } else if (is_two_byte_string) {
+ result ^= TwoByteString::New(length, space);
+ } else {
+ result ^= FourByteString::New(length, space);
}
- ASSERT(str.IsFourByteString());
- FourByteString& fourstr = FourByteString::Handle();
- fourstr ^= str.raw();
- return FourByteString::SubString(fourstr, begin_index, length, space);
+ String::Copy(result, 0, str, begin_index, length);
+ return result.raw();
}
@@ -6089,22 +6177,6 @@ RawOneByteString* OneByteString::ConcatAll(const Array& strings,
}
-RawString* OneByteString::SubString(const OneByteString& str,
- intptr_t begin_index,
- intptr_t length,
- Heap::Space space) {
- ASSERT(!str.IsNull());
- ASSERT(begin_index < str.Length());
- OneByteString& result = OneByteString::Handle();
- if (length <= (str.Length() - begin_index)) {
- result ^= OneByteString::New(length, space);
- String::Copy(result, 0, str, begin_index, length);
- }
- // TODO(5418937): return a non-null object on error.
- return result.raw();
-}
-
-
RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch),
const String& str,
Heap::Space space) {
@@ -6208,33 +6280,6 @@ RawTwoByteString* TwoByteString::ConcatAll(const Array& strings,
}
-RawString* TwoByteString::SubString(const TwoByteString& str,
- intptr_t begin_index,
- intptr_t length,
- Heap::Space space) {
- ASSERT(!str.IsNull());
- ASSERT(begin_index < str.Length());
- String& result = String::Handle();
- if (length <= (str.Length() - begin_index)) {
- bool is_one_byte_string = true;
- for (intptr_t i = begin_index; i < begin_index + length; ++i) {
- if (str.CharAt(i) > 0xFF) {
- is_one_byte_string = false;
- break;
- }
- }
- if (is_one_byte_string) {
- result ^= OneByteString::New(length, space);
- } else {
- result ^= TwoByteString::New(length, space);
- }
- String::Copy(result, 0, str, begin_index, length);
- }
- // TODO(5418937): return a non-null object on error.
- return result.raw();
-}
-
-
RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch),
const String& str,
Heap::Space space) {
@@ -6326,39 +6371,6 @@ RawFourByteString* FourByteString::ConcatAll(const Array& strings,
}
-RawString* FourByteString::SubString(const FourByteString& str,
- intptr_t begin_index,
- intptr_t length,
- Heap::Space space) {
- ASSERT(!str.IsNull());
- ASSERT(begin_index < str.Length());
- String& result = String::Handle();
- if (length <= (str.Length() - begin_index)) {
- bool is_one_byte_string = true;
- bool is_two_byte_string = true;
- for (intptr_t i = begin_index; i < begin_index + length; ++i) {
- if (str.CharAt(i) > 0xFFFF) {
- is_one_byte_string = false;
- is_two_byte_string = false;
- break;
- } else if (str.CharAt(i) > 0xFF) {
- is_one_byte_string = false;
- }
- }
- if (is_one_byte_string) {
- result ^= OneByteString::New(length, space);
- } else if (is_two_byte_string) {
- result ^= TwoByteString::New(length, space);
- } else {
- result ^= FourByteString::New(length, space);
- }
- String::Copy(result, 0, str, begin_index, length);
- }
- // TODO(5418937): return a non-null object on error.
- return result.raw();
-}
-
-
RawFourByteString* FourByteString::Transform(int32_t (*mapping)(int32_t ch),
const String& str,
Heap::Space space) {
@@ -6380,6 +6392,90 @@ const char* FourByteString::ToCString() const {
}
+RawExternalOneByteString* ExternalOneByteString::New(const uint8_t* data,
+ intptr_t len,
+ Finalizer finalizer,
+ Heap::Space space) {
+ Isolate* isolate = Isolate::Current();
+
+ const Class& cls =
+ Class::Handle(isolate->object_store()->external_one_byte_string_class());
+ ExternalOneByteString& result = ExternalOneByteString::Handle();
+ {
+ RawObject* raw = Object::Allocate(cls,
+ ExternalOneByteString::InstanceSize(),
+ space);
+ NoGCScope no_gc;
+ result ^= raw;
+ result.SetLength(len);
+ result.SetHash(0);
+ result.SetData(data);
+ }
+ return result.raw();
+}
+
+
+const char* ExternalOneByteString::ToCString() const {
+ return String::ToCString();
+}
+
+
+RawExternalTwoByteString* ExternalTwoByteString::New(const uint16_t* data,
+ intptr_t len,
+ Finalizer finalizer,
+ Heap::Space space) {
+ Isolate* isolate = Isolate::Current();
+
+ const Class& cls =
+ Class::Handle(isolate->object_store()->external_two_byte_string_class());
+ ExternalTwoByteString& result = ExternalTwoByteString::Handle();
+ {
+ RawObject* raw = Object::Allocate(cls,
+ ExternalTwoByteString::InstanceSize(),
+ space);
+ NoGCScope no_gc;
+ result ^= raw;
+ result.SetLength(len);
+ result.SetHash(0);
+ result.SetData(data);
+ }
+ return result.raw();
+}
+
+
+const char* ExternalTwoByteString::ToCString() const {
+ return String::ToCString();
+}
+
+
+RawExternalFourByteString* ExternalFourByteString::New(const uint32_t* data,
+ intptr_t len,
+ Finalizer finalizer,
+ Heap::Space space) {
+ Isolate* isolate = Isolate::Current();
+
+ const Class& cls =
+ Class::Handle(isolate->object_store()->external_four_byte_string_class());
+ ExternalFourByteString& result = ExternalFourByteString::Handle();
+ {
+ RawObject* raw = Object::Allocate(cls,
+ ExternalFourByteString::InstanceSize(),
+ space);
+ NoGCScope no_gc;
+ result ^= raw;
+ result.SetLength(len);
+ result.SetHash(0);
+ result.SetData(data);
+ }
+ return result.raw();
+}
+
+
+const char* ExternalFourByteString::ToCString() const {
+ return String::ToCString();
+}
+
+
RawBool* Bool::True() {
return Isolate::Current()->object_store()->true_value();
}

Powered by Google App Engine
This is Rietveld 408576698