Index: src/heap.cc |
diff --git a/src/heap.cc b/src/heap.cc |
index 8dbda270fe3644d6647db538d05b67274e19aacf..9ce6d52141c7ce6433e6b775d7bb2a1f8525c66a 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>); |
@@ -2558,6 +2562,10 @@ MaybeObject* Heap::AllocateConsString(String* first, String* second) { |
const char* src; |
if (first->IsExternalString()) { |
src = ExternalAsciiString::cast(first)->resource()->data(); |
+ } else if (first->IsSlicedString()) { |
+ SlicedString *slice = SlicedString::cast(first); |
+ src = SeqAsciiString::cast(slice->parent())->GetChars() |
+ + slice->offset(); |
} else { |
src = SeqAsciiString::cast(first)->GetChars(); |
} |
@@ -2565,6 +2573,10 @@ MaybeObject* Heap::AllocateConsString(String* first, String* second) { |
// Copy second part. |
if (second->IsExternalString()) { |
src = ExternalAsciiString::cast(second)->resource()->data(); |
+ } else if (second->IsSlicedString()) { |
+ SlicedString *slice = SlicedString::cast(second); |
+ src = SeqAsciiString::cast(slice->parent())->GetChars() |
+ + slice->offset(); |
} else { |
src = SeqAsciiString::cast(second)->GetChars(); |
} |
@@ -2636,22 +2648,56 @@ MaybeObject* Heap::AllocateSubString(String* buffer, |
// Make an attempt to flatten the buffer to reduce access time. |
buffer = buffer->TryFlattenGetString(); |
+ if (!buffer->IsFlat() || |
+ buffer->IsExternalString() || |
+ length < SlicedString::kMinLength) { |
+ 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()); |
+ |
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); |
+ sliced_string->set_parent(cons->first()); |
Yang
2011/07/27 12:47:24
There is no second part. I assert in line 2674 tha
antonm
2011/07/27 14:04:49
Thanks a lot for explanation! Maybe worth asserti
antonm
2011/07/27 14:04:49
just curious: is it possible to get:
cons strin
Yang
2011/07/28 15:43:06
There is no way to create such a cons string. The
|
+ 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); |
} |
return result; |