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/incremental-marking.h" | 7 #include "src/incremental-marking.h" |
8 | 8 |
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 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); | 670 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); |
671 SLOW_ASSERT(Marking::IsGrey(mark_bit) || | 671 SLOW_ASSERT(Marking::IsGrey(mark_bit) || |
672 (obj->IsFiller() && Marking::IsWhite(mark_bit)) || | 672 (obj->IsFiller() && Marking::IsWhite(mark_bit)) || |
673 (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) && | 673 (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) && |
674 Marking::IsBlack(mark_bit))); | 674 Marking::IsBlack(mark_bit))); |
675 #endif | 675 #endif |
676 MarkBlackOrKeepBlack(obj, mark_bit, size); | 676 MarkBlackOrKeepBlack(obj, mark_bit, size); |
677 } | 677 } |
678 | 678 |
679 | 679 |
680 void IncrementalMarking::ProcessMarkingDeque(intptr_t bytes_to_process) { | 680 intptr_t IncrementalMarking::ProcessMarkingDeque(intptr_t bytes_to_process) { |
| 681 intptr_t bytes_processed = 0; |
681 Map* filler_map = heap_->one_pointer_filler_map(); | 682 Map* filler_map = heap_->one_pointer_filler_map(); |
682 while (!marking_deque_.IsEmpty() && bytes_to_process > 0) { | 683 while (!marking_deque_.IsEmpty() && bytes_processed < bytes_to_process) { |
683 HeapObject* obj = marking_deque_.Pop(); | 684 HeapObject* obj = marking_deque_.Pop(); |
684 | 685 |
685 // Explicitly skip one word fillers. Incremental markbit patterns are | 686 // Explicitly skip one word fillers. Incremental markbit patterns are |
686 // correct only for objects that occupy at least two words. | 687 // correct only for objects that occupy at least two words. |
687 Map* map = obj->map(); | 688 Map* map = obj->map(); |
688 if (map == filler_map) continue; | 689 if (map == filler_map) continue; |
689 | 690 |
690 int size = obj->SizeFromMap(map); | 691 int size = obj->SizeFromMap(map); |
691 unscanned_bytes_of_large_object_ = 0; | 692 unscanned_bytes_of_large_object_ = 0; |
692 VisitObject(map, obj, size); | 693 VisitObject(map, obj, size); |
693 int delta = (size - unscanned_bytes_of_large_object_); | 694 int delta = (size - unscanned_bytes_of_large_object_); |
694 // TODO(jochen): remove after http://crbug.com/381820 is resolved. | 695 // TODO(jochen): remove after http://crbug.com/381820 is resolved. |
695 CHECK_LT(0, delta); | 696 CHECK_LT(0, delta); |
696 bytes_to_process -= delta; | 697 bytes_processed += delta; |
697 } | 698 } |
| 699 return bytes_processed; |
698 } | 700 } |
699 | 701 |
700 | 702 |
701 void IncrementalMarking::ProcessMarkingDeque() { | 703 void IncrementalMarking::ProcessMarkingDeque() { |
702 Map* filler_map = heap_->one_pointer_filler_map(); | 704 Map* filler_map = heap_->one_pointer_filler_map(); |
703 while (!marking_deque_.IsEmpty()) { | 705 while (!marking_deque_.IsEmpty()) { |
704 HeapObject* obj = marking_deque_.Pop(); | 706 HeapObject* obj = marking_deque_.Pop(); |
705 | 707 |
706 // Explicitly skip one word fillers. Incremental markbit patterns are | 708 // Explicitly skip one word fillers. Incremental markbit patterns are |
707 // correct only for objects that occupy at least two words. | 709 // correct only for objects that occupy at least two words. |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
866 // on | 868 // on |
867 // allocation), so to reduce the lumpiness we don't use the write barriers | 869 // allocation), so to reduce the lumpiness we don't use the write barriers |
868 // invoked since last step directly to determine the amount of work to do. | 870 // invoked since last step directly to determine the amount of work to do. |
869 intptr_t bytes_to_process = | 871 intptr_t bytes_to_process = |
870 marking_speed_ * | 872 marking_speed_ * |
871 Max(allocated_, write_barriers_invoked_since_last_step_); | 873 Max(allocated_, write_barriers_invoked_since_last_step_); |
872 allocated_ = 0; | 874 allocated_ = 0; |
873 write_barriers_invoked_since_last_step_ = 0; | 875 write_barriers_invoked_since_last_step_ = 0; |
874 | 876 |
875 bytes_scanned_ += bytes_to_process; | 877 bytes_scanned_ += bytes_to_process; |
| 878 intptr_t bytes_processed = 0; |
876 | 879 |
877 if (state_ == SWEEPING) { | 880 if (state_ == SWEEPING) { |
878 if (heap_->mark_compact_collector()->sweeping_in_progress() && | 881 if (heap_->mark_compact_collector()->sweeping_in_progress() && |
879 heap_->mark_compact_collector()->IsSweepingCompleted()) { | 882 heap_->mark_compact_collector()->IsSweepingCompleted()) { |
880 heap_->mark_compact_collector()->EnsureSweepingCompleted(); | 883 heap_->mark_compact_collector()->EnsureSweepingCompleted(); |
881 } | 884 } |
882 if (!heap_->mark_compact_collector()->sweeping_in_progress()) { | 885 if (!heap_->mark_compact_collector()->sweeping_in_progress()) { |
883 bytes_scanned_ = 0; | 886 bytes_scanned_ = 0; |
884 StartMarking(PREVENT_COMPACTION); | 887 StartMarking(PREVENT_COMPACTION); |
885 } | 888 } |
886 } else if (state_ == MARKING) { | 889 } else if (state_ == MARKING) { |
887 ProcessMarkingDeque(bytes_to_process); | 890 bytes_processed = ProcessMarkingDeque(bytes_to_process); |
888 if (marking_deque_.IsEmpty()) MarkingComplete(action); | 891 if (marking_deque_.IsEmpty()) MarkingComplete(action); |
889 } | 892 } |
890 | 893 |
891 steps_count_++; | 894 steps_count_++; |
892 | 895 |
893 bool speed_up = false; | 896 bool speed_up = false; |
894 | 897 |
895 if ((steps_count_ % kMarkingSpeedAccellerationInterval) == 0) { | 898 if ((steps_count_ % kMarkingSpeedAccellerationInterval) == 0) { |
896 if (FLAG_trace_gc) { | 899 if (FLAG_trace_gc) { |
897 PrintPID("Speed up marking after %d steps\n", | 900 PrintPID("Speed up marking after %d steps\n", |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
949 marking_speed_ = static_cast<int>( | 952 marking_speed_ = static_cast<int>( |
950 Min(kMaxMarkingSpeed, static_cast<intptr_t>(marking_speed_ * 1.3))); | 953 Min(kMaxMarkingSpeed, static_cast<intptr_t>(marking_speed_ * 1.3))); |
951 if (FLAG_trace_gc) { | 954 if (FLAG_trace_gc) { |
952 PrintPID("Marking speed increased to %d\n", marking_speed_); | 955 PrintPID("Marking speed increased to %d\n", marking_speed_); |
953 } | 956 } |
954 } | 957 } |
955 } | 958 } |
956 | 959 |
957 double end = base::OS::TimeCurrentMillis(); | 960 double end = base::OS::TimeCurrentMillis(); |
958 double duration = (end - start); | 961 double duration = (end - start); |
959 heap_->tracer()->AddIncrementalMarkingStep(duration, allocated_bytes); | 962 // Note that we report zero bytes here when sweeping was in progress or |
| 963 // when we just started incremental marking. In these cases we did not |
| 964 // process the marking deque. |
| 965 heap_->tracer()->AddIncrementalMarkingStep(duration, bytes_processed); |
960 heap_->AddMarkingTime(duration); | 966 heap_->AddMarkingTime(duration); |
961 } | 967 } |
962 } | 968 } |
963 | 969 |
964 | 970 |
965 void IncrementalMarking::ResetStepCounters() { | 971 void IncrementalMarking::ResetStepCounters() { |
966 steps_count_ = 0; | 972 steps_count_ = 0; |
967 old_generation_space_available_at_start_of_incremental_ = | 973 old_generation_space_available_at_start_of_incremental_ = |
968 SpaceLeftInOldSpace(); | 974 SpaceLeftInOldSpace(); |
969 old_generation_space_used_at_start_of_incremental_ = | 975 old_generation_space_used_at_start_of_incremental_ = |
970 heap_->PromotedTotalSize(); | 976 heap_->PromotedTotalSize(); |
971 bytes_rescanned_ = 0; | 977 bytes_rescanned_ = 0; |
972 marking_speed_ = kInitialMarkingSpeed; | 978 marking_speed_ = kInitialMarkingSpeed; |
973 bytes_scanned_ = 0; | 979 bytes_scanned_ = 0; |
974 write_barriers_invoked_since_last_step_ = 0; | 980 write_barriers_invoked_since_last_step_ = 0; |
975 } | 981 } |
976 | 982 |
977 | 983 |
978 int64_t IncrementalMarking::SpaceLeftInOldSpace() { | 984 int64_t IncrementalMarking::SpaceLeftInOldSpace() { |
979 return heap_->MaxOldGenerationSize() - heap_->PromotedSpaceSizeOfObjects(); | 985 return heap_->MaxOldGenerationSize() - heap_->PromotedSpaceSizeOfObjects(); |
980 } | 986 } |
981 | 987 |
982 } } // namespace v8::internal | 988 } } // namespace v8::internal |
OLD | NEW |