| 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 |