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

Unified Diff: src/objects.cc

Issue 8304021: Improve speed of Utf8Write by always flattening the string first and (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' 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
« no previous file with comments | « src/objects.h ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
===================================================================
--- src/objects.cc (revision 9658)
+++ src/objects.cc (working copy)
@@ -5519,24 +5519,6 @@
}
-int String::Utf8Length() {
- if (IsAsciiRepresentation()) return length();
- // Attempt to flatten before accessing the string. It probably
- // doesn't make Utf8Length faster, but it is very likely that
- // the string will be accessed later (for example by WriteUtf8)
- // so it's still a good idea.
- Heap* heap = GetHeap();
- TryFlatten();
- Access<StringInputBuffer> buffer(
- heap->isolate()->objects_string_input_buffer());
- buffer->Reset(0, this);
- int result = 0;
- while (buffer->has_more())
- result += unibrow::Utf8::Length(buffer->GetNext());
- return result;
-}
-
-
String::FlatContent String::GetFlatContent() {
int length = this->length();
StringShape shape(this);
@@ -5960,6 +5942,73 @@
}
+// This method determines the type of string involved and then gets the UTF8
+// length of the string. It doesn't flatten the string and has log(n) recursion
+// for a string of length n.
+int String::Utf8Length(String* input, int from, int to) {
+ if (from == to) return 0;
+ int total = 0;
+ while (true) {
+ if (input->IsAsciiRepresentation()) return total + to - from;
+ switch (StringShape(input).representation_tag()) {
+ case kConsStringTag: {
+ ConsString* str = ConsString::cast(input);
+ String* first = str->first();
+ String* second = str->second();
+ int first_length = first->length();
+ if (first_length - from < to - first_length) {
+ if (first_length > from) {
+ // Left hand side is shorter.
+ total += Utf8Length(first, from, first_length);
+ input = second;
+ from = 0;
+ to -= first_length;
+ } else {
+ // We only need the right hand side.
+ input = second;
+ from -= first_length;
+ to -= first_length;
+ }
+ } else {
+ if (first_length <= to) {
+ // Right hand side is shorter.
+ total += Utf8Length(second, 0, to - first_length);
+ input = first;
+ to = first_length;
+ } else {
+ // We only need the left hand side.
+ input = first;
+ }
+ }
+ continue;
+ }
+ case kExternalStringTag:
+ case kSeqStringTag: {
+ Vector<const uc16> vector = input->GetFlatContent().ToUC16Vector();
+ const uc16* p = vector.start();
+ for (int i = from; i < to; i++) {
+ total += unibrow::Utf8::Length(p[i]);
+ }
+ return total;
+ }
+ case kSlicedStringTag: {
+ SlicedString* str = SlicedString::cast(input);
+ int offset = str->offset();
+ input = str->parent();
+ from += offset;
+ to += offset;
+ continue;
+ }
+ default:
+ break;
+ }
+ UNREACHABLE();
+ return 0;
+ }
+ return 0;
+}
+
+
void Relocatable::PostGarbageCollectionProcessing() {
Isolate* isolate = Isolate::Current();
Relocatable* current = isolate->relocatable_top();
« no previous file with comments | « src/objects.h ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698