| 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" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 enum MarksHandling { TRANSFER_MARKS, IGNORE_MARKS }; | 23 enum MarksHandling { TRANSFER_MARKS, IGNORE_MARKS }; |
| 24 | 24 |
| 25 template <MarksHandling marks_handling, | 25 template <MarksHandling marks_handling, |
| 26 LoggingAndProfiling logging_and_profiling_mode> | 26 LoggingAndProfiling logging_and_profiling_mode> |
| 27 class ScavengingVisitor : public StaticVisitorBase { | 27 class ScavengingVisitor : public StaticVisitorBase { |
| 28 public: | 28 public: |
| 29 static void Initialize() { | 29 static void Initialize() { |
| 30 table_.Register(kVisitSeqOneByteString, &EvacuateSeqOneByteString); | 30 table_.Register(kVisitSeqOneByteString, &EvacuateSeqOneByteString); |
| 31 table_.Register(kVisitSeqTwoByteString, &EvacuateSeqTwoByteString); | 31 table_.Register(kVisitSeqTwoByteString, &EvacuateSeqTwoByteString); |
| 32 table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate); | 32 table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate); |
| 33 table_.Register(kVisitThinString, &EvacuateThinString); | |
| 34 table_.Register(kVisitByteArray, &EvacuateByteArray); | 33 table_.Register(kVisitByteArray, &EvacuateByteArray); |
| 35 table_.Register(kVisitFixedArray, &EvacuateFixedArray); | 34 table_.Register(kVisitFixedArray, &EvacuateFixedArray); |
| 36 table_.Register(kVisitFixedDoubleArray, &EvacuateFixedDoubleArray); | 35 table_.Register(kVisitFixedDoubleArray, &EvacuateFixedDoubleArray); |
| 37 table_.Register(kVisitFixedTypedArray, &EvacuateFixedTypedArray); | 36 table_.Register(kVisitFixedTypedArray, &EvacuateFixedTypedArray); |
| 38 table_.Register(kVisitFixedFloat64Array, &EvacuateFixedFloat64Array); | 37 table_.Register(kVisitFixedFloat64Array, &EvacuateFixedFloat64Array); |
| 39 table_.Register(kVisitJSArrayBuffer, | 38 table_.Register(kVisitJSArrayBuffer, |
| 40 &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit); | 39 &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit); |
| 41 | 40 |
| 42 table_.Register( | 41 table_.Register( |
| 43 kVisitNativeContext, | 42 kVisitNativeContext, |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 kVisitJSApiObject, kVisitJSApiObjectGeneric>(); | 82 kVisitJSApiObject, kVisitJSApiObjectGeneric>(); |
| 84 | 83 |
| 85 table_.RegisterSpecializations<ObjectEvacuationStrategy<POINTER_OBJECT>, | 84 table_.RegisterSpecializations<ObjectEvacuationStrategy<POINTER_OBJECT>, |
| 86 kVisitStruct, kVisitStructGeneric>(); | 85 kVisitStruct, kVisitStructGeneric>(); |
| 87 } | 86 } |
| 88 | 87 |
| 89 static VisitorDispatchTable<ScavengingCallback>* GetTable() { | 88 static VisitorDispatchTable<ScavengingCallback>* GetTable() { |
| 90 return &table_; | 89 return &table_; |
| 91 } | 90 } |
| 92 | 91 |
| 93 static void EvacuateThinStringNoShortcut(Map* map, HeapObject** slot, | |
| 94 HeapObject* object) { | |
| 95 EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, | |
| 96 ThinString::kSize); | |
| 97 } | |
| 98 | |
| 99 private: | 92 private: |
| 100 enum ObjectContents { DATA_OBJECT, POINTER_OBJECT }; | 93 enum ObjectContents { DATA_OBJECT, POINTER_OBJECT }; |
| 101 | 94 |
| 102 static void RecordCopiedObject(Heap* heap, HeapObject* obj) { | 95 static void RecordCopiedObject(Heap* heap, HeapObject* obj) { |
| 103 bool should_record = false; | 96 bool should_record = false; |
| 104 #ifdef DEBUG | 97 #ifdef DEBUG |
| 105 should_record = FLAG_heap_stats; | 98 should_record = FLAG_heap_stats; |
| 106 #endif | 99 #endif |
| 107 should_record = should_record || FLAG_log_gc; | 100 should_record = should_record || FLAG_log_gc; |
| 108 if (should_record) { | 101 if (should_record) { |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 Scavenger::ScavengeObjectSlow(slot, first); | 328 Scavenger::ScavengeObjectSlow(slot, first); |
| 336 object->set_map_word(MapWord::FromForwardingAddress(*slot)); | 329 object->set_map_word(MapWord::FromForwardingAddress(*slot)); |
| 337 return; | 330 return; |
| 338 } | 331 } |
| 339 | 332 |
| 340 int object_size = ConsString::kSize; | 333 int object_size = ConsString::kSize; |
| 341 EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, | 334 EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, |
| 342 object_size); | 335 object_size); |
| 343 } | 336 } |
| 344 | 337 |
| 345 static inline void EvacuateThinString(Map* map, HeapObject** slot, | |
| 346 HeapObject* object) { | |
| 347 if (marks_handling == IGNORE_MARKS) { | |
| 348 HeapObject* actual = ThinString::cast(object)->actual(); | |
| 349 *slot = actual; | |
| 350 // ThinStrings always refer to internalized strings, which are | |
| 351 // always in old space. | |
| 352 DCHECK(!map->GetHeap()->InNewSpace(actual)); | |
| 353 object->set_map_word(MapWord::FromForwardingAddress(actual)); | |
| 354 return; | |
| 355 } | |
| 356 | |
| 357 EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, | |
| 358 ThinString::kSize); | |
| 359 } | |
| 360 | |
| 361 template <ObjectContents object_contents> | 338 template <ObjectContents object_contents> |
| 362 class ObjectEvacuationStrategy { | 339 class ObjectEvacuationStrategy { |
| 363 public: | 340 public: |
| 364 template <int object_size> | 341 template <int object_size> |
| 365 static inline void VisitSpecialized(Map* map, HeapObject** slot, | 342 static inline void VisitSpecialized(Map* map, HeapObject** slot, |
| 366 HeapObject* object) { | 343 HeapObject* object) { |
| 367 EvacuateObject<object_contents, kWordAligned>(map, slot, object, | 344 EvacuateObject<object_contents, kWordAligned>(map, slot, object, |
| 368 object_size); | 345 object_size); |
| 369 } | 346 } |
| 370 | 347 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 | 412 |
| 436 if (heap()->incremental_marking()->IsCompacting()) { | 413 if (heap()->incremental_marking()->IsCompacting()) { |
| 437 // When compacting forbid short-circuiting of cons-strings. | 414 // When compacting forbid short-circuiting of cons-strings. |
| 438 // Scavenging code relies on the fact that new space object | 415 // Scavenging code relies on the fact that new space object |
| 439 // can't be evacuated into evacuation candidate but | 416 // can't be evacuated into evacuation candidate but |
| 440 // short-circuiting violates this assumption. | 417 // short-circuiting violates this assumption. |
| 441 scavenging_visitors_table_.Register( | 418 scavenging_visitors_table_.Register( |
| 442 StaticVisitorBase::kVisitShortcutCandidate, | 419 StaticVisitorBase::kVisitShortcutCandidate, |
| 443 scavenging_visitors_table_.GetVisitorById( | 420 scavenging_visitors_table_.GetVisitorById( |
| 444 StaticVisitorBase::kVisitConsString)); | 421 StaticVisitorBase::kVisitConsString)); |
| 445 scavenging_visitors_table_.Register( | |
| 446 StaticVisitorBase::kVisitThinString, | |
| 447 &ScavengingVisitor<TRANSFER_MARKS, LOGGING_AND_PROFILING_DISABLED>:: | |
| 448 EvacuateThinStringNoShortcut); | |
| 449 } | 422 } |
| 450 } | 423 } |
| 451 } | 424 } |
| 452 | 425 |
| 453 | 426 |
| 454 Isolate* Scavenger::isolate() { return heap()->isolate(); } | 427 Isolate* Scavenger::isolate() { return heap()->isolate(); } |
| 455 | 428 |
| 456 | 429 |
| 457 void ScavengeVisitor::VisitPointer(Object** p) { ScavengePointer(p); } | 430 void ScavengeVisitor::VisitPointer(Object** p) { ScavengePointer(p); } |
| 458 | 431 |
| 459 | 432 |
| 460 void ScavengeVisitor::VisitPointers(Object** start, Object** end) { | 433 void ScavengeVisitor::VisitPointers(Object** start, Object** end) { |
| 461 // Copy all HeapObject pointers in [start, end) | 434 // Copy all HeapObject pointers in [start, end) |
| 462 for (Object** p = start; p < end; p++) ScavengePointer(p); | 435 for (Object** p = start; p < end; p++) ScavengePointer(p); |
| 463 } | 436 } |
| 464 | 437 |
| 465 | 438 |
| 466 void ScavengeVisitor::ScavengePointer(Object** p) { | 439 void ScavengeVisitor::ScavengePointer(Object** p) { |
| 467 Object* object = *p; | 440 Object* object = *p; |
| 468 if (!heap_->InNewSpace(object)) return; | 441 if (!heap_->InNewSpace(object)) return; |
| 469 | 442 |
| 470 Scavenger::ScavengeObject(reinterpret_cast<HeapObject**>(p), | 443 Scavenger::ScavengeObject(reinterpret_cast<HeapObject**>(p), |
| 471 reinterpret_cast<HeapObject*>(object)); | 444 reinterpret_cast<HeapObject*>(object)); |
| 472 } | 445 } |
| 473 | 446 |
| 474 } // namespace internal | 447 } // namespace internal |
| 475 } // namespace v8 | 448 } // namespace v8 |
| OLD | NEW |