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/v8.h" | 5 #include "src/v8.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/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/compilation-cache.h" | 10 #include "src/compilation-cache.h" |
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
714 | 714 |
715 intptr_t estimated_release = 0; | 715 intptr_t estimated_release = 0; |
716 | 716 |
717 Candidate candidates[kMaxMaxEvacuationCandidates]; | 717 Candidate candidates[kMaxMaxEvacuationCandidates]; |
718 | 718 |
719 max_evacuation_candidates = | 719 max_evacuation_candidates = |
720 Min(kMaxMaxEvacuationCandidates, max_evacuation_candidates); | 720 Min(kMaxMaxEvacuationCandidates, max_evacuation_candidates); |
721 | 721 |
722 int count = 0; | 722 int count = 0; |
723 int fragmentation = 0; | 723 int fragmentation = 0; |
| 724 int page_number = 0; |
724 Candidate* least = NULL; | 725 Candidate* least = NULL; |
725 | 726 |
726 PageIterator it(space); | 727 PageIterator it(space); |
727 while (it.has_next()) { | 728 while (it.has_next()) { |
728 Page* p = it.next(); | 729 Page* p = it.next(); |
729 if (p->NeverEvacuate()) continue; | 730 if (p->NeverEvacuate()) continue; |
730 | 731 |
731 // Invariant: Evacuation candidates are just created when marking is | 732 // Invariant: Evacuation candidates are just created when marking is |
732 // started. At the end of a GC all evacuation candidates are cleared and | 733 // started. At the end of a GC all evacuation candidates are cleared and |
733 // their slot buffers are released. | 734 // their slot buffers are released. |
734 CHECK(!p->IsEvacuationCandidate()); | 735 CHECK(!p->IsEvacuationCandidate()); |
735 CHECK(p->slots_buffer() == NULL); | 736 CHECK(p->slots_buffer() == NULL); |
736 | 737 |
737 if (FLAG_stress_compaction) { | 738 if (FLAG_stress_compaction) { |
738 unsigned int counter = space->heap()->ms_count(); | 739 if (FLAG_manual_evacuation_candidates_selection) { |
739 uintptr_t page_number = reinterpret_cast<uintptr_t>(p) >> kPageSizeBits; | 740 if (p->IsFlagSet(MemoryChunk::FORCE_EVACUATION_CANDIDATE_FOR_TESTING)) { |
740 if ((counter & 1) == (page_number & 1)) fragmentation = 1; | 741 p->ClearFlag(MemoryChunk::FORCE_EVACUATION_CANDIDATE_FOR_TESTING); |
| 742 fragmentation = 1; |
| 743 } |
| 744 } else { |
| 745 unsigned int counter = space->heap()->ms_count(); |
| 746 if ((counter & 1) == (page_number & 1)) fragmentation = 1; |
| 747 page_number++; |
| 748 } |
741 } else if (mode == REDUCE_MEMORY_FOOTPRINT) { | 749 } else if (mode == REDUCE_MEMORY_FOOTPRINT) { |
742 // Don't try to release too many pages. | 750 // Don't try to release too many pages. |
743 if (estimated_release >= over_reserved) { | 751 if (estimated_release >= over_reserved) { |
744 continue; | 752 continue; |
745 } | 753 } |
746 | 754 |
747 intptr_t free_bytes = 0; | 755 intptr_t free_bytes = 0; |
748 | 756 |
749 if (!p->WasSwept()) { | 757 if (!p->WasSwept()) { |
750 free_bytes = (p->area_size() - p->LiveBytes()); | 758 free_bytes = (p->area_size() - p->LiveBytes()); |
(...skipping 3741 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4492 buffer = allocator->AllocateBuffer(buffer); | 4500 buffer = allocator->AllocateBuffer(buffer); |
4493 *buffer_address = buffer; | 4501 *buffer_address = buffer; |
4494 } | 4502 } |
4495 DCHECK(buffer->HasSpaceForTypedSlot()); | 4503 DCHECK(buffer->HasSpaceForTypedSlot()); |
4496 buffer->Add(reinterpret_cast<ObjectSlot>(type)); | 4504 buffer->Add(reinterpret_cast<ObjectSlot>(type)); |
4497 buffer->Add(reinterpret_cast<ObjectSlot>(addr)); | 4505 buffer->Add(reinterpret_cast<ObjectSlot>(addr)); |
4498 return true; | 4506 return true; |
4499 } | 4507 } |
4500 | 4508 |
4501 | 4509 |
| 4510 static Object* g_smi_slot = NULL; |
| 4511 |
| 4512 |
| 4513 void SlotsBuffer::RemoveSlot(SlotsBuffer* buffer, ObjectSlot slot_to_remove) { |
| 4514 DCHECK_EQ(Smi::FromInt(0), g_smi_slot); |
| 4515 DCHECK(!IsTypedSlot(slot_to_remove)); |
| 4516 while (buffer != NULL) { |
| 4517 ObjectSlot* slots = buffer->slots_; |
| 4518 // Remove entries by replacing them with a dummy slot containing a smi. |
| 4519 std::replace(&slots[0], &slots[buffer->idx_], slot_to_remove, &g_smi_slot); |
| 4520 buffer = buffer->next_; |
| 4521 } |
| 4522 } |
| 4523 |
| 4524 |
4502 static inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) { | 4525 static inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) { |
4503 if (RelocInfo::IsCodeTarget(rmode)) { | 4526 if (RelocInfo::IsCodeTarget(rmode)) { |
4504 return SlotsBuffer::CODE_TARGET_SLOT; | 4527 return SlotsBuffer::CODE_TARGET_SLOT; |
4505 } else if (RelocInfo::IsEmbeddedObject(rmode)) { | 4528 } else if (RelocInfo::IsEmbeddedObject(rmode)) { |
4506 return SlotsBuffer::EMBEDDED_OBJECT_SLOT; | 4529 return SlotsBuffer::EMBEDDED_OBJECT_SLOT; |
4507 } else if (RelocInfo::IsDebugBreakSlot(rmode)) { | 4530 } else if (RelocInfo::IsDebugBreakSlot(rmode)) { |
4508 return SlotsBuffer::DEBUG_TARGET_SLOT; | 4531 return SlotsBuffer::DEBUG_TARGET_SLOT; |
4509 } else if (RelocInfo::IsJSReturn(rmode)) { | 4532 } else if (RelocInfo::IsJSReturn(rmode)) { |
4510 return SlotsBuffer::JS_RETURN_SLOT; | 4533 return SlotsBuffer::JS_RETURN_SLOT; |
4511 } | 4534 } |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4633 SlotsBuffer* buffer = *buffer_address; | 4656 SlotsBuffer* buffer = *buffer_address; |
4634 while (buffer != NULL) { | 4657 while (buffer != NULL) { |
4635 SlotsBuffer* next_buffer = buffer->next(); | 4658 SlotsBuffer* next_buffer = buffer->next(); |
4636 DeallocateBuffer(buffer); | 4659 DeallocateBuffer(buffer); |
4637 buffer = next_buffer; | 4660 buffer = next_buffer; |
4638 } | 4661 } |
4639 *buffer_address = NULL; | 4662 *buffer_address = NULL; |
4640 } | 4663 } |
4641 } | 4664 } |
4642 } // namespace v8::internal | 4665 } // namespace v8::internal |
OLD | NEW |