| OLD | NEW | 
|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "src/heap/scavenger.h" | 5 #include "src/heap/scavenger.h" | 
| 6 | 6 | 
| 7 #include "src/contexts.h" | 7 #include "src/contexts.h" | 
| 8 #include "src/heap/heap.h" | 8 #include "src/heap/heap.h" | 
| 9 #include "src/heap/objects-visiting-inl.h" | 9 #include "src/heap/objects-visiting-inl.h" | 
| 10 #include "src/heap/scavenger-inl.h" | 10 #include "src/heap/scavenger-inl.h" | 
| 11 #include "src/isolate.h" | 11 #include "src/isolate.h" | 
| 12 #include "src/log.h" | 12 #include "src/log.h" | 
| 13 #include "src/profiler/cpu-profiler.h" | 13 #include "src/profiler/cpu-profiler.h" | 
| 14 | 14 | 
| 15 namespace v8 { | 15 namespace v8 { | 
| 16 namespace internal { | 16 namespace internal { | 
| 17 | 17 | 
| 18 enum LoggingAndProfiling { | 18 enum LoggingAndProfiling { | 
| 19   LOGGING_AND_PROFILING_ENABLED, | 19   LOGGING_AND_PROFILING_ENABLED, | 
| 20   LOGGING_AND_PROFILING_DISABLED | 20   LOGGING_AND_PROFILING_DISABLED | 
| 21 }; | 21 }; | 
| 22 | 22 | 
| 23 | 23 | 
| 24 enum MarksHandling { TRANSFER_MARKS, IGNORE_MARKS }; | 24 enum MarksHandling { TRANSFER_MARKS, IGNORE_MARKS }; | 
| 25 | 25 | 
| 26 | 26 template <MarksHandling marks_handling, PromotionMode promotion_mode, | 
| 27 template <MarksHandling marks_handling, |  | 
| 28           LoggingAndProfiling logging_and_profiling_mode> | 27           LoggingAndProfiling logging_and_profiling_mode> | 
| 29 class ScavengingVisitor : public StaticVisitorBase { | 28 class ScavengingVisitor : public StaticVisitorBase { | 
| 30  public: | 29  public: | 
| 31   static void Initialize() { | 30   static void Initialize() { | 
| 32     table_.Register(kVisitSeqOneByteString, &EvacuateSeqOneByteString); | 31     table_.Register(kVisitSeqOneByteString, &EvacuateSeqOneByteString); | 
| 33     table_.Register(kVisitSeqTwoByteString, &EvacuateSeqTwoByteString); | 32     table_.Register(kVisitSeqTwoByteString, &EvacuateSeqTwoByteString); | 
| 34     table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate); | 33     table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate); | 
| 35     table_.Register(kVisitByteArray, &EvacuateByteArray); | 34     table_.Register(kVisitByteArray, &EvacuateByteArray); | 
| 36     table_.Register(kVisitFixedArray, &EvacuateFixedArray); | 35     table_.Register(kVisitFixedArray, &EvacuateFixedArray); | 
| 37     table_.Register(kVisitFixedDoubleArray, &EvacuateFixedDoubleArray); | 36     table_.Register(kVisitFixedDoubleArray, &EvacuateFixedDoubleArray); | 
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 195             Marking::IsBlack(Marking::MarkBitFrom(object))); | 194             Marking::IsBlack(Marking::MarkBitFrom(object))); | 
| 196       } | 195       } | 
| 197       heap->IncrementPromotedObjectsSize(object_size); | 196       heap->IncrementPromotedObjectsSize(object_size); | 
| 198       return true; | 197       return true; | 
| 199     } | 198     } | 
| 200     return false; | 199     return false; | 
| 201   } | 200   } | 
| 202 | 201 | 
| 203   template <ObjectContents object_contents, AllocationAlignment alignment> | 202   template <ObjectContents object_contents, AllocationAlignment alignment> | 
| 204   static inline void EvacuateObject(Map* map, HeapObject** slot, | 203   static inline void EvacuateObject(Map* map, HeapObject** slot, | 
| 205                                     HeapObject* object, int object_size, | 204                                     HeapObject* object, int object_size) { | 
| 206                                     PromotionMode promotion_mode) { |  | 
| 207     SLOW_DCHECK(object_size <= Page::kAllocatableMemory); | 205     SLOW_DCHECK(object_size <= Page::kAllocatableMemory); | 
| 208     SLOW_DCHECK(object->Size() == object_size); | 206     SLOW_DCHECK(object->Size() == object_size); | 
| 209     Heap* heap = map->GetHeap(); | 207     Heap* heap = map->GetHeap(); | 
| 210 | 208 | 
| 211     if (promotion_mode != FORCE_PROMOTION && | 209     if (!heap->ShouldBePromoted<promotion_mode>(object->address(), | 
| 212         !heap->ShouldBePromoted(object->address(), object_size)) { | 210                                                 object_size)) { | 
| 213       // A semi-space copy may fail due to fragmentation. In that case, we | 211       // A semi-space copy may fail due to fragmentation. In that case, we | 
| 214       // try to promote the object. | 212       // try to promote the object. | 
| 215       if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) { | 213       if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) { | 
| 216         return; | 214         return; | 
| 217       } | 215       } | 
| 218     } | 216     } | 
| 219 | 217 | 
| 220     if (PromoteObject<object_contents, alignment>(map, slot, object, | 218     if (PromoteObject<object_contents, alignment>(map, slot, object, | 
| 221                                                   object_size)) { | 219                                                   object_size)) { | 
| 222       return; | 220       return; | 
| 223     } | 221     } | 
| 224     if (promotion_mode == FORCE_PROMOTION) { | 222     if (promotion_mode == FORCE_PROMOTION) { | 
| 225       FatalProcessOutOfMemory("Scavenger: forced promotion\n"); | 223       FatalProcessOutOfMemory("Scavenger: forced promotion\n"); | 
| 226     } | 224     } | 
|  | 225     if (promotion_mode == PROMOTE_MARKED) { | 
|  | 226       FatalProcessOutOfMemory("Scavenger: promoting marked\n"); | 
|  | 227     } | 
| 227     // If promotion failed, we try to copy the object to the other semi-space | 228     // If promotion failed, we try to copy the object to the other semi-space | 
| 228     if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) return; | 229     if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) return; | 
| 229 | 230 | 
| 230     FatalProcessOutOfMemory("Scavenger: semi-space copy\n"); | 231     FatalProcessOutOfMemory("Scavenger: semi-space copy\n"); | 
| 231   } | 232   } | 
| 232 | 233 | 
| 233   static inline void EvacuateJSFunction(Map* map, HeapObject** slot, | 234   static inline void EvacuateJSFunction(Map* map, HeapObject** slot, | 
| 234                                         HeapObject* object, | 235                                         HeapObject* object) { | 
| 235                                         PromotionMode promotion_mode) { | 236     ObjectEvacuationStrategy<POINTER_OBJECT>::Visit(map, slot, object); | 
| 236     ObjectEvacuationStrategy<POINTER_OBJECT>::Visit(map, slot, object, |  | 
| 237                                                     promotion_mode); |  | 
| 238 | 237 | 
| 239     if (marks_handling == IGNORE_MARKS) return; | 238     if (marks_handling == IGNORE_MARKS) return; | 
| 240 | 239 | 
| 241     MapWord map_word = object->map_word(); | 240     MapWord map_word = object->map_word(); | 
| 242     DCHECK(map_word.IsForwardingAddress()); | 241     DCHECK(map_word.IsForwardingAddress()); | 
| 243     HeapObject* target = map_word.ToForwardingAddress(); | 242     HeapObject* target = map_word.ToForwardingAddress(); | 
| 244 | 243 | 
| 245     MarkBit mark_bit = Marking::MarkBitFrom(target); | 244     MarkBit mark_bit = Marking::MarkBitFrom(target); | 
| 246     if (Marking::IsBlack(mark_bit)) { | 245     if (Marking::IsBlack(mark_bit)) { | 
| 247       // This object is black and it might not be rescanned by marker. | 246       // This object is black and it might not be rescanned by marker. | 
| 248       // We should explicitly record code entry slot for compaction because | 247       // We should explicitly record code entry slot for compaction because | 
| 249       // promotion queue processing (IteratePromotedObjectPointers) will | 248       // promotion queue processing (IteratePromotedObjectPointers) will | 
| 250       // miss it as it is not HeapObject-tagged. | 249       // miss it as it is not HeapObject-tagged. | 
| 251       Address code_entry_slot = | 250       Address code_entry_slot = | 
| 252           target->address() + JSFunction::kCodeEntryOffset; | 251           target->address() + JSFunction::kCodeEntryOffset; | 
| 253       Code* code = Code::cast(Code::GetObjectFromEntryAddress(code_entry_slot)); | 252       Code* code = Code::cast(Code::GetObjectFromEntryAddress(code_entry_slot)); | 
| 254       map->GetHeap()->mark_compact_collector()->RecordCodeEntrySlot( | 253       map->GetHeap()->mark_compact_collector()->RecordCodeEntrySlot( | 
| 255           target, code_entry_slot, code); | 254           target, code_entry_slot, code); | 
| 256     } | 255     } | 
| 257   } | 256   } | 
| 258 | 257 | 
| 259   static inline void EvacuateFixedArray(Map* map, HeapObject** slot, | 258   static inline void EvacuateFixedArray(Map* map, HeapObject** slot, | 
| 260                                         HeapObject* object, | 259                                         HeapObject* object) { | 
| 261                                         PromotionMode promotion_mode) { |  | 
| 262     int length = reinterpret_cast<FixedArray*>(object)->synchronized_length(); | 260     int length = reinterpret_cast<FixedArray*>(object)->synchronized_length(); | 
| 263     int object_size = FixedArray::SizeFor(length); | 261     int object_size = FixedArray::SizeFor(length); | 
| 264     EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, object_size, | 262     EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, | 
| 265                                                  promotion_mode); | 263                                                  object_size); | 
| 266   } | 264   } | 
| 267 | 265 | 
| 268   static inline void EvacuateFixedDoubleArray(Map* map, HeapObject** slot, | 266   static inline void EvacuateFixedDoubleArray(Map* map, HeapObject** slot, | 
| 269                                               HeapObject* object, | 267                                               HeapObject* object) { | 
| 270                                               PromotionMode promotion_mode) { |  | 
| 271     int length = reinterpret_cast<FixedDoubleArray*>(object)->length(); | 268     int length = reinterpret_cast<FixedDoubleArray*>(object)->length(); | 
| 272     int object_size = FixedDoubleArray::SizeFor(length); | 269     int object_size = FixedDoubleArray::SizeFor(length); | 
| 273     EvacuateObject<DATA_OBJECT, kDoubleAligned>(map, slot, object, object_size, | 270     EvacuateObject<DATA_OBJECT, kDoubleAligned>(map, slot, object, object_size); | 
| 274                                                 promotion_mode); |  | 
| 275   } | 271   } | 
| 276 | 272 | 
| 277   static inline void EvacuateFixedTypedArray(Map* map, HeapObject** slot, | 273   static inline void EvacuateFixedTypedArray(Map* map, HeapObject** slot, | 
| 278                                              HeapObject* object, | 274                                              HeapObject* object) { | 
| 279                                              PromotionMode promotion_mode) { |  | 
| 280     int object_size = reinterpret_cast<FixedTypedArrayBase*>(object)->size(); | 275     int object_size = reinterpret_cast<FixedTypedArrayBase*>(object)->size(); | 
| 281     EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, object_size, | 276     EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, | 
| 282                                                  promotion_mode); | 277                                                  object_size); | 
| 283   } | 278   } | 
| 284 | 279 | 
| 285   static inline void EvacuateFixedFloat64Array(Map* map, HeapObject** slot, | 280   static inline void EvacuateFixedFloat64Array(Map* map, HeapObject** slot, | 
| 286                                                HeapObject* object, | 281                                                HeapObject* object) { | 
| 287                                                PromotionMode promotion_mode) { |  | 
| 288     int object_size = reinterpret_cast<FixedFloat64Array*>(object)->size(); | 282     int object_size = reinterpret_cast<FixedFloat64Array*>(object)->size(); | 
| 289     EvacuateObject<POINTER_OBJECT, kDoubleAligned>(map, slot, object, | 283     EvacuateObject<POINTER_OBJECT, kDoubleAligned>(map, slot, object, | 
| 290                                                    object_size, promotion_mode); | 284                                                    object_size); | 
| 291   } | 285   } | 
| 292 | 286 | 
| 293   static inline void EvacuateJSArrayBuffer(Map* map, HeapObject** slot, | 287   static inline void EvacuateJSArrayBuffer(Map* map, HeapObject** slot, | 
| 294                                            HeapObject* object, | 288                                            HeapObject* object) { | 
| 295                                            PromotionMode promotion_mode) { | 289     ObjectEvacuationStrategy<POINTER_OBJECT>::Visit(map, slot, object); | 
| 296     ObjectEvacuationStrategy<POINTER_OBJECT>::Visit(map, slot, object, |  | 
| 297                                                     promotion_mode); |  | 
| 298 | 290 | 
| 299     Heap* heap = map->GetHeap(); | 291     Heap* heap = map->GetHeap(); | 
| 300     MapWord map_word = object->map_word(); | 292     MapWord map_word = object->map_word(); | 
| 301     DCHECK(map_word.IsForwardingAddress()); | 293     DCHECK(map_word.IsForwardingAddress()); | 
| 302     HeapObject* target = map_word.ToForwardingAddress(); | 294     HeapObject* target = map_word.ToForwardingAddress(); | 
| 303     if (!heap->InNewSpace(target)) { | 295     if (!heap->InNewSpace(target)) { | 
| 304       heap->array_buffer_tracker()->Promote(JSArrayBuffer::cast(target)); | 296       heap->array_buffer_tracker()->Promote(JSArrayBuffer::cast(target)); | 
| 305     } | 297     } | 
| 306   } | 298   } | 
| 307 | 299 | 
| 308   static inline void EvacuateByteArray(Map* map, HeapObject** slot, | 300   static inline void EvacuateByteArray(Map* map, HeapObject** slot, | 
| 309                                        HeapObject* object, | 301                                        HeapObject* object) { | 
| 310                                        PromotionMode promotion_mode) { |  | 
| 311     int object_size = reinterpret_cast<ByteArray*>(object)->ByteArraySize(); | 302     int object_size = reinterpret_cast<ByteArray*>(object)->ByteArraySize(); | 
| 312     EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size, | 303     EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size); | 
| 313                                               promotion_mode); |  | 
| 314   } | 304   } | 
| 315 | 305 | 
| 316   static inline void EvacuateSeqOneByteString(Map* map, HeapObject** slot, | 306   static inline void EvacuateSeqOneByteString(Map* map, HeapObject** slot, | 
| 317                                               HeapObject* object, | 307                                               HeapObject* object) { | 
| 318                                               PromotionMode promotion_mode) { |  | 
| 319     int object_size = SeqOneByteString::cast(object) | 308     int object_size = SeqOneByteString::cast(object) | 
| 320                           ->SeqOneByteStringSize(map->instance_type()); | 309                           ->SeqOneByteStringSize(map->instance_type()); | 
| 321     EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size, | 310     EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size); | 
| 322                                               promotion_mode); |  | 
| 323   } | 311   } | 
| 324 | 312 | 
| 325   static inline void EvacuateSeqTwoByteString(Map* map, HeapObject** slot, | 313   static inline void EvacuateSeqTwoByteString(Map* map, HeapObject** slot, | 
| 326                                               HeapObject* object, | 314                                               HeapObject* object) { | 
| 327                                               PromotionMode promotion_mode) { |  | 
| 328     int object_size = SeqTwoByteString::cast(object) | 315     int object_size = SeqTwoByteString::cast(object) | 
| 329                           ->SeqTwoByteStringSize(map->instance_type()); | 316                           ->SeqTwoByteStringSize(map->instance_type()); | 
| 330     EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size, | 317     EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size); | 
| 331                                               promotion_mode); |  | 
| 332   } | 318   } | 
| 333 | 319 | 
| 334   static inline void EvacuateShortcutCandidate(Map* map, HeapObject** slot, | 320   static inline void EvacuateShortcutCandidate(Map* map, HeapObject** slot, | 
| 335                                                HeapObject* object, | 321                                                HeapObject* object) { | 
| 336                                                PromotionMode promotion_mode) { |  | 
| 337     DCHECK(IsShortcutCandidate(map->instance_type())); | 322     DCHECK(IsShortcutCandidate(map->instance_type())); | 
| 338 | 323 | 
| 339     Heap* heap = map->GetHeap(); | 324     Heap* heap = map->GetHeap(); | 
| 340 | 325 | 
| 341     if (marks_handling == IGNORE_MARKS && | 326     if (marks_handling == IGNORE_MARKS && | 
| 342         ConsString::cast(object)->unchecked_second() == heap->empty_string()) { | 327         ConsString::cast(object)->unchecked_second() == heap->empty_string()) { | 
| 343       HeapObject* first = | 328       HeapObject* first = | 
| 344           HeapObject::cast(ConsString::cast(object)->unchecked_first()); | 329           HeapObject::cast(ConsString::cast(object)->unchecked_first()); | 
| 345 | 330 | 
| 346       *slot = first; | 331       *slot = first; | 
| 347 | 332 | 
| 348       if (!heap->InNewSpace(first)) { | 333       if (!heap->InNewSpace(first)) { | 
| 349         object->set_map_word(MapWord::FromForwardingAddress(first)); | 334         object->set_map_word(MapWord::FromForwardingAddress(first)); | 
| 350         return; | 335         return; | 
| 351       } | 336       } | 
| 352 | 337 | 
| 353       MapWord first_word = first->map_word(); | 338       MapWord first_word = first->map_word(); | 
| 354       if (first_word.IsForwardingAddress()) { | 339       if (first_word.IsForwardingAddress()) { | 
| 355         HeapObject* target = first_word.ToForwardingAddress(); | 340         HeapObject* target = first_word.ToForwardingAddress(); | 
| 356 | 341 | 
| 357         *slot = target; | 342         *slot = target; | 
| 358         object->set_map_word(MapWord::FromForwardingAddress(target)); | 343         object->set_map_word(MapWord::FromForwardingAddress(target)); | 
| 359         return; | 344         return; | 
| 360       } | 345       } | 
| 361 | 346 | 
| 362       Scavenger::ScavengeObjectSlow(slot, first, promotion_mode); | 347       Scavenger::ScavengeObjectSlow<promotion_mode>(slot, first); | 
| 363       object->set_map_word(MapWord::FromForwardingAddress(*slot)); | 348       object->set_map_word(MapWord::FromForwardingAddress(*slot)); | 
| 364       return; | 349       return; | 
| 365     } | 350     } | 
| 366 | 351 | 
| 367     int object_size = ConsString::kSize; | 352     int object_size = ConsString::kSize; | 
| 368     EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, object_size, | 353     EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, | 
| 369                                                  promotion_mode); | 354                                                  object_size); | 
| 370   } | 355   } | 
| 371 | 356 | 
| 372   template <ObjectContents object_contents> | 357   template <ObjectContents object_contents> | 
| 373   class ObjectEvacuationStrategy { | 358   class ObjectEvacuationStrategy { | 
| 374    public: | 359    public: | 
| 375     template <int object_size> | 360     template <int object_size> | 
| 376     static inline void VisitSpecialized(Map* map, HeapObject** slot, | 361     static inline void VisitSpecialized(Map* map, HeapObject** slot, | 
| 377                                         HeapObject* object, | 362                                         HeapObject* object) { | 
| 378                                         PromotionMode promotion_mode) { | 363       EvacuateObject<object_contents, kWordAligned>(map, slot, object, | 
| 379       EvacuateObject<object_contents, kWordAligned>( | 364                                                     object_size); | 
| 380           map, slot, object, object_size, promotion_mode); |  | 
| 381     } | 365     } | 
| 382 | 366 | 
| 383     static inline void Visit(Map* map, HeapObject** slot, HeapObject* object, | 367     static inline void Visit(Map* map, HeapObject** slot, HeapObject* object) { | 
| 384                              PromotionMode promotion_mode) { |  | 
| 385       int object_size = map->instance_size(); | 368       int object_size = map->instance_size(); | 
| 386       EvacuateObject<object_contents, kWordAligned>( | 369       EvacuateObject<object_contents, kWordAligned>(map, slot, object, | 
| 387           map, slot, object, object_size, promotion_mode); | 370                                                     object_size); | 
| 388     } | 371     } | 
| 389   }; | 372   }; | 
| 390 | 373 | 
| 391   static VisitorDispatchTable<ScavengingCallback> table_; | 374   static VisitorDispatchTable<ScavengingCallback> table_; | 
| 392 }; | 375 }; | 
| 393 | 376 | 
| 394 | 377 template <MarksHandling marks_handling, PromotionMode promotion_mode, | 
| 395 template <MarksHandling marks_handling, |  | 
| 396           LoggingAndProfiling logging_and_profiling_mode> | 378           LoggingAndProfiling logging_and_profiling_mode> | 
| 397 VisitorDispatchTable<ScavengingCallback> | 379 VisitorDispatchTable<ScavengingCallback> ScavengingVisitor< | 
| 398     ScavengingVisitor<marks_handling, logging_and_profiling_mode>::table_; | 380     marks_handling, promotion_mode, logging_and_profiling_mode>::table_; | 
| 399 |  | 
| 400 | 381 | 
| 401 // static | 382 // static | 
| 402 void Scavenger::Initialize() { | 383 void Scavenger::Initialize() { | 
| 403   ScavengingVisitor<TRANSFER_MARKS, | 384   ScavengingVisitor<TRANSFER_MARKS, PROMOTE_MARKED, | 
| 404                     LOGGING_AND_PROFILING_DISABLED>::Initialize(); | 385                     LOGGING_AND_PROFILING_DISABLED>::Initialize(); | 
| 405   ScavengingVisitor<IGNORE_MARKS, LOGGING_AND_PROFILING_DISABLED>::Initialize(); | 386   ScavengingVisitor<IGNORE_MARKS, DEFAULT_PROMOTION, | 
| 406   ScavengingVisitor<TRANSFER_MARKS, | 387                     LOGGING_AND_PROFILING_DISABLED>::Initialize(); | 
|  | 388   ScavengingVisitor<TRANSFER_MARKS, PROMOTE_MARKED, | 
| 407                     LOGGING_AND_PROFILING_ENABLED>::Initialize(); | 389                     LOGGING_AND_PROFILING_ENABLED>::Initialize(); | 
| 408   ScavengingVisitor<IGNORE_MARKS, LOGGING_AND_PROFILING_ENABLED>::Initialize(); | 390   ScavengingVisitor<IGNORE_MARKS, DEFAULT_PROMOTION, | 
|  | 391                     LOGGING_AND_PROFILING_ENABLED>::Initialize(); | 
| 409 } | 392 } | 
| 410 | 393 | 
| 411 | 394 | 
| 412 // static |  | 
| 413 void Scavenger::ScavengeObjectSlow(HeapObject** p, HeapObject* object, |  | 
| 414                                    PromotionMode promotion_mode) { |  | 
| 415   SLOW_DCHECK(object->GetIsolate()->heap()->InFromSpace(object)); |  | 
| 416   MapWord first_word = object->map_word(); |  | 
| 417   SLOW_DCHECK(!first_word.IsForwardingAddress()); |  | 
| 418   Map* map = first_word.ToMap(); |  | 
| 419   Scavenger* scavenger = map->GetHeap()->scavenge_collector_; |  | 
| 420   scavenger->scavenging_visitors_table_.GetVisitor(map)(map, p, object, |  | 
| 421                                                         promotion_mode); |  | 
| 422 } |  | 
| 423 |  | 
| 424 |  | 
| 425 void Scavenger::SelectScavengingVisitorsTable() { | 395 void Scavenger::SelectScavengingVisitorsTable() { | 
| 426   bool logging_and_profiling = | 396   bool logging_and_profiling = | 
| 427       FLAG_verify_predictable || isolate()->logger()->is_logging() || | 397       FLAG_verify_predictable || isolate()->logger()->is_logging() || | 
| 428       isolate()->cpu_profiler()->is_profiling() || | 398       isolate()->cpu_profiler()->is_profiling() || | 
| 429       (isolate()->heap_profiler() != NULL && | 399       (isolate()->heap_profiler() != NULL && | 
| 430        isolate()->heap_profiler()->is_tracking_object_moves()); | 400        isolate()->heap_profiler()->is_tracking_object_moves()); | 
| 431 | 401 | 
| 432   if (!heap()->incremental_marking()->IsMarking()) { | 402   if (!heap()->incremental_marking()->IsMarking()) { | 
| 433     if (!logging_and_profiling) { | 403     if (!logging_and_profiling) { | 
| 434       scavenging_visitors_table_.CopyFrom( | 404       scavenging_visitors_table_.CopyFrom( | 
| 435           ScavengingVisitor<IGNORE_MARKS, | 405           ScavengingVisitor<IGNORE_MARKS, DEFAULT_PROMOTION, | 
| 436                             LOGGING_AND_PROFILING_DISABLED>::GetTable()); | 406                             LOGGING_AND_PROFILING_DISABLED>::GetTable()); | 
| 437     } else { | 407     } else { | 
| 438       scavenging_visitors_table_.CopyFrom( | 408       scavenging_visitors_table_.CopyFrom( | 
| 439           ScavengingVisitor<IGNORE_MARKS, | 409           ScavengingVisitor<IGNORE_MARKS, DEFAULT_PROMOTION, | 
| 440                             LOGGING_AND_PROFILING_ENABLED>::GetTable()); | 410                             LOGGING_AND_PROFILING_ENABLED>::GetTable()); | 
| 441     } | 411     } | 
| 442   } else { | 412   } else { | 
| 443     if (!logging_and_profiling) { | 413     if (!logging_and_profiling) { | 
| 444       scavenging_visitors_table_.CopyFrom( | 414       scavenging_visitors_table_.CopyFrom( | 
| 445           ScavengingVisitor<TRANSFER_MARKS, | 415           ScavengingVisitor<TRANSFER_MARKS, PROMOTE_MARKED, | 
| 446                             LOGGING_AND_PROFILING_DISABLED>::GetTable()); | 416                             LOGGING_AND_PROFILING_DISABLED>::GetTable()); | 
| 447     } else { | 417     } else { | 
| 448       scavenging_visitors_table_.CopyFrom( | 418       scavenging_visitors_table_.CopyFrom( | 
| 449           ScavengingVisitor<TRANSFER_MARKS, | 419           ScavengingVisitor<TRANSFER_MARKS, PROMOTE_MARKED, | 
| 450                             LOGGING_AND_PROFILING_ENABLED>::GetTable()); | 420                             LOGGING_AND_PROFILING_ENABLED>::GetTable()); | 
| 451     } | 421     } | 
| 452 | 422 | 
| 453     if (heap()->incremental_marking()->IsCompacting()) { | 423     if (heap()->incremental_marking()->IsCompacting()) { | 
| 454       // When compacting forbid short-circuiting of cons-strings. | 424       // When compacting forbid short-circuiting of cons-strings. | 
| 455       // Scavenging code relies on the fact that new space object | 425       // Scavenging code relies on the fact that new space object | 
| 456       // can't be evacuated into evacuation candidate but | 426       // can't be evacuated into evacuation candidate but | 
| 457       // short-circuiting violates this assumption. | 427       // short-circuiting violates this assumption. | 
| 458       scavenging_visitors_table_.Register( | 428       scavenging_visitors_table_.Register( | 
| 459           StaticVisitorBase::kVisitShortcutCandidate, | 429           StaticVisitorBase::kVisitShortcutCandidate, | 
| 460           scavenging_visitors_table_.GetVisitorById( | 430           scavenging_visitors_table_.GetVisitorById( | 
| 461               StaticVisitorBase::kVisitConsString)); | 431               StaticVisitorBase::kVisitConsString)); | 
| 462     } | 432     } | 
| 463   } | 433   } | 
| 464 } | 434 } | 
| 465 | 435 | 
| 466 | 436 | 
| 467 Isolate* Scavenger::isolate() { return heap()->isolate(); } | 437 Isolate* Scavenger::isolate() { return heap()->isolate(); } | 
| 468 | 438 | 
| 469 | 439 | 
| 470 void ScavengeVisitor::VisitPointer(Object** p) { ScavengePointer(p); } |  | 
| 471 |  | 
| 472 |  | 
| 473 void ScavengeVisitor::VisitPointers(Object** start, Object** end) { |  | 
| 474   // Copy all HeapObject pointers in [start, end) |  | 
| 475   for (Object** p = start; p < end; p++) ScavengePointer(p); |  | 
| 476 } |  | 
| 477 |  | 
| 478 |  | 
| 479 void ScavengeVisitor::ScavengePointer(Object** p) { |  | 
| 480   Object* object = *p; |  | 
| 481   if (!heap_->InNewSpace(object)) return; |  | 
| 482   Scavenger::ScavengeObject(reinterpret_cast<HeapObject**>(p), |  | 
| 483                             reinterpret_cast<HeapObject*>(object)); |  | 
| 484 } |  | 
| 485 |  | 
| 486 }  // namespace internal | 440 }  // namespace internal | 
| 487 }  // namespace v8 | 441 }  // namespace v8 | 
| OLD | NEW | 
|---|