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

Unified Diff: src/objects-inl.h

Issue 11428106: Add StringBufferStream (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Right traversal optimization Created 8 years 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: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index b99ba44723122cbd4b38fa9e1cdd1b070c7710d9..f633a5c54d71ae6ba81c80b0164936482d9b6613 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -2512,6 +2512,79 @@ String* String::GetUnderlying() {
}
+template<class Visitor, class ConsOp>
+void String::Visit(
+ String* string,
+ unsigned offset,
+ Visitor& visitor,
+ ConsOp& consOp,
+ int32_t type,
+ unsigned length) {
+
+ ASSERT(length == static_cast<unsigned>(string->length()));
+ ASSERT(offset <= length);
+
+ unsigned sliceOffset = offset;
+ while (true) {
+ ASSERT(type == string->map()->instance_type());
+
+ switch (type & (kStringRepresentationMask | kStringEncodingMask)) {
+ case kSeqStringTag | kOneByteStringTag:
Yang 2012/12/04 14:49:11 We usually indent switch-case-clauses like switch
+ visitor.VisitOneByteString(
+ reinterpret_cast<const uint8_t*>(
+ SeqOneByteString::cast(string)->GetChars()) + sliceOffset,
+ length - offset);
Yang 2012/12/04 14:49:11 I suggest adding four more spaces as indentation.
+ return;
+
+ case kSeqStringTag | kTwoByteStringTag:
+ visitor.VisitTwoByteString(
+ reinterpret_cast<const uint16_t*>(
+ SeqTwoByteString::cast(string)->GetChars()) + sliceOffset,
+ length - offset);
+ return;
+
+ case kExternalStringTag | kOneByteStringTag:
+ visitor.VisitOneByteString(
+ reinterpret_cast<const uint8_t*>(
+ ExternalAsciiString::cast(string)->GetChars()) + sliceOffset,
+ length - offset);
+ return;
+
+ case kExternalStringTag | kTwoByteStringTag:
+ visitor.VisitTwoByteString(
+ reinterpret_cast<const uint16_t*>(
+ ExternalTwoByteString::cast(string)->GetChars()) + sliceOffset,
+ length - offset);
+ return;
+
+ case kSlicedStringTag | kOneByteStringTag:
+ case kSlicedStringTag | kTwoByteStringTag:
+ {
+ SlicedString* slicedString = SlicedString::cast(string);
+ sliceOffset += slicedString->offset();
+ string = slicedString->parent();
+ type = string->map()->instance_type();
+ continue;
+ }
+
+ case kConsStringTag | kOneByteStringTag:
+ case kConsStringTag | kTwoByteStringTag:
+ string = consOp.Operate(
+ ConsString::cast(string), &offset, &type, &length);
+ if (string == NULL)
Yang 2012/12/04 14:49:11 no line break here.
+ return;
+ sliceOffset = offset;
+ ASSERT(length == static_cast<unsigned>(string->length()));
+ continue;
+
+ default:
+ UNREACHABLE();
+ return;
+ }
+ }
+}
+
+
uint16_t SeqOneByteString::SeqOneByteStringGet(int index) {
ASSERT(index >= 0 && index < length());
return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
@@ -2690,6 +2763,149 @@ const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
}
+unsigned ConsStringIteratorOp::OffsetForDepth(unsigned depth) {
+ return depth & depthMask;
+}
+
+
+uint32_t ConsStringIteratorOp::MaskForDepth(unsigned depth) {
+ return 1 << OffsetForDepth(depth);
+}
+
+
+void ConsStringIteratorOp::SetRightDescent() {
+ trace |= MaskForDepth(depth - 1);
+}
+
+
+void ConsStringIteratorOp::ClearRightDescent() {
+ trace &= ~MaskForDepth(depth - 1);
+}
+
+
+void ConsStringIteratorOp::PushLeft(ConsString* string) {
+ frames[depth++ & depthMask] = string;
+}
+
+
+void ConsStringIteratorOp::PushRight(ConsString* string, int32_t type) {
+ // Inplace update
+ frames[depth-1 & depthMask] = string;
+ // Optimization: can replace root here.
+ if (depth == 1) {
+ root = string;
+ rootType = type;
+ rootLength = root->length();
+ }
+}
+
+
+void ConsStringIteratorOp::AdjustMaximumDepth() {
+ if (depth > maximumDepth)
+ maximumDepth = depth;
Yang 2012/12/04 14:49:11 No line break here.
+}
+
+
+void ConsStringIteratorOp::Pop() {
+ ASSERT(depth > 0);
+ ASSERT(depth <= maximumDepth);
+ depth--;
+}
+
+
+void ConsStringIteratorOp::Reset() {
+ consumed = 0;
+ ResetStack();
+}
+
+
+bool ConsStringIteratorOp::HasMore() {
+ return depth != 0;
+}
+
+
+void ConsStringIteratorOp::ResetStack() {
+ depth = 0;
+ maximumDepth = 0;
+}
+
+
+bool ConsStringIteratorOp::ContinueOperation(ContinueResponse* response) {
+ bool blewStack;
+ int32_t type;
+ String* string = NextLeaf(&blewStack, &type);
+ // String found.
+ if (string != NULL) {
+ unsigned length = string->length();
+ consumed += length;
+ response->string = string;
+ response->offset = 0;
+ response->length = length;
+ response->type = type;
+ return true;
+ }
+ // Traversal complete.
+ if (!blewStack)
+ return false;
Yang 2012/12/04 14:49:11 no line break.
+ // Restart search.
+ ResetStack();
+ response->string = root;
+ response->offset = consumed;
+ response->length = root->length();
+ response->type = rootType;
+ return true;
+}
+
+
+uint16_t StringBufferStream::GetNext() {
+ return isOneByte ? *buffer8++ : *buffer16++;
+}
+
+
+void StringBufferStream::Reset(String* string, unsigned offset,
Yang 2012/12/04 14:49:11 Please put all arguments on the second line.
+ ConsStringIteratorOp* op) {
+ buffer8 = NULL;
+ end = NULL;
+ this->op = op;
+ op->Reset();
+ String::Visit(string,
+ offset, *this, *op, string->map()->instance_type(), string->length());
+}
+
+
+bool StringBufferStream::has_more() {
+ if (buffer8 != end)
+ return true;
Yang 2012/12/04 14:49:11 no line break here and in the following if.
+ if (!op->HasMore())
+ return false;
+ ConsStringIteratorOp::ContinueResponse response;
+ // This has been checked above
+ if (!op->ContinueOperation(&response)) {
+ UNREACHABLE();
+ return false;
+ }
+ String::Visit(response.string,
+ response.offset, *this, *op, response.type, response.length);
+ return true;
+}
+
+
+void StringBufferStream::VisitOneByteString(const uint8_t* chars,
+ unsigned length) {
Yang 2012/12/04 14:49:11 Either align the two arguments or put both on the
+ isOneByte = true;
+ buffer8 = chars;
+ end = chars + length;
+}
+
+
+void StringBufferStream::VisitTwoByteString(const uint16_t* chars,
+ unsigned length) {
Yang 2012/12/04 14:49:11 Ditto.
+ isOneByte = false;
+ buffer16 = chars;
+ end = reinterpret_cast<const uint8_t*>(chars + length);
+}
+
+
void JSFunctionResultCache::MakeZeroSize() {
set_finger_index(kEntriesIndex);
set_size(kEntriesIndex);
« src/objects.cc ('K') | « src/objects.cc ('k') | test/cctest/test-strings.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698