Chromium Code Reviews| Index: src/heap.cc |
| diff --git a/src/heap.cc b/src/heap.cc |
| index 8dbda270fe3644d6647db538d05b67274e19aacf..8f6d8b4c3926daa152ae6014a2403efb78f4b98c 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,57 @@ 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); |
| + WriteBarrierMode mode = sliced_string->GetWriteBarrierMode(no_gc); |
|
antonm
2011/07/27 12:16:39
sliced_string should be allocated in new space, so
|
| + 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(), mode); |
|
antonm
2011/07/27 12:16:39
why first? what if I slice in the second part?
|
| + 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(), mode); |
| + 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, mode); |
| + sliced_string->set_offset(start); |
| } |
| return result; |