OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/mark-compact.h" | 5 #include "src/heap/mark-compact.h" |
6 | 6 |
7 #include "src/base/atomicops.h" | 7 #include "src/base/atomicops.h" |
8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
9 #include "src/base/sys-info.h" | 9 #include "src/base/sys-info.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 } | 308 } |
309 | 309 |
310 return compacting_; | 310 return compacting_; |
311 } | 311 } |
312 | 312 |
313 | 313 |
314 void MarkCompactCollector::ClearInvalidStoreAndSlotsBufferEntries() { | 314 void MarkCompactCollector::ClearInvalidStoreAndSlotsBufferEntries() { |
315 { | 315 { |
316 GCTracer::Scope gc_scope(heap()->tracer(), | 316 GCTracer::Scope gc_scope(heap()->tracer(), |
317 GCTracer::Scope::MC_CLEAR_STORE_BUFFER); | 317 GCTracer::Scope::MC_CLEAR_STORE_BUFFER); |
318 heap_->store_buffer()->ClearInvalidStoreBufferEntries(); | 318 RememberedSet<OLD_TO_NEW>::ClearInvalidSlots(heap()); |
319 } | 319 } |
320 | 320 |
321 { | 321 { |
322 GCTracer::Scope gc_scope(heap()->tracer(), | 322 GCTracer::Scope gc_scope(heap()->tracer(), |
323 GCTracer::Scope::MC_CLEAR_SLOTS_BUFFER); | 323 GCTracer::Scope::MC_CLEAR_SLOTS_BUFFER); |
324 for (Page* p : evacuation_candidates_) { | 324 for (Page* p : evacuation_candidates_) { |
325 SlotsBuffer::RemoveInvalidSlots(heap_, p->slots_buffer()); | 325 SlotsBuffer::RemoveInvalidSlots(heap_, p->slots_buffer()); |
326 } | 326 } |
327 } | 327 } |
328 #ifdef VERIFY_HEAP | 328 #ifdef VERIFY_HEAP |
329 if (FLAG_verify_heap) { | 329 if (FLAG_verify_heap) { |
330 VerifyValidStoreAndSlotsBufferEntries(); | 330 VerifyValidStoreAndSlotsBufferEntries(); |
331 } | 331 } |
332 #endif | 332 #endif |
333 } | 333 } |
334 | 334 |
335 | 335 |
336 #ifdef VERIFY_HEAP | 336 #ifdef VERIFY_HEAP |
337 static void VerifyValidSlotsBufferEntries(Heap* heap, PagedSpace* space) { | 337 static void VerifyValidSlotsBufferEntries(Heap* heap, PagedSpace* space) { |
338 PageIterator it(space); | 338 PageIterator it(space); |
339 while (it.has_next()) { | 339 while (it.has_next()) { |
340 Page* p = it.next(); | 340 Page* p = it.next(); |
341 SlotsBuffer::VerifySlots(heap, p->slots_buffer()); | 341 SlotsBuffer::VerifySlots(heap, p->slots_buffer()); |
342 } | 342 } |
343 } | 343 } |
344 | 344 |
345 | 345 |
346 void MarkCompactCollector::VerifyValidStoreAndSlotsBufferEntries() { | 346 void MarkCompactCollector::VerifyValidStoreAndSlotsBufferEntries() { |
347 heap()->store_buffer()->VerifyValidStoreBufferEntries(); | 347 RememberedSet<OLD_TO_NEW>::VerifyValidSlots(heap()); |
348 | 348 |
349 VerifyValidSlotsBufferEntries(heap(), heap()->old_space()); | 349 VerifyValidSlotsBufferEntries(heap(), heap()->old_space()); |
350 VerifyValidSlotsBufferEntries(heap(), heap()->code_space()); | 350 VerifyValidSlotsBufferEntries(heap(), heap()->code_space()); |
351 VerifyValidSlotsBufferEntries(heap(), heap()->map_space()); | 351 VerifyValidSlotsBufferEntries(heap(), heap()->map_space()); |
352 | 352 |
353 LargeObjectIterator it(heap()->lo_space()); | 353 LargeObjectIterator it(heap()->lo_space()); |
354 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { | 354 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { |
355 MemoryChunk* chunk = MemoryChunk::FromAddress(object->address()); | 355 MemoryChunk* chunk = MemoryChunk::FromAddress(object->address()); |
356 SlotsBuffer::VerifySlots(heap(), chunk->slots_buffer()); | 356 SlotsBuffer::VerifySlots(heap(), chunk->slots_buffer()); |
357 } | 357 } |
(...skipping 2185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2543 | 2543 |
2544 void MarkCompactCollector::RecordMigratedSlot( | 2544 void MarkCompactCollector::RecordMigratedSlot( |
2545 Object* value, Address slot, SlotsBuffer** evacuation_slots_buffer, | 2545 Object* value, Address slot, SlotsBuffer** evacuation_slots_buffer, |
2546 LocalStoreBuffer* local_store_buffer) { | 2546 LocalStoreBuffer* local_store_buffer) { |
2547 // When parallel compaction is in progress, store and slots buffer entries | 2547 // When parallel compaction is in progress, store and slots buffer entries |
2548 // require synchronization. | 2548 // require synchronization. |
2549 if (heap_->InNewSpace(value)) { | 2549 if (heap_->InNewSpace(value)) { |
2550 if (compaction_in_progress_) { | 2550 if (compaction_in_progress_) { |
2551 local_store_buffer->Record(slot); | 2551 local_store_buffer->Record(slot); |
2552 } else { | 2552 } else { |
2553 heap_->store_buffer()->Mark(slot); | 2553 Page* page = Page::FromAddress(slot); |
| 2554 RememberedSet<OLD_TO_NEW>::Insert(page, slot); |
2554 } | 2555 } |
2555 } else if (value->IsHeapObject() && IsOnEvacuationCandidate(value)) { | 2556 } else if (value->IsHeapObject() && IsOnEvacuationCandidate(value)) { |
2556 SlotsBuffer::AddTo(slots_buffer_allocator_, evacuation_slots_buffer, | 2557 SlotsBuffer::AddTo(slots_buffer_allocator_, evacuation_slots_buffer, |
2557 reinterpret_cast<Object**>(slot), | 2558 reinterpret_cast<Object**>(slot), |
2558 SlotsBuffer::IGNORE_OVERFLOW); | 2559 SlotsBuffer::IGNORE_OVERFLOW); |
2559 } | 2560 } |
2560 } | 2561 } |
2561 | 2562 |
2562 | 2563 |
2563 void MarkCompactCollector::RecordMigratedCodeEntrySlot( | 2564 void MarkCompactCollector::RecordMigratedCodeEntrySlot( |
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3082 class MarkCompactCollector::Evacuator : public Malloced { | 3083 class MarkCompactCollector::Evacuator : public Malloced { |
3083 public: | 3084 public: |
3084 Evacuator(MarkCompactCollector* collector, | 3085 Evacuator(MarkCompactCollector* collector, |
3085 const List<Page*>& evacuation_candidates, | 3086 const List<Page*>& evacuation_candidates, |
3086 const List<NewSpacePage*>& newspace_evacuation_candidates) | 3087 const List<NewSpacePage*>& newspace_evacuation_candidates) |
3087 : collector_(collector), | 3088 : collector_(collector), |
3088 evacuation_candidates_(evacuation_candidates), | 3089 evacuation_candidates_(evacuation_candidates), |
3089 newspace_evacuation_candidates_(newspace_evacuation_candidates), | 3090 newspace_evacuation_candidates_(newspace_evacuation_candidates), |
3090 compaction_spaces_(collector->heap()), | 3091 compaction_spaces_(collector->heap()), |
3091 local_slots_buffer_(nullptr), | 3092 local_slots_buffer_(nullptr), |
3092 local_store_buffer_(), | 3093 local_store_buffer_(collector->heap()), |
3093 local_pretenuring_feedback_(HashMap::PointersMatch, | 3094 local_pretenuring_feedback_(HashMap::PointersMatch, |
3094 kInitialLocalPretenuringFeedbackCapacity), | 3095 kInitialLocalPretenuringFeedbackCapacity), |
3095 new_space_visitor_(collector->heap(), &compaction_spaces_, | 3096 new_space_visitor_(collector->heap(), &compaction_spaces_, |
3096 &local_slots_buffer_, &local_store_buffer_, | 3097 &local_slots_buffer_, &local_store_buffer_, |
3097 &local_pretenuring_feedback_), | 3098 &local_pretenuring_feedback_), |
3098 old_space_visitor_(collector->heap(), &compaction_spaces_, | 3099 old_space_visitor_(collector->heap(), &compaction_spaces_, |
3099 &local_slots_buffer_, &local_store_buffer_), | 3100 &local_slots_buffer_, &local_store_buffer_), |
3100 duration_(0.0), | 3101 duration_(0.0), |
3101 bytes_compacted_(0), | 3102 bytes_compacted_(0), |
3102 task_id_(0) {} | 3103 task_id_(0) {} |
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3731 SemiSpaceIterator to_it(heap()->new_space()); | 3732 SemiSpaceIterator to_it(heap()->new_space()); |
3732 for (HeapObject* object = to_it.Next(); object != NULL; | 3733 for (HeapObject* object = to_it.Next(); object != NULL; |
3733 object = to_it.Next()) { | 3734 object = to_it.Next()) { |
3734 Map* map = object->map(); | 3735 Map* map = object->map(); |
3735 object->IterateBody(map->instance_type(), object->SizeFromMap(map), | 3736 object->IterateBody(map->instance_type(), object->SizeFromMap(map), |
3736 &updating_visitor); | 3737 &updating_visitor); |
3737 } | 3738 } |
3738 // Update roots. | 3739 // Update roots. |
3739 heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE); | 3740 heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE); |
3740 | 3741 |
3741 heap_->store_buffer()->IteratePointersToNewSpace(&UpdatePointer); | 3742 RememberedSet<OLD_TO_NEW>::IterateWithWrapper(heap_, UpdatePointer); |
3742 } | 3743 } |
3743 | 3744 |
3744 { | 3745 { |
3745 GCTracer::Scope gc_scope( | 3746 GCTracer::Scope gc_scope( |
3746 heap()->tracer(), | 3747 heap()->tracer(), |
3747 GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_BETWEEN_EVACUATED); | 3748 GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_BETWEEN_EVACUATED); |
3748 for (Page* p : evacuation_candidates_) { | 3749 for (Page* p : evacuation_candidates_) { |
3749 DCHECK(p->IsEvacuationCandidate() || | 3750 DCHECK(p->IsEvacuationCandidate() || |
3750 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); | 3751 p->IsFlagSet(Page::RESCAN_ON_EVACUATION)); |
3751 | 3752 |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4066 MarkBit mark_bit = Marking::MarkBitFrom(host); | 4067 MarkBit mark_bit = Marking::MarkBitFrom(host); |
4067 if (Marking::IsBlack(mark_bit)) { | 4068 if (Marking::IsBlack(mark_bit)) { |
4068 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); | 4069 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); |
4069 RecordRelocSlot(&rinfo, target); | 4070 RecordRelocSlot(&rinfo, target); |
4070 } | 4071 } |
4071 } | 4072 } |
4072 } | 4073 } |
4073 | 4074 |
4074 } // namespace internal | 4075 } // namespace internal |
4075 } // namespace v8 | 4076 } // namespace v8 |
OLD | NEW |