| Index: src/heap.cc
|
| diff --git a/src/heap.cc b/src/heap.cc
|
| index 526fea04b3e17b721cf72d0b01bce6db3a1f7144..b8063d73ef78e8b37ab53a4b46b2aa64ba683685 100644
|
| --- a/src/heap.cc
|
| +++ b/src/heap.cc
|
| @@ -1278,6 +1278,7 @@ class ScavengingVisitor : public StaticVisitorBase {
|
| table_.Register(kVisitSeqAsciiString, &EvacuateSeqAsciiString);
|
| table_.Register(kVisitSeqTwoByteString, &EvacuateSeqTwoByteString);
|
| table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate);
|
| + table_.Register(kVisitSlicedString, &EvacuateSlicedString);
|
| table_.Register(kVisitByteArray, &EvacuateByteArray);
|
| table_.Register(kVisitFixedArray, &EvacuateFixedArray);
|
| table_.Register(kVisitFixedDoubleArray, &EvacuateFixedDoubleArray);
|
| @@ -1290,10 +1291,6 @@ 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>);
|
| @@ -1346,16 +1343,10 @@ class ScavengingVisitor : public StaticVisitorBase {
|
| }
|
| }
|
|
|
| - // Helper function used by CopyObject to copy a source object to an
|
| - // allocated target object and update the forwarding pointer in the source
|
| - // object. Returns the target object.
|
| - INLINE(static HeapObject* MigrateObject(Heap* heap,
|
| - HeapObject* source,
|
| - HeapObject* target,
|
| - int size)) {
|
| - // Copy the content of source to target.
|
| - heap->CopyBlock(target->address(), source->address(), size);
|
|
|
| + INLINE(static void ForwardAndLogMigration(Heap* heap,
|
| + HeapObject* source,
|
| + HeapObject* target)) {
|
| // Set the forwarding address.
|
| source->set_map_word(MapWord::FromForwardingAddress(target));
|
|
|
| @@ -1372,6 +1363,19 @@ class ScavengingVisitor : public StaticVisitorBase {
|
| }
|
| }
|
| }
|
| + }
|
| +
|
| + // Helper function used by CopyObject to copy a source object to an
|
| + // allocated target object and update the forwarding pointer in the source
|
| + // object. Returns the target object.
|
| + INLINE(static HeapObject* MigrateObject(Heap* heap,
|
| + HeapObject* source,
|
| + HeapObject* target,
|
| + int size)) {
|
| + // Copy the content of source to target.
|
| + heap->CopyBlock(target->address(), source->address(), size);
|
| +
|
| + ForwardAndLogMigration(heap, source, target);
|
|
|
| return target;
|
| }
|
| @@ -1404,7 +1408,7 @@ class ScavengingVisitor : public StaticVisitorBase {
|
| Object* result = NULL; // Initialization to please compiler.
|
| if (maybe_result->ToObject(&result)) {
|
| HeapObject* target = HeapObject::cast(result);
|
| - *slot = MigrateObject(heap, object , target, object_size);
|
| + *slot = MigrateObject(heap, object, target, object_size);
|
|
|
| if (object_contents == POINTER_OBJECT) {
|
| heap->promotion_queue()->insert(target, object_size);
|
| @@ -1470,6 +1474,68 @@ class ScavengingVisitor : public StaticVisitorBase {
|
| }
|
|
|
|
|
| + static inline void EvacuateSlicedString(Map* map,
|
| + HeapObject** slot,
|
| + HeapObject* object) {
|
| + ASSERT(object->IsSlicedString());
|
| + Heap* heap = map->heap();
|
| + int slice_size = SlicedString::kSize;
|
| + if (heap->ShouldBePromoted(object->address(), slice_size)) {
|
| + SlicedString* slice = SlicedString::cast(object);
|
| + String* parent = slice->parent();
|
| +
|
| + // Parent string might just have been moved and forwarded.
|
| + MapWord parent_word = parent->map_word();
|
| + if (parent_word.IsForwardingAddress()) {
|
| + parent = String::cast(parent_word.ToForwardingAddress());
|
| + }
|
| + ASSERT(!StringShape(parent).IsIndirect());
|
| +
|
| + int length = slice->length();
|
| + // Allocate space for unpacked and truncated substring.
|
| + int size = parent->IsAsciiRepresentation()
|
| + ? SeqAsciiString::SizeFor(length)
|
| + : SeqTwoByteString::SizeFor(length);
|
| + MaybeObject* maybe_result;
|
| + if (size > Page::kMaxHeapObjectSize) {
|
| + maybe_result = heap->lo_space()->AllocateRawFixedArray(size);
|
| + } else {
|
| + maybe_result = heap->old_data_space()->AllocateRaw(size);
|
| + }
|
| +
|
| + Object* result = NULL;
|
| + // Write substring to allocated space.
|
| + if (maybe_result->ToObject(&result)) {
|
| + int offset = slice->offset();
|
| + if (parent->IsAsciiRepresentation()) {
|
| + HeapObject::cast(result)->set_map(heap->ascii_string_map());
|
| + char* dest = SeqAsciiString::cast(result)->GetChars();
|
| + String::WriteToFlat(parent, dest, offset, length + offset);
|
| + } else {
|
| + HeapObject::cast(result)->set_map(heap->string_map());
|
| + uc16* dest = SeqTwoByteString::cast(result)->GetChars();
|
| + String::WriteToFlat(parent, dest, offset, length + offset);
|
| + }
|
| + ASSERT(!heap->InNewSpace(result));
|
| + String* string_result = String::cast(result);
|
| + string_result->set_length(length);
|
| + string_result->set_hash_field(parent->hash_field());
|
| +
|
| + *slot = HeapObject::cast(result);
|
| + ForwardAndLogMigration(heap, object, *slot);
|
| +
|
| + heap->tracer()->increment_promoted_objects_size(size);
|
| + return;
|
| + }
|
| + // If allocation failed, just skip promotion.
|
| + }
|
| + Object* result =
|
| + heap->new_space()->AllocateRaw(slice_size)->ToObjectUnchecked();
|
| + *slot = MigrateObject(heap, object, HeapObject::cast(result), slice_size);
|
| + return;
|
| + }
|
| +
|
| +
|
| static inline bool IsShortcutCandidate(int type) {
|
| return ((type & kShortcutTypeMask) == kShortcutTypeTag);
|
| }
|
|
|