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

Side by Side Diff: src/heap/heap.cc

Issue 1247723003: Remove high promotion mode (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 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
« no previous file with comments | « src/heap/heap.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/bits.h" 9 #include "src/base/bits.h"
10 #include "src/base/once.h" 10 #include "src/base/once.h"
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 allocation_timeout_(0), 108 allocation_timeout_(0),
109 #endif // DEBUG 109 #endif // DEBUG
110 old_generation_allocation_limit_(initial_old_generation_size_), 110 old_generation_allocation_limit_(initial_old_generation_size_),
111 old_gen_exhausted_(false), 111 old_gen_exhausted_(false),
112 inline_allocation_disabled_(false), 112 inline_allocation_disabled_(false),
113 store_buffer_rebuilder_(store_buffer()), 113 store_buffer_rebuilder_(store_buffer()),
114 hidden_string_(NULL), 114 hidden_string_(NULL),
115 gc_safe_size_of_old_object_(NULL), 115 gc_safe_size_of_old_object_(NULL),
116 total_regexp_code_generated_(0), 116 total_regexp_code_generated_(0),
117 tracer_(this), 117 tracer_(this),
118 new_space_high_promotion_mode_active_(false),
119 gathering_lifetime_feedback_(0),
120 high_survival_rate_period_length_(0), 118 high_survival_rate_period_length_(0),
121 promoted_objects_size_(0), 119 promoted_objects_size_(0),
122 low_survival_rate_period_length_(0),
123 survival_rate_(0),
124 promotion_ratio_(0), 120 promotion_ratio_(0),
125 semi_space_copied_object_size_(0), 121 semi_space_copied_object_size_(0),
126 previous_semi_space_copied_object_size_(0), 122 previous_semi_space_copied_object_size_(0),
127 semi_space_copied_rate_(0), 123 semi_space_copied_rate_(0),
128 nodes_died_in_new_space_(0), 124 nodes_died_in_new_space_(0),
129 nodes_copied_in_new_space_(0), 125 nodes_copied_in_new_space_(0),
130 nodes_promoted_(0), 126 nodes_promoted_(0),
131 maximum_size_scavenges_(0), 127 maximum_size_scavenges_(0),
132 previous_survival_rate_trend_(Heap::STABLE),
133 survival_rate_trend_(Heap::STABLE),
134 max_gc_pause_(0.0), 128 max_gc_pause_(0.0),
135 total_gc_time_ms_(0.0), 129 total_gc_time_ms_(0.0),
136 max_alive_after_gc_(0), 130 max_alive_after_gc_(0),
137 min_in_mutator_(kMaxInt), 131 min_in_mutator_(kMaxInt),
138 marking_time_(0.0), 132 marking_time_(0.0),
139 sweeping_time_(0.0), 133 sweeping_time_(0.0),
140 last_idle_notification_time_(0.0), 134 last_idle_notification_time_(0.0),
141 last_gc_time_(0.0), 135 last_gc_time_(0.0),
142 mark_compact_collector_(this), 136 mark_compact_collector_(this),
143 store_buffer_(this), 137 store_buffer_(this),
(...skipping 1049 matching lines...) Expand 10 before | Expand all | Expand 10 after
1193 (static_cast<double>(semi_space_copied_object_size_) / 1187 (static_cast<double>(semi_space_copied_object_size_) /
1194 static_cast<double>(start_new_space_size) * 100); 1188 static_cast<double>(start_new_space_size) * 100);
1195 1189
1196 double survival_rate = promotion_ratio_ + semi_space_copied_rate_; 1190 double survival_rate = promotion_ratio_ + semi_space_copied_rate_;
1197 tracer()->AddSurvivalRatio(survival_rate); 1191 tracer()->AddSurvivalRatio(survival_rate);
1198 if (survival_rate > kYoungSurvivalRateHighThreshold) { 1192 if (survival_rate > kYoungSurvivalRateHighThreshold) {
1199 high_survival_rate_period_length_++; 1193 high_survival_rate_period_length_++;
1200 } else { 1194 } else {
1201 high_survival_rate_period_length_ = 0; 1195 high_survival_rate_period_length_ = 0;
1202 } 1196 }
1203
1204 if (survival_rate < kYoungSurvivalRateLowThreshold) {
1205 low_survival_rate_period_length_++;
1206 } else {
1207 low_survival_rate_period_length_ = 0;
1208 }
1209
1210 double survival_rate_diff = survival_rate_ - survival_rate;
1211
1212 if (survival_rate_diff > kYoungSurvivalRateAllowedDeviation) {
1213 set_survival_rate_trend(DECREASING);
1214 } else if (survival_rate_diff < -kYoungSurvivalRateAllowedDeviation) {
1215 set_survival_rate_trend(INCREASING);
1216 } else {
1217 set_survival_rate_trend(STABLE);
1218 }
1219
1220 survival_rate_ = survival_rate;
1221 } 1197 }
1222 1198
1223 bool Heap::PerformGarbageCollection( 1199 bool Heap::PerformGarbageCollection(
1224 GarbageCollector collector, const v8::GCCallbackFlags gc_callback_flags) { 1200 GarbageCollector collector, const v8::GCCallbackFlags gc_callback_flags) {
1225 int freed_global_handles = 0; 1201 int freed_global_handles = 0;
1226 1202
1227 if (collector != SCAVENGER) { 1203 if (collector != SCAVENGER) {
1228 PROFILE(isolate_, CodeMovingGCEvent()); 1204 PROFILE(isolate_, CodeMovingGCEvent());
1229 } 1205 }
1230 1206
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1268 old_generation_size_configured_ = true; 1244 old_generation_size_configured_ = true;
1269 // This should be updated before PostGarbageCollectionProcessing, which can 1245 // This should be updated before PostGarbageCollectionProcessing, which can
1270 // cause another GC. Take into account the objects promoted during GC. 1246 // cause another GC. Take into account the objects promoted during GC.
1271 old_generation_allocation_counter_ += 1247 old_generation_allocation_counter_ +=
1272 static_cast<size_t>(promoted_objects_size_); 1248 static_cast<size_t>(promoted_objects_size_);
1273 old_generation_size_at_last_gc_ = PromotedSpaceSizeOfObjects(); 1249 old_generation_size_at_last_gc_ = PromotedSpaceSizeOfObjects();
1274 } else { 1250 } else {
1275 Scavenge(); 1251 Scavenge();
1276 } 1252 }
1277 1253
1278 bool deopted = ProcessPretenuringFeedback(); 1254 ProcessPretenuringFeedback();
1279 UpdateSurvivalStatistics(start_new_space_size); 1255 UpdateSurvivalStatistics(start_new_space_size);
1280
1281 // When pretenuring is collecting new feedback, we do not shrink the new space
1282 // right away.
1283 if (deopted) {
1284 RecordDeoptForPretenuring();
1285 } else {
1286 ConfigureNewGenerationSize();
1287 }
1288 ConfigureInitialOldGenerationSize(); 1256 ConfigureInitialOldGenerationSize();
1289 1257
1290 isolate_->counters()->objs_since_last_young()->Set(0); 1258 isolate_->counters()->objs_since_last_young()->Set(0);
1291 1259
1292 if (collector != SCAVENGER) { 1260 if (collector != SCAVENGER) {
1293 // Callbacks that fire after this point might trigger nested GCs and 1261 // Callbacks that fire after this point might trigger nested GCs and
1294 // restart incremental marking, the assertion can't be moved down. 1262 // restart incremental marking, the assertion can't be moved down.
1295 DCHECK(incremental_marking()->IsStopped()); 1263 DCHECK(incremental_marking()->IsStopped());
1296 1264
1297 // We finished a marking cycle. We can uncommit the marking deque until 1265 // We finished a marking cycle. We can uncommit the marking deque until
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
1502 void Heap::CheckNewSpaceExpansionCriteria() { 1470 void Heap::CheckNewSpaceExpansionCriteria() {
1503 if (FLAG_experimental_new_space_growth_heuristic) { 1471 if (FLAG_experimental_new_space_growth_heuristic) {
1504 if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() && 1472 if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() &&
1505 survived_last_scavenge_ * 100 / new_space_.TotalCapacity() >= 10) { 1473 survived_last_scavenge_ * 100 / new_space_.TotalCapacity() >= 10) {
1506 // Grow the size of new space if there is room to grow, and more than 10% 1474 // Grow the size of new space if there is room to grow, and more than 10%
1507 // have survived the last scavenge. 1475 // have survived the last scavenge.
1508 new_space_.Grow(); 1476 new_space_.Grow();
1509 survived_since_last_expansion_ = 0; 1477 survived_since_last_expansion_ = 0;
1510 } 1478 }
1511 } else if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() && 1479 } else if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() &&
1512 survived_since_last_expansion_ > new_space_.TotalCapacity() && 1480 survived_since_last_expansion_ > new_space_.TotalCapacity()) {
1513 !new_space_high_promotion_mode_active_) {
1514 // Grow the size of new space if there is room to grow, and enough data 1481 // Grow the size of new space if there is room to grow, and enough data
1515 // has survived scavenge since the last expansion. 1482 // has survived scavenge since the last expansion.
1516 new_space_.Grow(); 1483 new_space_.Grow();
1517 survived_since_last_expansion_ = 0; 1484 survived_since_last_expansion_ = 0;
1518 } 1485 }
1519 } 1486 }
1520 1487
1521 1488
1522 static bool IsUnscavengedHeapObject(Heap* heap, Object** p) { 1489 static bool IsUnscavengedHeapObject(Heap* heap, Object** p) {
1523 return heap->InNewSpace(*p) && 1490 return heap->InNewSpace(*p) &&
(...skipping 1133 matching lines...) Expand 10 before | Expand all | Expand 10 after
2657 if (!old_generation_size_configured_ && tracer()->SurvivalEventsRecorded()) { 2624 if (!old_generation_size_configured_ && tracer()->SurvivalEventsRecorded()) {
2658 old_generation_allocation_limit_ = 2625 old_generation_allocation_limit_ =
2659 Max(kMinimumOldGenerationAllocationLimit, 2626 Max(kMinimumOldGenerationAllocationLimit,
2660 static_cast<intptr_t>( 2627 static_cast<intptr_t>(
2661 static_cast<double>(old_generation_allocation_limit_) * 2628 static_cast<double>(old_generation_allocation_limit_) *
2662 (tracer()->AverageSurvivalRatio() / 100))); 2629 (tracer()->AverageSurvivalRatio() / 100)));
2663 } 2630 }
2664 } 2631 }
2665 2632
2666 2633
2667 void Heap::ConfigureNewGenerationSize() {
2668 bool still_gathering_lifetime_data = gathering_lifetime_feedback_ != 0;
2669 if (gathering_lifetime_feedback_ != 0) gathering_lifetime_feedback_--;
2670 if (!new_space_high_promotion_mode_active_ &&
2671 new_space_.TotalCapacity() == new_space_.MaximumCapacity() &&
2672 IsStableOrIncreasingSurvivalTrend() && IsHighSurvivalRate()) {
2673 // Stable high survival rates even though young generation is at
2674 // maximum capacity indicates that most objects will be promoted.
2675 // To decrease scavenger pauses and final mark-sweep pauses, we
2676 // have to limit maximal capacity of the young generation.
2677 if (still_gathering_lifetime_data) {
2678 if (FLAG_trace_gc) {
2679 PrintPID(
2680 "Postpone entering high promotion mode as optimized pretenuring "
2681 "code is still being generated\n");
2682 }
2683 } else {
2684 new_space_high_promotion_mode_active_ = true;
2685 if (FLAG_trace_gc) {
2686 PrintPID("Limited new space size due to high promotion rate: %d MB\n",
2687 new_space_.InitialTotalCapacity() / MB);
2688 }
2689 }
2690 } else if (new_space_high_promotion_mode_active_ &&
2691 IsStableOrDecreasingSurvivalTrend() && IsLowSurvivalRate()) {
2692 // Decreasing low survival rates might indicate that the above high
2693 // promotion mode is over and we should allow the young generation
2694 // to grow again.
2695 new_space_high_promotion_mode_active_ = false;
2696 if (FLAG_trace_gc) {
2697 PrintPID("Unlimited new space size due to low promotion rate: %d MB\n",
2698 new_space_.MaximumCapacity() / MB);
2699 }
2700 }
2701
2702 if (new_space_high_promotion_mode_active_ &&
2703 new_space_.TotalCapacity() > new_space_.InitialTotalCapacity()) {
2704 new_space_.Shrink();
2705 }
2706 }
2707
2708
2709 AllocationResult Heap::AllocatePartialMap(InstanceType instance_type, 2634 AllocationResult Heap::AllocatePartialMap(InstanceType instance_type,
2710 int instance_size) { 2635 int instance_size) {
2711 Object* result = nullptr; 2636 Object* result = nullptr;
2712 AllocationResult allocation = AllocateRaw(Map::kSize, MAP_SPACE, MAP_SPACE); 2637 AllocationResult allocation = AllocateRaw(Map::kSize, MAP_SPACE, MAP_SPACE);
2713 if (!allocation.To(&result)) return allocation; 2638 if (!allocation.To(&result)) return allocation;
2714 2639
2715 // Map::cast cannot be used due to uninitialized map field. 2640 // Map::cast cannot be used due to uninitialized map field.
2716 reinterpret_cast<Map*>(result)->set_map(raw_unchecked_meta_map()); 2641 reinterpret_cast<Map*>(result)->set_map(raw_unchecked_meta_map());
2717 reinterpret_cast<Map*>(result)->set_instance_type(instance_type); 2642 reinterpret_cast<Map*>(result)->set_instance_type(instance_type);
2718 reinterpret_cast<Map*>(result)->set_instance_size(instance_size); 2643 reinterpret_cast<Map*>(result)->set_instance_size(instance_size);
(...skipping 4168 matching lines...) Expand 10 before | Expand all | Expand 10 after
6887 *object_type = "CODE_TYPE"; \ 6812 *object_type = "CODE_TYPE"; \
6888 *object_sub_type = "CODE_AGE/" #name; \ 6813 *object_sub_type = "CODE_AGE/" #name; \
6889 return true; 6814 return true;
6890 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) 6815 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME)
6891 #undef COMPARE_AND_RETURN_NAME 6816 #undef COMPARE_AND_RETURN_NAME
6892 } 6817 }
6893 return false; 6818 return false;
6894 } 6819 }
6895 } // namespace internal 6820 } // namespace internal
6896 } // namespace v8 6821 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/heap.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698