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/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 #undef UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE | 726 #undef UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE |
727 | 727 |
728 #ifdef DEBUG | 728 #ifdef DEBUG |
729 ReportStatisticsAfterGC(); | 729 ReportStatisticsAfterGC(); |
730 #endif // DEBUG | 730 #endif // DEBUG |
731 | 731 |
732 // Remember the last top pointer so that we can later find out | 732 // Remember the last top pointer so that we can later find out |
733 // whether we allocated in new space since the last GC. | 733 // whether we allocated in new space since the last GC. |
734 new_space_top_after_last_gc_ = new_space()->top(); | 734 new_space_top_after_last_gc_ = new_space()->top(); |
735 last_gc_time_ = MonotonicallyIncreasingTimeInMs(); | 735 last_gc_time_ = MonotonicallyIncreasingTimeInMs(); |
| 736 |
| 737 ReduceNewSpaceSize( |
| 738 tracer()->CurrentNewSpaceAllocationThroughputInBytesPerMillisecond()); |
736 } | 739 } |
737 | 740 |
738 | 741 |
739 void Heap::PreprocessStackTraces() { | 742 void Heap::PreprocessStackTraces() { |
740 if (!weak_stack_trace_list()->IsWeakFixedArray()) return; | 743 if (!weak_stack_trace_list()->IsWeakFixedArray()) return; |
741 WeakFixedArray* array = WeakFixedArray::cast(weak_stack_trace_list()); | 744 WeakFixedArray* array = WeakFixedArray::cast(weak_stack_trace_list()); |
742 int length = array->Length(); | 745 int length = array->Length(); |
743 for (int i = 0; i < length; i++) { | 746 for (int i = 0; i < length; i++) { |
744 if (array->IsEmptySlot(i)) continue; | 747 if (array->IsEmptySlot(i)) continue; |
745 FixedArray* elements = FixedArray::cast(array->Get(i)); | 748 FixedArray* elements = FixedArray::cast(array->Get(i)); |
(...skipping 3816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4562 if (!IsHeapIterable()) { | 4565 if (!IsHeapIterable()) { |
4563 CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable"); | 4566 CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable"); |
4564 } | 4567 } |
4565 if (mark_compact_collector()->sweeping_in_progress()) { | 4568 if (mark_compact_collector()->sweeping_in_progress()) { |
4566 mark_compact_collector()->EnsureSweepingCompleted(); | 4569 mark_compact_collector()->EnsureSweepingCompleted(); |
4567 } | 4570 } |
4568 DCHECK(IsHeapIterable()); | 4571 DCHECK(IsHeapIterable()); |
4569 } | 4572 } |
4570 | 4573 |
4571 | 4574 |
4572 void Heap::ReduceNewSpaceSize(GCIdleTimeAction action) { | 4575 bool Heap::HasLowAllocationRate(size_t allocation_rate) { |
4573 if (action.reduce_memory && | 4576 static const size_t kLowAllocationRate = 1000; |
4574 (action.type == DO_SCAVENGE || action.type == DO_FULL_GC || | 4577 if (allocation_rate == 0) return false; |
4575 (action.type == DO_INCREMENTAL_MARKING && | 4578 return allocation_rate < kLowAllocationRate; |
4576 incremental_marking()->IsStopped()))) { | 4579 } |
| 4580 |
| 4581 |
| 4582 void Heap::ReduceNewSpaceSize(size_t allocation_rate) { |
| 4583 if (HasLowAllocationRate(allocation_rate)) { |
4577 new_space_.Shrink(); | 4584 new_space_.Shrink(); |
4578 UncommitFromSpace(); | 4585 UncommitFromSpace(); |
4579 } | 4586 } |
4580 } | 4587 } |
4581 | 4588 |
4582 | 4589 |
4583 bool Heap::TryFinalizeIdleIncrementalMarking( | 4590 bool Heap::TryFinalizeIdleIncrementalMarking( |
4584 double idle_time_in_ms, size_t size_of_objects, | 4591 double idle_time_in_ms, size_t size_of_objects, |
4585 size_t final_incremental_mark_compact_speed_in_bytes_per_ms) { | 4592 size_t final_incremental_mark_compact_speed_in_bytes_per_ms) { |
4586 if (FLAG_overapproximate_weak_closure && | 4593 if (FLAG_overapproximate_weak_closure && |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4632 tracer()->IncrementalMarkingSpeedInBytesPerMillisecond()); | 4639 tracer()->IncrementalMarkingSpeedInBytesPerMillisecond()); |
4633 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms = | 4640 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms = |
4634 static_cast<size_t>( | 4641 static_cast<size_t>( |
4635 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()); | 4642 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()); |
4636 heap_state.scavenge_speed_in_bytes_per_ms = | 4643 heap_state.scavenge_speed_in_bytes_per_ms = |
4637 static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond()); | 4644 static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond()); |
4638 heap_state.used_new_space_size = new_space_.Size(); | 4645 heap_state.used_new_space_size = new_space_.Size(); |
4639 heap_state.new_space_capacity = new_space_.Capacity(); | 4646 heap_state.new_space_capacity = new_space_.Capacity(); |
4640 heap_state.new_space_allocation_throughput_in_bytes_per_ms = | 4647 heap_state.new_space_allocation_throughput_in_bytes_per_ms = |
4641 tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond(); | 4648 tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond(); |
| 4649 heap_state.current_new_space_allocation_throughput_in_bytes_per_ms = |
| 4650 tracer()->CurrentNewSpaceAllocationThroughputInBytesPerMillisecond(); |
4642 return heap_state; | 4651 return heap_state; |
4643 } | 4652 } |
4644 | 4653 |
4645 | 4654 |
4646 bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, | 4655 bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, |
4647 GCIdleTimeHandler::HeapState heap_state, | 4656 GCIdleTimeHandler::HeapState heap_state, |
4648 double deadline_in_ms, | 4657 double deadline_in_ms, |
4649 bool is_long_idle_notification) { | 4658 bool is_long_idle_notification) { |
4650 bool result = false; | 4659 bool result = false; |
4651 switch (action.type) { | 4660 switch (action.type) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4694 case DO_SCAVENGE: | 4703 case DO_SCAVENGE: |
4695 CollectGarbage(NEW_SPACE, "idle notification: scavenge"); | 4704 CollectGarbage(NEW_SPACE, "idle notification: scavenge"); |
4696 break; | 4705 break; |
4697 case DO_FINALIZE_SWEEPING: | 4706 case DO_FINALIZE_SWEEPING: |
4698 mark_compact_collector()->EnsureSweepingCompleted(); | 4707 mark_compact_collector()->EnsureSweepingCompleted(); |
4699 break; | 4708 break; |
4700 case DO_NOTHING: | 4709 case DO_NOTHING: |
4701 break; | 4710 break; |
4702 } | 4711 } |
4703 | 4712 |
4704 ReduceNewSpaceSize(action); | |
4705 return result; | 4713 return result; |
4706 } | 4714 } |
4707 | 4715 |
4708 | 4716 |
4709 void Heap::IdleNotificationEpilogue(GCIdleTimeAction action, | 4717 void Heap::IdleNotificationEpilogue(GCIdleTimeAction action, |
4710 GCIdleTimeHandler::HeapState heap_state, | 4718 GCIdleTimeHandler::HeapState heap_state, |
4711 double start_ms, double deadline_in_ms, | 4719 double start_ms, double deadline_in_ms, |
4712 bool is_long_idle_notification) { | 4720 bool is_long_idle_notification) { |
4713 double idle_time_in_ms = deadline_in_ms - start_ms; | 4721 double idle_time_in_ms = deadline_in_ms - start_ms; |
4714 double current_time = MonotonicallyIncreasingTimeInMs(); | 4722 double current_time = MonotonicallyIncreasingTimeInMs(); |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4959 | 4967 |
4960 VerifyPointersVisitor no_dirty_regions_visitor; | 4968 VerifyPointersVisitor no_dirty_regions_visitor; |
4961 code_space_->Verify(&no_dirty_regions_visitor); | 4969 code_space_->Verify(&no_dirty_regions_visitor); |
4962 | 4970 |
4963 lo_space_->Verify(); | 4971 lo_space_->Verify(); |
4964 } | 4972 } |
4965 #endif | 4973 #endif |
4966 | 4974 |
4967 | 4975 |
4968 void Heap::ZapFromSpace() { | 4976 void Heap::ZapFromSpace() { |
| 4977 if (!new_space_.IsFromSpaceCommitted()) return; |
4969 NewSpacePageIterator it(new_space_.FromSpaceStart(), | 4978 NewSpacePageIterator it(new_space_.FromSpaceStart(), |
4970 new_space_.FromSpaceEnd()); | 4979 new_space_.FromSpaceEnd()); |
4971 while (it.has_next()) { | 4980 while (it.has_next()) { |
4972 NewSpacePage* page = it.next(); | 4981 NewSpacePage* page = it.next(); |
4973 for (Address cursor = page->area_start(), limit = page->area_end(); | 4982 for (Address cursor = page->area_start(), limit = page->area_end(); |
4974 cursor < limit; cursor += kPointerSize) { | 4983 cursor < limit; cursor += kPointerSize) { |
4975 Memory::Address_at(cursor) = kFromSpaceZapValue; | 4984 Memory::Address_at(cursor) = kFromSpaceZapValue; |
4976 } | 4985 } |
4977 } | 4986 } |
4978 } | 4987 } |
(...skipping 1612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6591 *object_type = "CODE_TYPE"; \ | 6600 *object_type = "CODE_TYPE"; \ |
6592 *object_sub_type = "CODE_AGE/" #name; \ | 6601 *object_sub_type = "CODE_AGE/" #name; \ |
6593 return true; | 6602 return true; |
6594 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) | 6603 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) |
6595 #undef COMPARE_AND_RETURN_NAME | 6604 #undef COMPARE_AND_RETURN_NAME |
6596 } | 6605 } |
6597 return false; | 6606 return false; |
6598 } | 6607 } |
6599 } | 6608 } |
6600 } // namespace v8::internal | 6609 } // namespace v8::internal |
OLD | NEW |