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