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 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
705 | 705 |
706 intptr_t estimated_release = 0; | 706 intptr_t estimated_release = 0; |
707 | 707 |
708 Candidate candidates[kMaxMaxEvacuationCandidates]; | 708 Candidate candidates[kMaxMaxEvacuationCandidates]; |
709 | 709 |
710 max_evacuation_candidates = | 710 max_evacuation_candidates = |
711 Min(kMaxMaxEvacuationCandidates, max_evacuation_candidates); | 711 Min(kMaxMaxEvacuationCandidates, max_evacuation_candidates); |
712 | 712 |
713 int count = 0; | 713 int count = 0; |
714 int fragmentation = 0; | 714 int fragmentation = 0; |
715 int page_number = 0; | |
715 Candidate* least = NULL; | 716 Candidate* least = NULL; |
716 | 717 |
717 PageIterator it(space); | 718 PageIterator it(space); |
718 while (it.has_next()) { | 719 while (it.has_next()) { |
719 Page* p = it.next(); | 720 Page* p = it.next(); |
720 if (p->NeverEvacuate()) continue; | 721 if (p->NeverEvacuate()) continue; |
721 | 722 |
722 // Invariant: Evacuation candidates are just created when marking is | 723 // Invariant: Evacuation candidates are just created when marking is |
723 // started. At the end of a GC all evacuation candidates are cleared and | 724 // started. At the end of a GC all evacuation candidates are cleared and |
724 // their slot buffers are released. | 725 // their slot buffers are released. |
725 CHECK(!p->IsEvacuationCandidate()); | 726 CHECK(!p->IsEvacuationCandidate()); |
726 CHECK(p->slots_buffer() == NULL); | 727 CHECK(p->slots_buffer() == NULL); |
727 | 728 |
728 if (FLAG_stress_compaction) { | 729 if (FLAG_stress_compaction) { |
729 unsigned int counter = space->heap()->ms_count(); | 730 if (FLAG_manual_evacuation_candidates_selection) { |
730 uintptr_t page_number = reinterpret_cast<uintptr_t>(p) >> kPageSizeBits; | 731 if (p->IsFlagSet(MemoryChunk::FORCE_EVACUATION_CANDIDATE_FOR_TESTING)) { |
731 if ((counter & 1) == (page_number & 1)) fragmentation = 1; | 732 p->ClearFlag(MemoryChunk::FORCE_EVACUATION_CANDIDATE_FOR_TESTING); |
733 fragmentation = 1; | |
734 } | |
735 } else { | |
736 unsigned int counter = space->heap()->ms_count(); | |
737 if ((counter & 1) == (page_number & 1)) fragmentation = 1; | |
738 page_number++; | |
739 } | |
732 } else if (mode == REDUCE_MEMORY_FOOTPRINT) { | 740 } else if (mode == REDUCE_MEMORY_FOOTPRINT) { |
733 // Don't try to release too many pages. | 741 // Don't try to release too many pages. |
734 if (estimated_release >= over_reserved) { | 742 if (estimated_release >= over_reserved) { |
735 continue; | 743 continue; |
736 } | 744 } |
737 | 745 |
738 intptr_t free_bytes = 0; | 746 intptr_t free_bytes = 0; |
739 | 747 |
740 if (!p->WasSwept()) { | 748 if (!p->WasSwept()) { |
741 free_bytes = (p->area_size() - p->LiveBytes()); | 749 free_bytes = (p->area_size() - p->LiveBytes()); |
(...skipping 3532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4274 buffer = allocator->AllocateBuffer(buffer); | 4282 buffer = allocator->AllocateBuffer(buffer); |
4275 *buffer_address = buffer; | 4283 *buffer_address = buffer; |
4276 } | 4284 } |
4277 DCHECK(buffer->HasSpaceForTypedSlot()); | 4285 DCHECK(buffer->HasSpaceForTypedSlot()); |
4278 buffer->Add(reinterpret_cast<ObjectSlot>(type)); | 4286 buffer->Add(reinterpret_cast<ObjectSlot>(type)); |
4279 buffer->Add(reinterpret_cast<ObjectSlot>(addr)); | 4287 buffer->Add(reinterpret_cast<ObjectSlot>(addr)); |
4280 return true; | 4288 return true; |
4281 } | 4289 } |
4282 | 4290 |
4283 | 4291 |
4292 void SlotsBuffer::RemoveSlot(SlotsBuffer* buffer, ObjectSlot slot_to_remove) { | |
Hannes Payer (out of office)
2015/03/03 09:48:53
I think it would be more efficient to just clear t
Igor Sheludko
2015/03/04 14:54:19
Done.
| |
4293 DCHECK(!IsTypedSlot(slot_to_remove)); | |
4294 while (buffer != NULL) { | |
4295 intptr_t written = 0; | |
4296 intptr_t length = buffer->idx_; | |
4297 | |
4298 ObjectSlot* slots = buffer->slots_; | |
4299 for (int slot_idx = 0; slot_idx < length; ++slot_idx) { | |
4300 ObjectSlot slot = slots[slot_idx]; | |
4301 if (!IsTypedSlot(slot)) { | |
4302 if (slot != slot_to_remove) { | |
4303 if (written != slot_idx) slots[written] = slot; | |
4304 ++written; | |
4305 } | |
4306 } else { | |
4307 ++slot_idx; | |
4308 DCHECK(slot_idx < length); | |
4309 ObjectSlot typed_slot = slots[slot_idx]; | |
4310 if (typed_slot != slot_to_remove) { | |
4311 if (written != slot_idx - 1) { | |
4312 slots[written++] = slot; | |
4313 slots[written++] = typed_slot; | |
4314 } else { | |
4315 written += 2; | |
4316 } | |
4317 } | |
4318 } | |
4319 } | |
4320 buffer->idx_ = written; | |
4321 buffer = buffer->next_; | |
4322 } | |
4323 } | |
4324 | |
4325 | |
4284 static inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) { | 4326 static inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) { |
4285 if (RelocInfo::IsCodeTarget(rmode)) { | 4327 if (RelocInfo::IsCodeTarget(rmode)) { |
4286 return SlotsBuffer::CODE_TARGET_SLOT; | 4328 return SlotsBuffer::CODE_TARGET_SLOT; |
4287 } else if (RelocInfo::IsEmbeddedObject(rmode)) { | 4329 } else if (RelocInfo::IsEmbeddedObject(rmode)) { |
4288 return SlotsBuffer::EMBEDDED_OBJECT_SLOT; | 4330 return SlotsBuffer::EMBEDDED_OBJECT_SLOT; |
4289 } else if (RelocInfo::IsDebugBreakSlot(rmode)) { | 4331 } else if (RelocInfo::IsDebugBreakSlot(rmode)) { |
4290 return SlotsBuffer::DEBUG_TARGET_SLOT; | 4332 return SlotsBuffer::DEBUG_TARGET_SLOT; |
4291 } else if (RelocInfo::IsJSReturn(rmode)) { | 4333 } else if (RelocInfo::IsJSReturn(rmode)) { |
4292 return SlotsBuffer::JS_RETURN_SLOT; | 4334 return SlotsBuffer::JS_RETURN_SLOT; |
4293 } | 4335 } |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4415 SlotsBuffer* buffer = *buffer_address; | 4457 SlotsBuffer* buffer = *buffer_address; |
4416 while (buffer != NULL) { | 4458 while (buffer != NULL) { |
4417 SlotsBuffer* next_buffer = buffer->next(); | 4459 SlotsBuffer* next_buffer = buffer->next(); |
4418 DeallocateBuffer(buffer); | 4460 DeallocateBuffer(buffer); |
4419 buffer = next_buffer; | 4461 buffer = next_buffer; |
4420 } | 4462 } |
4421 *buffer_address = NULL; | 4463 *buffer_address = NULL; |
4422 } | 4464 } |
4423 } | 4465 } |
4424 } // namespace v8::internal | 4466 } // namespace v8::internal |
OLD | NEW |