| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index dbbec582228aad3e6d7b610d2a51d44205461ab9..7aea7f4cf24eee66dc42769967469d566a48ec10 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -7626,33 +7626,45 @@ bool String::SlowAsArrayIndex(uint32_t* index) {
|
| }
|
|
|
|
|
| -String* SeqString::Truncate(int new_length) {
|
| - Heap* heap = GetHeap();
|
| - if (new_length <= 0) return heap->empty_string();
|
| +Handle<String> SeqString::Truncate(Handle<SeqString> string, int new_length) {
|
| + int new_size, old_size;
|
| + int old_length = string->length();
|
| + if (old_length <= new_length) return string;
|
| +
|
| + if (string->IsSeqOneByteString()) {
|
| + old_size = SeqOneByteString::SizeFor(old_length);
|
| + new_size = SeqOneByteString::SizeFor(new_length);
|
| + } else {
|
| + ASSERT(string->IsSeqTwoByteString());
|
| + old_size = SeqTwoByteString::SizeFor(old_length);
|
| + new_size = SeqTwoByteString::SizeFor(new_length);
|
| + }
|
| +
|
| + int delta = old_size - new_size;
|
| + string->set_length(new_length);
|
|
|
| - int string_size, allocated_string_size;
|
| - int old_length = length();
|
| - if (old_length <= new_length) return this;
|
| + Address start_of_string = string->address();
|
| + ASSERT_OBJECT_ALIGNED(start_of_string);
|
| + ASSERT_OBJECT_ALIGNED(start_of_string + new_size);
|
|
|
| - if (IsSeqOneByteString()) {
|
| - allocated_string_size = SeqOneByteString::SizeFor(old_length);
|
| - string_size = SeqOneByteString::SizeFor(new_length);
|
| + Heap* heap = string->GetHeap();
|
| + NewSpace* newspace = heap->new_space();
|
| + if (newspace->Contains(start_of_string) &&
|
| + newspace->top() == start_of_string + old_size) {
|
| + // Last allocated object in new space. Simply lower allocation top.
|
| + *(newspace->allocation_top_address()) = start_of_string + new_size;
|
| } else {
|
| - allocated_string_size = SeqTwoByteString::SizeFor(old_length);
|
| - string_size = SeqTwoByteString::SizeFor(new_length);
|
| + // Sizes are pointer size aligned, so that we can use filler objects
|
| + // that are a multiple of pointer size.
|
| + heap->CreateFillerObjectAt(start_of_string + new_size, delta);
|
| + }
|
| + if (Marking::IsBlack(Marking::MarkBitFrom(start_of_string))) {
|
| + MemoryChunk::IncrementLiveBytesFromMutator(start_of_string, -delta);
|
| }
|
|
|
| - int delta = allocated_string_size - string_size;
|
| - set_length(new_length);
|
|
|
| - // String sizes are pointer size aligned, so that we can use filler objects
|
| - // that are a multiple of pointer size.
|
| - Address end_of_string = address() + string_size;
|
| - heap->CreateFillerObjectAt(end_of_string, delta);
|
| - if (Marking::IsBlack(Marking::MarkBitFrom(this))) {
|
| - MemoryChunk::IncrementLiveBytesFromMutator(address(), -delta);
|
| - }
|
| - return this;
|
| + if (new_length == 0) return heap->isolate()->factory()->empty_string();
|
| + return string;
|
| }
|
|
|
|
|
|
|