| 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 "v8.h" |     5 #include "v8.h" | 
|     6  |     6  | 
|     7 #include "accessors.h" |     7 #include "accessors.h" | 
|     8 #include "api.h" |     8 #include "api.h" | 
|     9 #include "bootstrapper.h" |     9 #include "bootstrapper.h" | 
|    10 #include "codegen.h" |    10 #include "codegen.h" | 
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|    77       lo_space_(NULL), |    77       lo_space_(NULL), | 
|    78       gc_state_(NOT_IN_GC), |    78       gc_state_(NOT_IN_GC), | 
|    79       gc_post_processing_depth_(0), |    79       gc_post_processing_depth_(0), | 
|    80       ms_count_(0), |    80       ms_count_(0), | 
|    81       gc_count_(0), |    81       gc_count_(0), | 
|    82       remembered_unmapped_pages_index_(0), |    82       remembered_unmapped_pages_index_(0), | 
|    83       unflattened_strings_length_(0), |    83       unflattened_strings_length_(0), | 
|    84 #ifdef DEBUG |    84 #ifdef DEBUG | 
|    85       allocation_timeout_(0), |    85       allocation_timeout_(0), | 
|    86 #endif  // DEBUG |    86 #endif  // DEBUG | 
|    87       new_space_high_promotion_mode_active_(false), |  | 
|    88       old_generation_allocation_limit_(kMinimumOldGenerationAllocationLimit), |    87       old_generation_allocation_limit_(kMinimumOldGenerationAllocationLimit), | 
|    89       size_of_old_gen_at_last_old_space_gc_(0), |    88       size_of_old_gen_at_last_old_space_gc_(0), | 
|    90       external_allocation_limit_(0), |    89       external_allocation_limit_(0), | 
|    91       amount_of_external_allocated_memory_(0), |    90       amount_of_external_allocated_memory_(0), | 
|    92       amount_of_external_allocated_memory_at_last_global_gc_(0), |    91       amount_of_external_allocated_memory_at_last_global_gc_(0), | 
|    93       old_gen_exhausted_(false), |    92       old_gen_exhausted_(false), | 
|    94       inline_allocation_disabled_(false), |    93       inline_allocation_disabled_(false), | 
|    95       store_buffer_rebuilder_(store_buffer()), |    94       store_buffer_rebuilder_(store_buffer()), | 
|    96       hidden_string_(NULL), |    95       hidden_string_(NULL), | 
|    97       gc_safe_size_of_old_object_(NULL), |    96       gc_safe_size_of_old_object_(NULL), | 
|    98       total_regexp_code_generated_(0), |    97       total_regexp_code_generated_(0), | 
|    99       tracer_(NULL), |    98       tracer_(NULL), | 
|   100       high_survival_rate_period_length_(0), |    99       high_survival_rate_period_length_(0), | 
|   101       low_survival_rate_period_length_(0), |  | 
|   102       survival_rate_(0), |  | 
|   103       promoted_objects_size_(0), |   100       promoted_objects_size_(0), | 
|   104       promotion_rate_(0), |   101       promotion_rate_(0), | 
|   105       semi_space_copied_object_size_(0), |   102       semi_space_copied_object_size_(0), | 
|   106       semi_space_copied_rate_(0), |   103       semi_space_copied_rate_(0), | 
|   107       previous_survival_rate_trend_(Heap::STABLE), |  | 
|   108       survival_rate_trend_(Heap::STABLE), |  | 
|   109       max_gc_pause_(0.0), |   104       max_gc_pause_(0.0), | 
|   110       total_gc_time_ms_(0.0), |   105       total_gc_time_ms_(0.0), | 
|   111       max_alive_after_gc_(0), |   106       max_alive_after_gc_(0), | 
|   112       min_in_mutator_(kMaxInt), |   107       min_in_mutator_(kMaxInt), | 
|   113       alive_after_last_gc_(0), |   108       alive_after_last_gc_(0), | 
|   114       last_gc_end_timestamp_(0.0), |   109       last_gc_end_timestamp_(0.0), | 
|   115       marking_time_(0.0), |   110       marking_time_(0.0), | 
|   116       sweeping_time_(0.0), |   111       sweeping_time_(0.0), | 
|   117       mark_compact_collector_(this), |   112       mark_compact_collector_(this), | 
|   118       store_buffer_(this), |   113       store_buffer_(this), | 
| (...skipping 887 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1006     Object* cache = |  1001     Object* cache = | 
|  1007         Context::cast(context)->get(Context::NORMALIZED_MAP_CACHE_INDEX); |  1002         Context::cast(context)->get(Context::NORMALIZED_MAP_CACHE_INDEX); | 
|  1008     if (!cache->IsUndefined()) { |  1003     if (!cache->IsUndefined()) { | 
|  1009       NormalizedMapCache::cast(cache)->Clear(); |  1004       NormalizedMapCache::cast(cache)->Clear(); | 
|  1010     } |  1005     } | 
|  1011     context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK); |  1006     context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK); | 
|  1012   } |  1007   } | 
|  1013 } |  1008 } | 
|  1014  |  1009  | 
|  1015  |  1010  | 
|  1016 void Heap::UpdateSurvivalRateTrend(int start_new_space_size) { |  1011 void Heap::UpdateSurvivalStatistics(int start_new_space_size) { | 
|  1017   if (start_new_space_size == 0) return; |  1012   if (start_new_space_size == 0) return; | 
|  1018  |  1013  | 
|  1019   promotion_rate_ = |  1014   promotion_rate_ = | 
|  1020         (static_cast<double>(promoted_objects_size_) / |  1015         (static_cast<double>(promoted_objects_size_) / | 
|  1021             static_cast<double>(start_new_space_size) * 100); |  1016             static_cast<double>(start_new_space_size) * 100); | 
|  1022  |  1017  | 
|  1023   semi_space_copied_rate_ = |  1018   semi_space_copied_rate_ = | 
|  1024         (static_cast<double>(semi_space_copied_object_size_) / |  1019         (static_cast<double>(semi_space_copied_object_size_) / | 
|  1025             static_cast<double>(start_new_space_size) * 100); |  1020             static_cast<double>(start_new_space_size) * 100); | 
|  1026  |  1021  | 
|  1027   double survival_rate = promotion_rate_ + semi_space_copied_rate_; |  1022   double survival_rate = promotion_rate_ + semi_space_copied_rate_; | 
|  1028  |  1023  | 
|  1029   if (survival_rate > kYoungSurvivalRateHighThreshold) { |  1024   if (survival_rate > kYoungSurvivalRateHighThreshold) { | 
|  1030     high_survival_rate_period_length_++; |  1025     high_survival_rate_period_length_++; | 
|  1031   } else { |  1026   } else { | 
|  1032     high_survival_rate_period_length_ = 0; |  1027     high_survival_rate_period_length_ = 0; | 
|  1033   } |  1028   } | 
|  1034  |  | 
|  1035   if (survival_rate < kYoungSurvivalRateLowThreshold) { |  | 
|  1036     low_survival_rate_period_length_++; |  | 
|  1037   } else { |  | 
|  1038     low_survival_rate_period_length_ = 0; |  | 
|  1039   } |  | 
|  1040  |  | 
|  1041   double survival_rate_diff = survival_rate_ - survival_rate; |  | 
|  1042  |  | 
|  1043   if (survival_rate_diff > kYoungSurvivalRateAllowedDeviation) { |  | 
|  1044     set_survival_rate_trend(DECREASING); |  | 
|  1045   } else if (survival_rate_diff < -kYoungSurvivalRateAllowedDeviation) { |  | 
|  1046     set_survival_rate_trend(INCREASING); |  | 
|  1047   } else { |  | 
|  1048     set_survival_rate_trend(STABLE); |  | 
|  1049   } |  | 
|  1050  |  | 
|  1051   survival_rate_ = survival_rate; |  | 
|  1052 } |  1029 } | 
|  1053  |  1030  | 
|  1054 bool Heap::PerformGarbageCollection( |  1031 bool Heap::PerformGarbageCollection( | 
|  1055     GarbageCollector collector, |  1032     GarbageCollector collector, | 
|  1056     GCTracer* tracer, |  1033     GCTracer* tracer, | 
|  1057     const v8::GCCallbackFlags gc_callback_flags) { |  1034     const v8::GCCallbackFlags gc_callback_flags) { | 
|  1058   bool next_gc_likely_to_collect_more = false; |  1035   bool next_gc_likely_to_collect_more = false; | 
|  1059  |  1036  | 
|  1060   if (collector != SCAVENGER) { |  1037   if (collector != SCAVENGER) { | 
|  1061     PROFILE(isolate_, CodeMovingGCEvent()); |  1038     PROFILE(isolate_, CodeMovingGCEvent()); | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1101     old_generation_allocation_limit_ = |  1078     old_generation_allocation_limit_ = | 
|  1102         OldGenerationAllocationLimit(size_of_old_gen_at_last_old_space_gc_); |  1079         OldGenerationAllocationLimit(size_of_old_gen_at_last_old_space_gc_); | 
|  1103  |  1080  | 
|  1104     old_gen_exhausted_ = false; |  1081     old_gen_exhausted_ = false; | 
|  1105   } else { |  1082   } else { | 
|  1106     tracer_ = tracer; |  1083     tracer_ = tracer; | 
|  1107     Scavenge(); |  1084     Scavenge(); | 
|  1108     tracer_ = NULL; |  1085     tracer_ = NULL; | 
|  1109   } |  1086   } | 
|  1110  |  1087  | 
|  1111   UpdateSurvivalRateTrend(start_new_space_size); |  1088   UpdateSurvivalStatistics(start_new_space_size); | 
|  1112  |  | 
|  1113   if (!new_space_high_promotion_mode_active_ && |  | 
|  1114       new_space_.Capacity() == new_space_.MaximumCapacity() && |  | 
|  1115       IsStableOrIncreasingSurvivalTrend() && |  | 
|  1116       IsHighSurvivalRate()) { |  | 
|  1117     // Stable high survival rates even though young generation is at |  | 
|  1118     // maximum capacity indicates that most objects will be promoted. |  | 
|  1119     // To decrease scavenger pauses and final mark-sweep pauses, we |  | 
|  1120     // have to limit maximal capacity of the young generation. |  | 
|  1121     SetNewSpaceHighPromotionModeActive(true); |  | 
|  1122     if (FLAG_trace_gc) { |  | 
|  1123       PrintPID("Limited new space size due to high promotion rate: %d MB\n", |  | 
|  1124                new_space_.InitialCapacity() / MB); |  | 
|  1125     } |  | 
|  1126     // The high promotion mode is our indicator to turn on pretenuring. We have |  | 
|  1127     // to deoptimize all optimized code in global pretenuring mode and all |  | 
|  1128     // code which should be tenured in local pretenuring mode. |  | 
|  1129     if (FLAG_pretenuring) { |  | 
|  1130       if (!FLAG_allocation_site_pretenuring) { |  | 
|  1131         isolate_->stack_guard()->RequestFullDeopt(); |  | 
|  1132       } |  | 
|  1133     } |  | 
|  1134   } else if (new_space_high_promotion_mode_active_ && |  | 
|  1135       IsStableOrDecreasingSurvivalTrend() && |  | 
|  1136       IsLowSurvivalRate()) { |  | 
|  1137     // Decreasing low survival rates might indicate that the above high |  | 
|  1138     // promotion mode is over and we should allow the young generation |  | 
|  1139     // to grow again. |  | 
|  1140     SetNewSpaceHighPromotionModeActive(false); |  | 
|  1141     if (FLAG_trace_gc) { |  | 
|  1142       PrintPID("Unlimited new space size due to low promotion rate: %d MB\n", |  | 
|  1143                new_space_.MaximumCapacity() / MB); |  | 
|  1144     } |  | 
|  1145     // Trigger deoptimization here to turn off global pretenuring as soon as |  | 
|  1146     // possible. |  | 
|  1147     if (FLAG_pretenuring && !FLAG_allocation_site_pretenuring) { |  | 
|  1148       isolate_->stack_guard()->RequestFullDeopt(); |  | 
|  1149     } |  | 
|  1150   } |  | 
|  1151  |  | 
|  1152   if (new_space_high_promotion_mode_active_ && |  | 
|  1153       new_space_.Capacity() > new_space_.InitialCapacity()) { |  | 
|  1154     new_space_.Shrink(); |  | 
|  1155   } |  | 
|  1156  |  1089  | 
|  1157   isolate_->counters()->objs_since_last_young()->Set(0); |  1090   isolate_->counters()->objs_since_last_young()->Set(0); | 
|  1158  |  1091  | 
|  1159   // Callbacks that fire after this point might trigger nested GCs and |  1092   // Callbacks that fire after this point might trigger nested GCs and | 
|  1160   // restart incremental marking, the assertion can't be moved down. |  1093   // restart incremental marking, the assertion can't be moved down. | 
|  1161   ASSERT(collector == SCAVENGER || incremental_marking()->IsStopped()); |  1094   ASSERT(collector == SCAVENGER || incremental_marking()->IsStopped()); | 
|  1162  |  1095  | 
|  1163   gc_post_processing_depth_++; |  1096   gc_post_processing_depth_++; | 
|  1164   { AllowHeapAllocation allow_allocation; |  1097   { AllowHeapAllocation allow_allocation; | 
|  1165     GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); |  1098     GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); | 
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1346     for (HeapObject* object = data_it.Next(); |  1279     for (HeapObject* object = data_it.Next(); | 
|  1347          object != NULL; object = data_it.Next()) |  1280          object != NULL; object = data_it.Next()) | 
|  1348       object->Iterate(&v); |  1281       object->Iterate(&v); | 
|  1349   } |  1282   } | 
|  1350 } |  1283 } | 
|  1351 #endif  // VERIFY_HEAP |  1284 #endif  // VERIFY_HEAP | 
|  1352  |  1285  | 
|  1353  |  1286  | 
|  1354 void Heap::CheckNewSpaceExpansionCriteria() { |  1287 void Heap::CheckNewSpaceExpansionCriteria() { | 
|  1355   if (new_space_.Capacity() < new_space_.MaximumCapacity() && |  1288   if (new_space_.Capacity() < new_space_.MaximumCapacity() && | 
|  1356       survived_since_last_expansion_ > new_space_.Capacity() && |  1289       survived_since_last_expansion_ > new_space_.Capacity()) { | 
|  1357       !new_space_high_promotion_mode_active_) { |  | 
|  1358     // Grow the size of new space if there is room to grow, enough data |  1290     // Grow the size of new space if there is room to grow, enough data | 
|  1359     // has survived scavenge since the last expansion and we are not in |  1291     // has survived scavenge since the last expansion and we are not in | 
|  1360     // high promotion mode. |  1292     // high promotion mode. | 
|  1361     new_space_.Grow(); |  1293     new_space_.Grow(); | 
|  1362     survived_since_last_expansion_ = 0; |  1294     survived_since_last_expansion_ = 0; | 
|  1363   } |  1295   } | 
|  1364 } |  1296 } | 
|  1365  |  1297  | 
|  1366  |  1298  | 
|  1367 static bool IsUnscavengedHeapObject(Heap* heap, Object** p) { |  1299 static bool IsUnscavengedHeapObject(Heap* heap, Object** p) { | 
| (...skipping 4828 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  6196            in_free_list_or_wasted_before_gc_); |  6128            in_free_list_or_wasted_before_gc_); | 
|  6197     PrintF("holes_size_after=%" V8_PTR_PREFIX "d ", CountTotalHolesSize(heap_)); |  6129     PrintF("holes_size_after=%" V8_PTR_PREFIX "d ", CountTotalHolesSize(heap_)); | 
|  6198  |  6130  | 
|  6199     PrintF("allocated=%" V8_PTR_PREFIX "d ", allocated_since_last_gc_); |  6131     PrintF("allocated=%" V8_PTR_PREFIX "d ", allocated_since_last_gc_); | 
|  6200     PrintF("promoted=%" V8_PTR_PREFIX "d ", heap_->promoted_objects_size_); |  6132     PrintF("promoted=%" V8_PTR_PREFIX "d ", heap_->promoted_objects_size_); | 
|  6201     PrintF("semi_space_copied=%" V8_PTR_PREFIX "d ", |  6133     PrintF("semi_space_copied=%" V8_PTR_PREFIX "d ", | 
|  6202         heap_->semi_space_copied_object_size_); |  6134         heap_->semi_space_copied_object_size_); | 
|  6203     PrintF("nodes_died_in_new=%d ", nodes_died_in_new_space_); |  6135     PrintF("nodes_died_in_new=%d ", nodes_died_in_new_space_); | 
|  6204     PrintF("nodes_copied_in_new=%d ", nodes_copied_in_new_space_); |  6136     PrintF("nodes_copied_in_new=%d ", nodes_copied_in_new_space_); | 
|  6205     PrintF("nodes_promoted=%d ", nodes_promoted_); |  6137     PrintF("nodes_promoted=%d ", nodes_promoted_); | 
|  6206     PrintF("survival_rate=%.1f%% ", heap_->survival_rate_); |  | 
|  6207     PrintF("promotion_rate=%.1f%% ", heap_->promotion_rate_); |  6138     PrintF("promotion_rate=%.1f%% ", heap_->promotion_rate_); | 
|  6208     PrintF("semi_space_copy_rate=%.1f%% ", heap_->semi_space_copied_rate_); |  6139     PrintF("semi_space_copy_rate=%.1f%% ", heap_->semi_space_copied_rate_); | 
|  6209  |  6140  | 
|  6210     if (collector_ == SCAVENGER) { |  6141     if (collector_ == SCAVENGER) { | 
|  6211       PrintF("stepscount=%d ", steps_count_since_last_gc_); |  6142       PrintF("stepscount=%d ", steps_count_since_last_gc_); | 
|  6212       PrintF("stepstook=%.1f ", steps_took_since_last_gc_); |  6143       PrintF("stepstook=%.1f ", steps_took_since_last_gc_); | 
|  6213     } else { |  6144     } else { | 
|  6214       PrintF("stepscount=%d ", steps_count_); |  6145       PrintF("stepscount=%d ", steps_count_); | 
|  6215       PrintF("stepstook=%.1f ", steps_took_); |  6146       PrintF("stepstook=%.1f ", steps_took_); | 
|  6216       PrintF("longeststep=%.1f ", longest_step_); |  6147       PrintF("longeststep=%.1f ", longest_step_); | 
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  6492       static_cast<int>(object_sizes_last_time_[index])); |  6423       static_cast<int>(object_sizes_last_time_[index])); | 
|  6493   CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) |  6424   CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) | 
|  6494 #undef ADJUST_LAST_TIME_OBJECT_COUNT |  6425 #undef ADJUST_LAST_TIME_OBJECT_COUNT | 
|  6495  |  6426  | 
|  6496   OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); |  6427   OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); | 
|  6497   OS::MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); |  6428   OS::MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); | 
|  6498   ClearObjectStats(); |  6429   ClearObjectStats(); | 
|  6499 } |  6430 } | 
|  6500  |  6431  | 
|  6501 } }  // namespace v8::internal |  6432 } }  // namespace v8::internal | 
| OLD | NEW |