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

Unified Diff: src/heap.cc

Issue 7477045: Tentative implementation of string slices (hidden under the flag --string-slices). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Some more suggested changes. Created 9 years, 4 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: src/heap.cc
diff --git a/src/heap.cc b/src/heap.cc
index 8dbda270fe3644d6647db538d05b67274e19aacf..6d66dda02df7f558c08ebe76e08dd30d988accdb 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -1288,6 +1288,10 @@ class ScavengingVisitor : public StaticVisitorBase {
&ObjectEvacuationStrategy<POINTER_OBJECT>::
template VisitSpecialized<ConsString::kSize>);
+ table_.Register(kVisitSlicedString,
+ &ObjectEvacuationStrategy<POINTER_OBJECT>::
+ template VisitSpecialized<SlicedString::kSize>);
+
table_.Register(kVisitSharedFunctionInfo,
&ObjectEvacuationStrategy<POINTER_OBJECT>::
template VisitSpecialized<SharedFunctionInfo::kSize>);
@@ -2545,6 +2549,8 @@ MaybeObject* Heap::AllocateConsString(String* first, String* second) {
// If the resulting string is small make a flat string.
if (length < String::kMinNonFlatLength) {
+ // Note that neither of the two inputs can be a slice because:
+ STATIC_ASSERT(String::kMinNonFlatLength <= SlicedString::kMinLength);
ASSERT(first->IsFlat());
ASSERT(second->IsFlat());
if (is_ascii) {
@@ -2636,24 +2642,69 @@ MaybeObject* Heap::AllocateSubString(String* buffer,
// Make an attempt to flatten the buffer to reduce access time.
buffer = buffer->TryFlattenGetString();
+ // TODO(1626): For now slicing external strings is not supported. However,
+ // a flat cons string can have an external string as first part in some cases.
+ // Therefore we have to single out this case as well.
+ if (!FLAG_string_slices ||
+ (buffer->IsConsString() &&
+ (!buffer->IsFlat() ||
+ !ConsString::cast(buffer)->first()->IsSeqString())) ||
+ buffer->IsExternalString() ||
+ length < SlicedString::kMinLength ||
+ pretenure == TENURED) {
+ Object* result;
+ { MaybeObject* maybe_result = buffer->IsAsciiRepresentation()
+ ? AllocateRawAsciiString(length, pretenure)
+ : AllocateRawTwoByteString(length, pretenure);
+ if (!maybe_result->ToObject(&result)) return maybe_result;
+ }
+ String* string_result = String::cast(result);
+ // Copy the characters into the new object.
+ if (buffer->IsAsciiRepresentation()) {
+ ASSERT(string_result->IsAsciiRepresentation());
+ char* dest = SeqAsciiString::cast(string_result)->GetChars();
+ String::WriteToFlat(buffer, dest, start, end);
+ } else {
+ ASSERT(string_result->IsTwoByteRepresentation());
+ uc16* dest = SeqTwoByteString::cast(string_result)->GetChars();
+ String::WriteToFlat(buffer, dest, start, end);
+ }
+ return result;
+ }
+
+ ASSERT(buffer->IsFlat());
+ ASSERT(!buffer->IsExternalString());
+#if DEBUG
+ buffer->StringVerify();
+#endif
+
Object* result;
- { MaybeObject* maybe_result = buffer->IsAsciiRepresentation()
- ? AllocateRawAsciiString(length, pretenure )
- : AllocateRawTwoByteString(length, pretenure);
+ { Map* map = buffer->IsAsciiRepresentation()
+ ? sliced_ascii_string_map()
+ : sliced_string_map();
+ MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
if (!maybe_result->ToObject(&result)) return maybe_result;
}
- String* string_result = String::cast(result);
- // Copy the characters into the new object.
- if (buffer->IsAsciiRepresentation()) {
- ASSERT(string_result->IsAsciiRepresentation());
- char* dest = SeqAsciiString::cast(string_result)->GetChars();
- String::WriteToFlat(buffer, dest, start, end);
+
+ AssertNoAllocation no_gc;
+ SlicedString* sliced_string = SlicedString::cast(result);
+ sliced_string->set_length(length);
+ sliced_string->set_hash_field(String::kEmptyHashField);
+ if (buffer->IsConsString()) {
+ ConsString* cons = ConsString::cast(buffer);
+ ASSERT(cons->second()->length() == 0);
+ sliced_string->set_parent(cons->first());
+ sliced_string->set_offset(start);
+ } else if (buffer->IsSlicedString()) {
+ // Prevent nesting sliced strings.
+ SlicedString* parent_slice = SlicedString::cast(buffer);
+ sliced_string->set_parent(parent_slice->parent());
+ sliced_string->set_offset(start + parent_slice->offset());
} else {
- ASSERT(string_result->IsTwoByteRepresentation());
- uc16* dest = SeqTwoByteString::cast(string_result)->GetChars();
- String::WriteToFlat(buffer, dest, start, end);
+ sliced_string->set_parent(buffer);
+ sliced_string->set_offset(start);
}
-
+ ASSERT(sliced_string->parent()->IsSeqString());
return result;
}

Powered by Google App Engine
This is Rietveld 408576698