| OLD | NEW | 
|     1 // Copyright 2011 the V8 project authors. All rights reserved. |     1 // Copyright 2011 the V8 project authors. All rights reserved. | 
|     2 // Redistribution and use in source and binary forms, with or without |     2 // Redistribution and use in source and binary forms, with or without | 
|     3 // modification, are permitted provided that the following conditions are |     3 // modification, are permitted provided that the following conditions are | 
|     4 // met: |     4 // met: | 
|     5 // |     5 // | 
|     6 //     * Redistributions of source code must retain the above copyright |     6 //     * Redistributions of source code must retain the above copyright | 
|     7 //       notice, this list of conditions and the following disclaimer. |     7 //       notice, this list of conditions and the following disclaimer. | 
|     8 //     * Redistributions in binary form must reproduce the above |     8 //     * Redistributions in binary form must reproduce the above | 
|     9 //       copyright notice, this list of conditions and the following |     9 //       copyright notice, this list of conditions and the following | 
|    10 //       disclaimer in the documentation and/or other materials provided |    10 //       disclaimer in the documentation and/or other materials provided | 
| (...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   681     context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK); |   681     context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK); | 
|   682   } |   682   } | 
|   683 } |   683 } | 
|   684  |   684  | 
|   685  |   685  | 
|   686 void Heap::UpdateSurvivalRateTrend(int start_new_space_size) { |   686 void Heap::UpdateSurvivalRateTrend(int start_new_space_size) { | 
|   687   double survival_rate = |   687   double survival_rate = | 
|   688       (static_cast<double>(young_survivors_after_last_gc_) * 100) / |   688       (static_cast<double>(young_survivors_after_last_gc_) * 100) / | 
|   689       start_new_space_size; |   689       start_new_space_size; | 
|   690  |   690  | 
|   691   if (survival_rate > kYoungSurvivalRateThreshold) { |   691   if (survival_rate > kYoungSurvivalRateHighThreshold) { | 
|   692     high_survival_rate_period_length_++; |   692     high_survival_rate_period_length_++; | 
|   693   } else { |   693   } else { | 
|   694     high_survival_rate_period_length_ = 0; |   694     high_survival_rate_period_length_ = 0; | 
|   695   } |   695   } | 
|   696  |   696  | 
 |   697   if (survival_rate < kYoungSurvivalRateLowThreshold) { | 
 |   698     low_survival_rate_period_length_++; | 
 |   699   } else { | 
 |   700     low_survival_rate_period_length_ = 0; | 
 |   701   } | 
 |   702  | 
|   697   double survival_rate_diff = survival_rate_ - survival_rate; |   703   double survival_rate_diff = survival_rate_ - survival_rate; | 
|   698  |   704  | 
|   699   if (survival_rate_diff > kYoungSurvivalRateAllowedDeviation) { |   705   if (survival_rate_diff > kYoungSurvivalRateAllowedDeviation) { | 
|   700     set_survival_rate_trend(DECREASING); |   706     set_survival_rate_trend(DECREASING); | 
|   701   } else if (survival_rate_diff < -kYoungSurvivalRateAllowedDeviation) { |   707   } else if (survival_rate_diff < -kYoungSurvivalRateAllowedDeviation) { | 
|   702     set_survival_rate_trend(INCREASING); |   708     set_survival_rate_trend(INCREASING); | 
|   703   } else { |   709   } else { | 
|   704     set_survival_rate_trend(STABLE); |   710     set_survival_rate_trend(STABLE); | 
|   705   } |   711   } | 
|   706  |   712  | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   746  |   752  | 
|   747   if (collector == MARK_COMPACTOR) { |   753   if (collector == MARK_COMPACTOR) { | 
|   748     // Perform mark-sweep with optional compaction. |   754     // Perform mark-sweep with optional compaction. | 
|   749     MarkCompact(tracer); |   755     MarkCompact(tracer); | 
|   750     sweep_generation_++; |   756     sweep_generation_++; | 
|   751     bool high_survival_rate_during_scavenges = IsHighSurvivalRate() && |   757     bool high_survival_rate_during_scavenges = IsHighSurvivalRate() && | 
|   752         IsStableOrIncreasingSurvivalTrend(); |   758         IsStableOrIncreasingSurvivalTrend(); | 
|   753  |   759  | 
|   754     UpdateSurvivalRateTrend(start_new_space_size); |   760     UpdateSurvivalRateTrend(start_new_space_size); | 
|   755  |   761  | 
|   756     if (!new_space_high_promotion_mode_active_ && |  | 
|   757         new_space_.Capacity() == new_space_.MaximumCapacity() && |  | 
|   758         IsStableOrIncreasingSurvivalTrend() && |  | 
|   759         IsHighSurvivalRate()) { |  | 
|   760       // Stable high survival rates even though young generation is at |  | 
|   761       // maximum capacity indicates that most objects will be promoted. |  | 
|   762       // To decrease scavenger pauses and final mark-sweep pauses, we |  | 
|   763       // have to limit maximal capacity of the young generation. |  | 
|   764       new_space_high_promotion_mode_active_ = true; |  | 
|   765       if (FLAG_trace_gc) { |  | 
|   766         PrintF("Limited new space size due to high promotion rate: %d MB\n", |  | 
|   767                new_space_.InitialCapacity() / MB); |  | 
|   768       } |  | 
|   769     } else if (new_space_high_promotion_mode_active_ && |  | 
|   770         IsDecreasingSurvivalTrend() && |  | 
|   771         !IsHighSurvivalRate()) { |  | 
|   772       // Decreasing low survival rates might indicate that the above high |  | 
|   773       // promotion mode is over and we should allow the young generation |  | 
|   774       // to grow again. |  | 
|   775       new_space_high_promotion_mode_active_ = false; |  | 
|   776       if (FLAG_trace_gc) { |  | 
|   777         PrintF("Unlimited new space size due to low promotion rate: %d MB\n", |  | 
|   778                new_space_.MaximumCapacity() / MB); |  | 
|   779       } |  | 
|   780     } |  | 
|   781  |  | 
|   782     size_of_old_gen_at_last_old_space_gc_ = PromotedSpaceSize(); |   762     size_of_old_gen_at_last_old_space_gc_ = PromotedSpaceSize(); | 
|   783  |   763  | 
|   784     if (high_survival_rate_during_scavenges && |   764     if (high_survival_rate_during_scavenges && | 
|   785         IsStableOrIncreasingSurvivalTrend()) { |   765         IsStableOrIncreasingSurvivalTrend()) { | 
|   786       // Stable high survival rates of young objects both during partial and |   766       // Stable high survival rates of young objects both during partial and | 
|   787       // full collection indicate that mutator is either building or modifying |   767       // full collection indicate that mutator is either building or modifying | 
|   788       // a structure with a long lifetime. |   768       // a structure with a long lifetime. | 
|   789       // In this case we aggressively raise old generation memory limits to |   769       // In this case we aggressively raise old generation memory limits to | 
|   790       // postpone subsequent mark-sweep collection and thus trade memory |   770       // postpone subsequent mark-sweep collection and thus trade memory | 
|   791       // space for the mutation speed. |   771       // space for the mutation speed. | 
|   792       old_gen_limit_factor_ = 2; |   772       old_gen_limit_factor_ = 2; | 
|   793     } else { |   773     } else { | 
|   794       old_gen_limit_factor_ = 1; |   774       old_gen_limit_factor_ = 1; | 
|   795     } |   775     } | 
|   796  |   776  | 
|   797     old_gen_promotion_limit_ = |   777     old_gen_promotion_limit_ = | 
|   798         OldGenPromotionLimit(size_of_old_gen_at_last_old_space_gc_); |   778         OldGenPromotionLimit(size_of_old_gen_at_last_old_space_gc_); | 
|   799     old_gen_allocation_limit_ = |   779     old_gen_allocation_limit_ = | 
|   800         OldGenAllocationLimit(size_of_old_gen_at_last_old_space_gc_); |   780         OldGenAllocationLimit(size_of_old_gen_at_last_old_space_gc_); | 
|   801  |   781  | 
|   802     old_gen_exhausted_ = false; |   782     old_gen_exhausted_ = false; | 
|   803   } else { |   783   } else { | 
|   804     tracer_ = tracer; |   784     tracer_ = tracer; | 
|   805     Scavenge(); |   785     Scavenge(); | 
|   806     tracer_ = NULL; |   786     tracer_ = NULL; | 
|   807  |   787  | 
|   808     UpdateSurvivalRateTrend(start_new_space_size); |   788     UpdateSurvivalRateTrend(start_new_space_size); | 
|   809   } |   789   } | 
|   810  |   790  | 
 |   791   if (!new_space_high_promotion_mode_active_ && | 
 |   792       new_space_.Capacity() == new_space_.MaximumCapacity() && | 
 |   793       IsStableOrIncreasingSurvivalTrend() && | 
 |   794       IsHighSurvivalRate()) { | 
 |   795     // Stable high survival rates even though young generation is at | 
 |   796     // maximum capacity indicates that most objects will be promoted. | 
 |   797     // To decrease scavenger pauses and final mark-sweep pauses, we | 
 |   798     // have to limit maximal capacity of the young generation. | 
 |   799     new_space_high_promotion_mode_active_ = true; | 
 |   800     if (FLAG_trace_gc) { | 
 |   801       PrintF("Limited new space size due to high promotion rate: %d MB\n", | 
 |   802              new_space_.InitialCapacity() / MB); | 
 |   803     } | 
 |   804   } else if (new_space_high_promotion_mode_active_ && | 
 |   805       IsStableOrDecreasingSurvivalTrend() && | 
 |   806       IsLowSurvivalRate()) { | 
 |   807     // Decreasing low survival rates might indicate that the above high | 
 |   808     // promotion mode is over and we should allow the young generation | 
 |   809     // to grow again. | 
 |   810     new_space_high_promotion_mode_active_ = false; | 
 |   811     if (FLAG_trace_gc) { | 
 |   812       PrintF("Unlimited new space size due to low promotion rate: %d MB\n", | 
 |   813              new_space_.MaximumCapacity() / MB); | 
 |   814     } | 
 |   815   } | 
 |   816  | 
|   811   if (new_space_high_promotion_mode_active_ && |   817   if (new_space_high_promotion_mode_active_ && | 
|   812       new_space_.Capacity() > new_space_.InitialCapacity()) { |   818       new_space_.Capacity() > new_space_.InitialCapacity()) { | 
|   813     new_space_.Shrink(); |   819     new_space_.Shrink(); | 
|   814   } |   820   } | 
|   815  |   821  | 
|   816   isolate_->counters()->objs_since_last_young()->Set(0); |   822   isolate_->counters()->objs_since_last_young()->Set(0); | 
|   817  |   823  | 
|   818   gc_post_processing_depth_++; |   824   gc_post_processing_depth_++; | 
|   819   { DisableAssertNoAllocation allow_allocation; |   825   { DisableAssertNoAllocation allow_allocation; | 
|   820     GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); |   826     GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); | 
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1083  |  1089  | 
|  1084   gc_state_ = SCAVENGE; |  1090   gc_state_ = SCAVENGE; | 
|  1085  |  1091  | 
|  1086   // Implements Cheney's copying algorithm |  1092   // Implements Cheney's copying algorithm | 
|  1087   LOG(isolate_, ResourceEvent("scavenge", "begin")); |  1093   LOG(isolate_, ResourceEvent("scavenge", "begin")); | 
|  1088  |  1094  | 
|  1089   // Clear descriptor cache. |  1095   // Clear descriptor cache. | 
|  1090   isolate_->descriptor_lookup_cache()->Clear(); |  1096   isolate_->descriptor_lookup_cache()->Clear(); | 
|  1091  |  1097  | 
|  1092   // Used for updating survived_since_last_expansion_ at function end. |  1098   // Used for updating survived_since_last_expansion_ at function end. | 
|  1093   intptr_t survived_watermark = PromotedSpaceSize(); |  1099   intptr_t survived_watermark = PromotedSpaceSizeOfObjects(); | 
|  1094  |  1100  | 
|  1095   CheckNewSpaceExpansionCriteria(); |  1101   CheckNewSpaceExpansionCriteria(); | 
|  1096  |  1102  | 
|  1097   SelectScavengingVisitorsTable(); |  1103   SelectScavengingVisitorsTable(); | 
|  1098  |  1104  | 
|  1099   incremental_marking()->PrepareForScavenge(); |  1105   incremental_marking()->PrepareForScavenge(); | 
|  1100  |  1106  | 
|  1101   AdvanceSweepers(static_cast<int>(new_space_.Size())); |  1107   AdvanceSweepers(static_cast<int>(new_space_.Size())); | 
|  1102  |  1108  | 
|  1103   // Flip the semispaces.  After flipping, to space is empty, from space has |  1109   // Flip the semispaces.  After flipping, to space is empty, from space has | 
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1175   ASSERT(new_space_front == new_space_.top()); |  1181   ASSERT(new_space_front == new_space_.top()); | 
|  1176  |  1182  | 
|  1177   // Set age mark. |  1183   // Set age mark. | 
|  1178   new_space_.set_age_mark(new_space_.top()); |  1184   new_space_.set_age_mark(new_space_.top()); | 
|  1179  |  1185  | 
|  1180   new_space_.LowerInlineAllocationLimit( |  1186   new_space_.LowerInlineAllocationLimit( | 
|  1181       new_space_.inline_allocation_limit_step()); |  1187       new_space_.inline_allocation_limit_step()); | 
|  1182  |  1188  | 
|  1183   // Update how much has survived scavenge. |  1189   // Update how much has survived scavenge. | 
|  1184   IncrementYoungSurvivorsCounter(static_cast<int>( |  1190   IncrementYoungSurvivorsCounter(static_cast<int>( | 
|  1185       (PromotedSpaceSize() - survived_watermark) + new_space_.Size())); |  1191       (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size())); | 
|  1186  |  1192  | 
|  1187   LOG(isolate_, ResourceEvent("scavenge", "end")); |  1193   LOG(isolate_, ResourceEvent("scavenge", "end")); | 
|  1188  |  1194  | 
|  1189   gc_state_ = NOT_IN_GC; |  1195   gc_state_ = NOT_IN_GC; | 
|  1190  |  1196  | 
|  1191   scavenges_since_last_idle_round_++; |  1197   scavenges_since_last_idle_round_++; | 
|  1192 } |  1198 } | 
|  1193  |  1199  | 
|  1194  |  1200  | 
|  1195 String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap, |  1201 String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap, | 
| (...skipping 4210 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5406 intptr_t Heap::PromotedSpaceSize() { |  5412 intptr_t Heap::PromotedSpaceSize() { | 
|  5407   return old_pointer_space_->Size() |  5413   return old_pointer_space_->Size() | 
|  5408       + old_data_space_->Size() |  5414       + old_data_space_->Size() | 
|  5409       + code_space_->Size() |  5415       + code_space_->Size() | 
|  5410       + map_space_->Size() |  5416       + map_space_->Size() | 
|  5411       + cell_space_->Size() |  5417       + cell_space_->Size() | 
|  5412       + lo_space_->Size(); |  5418       + lo_space_->Size(); | 
|  5413 } |  5419 } | 
|  5414  |  5420  | 
|  5415  |  5421  | 
 |  5422 intptr_t Heap::PromotedSpaceSizeOfObjects() { | 
 |  5423   return old_pointer_space_->SizeOfObjects() | 
 |  5424       + old_data_space_->SizeOfObjects() | 
 |  5425       + code_space_->SizeOfObjects() | 
 |  5426       + map_space_->SizeOfObjects() | 
 |  5427       + cell_space_->SizeOfObjects() | 
 |  5428       + lo_space_->SizeOfObjects(); | 
 |  5429 } | 
 |  5430  | 
 |  5431  | 
|  5416 int Heap::PromotedExternalMemorySize() { |  5432 int Heap::PromotedExternalMemorySize() { | 
|  5417   if (amount_of_external_allocated_memory_ |  5433   if (amount_of_external_allocated_memory_ | 
|  5418       <= amount_of_external_allocated_memory_at_last_global_gc_) return 0; |  5434       <= amount_of_external_allocated_memory_at_last_global_gc_) return 0; | 
|  5419   return amount_of_external_allocated_memory_ |  5435   return amount_of_external_allocated_memory_ | 
|  5420       - amount_of_external_allocated_memory_at_last_global_gc_; |  5436       - amount_of_external_allocated_memory_at_last_global_gc_; | 
|  5421 } |  5437 } | 
|  5422  |  5438  | 
|  5423 #ifdef DEBUG |  5439 #ifdef DEBUG | 
|  5424  |  5440  | 
|  5425 // Tags 0, 1, and 3 are used. Use 2 for marking visited HeapObject. |  5441 // Tags 0, 1, and 3 are used. Use 2 for marking visited HeapObject. | 
| (...skipping 1228 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  6654   isolate_->heap()->store_buffer()->Compact(); |  6670   isolate_->heap()->store_buffer()->Compact(); | 
|  6655   isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); |  6671   isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); | 
|  6656   for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { |  6672   for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { | 
|  6657     next = chunk->next_chunk(); |  6673     next = chunk->next_chunk(); | 
|  6658     isolate_->memory_allocator()->Free(chunk); |  6674     isolate_->memory_allocator()->Free(chunk); | 
|  6659   } |  6675   } | 
|  6660   chunks_queued_for_free_ = NULL; |  6676   chunks_queued_for_free_ = NULL; | 
|  6661 } |  6677 } | 
|  6662  |  6678  | 
|  6663 } }  // namespace v8::internal |  6679 } }  // namespace v8::internal | 
| OLD | NEW |