Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Side by Side Diff: src/heap.cc

Issue 390823003: v8: make GCTracer persistent. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/once.h" 9 #include "src/base/once.h"
10 #include "src/base/utils/random-number-generator.h" 10 #include "src/base/utils/random-number-generator.h"
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 #ifdef DEBUG 92 #ifdef DEBUG
93 allocation_timeout_(0), 93 allocation_timeout_(0),
94 #endif // DEBUG 94 #endif // DEBUG
95 old_generation_allocation_limit_(kMinimumOldGenerationAllocationLimit), 95 old_generation_allocation_limit_(kMinimumOldGenerationAllocationLimit),
96 old_gen_exhausted_(false), 96 old_gen_exhausted_(false),
97 inline_allocation_disabled_(false), 97 inline_allocation_disabled_(false),
98 store_buffer_rebuilder_(store_buffer()), 98 store_buffer_rebuilder_(store_buffer()),
99 hidden_string_(NULL), 99 hidden_string_(NULL),
100 gc_safe_size_of_old_object_(NULL), 100 gc_safe_size_of_old_object_(NULL),
101 total_regexp_code_generated_(0), 101 total_regexp_code_generated_(0),
102 tracer_(NULL), 102 tracer_(this),
103 high_survival_rate_period_length_(0), 103 high_survival_rate_period_length_(0),
104 promoted_objects_size_(0), 104 promoted_objects_size_(0),
105 promotion_rate_(0), 105 promotion_rate_(0),
106 semi_space_copied_object_size_(0), 106 semi_space_copied_object_size_(0),
107 semi_space_copied_rate_(0), 107 semi_space_copied_rate_(0),
108 maximum_size_scavenges_(0), 108 maximum_size_scavenges_(0),
109 max_gc_pause_(0.0), 109 max_gc_pause_(0.0),
110 total_gc_time_ms_(0.0), 110 total_gc_time_ms_(0.0),
111 max_alive_after_gc_(0), 111 max_alive_after_gc_(0),
112 min_in_mutator_(kMaxInt), 112 min_in_mutator_(kMaxInt),
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 if (FLAG_trace_incremental_marking) { 827 if (FLAG_trace_incremental_marking) {
828 PrintF("[IncrementalMarking] Delaying MarkSweep.\n"); 828 PrintF("[IncrementalMarking] Delaying MarkSweep.\n");
829 } 829 }
830 collector = SCAVENGER; 830 collector = SCAVENGER;
831 collector_reason = "incremental marking delaying mark-sweep"; 831 collector_reason = "incremental marking delaying mark-sweep";
832 } 832 }
833 } 833 }
834 834
835 bool next_gc_likely_to_collect_more = false; 835 bool next_gc_likely_to_collect_more = false;
836 836
837 { GCTracer tracer(this, gc_reason, collector_reason); 837 { tracer()->start(gc_reason, collector_reason);
838 ASSERT(AllowHeapAllocation::IsAllowed()); 838 ASSERT(AllowHeapAllocation::IsAllowed());
839 DisallowHeapAllocation no_allocation_during_gc; 839 DisallowHeapAllocation no_allocation_during_gc;
840 GarbageCollectionPrologue(); 840 GarbageCollectionPrologue();
841 // The GC count was incremented in the prologue. Tell the tracer about 841 // The GC count was incremented in the prologue. Tell the tracer about
842 // it. 842 // it.
843 tracer.set_gc_count(gc_count_); 843 tracer()->set_gc_count(gc_count_);
844 844
845 // Tell the tracer which collector we've selected. 845 // Tell the tracer which collector we've selected.
846 tracer.set_collector(collector); 846 tracer()->set_collector(collector);
847 847
848 { 848 {
849 HistogramTimerScope histogram_timer_scope( 849 HistogramTimerScope histogram_timer_scope(
850 (collector == SCAVENGER) ? isolate_->counters()->gc_scavenger() 850 (collector == SCAVENGER) ? isolate_->counters()->gc_scavenger()
851 : isolate_->counters()->gc_compactor()); 851 : isolate_->counters()->gc_compactor());
852 next_gc_likely_to_collect_more = 852 next_gc_likely_to_collect_more =
853 PerformGarbageCollection(collector, &tracer, gc_callback_flags); 853 PerformGarbageCollection(collector, gc_callback_flags);
854 } 854 }
855 855
856 GarbageCollectionEpilogue(); 856 GarbageCollectionEpilogue();
857 tracer()->stop();
857 } 858 }
858 859
859 // Start incremental marking for the next cycle. The heap snapshot 860 // Start incremental marking for the next cycle. The heap snapshot
860 // generator needs incremental marking to stay off after it aborted. 861 // generator needs incremental marking to stay off after it aborted.
861 if (!mark_compact_collector()->abort_incremental_marking() && 862 if (!mark_compact_collector()->abort_incremental_marking() &&
862 incremental_marking()->IsStopped() && 863 incremental_marking()->IsStopped() &&
863 incremental_marking()->WorthActivating() && 864 incremental_marking()->WorthActivating() &&
864 NextGCIsLikelyToBeFull()) { 865 NextGCIsLikelyToBeFull()) {
865 incremental_marking()->Start(); 866 incremental_marking()->Start();
866 } 867 }
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1048 1049
1049 if (survival_rate > kYoungSurvivalRateHighThreshold) { 1050 if (survival_rate > kYoungSurvivalRateHighThreshold) {
1050 high_survival_rate_period_length_++; 1051 high_survival_rate_period_length_++;
1051 } else { 1052 } else {
1052 high_survival_rate_period_length_ = 0; 1053 high_survival_rate_period_length_ = 0;
1053 } 1054 }
1054 } 1055 }
1055 1056
1056 bool Heap::PerformGarbageCollection( 1057 bool Heap::PerformGarbageCollection(
1057 GarbageCollector collector, 1058 GarbageCollector collector,
1058 GCTracer* tracer,
1059 const v8::GCCallbackFlags gc_callback_flags) { 1059 const v8::GCCallbackFlags gc_callback_flags) {
1060 int freed_global_handles = 0; 1060 int freed_global_handles = 0;
1061 1061
1062 if (collector != SCAVENGER) { 1062 if (collector != SCAVENGER) {
1063 PROFILE(isolate_, CodeMovingGCEvent()); 1063 PROFILE(isolate_, CodeMovingGCEvent());
1064 } 1064 }
1065 1065
1066 #ifdef VERIFY_HEAP 1066 #ifdef VERIFY_HEAP
1067 if (FLAG_verify_heap) { 1067 if (FLAG_verify_heap) {
1068 VerifyStringTable(this); 1068 VerifyStringTable(this);
1069 } 1069 }
1070 #endif 1070 #endif
1071 1071
1072 GCType gc_type = 1072 GCType gc_type =
1073 collector == MARK_COMPACTOR ? kGCTypeMarkSweepCompact : kGCTypeScavenge; 1073 collector == MARK_COMPACTOR ? kGCTypeMarkSweepCompact : kGCTypeScavenge;
1074 1074
1075 { GCCallbacksScope scope(this); 1075 { GCCallbacksScope scope(this);
1076 if (scope.CheckReenter()) { 1076 if (scope.CheckReenter()) {
1077 AllowHeapAllocation allow_allocation; 1077 AllowHeapAllocation allow_allocation;
1078 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); 1078 GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL);
1079 VMState<EXTERNAL> state(isolate_); 1079 VMState<EXTERNAL> state(isolate_);
1080 HandleScope handle_scope(isolate_); 1080 HandleScope handle_scope(isolate_);
1081 CallGCPrologueCallbacks(gc_type, kNoGCCallbackFlags); 1081 CallGCPrologueCallbacks(gc_type, kNoGCCallbackFlags);
1082 } 1082 }
1083 } 1083 }
1084 1084
1085 EnsureFromSpaceIsCommitted(); 1085 EnsureFromSpaceIsCommitted();
1086 1086
1087 int start_new_space_size = Heap::new_space()->SizeAsInt(); 1087 int start_new_space_size = Heap::new_space()->SizeAsInt();
1088 1088
1089 if (IsHighSurvivalRate()) { 1089 if (IsHighSurvivalRate()) {
1090 // We speed up the incremental marker if it is running so that it 1090 // We speed up the incremental marker if it is running so that it
1091 // does not fall behind the rate of promotion, which would cause a 1091 // does not fall behind the rate of promotion, which would cause a
1092 // constantly growing old space. 1092 // constantly growing old space.
1093 incremental_marking()->NotifyOfHighPromotionRate(); 1093 incremental_marking()->NotifyOfHighPromotionRate();
1094 } 1094 }
1095 1095
1096 if (collector == MARK_COMPACTOR) { 1096 if (collector == MARK_COMPACTOR) {
1097 // Perform mark-sweep with optional compaction. 1097 // Perform mark-sweep with optional compaction.
1098 MarkCompact(tracer); 1098 MarkCompact();
1099 sweep_generation_++; 1099 sweep_generation_++;
1100 // Temporarily set the limit for case when PostGarbageCollectionProcessing 1100 // Temporarily set the limit for case when PostGarbageCollectionProcessing
1101 // allocates and triggers GC. The real limit is set at after 1101 // allocates and triggers GC. The real limit is set at after
1102 // PostGarbageCollectionProcessing. 1102 // PostGarbageCollectionProcessing.
1103 old_generation_allocation_limit_ = 1103 old_generation_allocation_limit_ =
1104 OldGenerationAllocationLimit(PromotedSpaceSizeOfObjects(), 0); 1104 OldGenerationAllocationLimit(PromotedSpaceSizeOfObjects(), 0);
1105 old_gen_exhausted_ = false; 1105 old_gen_exhausted_ = false;
1106 } else { 1106 } else {
1107 tracer_ = tracer;
1108 Scavenge(); 1107 Scavenge();
1109 tracer_ = NULL;
1110 } 1108 }
1111 1109
1112 UpdateSurvivalStatistics(start_new_space_size); 1110 UpdateSurvivalStatistics(start_new_space_size);
1113 1111
1114 isolate_->counters()->objs_since_last_young()->Set(0); 1112 isolate_->counters()->objs_since_last_young()->Set(0);
1115 1113
1116 // Callbacks that fire after this point might trigger nested GCs and 1114 // Callbacks that fire after this point might trigger nested GCs and
1117 // restart incremental marking, the assertion can't be moved down. 1115 // restart incremental marking, the assertion can't be moved down.
1118 ASSERT(collector == SCAVENGER || incremental_marking()->IsStopped()); 1116 ASSERT(collector == SCAVENGER || incremental_marking()->IsStopped());
1119 1117
1120 gc_post_processing_depth_++; 1118 gc_post_processing_depth_++;
1121 { AllowHeapAllocation allow_allocation; 1119 { AllowHeapAllocation allow_allocation;
1122 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); 1120 GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL);
1123 freed_global_handles = 1121 freed_global_handles =
1124 isolate_->global_handles()->PostGarbageCollectionProcessing( 1122 isolate_->global_handles()->PostGarbageCollectionProcessing(
1125 collector, tracer); 1123 collector);
1126 } 1124 }
1127 gc_post_processing_depth_--; 1125 gc_post_processing_depth_--;
1128 1126
1129 isolate_->eternal_handles()->PostGarbageCollectionProcessing(this); 1127 isolate_->eternal_handles()->PostGarbageCollectionProcessing(this);
1130 1128
1131 // Update relocatables. 1129 // Update relocatables.
1132 Relocatable::PostGarbageCollectionProcessing(isolate_); 1130 Relocatable::PostGarbageCollectionProcessing(isolate_);
1133 1131
1134 if (collector == MARK_COMPACTOR) { 1132 if (collector == MARK_COMPACTOR) {
1135 // Register the amount of external allocated memory. 1133 // Register the amount of external allocated memory.
1136 amount_of_external_allocated_memory_at_last_global_gc_ = 1134 amount_of_external_allocated_memory_at_last_global_gc_ =
1137 amount_of_external_allocated_memory_; 1135 amount_of_external_allocated_memory_;
1138 old_generation_allocation_limit_ = 1136 old_generation_allocation_limit_ =
1139 OldGenerationAllocationLimit(PromotedSpaceSizeOfObjects(), 1137 OldGenerationAllocationLimit(PromotedSpaceSizeOfObjects(),
1140 freed_global_handles); 1138 freed_global_handles);
1141 } 1139 }
1142 1140
1143 { GCCallbacksScope scope(this); 1141 { GCCallbacksScope scope(this);
1144 if (scope.CheckReenter()) { 1142 if (scope.CheckReenter()) {
1145 AllowHeapAllocation allow_allocation; 1143 AllowHeapAllocation allow_allocation;
1146 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); 1144 GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL);
1147 VMState<EXTERNAL> state(isolate_); 1145 VMState<EXTERNAL> state(isolate_);
1148 HandleScope handle_scope(isolate_); 1146 HandleScope handle_scope(isolate_);
1149 CallGCEpilogueCallbacks(gc_type, gc_callback_flags); 1147 CallGCEpilogueCallbacks(gc_type, gc_callback_flags);
1150 } 1148 }
1151 } 1149 }
1152 1150
1153 #ifdef VERIFY_HEAP 1151 #ifdef VERIFY_HEAP
1154 if (FLAG_verify_heap) { 1152 if (FLAG_verify_heap) {
1155 VerifyStringTable(this); 1153 VerifyStringTable(this);
1156 } 1154 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1189 } else { 1187 } else {
1190 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate()); 1188 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate());
1191 gc_epilogue_callbacks_[i].callback( 1189 gc_epilogue_callbacks_[i].callback(
1192 isolate, gc_type, gc_callback_flags); 1190 isolate, gc_type, gc_callback_flags);
1193 } 1191 }
1194 } 1192 }
1195 } 1193 }
1196 } 1194 }
1197 1195
1198 1196
1199 void Heap::MarkCompact(GCTracer* tracer) { 1197 void Heap::MarkCompact() {
1200 gc_state_ = MARK_COMPACT; 1198 gc_state_ = MARK_COMPACT;
1201 LOG(isolate_, ResourceEvent("markcompact", "begin")); 1199 LOG(isolate_, ResourceEvent("markcompact", "begin"));
1202 1200
1203 uint64_t size_of_objects_before_gc = SizeOfObjects(); 1201 uint64_t size_of_objects_before_gc = SizeOfObjects();
1204 1202
1205 mark_compact_collector_.Prepare(tracer); 1203 mark_compact_collector_.Prepare();
1206 1204
1207 ms_count_++; 1205 ms_count_++;
1208 tracer->set_full_gc_count(ms_count_); 1206 tracer()->set_full_gc_count(ms_count_);
1209 1207
1210 MarkCompactPrologue(); 1208 MarkCompactPrologue();
1211 1209
1212 mark_compact_collector_.CollectGarbage(); 1210 mark_compact_collector_.CollectGarbage();
1213 1211
1214 LOG(isolate_, ResourceEvent("markcompact", "end")); 1212 LOG(isolate_, ResourceEvent("markcompact", "end"));
1215 1213
1216 gc_state_ = NOT_IN_GC; 1214 gc_state_ = NOT_IN_GC;
1217 1215
1218 isolate_->counters()->objs_since_last_full()->Set(0); 1216 isolate_->counters()->objs_since_last_full()->Set(0);
(...skipping 4735 matching lines...) Expand 10 before | Expand all | Expand 10 after
5954 OldSpaces spaces(heap); 5952 OldSpaces spaces(heap);
5955 for (OldSpace* space = spaces.next(); 5953 for (OldSpace* space = spaces.next();
5956 space != NULL; 5954 space != NULL;
5957 space = spaces.next()) { 5955 space = spaces.next()) {
5958 holes_size += space->Waste() + space->Available(); 5956 holes_size += space->Waste() + space->Available();
5959 } 5957 }
5960 return holes_size; 5958 return holes_size;
5961 } 5959 }
5962 5960
5963 5961
5964 GCTracer::GCTracer(Heap* heap, 5962 GCTracer::GCTracer(Heap* heap)
5965 const char* gc_reason,
5966 const char* collector_reason)
5967 : start_time_(0.0), 5963 : start_time_(0.0),
5968 start_object_size_(0), 5964 start_object_size_(0),
5969 start_memory_size_(0), 5965 start_memory_size_(0),
5970 gc_count_(0), 5966 gc_count_(0),
5971 full_gc_count_(0), 5967 full_gc_count_(0),
5968 in_free_list_or_wasted_before_gc_(0),
5972 allocated_since_last_gc_(0), 5969 allocated_since_last_gc_(0),
5973 spent_in_mutator_(0), 5970 spent_in_mutator_(0),
5974 nodes_died_in_new_space_(0), 5971 nodes_died_in_new_space_(0),
5975 nodes_copied_in_new_space_(0), 5972 nodes_copied_in_new_space_(0),
5976 nodes_promoted_(0), 5973 nodes_promoted_(0),
5974 steps_count_(0),
5975 steps_took_(0.0),
5976 longest_step_(0.0),
5977 steps_count_since_last_gc_(0),
5978 steps_took_since_last_gc_(0.0),
5977 heap_(heap), 5979 heap_(heap),
5978 gc_reason_(gc_reason), 5980 gc_reason_(NULL),
5979 collector_reason_(collector_reason) { 5981 collector_reason_(NULL) {
5980 if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return; 5982
5983 for (int i = 0; i < Scope::kNumberOfScopes; i++) {
5984 scopes_[i] = 0;
5985 }
5986 }
5987
5988
5989 GCTracer::~GCTracer() {
5990 }
5991
5992
5993 void GCTracer::start(const char* gc_reason, const char* collector_reason) {
5994 if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat)
5995 return;
5996
5997 gc_count_ = 0;
5998 full_gc_count_ = 0;
5999 spent_in_mutator_ = 0;
6000 nodes_died_in_new_space_ = 0;
6001 nodes_copied_in_new_space_ = 0;
6002 nodes_promoted_ = 0;
6003 gc_reason_ = gc_reason;
6004 collector_reason_ = collector_reason;
6005
5981 start_time_ = base::OS::TimeCurrentMillis(); 6006 start_time_ = base::OS::TimeCurrentMillis();
5982 start_object_size_ = heap_->SizeOfObjects(); 6007 start_object_size_ = heap_->SizeOfObjects();
5983 start_memory_size_ = heap_->isolate()->memory_allocator()->Size(); 6008 start_memory_size_ = heap_->isolate()->memory_allocator()->Size();
5984 6009
5985 for (int i = 0; i < Scope::kNumberOfScopes; i++) { 6010 for (int i = 0; i < Scope::kNumberOfScopes; i++) {
5986 scopes_[i] = 0; 6011 scopes_[i] = 0;
5987 } 6012 }
5988 6013
5989 in_free_list_or_wasted_before_gc_ = CountTotalHolesSize(heap); 6014 in_free_list_or_wasted_before_gc_ = CountTotalHolesSize(heap_);
5990 6015
5991 allocated_since_last_gc_ = 6016 allocated_since_last_gc_ =
5992 heap_->SizeOfObjects() - heap_->alive_after_last_gc_; 6017 heap_->SizeOfObjects() - heap_->alive_after_last_gc_;
5993 6018
5994 if (heap_->last_gc_end_timestamp_ > 0) { 6019 if (heap_->last_gc_end_timestamp_ > 0) {
5995 spent_in_mutator_ = Max(start_time_ - heap_->last_gc_end_timestamp_, 0.0); 6020 spent_in_mutator_ = Max(start_time_ - heap_->last_gc_end_timestamp_, 0.0);
5996 } 6021 }
5997
5998 steps_count_ = heap_->incremental_marking()->steps_count();
5999 steps_took_ = heap_->incremental_marking()->steps_took();
6000 longest_step_ = heap_->incremental_marking()->longest_step();
6001 steps_count_since_last_gc_ =
6002 heap_->incremental_marking()->steps_count_since_last_gc();
6003 steps_took_since_last_gc_ =
6004 heap_->incremental_marking()->steps_took_since_last_gc();
6005 } 6022 }
6006 6023
6007 6024
6008 GCTracer::~GCTracer() { 6025 void GCTracer::stop() {
6009 // Printf ONE line iff flag is set. 6026 // Printf ONE line iff flag is set.
6010 if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return; 6027 if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return;
6011 6028
6012 bool first_gc = (heap_->last_gc_end_timestamp_ == 0); 6029 bool first_gc = (heap_->last_gc_end_timestamp_ == 0);
6013 6030
6014 heap_->alive_after_last_gc_ = heap_->SizeOfObjects(); 6031 heap_->alive_after_last_gc_ = heap_->SizeOfObjects();
6015 heap_->last_gc_end_timestamp_ = base::OS::TimeCurrentMillis(); 6032 heap_->last_gc_end_timestamp_ = base::OS::TimeCurrentMillis();
6016 6033
6017 double time = heap_->last_gc_end_timestamp_ - start_time_; 6034 double time = heap_->last_gc_end_timestamp_ - start_time_;
6018 6035
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
6415 static_cast<int>(object_sizes_last_time_[index])); 6432 static_cast<int>(object_sizes_last_time_[index]));
6416 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) 6433 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT)
6417 #undef ADJUST_LAST_TIME_OBJECT_COUNT 6434 #undef ADJUST_LAST_TIME_OBJECT_COUNT
6418 6435
6419 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 6436 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
6420 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 6437 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
6421 ClearObjectStats(); 6438 ClearObjectStats();
6422 } 6439 }
6423 6440
6424 } } // namespace v8::internal 6441 } } // namespace v8::internal
OLDNEW
« src/heap.h ('K') | « src/heap.h ('k') | src/incremental-marking.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698