Chromium Code Reviews| Index: src/heap.cc |
| diff --git a/src/heap.cc b/src/heap.cc |
| index 8dbda270fe3644d6647db538d05b67274e19aacf..e4cee168b2e9cf0aa965006aea7249af092d0267 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 both parts cannot be string slices since: |
| + STATIC_ASSERT(String::kMinNonFlatLength <= SlicedString::kMinLength); |
| ASSERT(first->IsFlat()); |
| ASSERT(second->IsFlat()); |
| if (is_ascii) { |
| @@ -2636,23 +2642,60 @@ MaybeObject* Heap::AllocateSubString(String* buffer, |
| // Make an attempt to flatten the buffer to reduce access time. |
| buffer = buffer->TryFlattenGetString(); |
| + if (!FLAG_string_slices || |
| + !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); |
| + 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()); |
|
Vitaly Repeshko
2011/08/05 12:14:14
I think we can have flat cons with external first.
Yang
2011/08/11 13:23:43
Actually a flat cons with external first can't exi
Vitaly Repeshko
2011/08/12 19:00:59
Possible scenario:
1. a cons is flattened (its fir
|
| return result; |
| } |