| Index: src/heap/scavenger.cc | 
| diff --git a/src/heap/scavenger.cc b/src/heap/scavenger.cc | 
| index 1d785d08d24232388be4d45603d68f9da313c22a..e6c181f8604bb012723018c780d958813366d409 100644 | 
| --- a/src/heap/scavenger.cc | 
| +++ b/src/heap/scavenger.cc | 
| @@ -200,15 +200,16 @@ class ScavengingVisitor : public StaticVisitorBase { | 
| return false; | 
| } | 
|  | 
| - | 
| template <ObjectContents object_contents, AllocationAlignment alignment> | 
| static inline void EvacuateObject(Map* map, HeapObject** slot, | 
| -                                    HeapObject* object, int object_size) { | 
| +                                    HeapObject* object, int object_size, | 
| +                                    bool force_promotion) { | 
| SLOW_DCHECK(object_size <= Page::kAllocatableMemory); | 
| SLOW_DCHECK(object->Size() == object_size); | 
| Heap* heap = map->GetHeap(); | 
|  | 
| -    if (!heap->ShouldBePromoted(object->address(), object_size)) { | 
| +    if (!force_promotion && | 
| +        !heap->ShouldBePromoted(object->address(), object_size)) { | 
| // A semi-space copy may fail due to fragmentation. In that case, we | 
| // try to promote the object. | 
| if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) { | 
| @@ -227,10 +228,11 @@ class ScavengingVisitor : public StaticVisitorBase { | 
| FatalProcessOutOfMemory("Scavenger: semi-space copy\n"); | 
| } | 
|  | 
| - | 
| static inline void EvacuateJSFunction(Map* map, HeapObject** slot, | 
| -                                        HeapObject* object) { | 
| -    ObjectEvacuationStrategy<POINTER_OBJECT>::Visit(map, slot, object); | 
| +                                        HeapObject* object, | 
| +                                        bool force_promotion) { | 
| +    ObjectEvacuationStrategy<POINTER_OBJECT>::Visit(map, slot, object, | 
| +                                                    force_promotion); | 
|  | 
| if (marks_handling == IGNORE_MARKS) return; | 
|  | 
| @@ -252,43 +254,45 @@ class ScavengingVisitor : public StaticVisitorBase { | 
| } | 
| } | 
|  | 
| - | 
| static inline void EvacuateFixedArray(Map* map, HeapObject** slot, | 
| -                                        HeapObject* object) { | 
| +                                        HeapObject* object, | 
| +                                        bool force_promotion) { | 
| int length = reinterpret_cast<FixedArray*>(object)->synchronized_length(); | 
| int object_size = FixedArray::SizeFor(length); | 
| -    EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, | 
| -                                                 object_size); | 
| +    EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, object_size, | 
| +                                                 force_promotion); | 
| } | 
|  | 
| - | 
| static inline void EvacuateFixedDoubleArray(Map* map, HeapObject** slot, | 
| -                                              HeapObject* object) { | 
| +                                              HeapObject* object, | 
| +                                              bool force_promotion) { | 
| int length = reinterpret_cast<FixedDoubleArray*>(object)->length(); | 
| int object_size = FixedDoubleArray::SizeFor(length); | 
| -    EvacuateObject<DATA_OBJECT, kDoubleAligned>(map, slot, object, object_size); | 
| +    EvacuateObject<DATA_OBJECT, kDoubleAligned>(map, slot, object, object_size, | 
| +                                                force_promotion); | 
| } | 
|  | 
| - | 
| static inline void EvacuateFixedTypedArray(Map* map, HeapObject** slot, | 
| -                                             HeapObject* object) { | 
| +                                             HeapObject* object, | 
| +                                             bool force_promotion) { | 
| int object_size = reinterpret_cast<FixedTypedArrayBase*>(object)->size(); | 
| -    EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, | 
| -                                                 object_size); | 
| +    EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, object_size, | 
| +                                                 force_promotion); | 
| } | 
|  | 
| - | 
| static inline void EvacuateFixedFloat64Array(Map* map, HeapObject** slot, | 
| -                                               HeapObject* object) { | 
| +                                               HeapObject* object, | 
| +                                               bool force_promotion) { | 
| int object_size = reinterpret_cast<FixedFloat64Array*>(object)->size(); | 
| -    EvacuateObject<POINTER_OBJECT, kDoubleAligned>(map, slot, object, | 
| -                                                   object_size); | 
| +    EvacuateObject<POINTER_OBJECT, kDoubleAligned>( | 
| +        map, slot, object, object_size, force_promotion); | 
| } | 
|  | 
| - | 
| static inline void EvacuateJSArrayBuffer(Map* map, HeapObject** slot, | 
| -                                           HeapObject* object) { | 
| -    ObjectEvacuationStrategy<POINTER_OBJECT>::Visit(map, slot, object); | 
| +                                           HeapObject* object, | 
| +                                           bool force_promotion) { | 
| +    ObjectEvacuationStrategy<POINTER_OBJECT>::Visit(map, slot, object, | 
| +                                                    force_promotion); | 
|  | 
| Heap* heap = map->GetHeap(); | 
| MapWord map_word = object->map_word(); | 
| @@ -299,32 +303,35 @@ class ScavengingVisitor : public StaticVisitorBase { | 
| } | 
| } | 
|  | 
| - | 
| static inline void EvacuateByteArray(Map* map, HeapObject** slot, | 
| -                                       HeapObject* object) { | 
| +                                       HeapObject* object, | 
| +                                       bool force_promotion) { | 
| int object_size = reinterpret_cast<ByteArray*>(object)->ByteArraySize(); | 
| -    EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size); | 
| +    EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size, | 
| +                                              force_promotion); | 
| } | 
|  | 
| - | 
| static inline void EvacuateSeqOneByteString(Map* map, HeapObject** slot, | 
| -                                              HeapObject* object) { | 
| +                                              HeapObject* object, | 
| +                                              bool force_promotion) { | 
| int object_size = SeqOneByteString::cast(object) | 
| ->SeqOneByteStringSize(map->instance_type()); | 
| -    EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size); | 
| +    EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size, | 
| +                                              force_promotion); | 
| } | 
|  | 
| - | 
| static inline void EvacuateSeqTwoByteString(Map* map, HeapObject** slot, | 
| -                                              HeapObject* object) { | 
| +                                              HeapObject* object, | 
| +                                              bool force_promotion) { | 
| int object_size = SeqTwoByteString::cast(object) | 
| ->SeqTwoByteStringSize(map->instance_type()); | 
| -    EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size); | 
| +    EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size, | 
| +                                              force_promotion); | 
| } | 
|  | 
| - | 
| static inline void EvacuateShortcutCandidate(Map* map, HeapObject** slot, | 
| -                                               HeapObject* object) { | 
| +                                               HeapObject* object, | 
| +                                               bool force_promotion) { | 
| DCHECK(IsShortcutCandidate(map->instance_type())); | 
|  | 
| Heap* heap = map->GetHeap(); | 
| @@ -350,14 +357,14 @@ class ScavengingVisitor : public StaticVisitorBase { | 
| return; | 
| } | 
|  | 
| -      Scavenger::ScavengeObjectSlow(slot, first); | 
| +      Scavenger::ScavengeObjectSlow(slot, first, force_promotion); | 
| object->set_map_word(MapWord::FromForwardingAddress(*slot)); | 
| return; | 
| } | 
|  | 
| int object_size = ConsString::kSize; | 
| -    EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, | 
| -                                                 object_size); | 
| +    EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, object_size, | 
| +                                                 force_promotion); | 
| } | 
|  | 
| template <ObjectContents object_contents> | 
| @@ -365,15 +372,17 @@ class ScavengingVisitor : public StaticVisitorBase { | 
| public: | 
| template <int object_size> | 
| static inline void VisitSpecialized(Map* map, HeapObject** slot, | 
| -                                        HeapObject* object) { | 
| -      EvacuateObject<object_contents, kWordAligned>(map, slot, object, | 
| -                                                    object_size); | 
| +                                        HeapObject* object, | 
| +                                        bool force_promotion) { | 
| +      EvacuateObject<object_contents, kWordAligned>( | 
| +          map, slot, object, object_size, force_promotion); | 
| } | 
|  | 
| -    static inline void Visit(Map* map, HeapObject** slot, HeapObject* object) { | 
| +    static inline void Visit(Map* map, HeapObject** slot, HeapObject* object, | 
| +                             bool force_promotion) { | 
| int object_size = map->instance_size(); | 
| -      EvacuateObject<object_contents, kWordAligned>(map, slot, object, | 
| -                                                    object_size); | 
| +      EvacuateObject<object_contents, kWordAligned>( | 
| +          map, slot, object, object_size, force_promotion); | 
| } | 
| }; | 
|  | 
| @@ -399,13 +408,15 @@ void Scavenger::Initialize() { | 
|  | 
|  | 
| // static | 
| -void Scavenger::ScavengeObjectSlow(HeapObject** p, HeapObject* object) { | 
| +void Scavenger::ScavengeObjectSlow(HeapObject** p, HeapObject* object, | 
| +                                   bool force_promotion) { | 
| SLOW_DCHECK(object->GetIsolate()->heap()->InFromSpace(object)); | 
| MapWord first_word = object->map_word(); | 
| SLOW_DCHECK(!first_word.IsForwardingAddress()); | 
| Map* map = first_word.ToMap(); | 
| Scavenger* scavenger = map->GetHeap()->scavenge_collector_; | 
| -  scavenger->scavenging_visitors_table_.GetVisitor(map)(map, p, object); | 
| +  scavenger->scavenging_visitors_table_.GetVisitor(map)(map, p, object, | 
| +                                                        force_promotion); | 
| } | 
|  | 
|  | 
|  |