| 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/heap/heap.h" | 5 #include "src/heap/heap.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/ast/context-slot-cache.h" | 9 #include "src/ast/context-slot-cache.h" |
| 10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 new_space_->Size()) { | 279 new_space_->Size()) { |
| 280 isolate_->counters() | 280 isolate_->counters() |
| 281 ->gc_compactor_caused_by_oldspace_exhaustion() | 281 ->gc_compactor_caused_by_oldspace_exhaustion() |
| 282 ->Increment(); | 282 ->Increment(); |
| 283 *reason = "scavenge might not succeed"; | 283 *reason = "scavenge might not succeed"; |
| 284 return MARK_COMPACTOR; | 284 return MARK_COMPACTOR; |
| 285 } | 285 } |
| 286 | 286 |
| 287 // Default | 287 // Default |
| 288 *reason = NULL; | 288 *reason = NULL; |
| 289 return SCAVENGER; | 289 return YoungGenerationCollector(); |
| 290 } | 290 } |
| 291 | 291 |
| 292 | 292 |
| 293 // TODO(1238405): Combine the infrastructure for --heap-stats and | 293 // TODO(1238405): Combine the infrastructure for --heap-stats and |
| 294 // --log-gc to avoid the complicated preprocessor and flag testing. | 294 // --log-gc to avoid the complicated preprocessor and flag testing. |
| 295 void Heap::ReportStatisticsBeforeGC() { | 295 void Heap::ReportStatisticsBeforeGC() { |
| 296 // Heap::ReportHeapStatistics will also log NewSpace statistics when | 296 // Heap::ReportHeapStatistics will also log NewSpace statistics when |
| 297 // compiled --log-gc is set. The following logic is used to avoid | 297 // compiled --log-gc is set. The following logic is used to avoid |
| 298 // double logging. | 298 // double logging. |
| 299 #ifdef DEBUG | 299 #ifdef DEBUG |
| (...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 815 TRACE_GC(tracer(), GCTracer::Scope::MC_INCREMENTAL_EXTERNAL_EPILOGUE); | 815 TRACE_GC(tracer(), GCTracer::Scope::MC_INCREMENTAL_EXTERNAL_EPILOGUE); |
| 816 VMState<EXTERNAL> state(isolate_); | 816 VMState<EXTERNAL> state(isolate_); |
| 817 HandleScope handle_scope(isolate_); | 817 HandleScope handle_scope(isolate_); |
| 818 CallGCEpilogueCallbacks(kGCTypeIncrementalMarking, kNoGCCallbackFlags); | 818 CallGCEpilogueCallbacks(kGCTypeIncrementalMarking, kNoGCCallbackFlags); |
| 819 } | 819 } |
| 820 } | 820 } |
| 821 } | 821 } |
| 822 | 822 |
| 823 | 823 |
| 824 HistogramTimer* Heap::GCTypeTimer(GarbageCollector collector) { | 824 HistogramTimer* Heap::GCTypeTimer(GarbageCollector collector) { |
| 825 if (collector == SCAVENGER) { | 825 if (IsYoungGenerationCollector(collector)) { |
| 826 return isolate_->counters()->gc_scavenger(); | 826 return isolate_->counters()->gc_scavenger(); |
| 827 } else { | 827 } else { |
| 828 if (!incremental_marking()->IsStopped()) { | 828 if (!incremental_marking()->IsStopped()) { |
| 829 if (ShouldReduceMemory()) { | 829 if (ShouldReduceMemory()) { |
| 830 return isolate_->counters()->gc_finalize_reduce_memory(); | 830 return isolate_->counters()->gc_finalize_reduce_memory(); |
| 831 } else { | 831 } else { |
| 832 return isolate_->counters()->gc_finalize(); | 832 return isolate_->counters()->gc_finalize(); |
| 833 } | 833 } |
| 834 } else { | 834 } else { |
| 835 return isolate_->counters()->gc_compactor(); | 835 return isolate_->counters()->gc_compactor(); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 945 // Reset the allocation timeout to the GC interval, but make sure to | 945 // Reset the allocation timeout to the GC interval, but make sure to |
| 946 // allow at least a few allocations after a collection. The reason | 946 // allow at least a few allocations after a collection. The reason |
| 947 // for this is that we have a lot of allocation sequences and we | 947 // for this is that we have a lot of allocation sequences and we |
| 948 // assume that a garbage collection will allow the subsequent | 948 // assume that a garbage collection will allow the subsequent |
| 949 // allocation attempts to go through. | 949 // allocation attempts to go through. |
| 950 allocation_timeout_ = Max(6, FLAG_gc_interval); | 950 allocation_timeout_ = Max(6, FLAG_gc_interval); |
| 951 #endif | 951 #endif |
| 952 | 952 |
| 953 EnsureFillerObjectAtTop(); | 953 EnsureFillerObjectAtTop(); |
| 954 | 954 |
| 955 if (collector == SCAVENGER && !incremental_marking()->IsStopped()) { | 955 if (IsYoungGenerationCollector(collector) && |
| 956 !incremental_marking()->IsStopped()) { |
| 956 if (FLAG_trace_incremental_marking) { | 957 if (FLAG_trace_incremental_marking) { |
| 957 isolate()->PrintWithTimestamp( | 958 isolate()->PrintWithTimestamp( |
| 958 "[IncrementalMarking] Scavenge during marking.\n"); | 959 "[IncrementalMarking] Scavenge during marking.\n"); |
| 959 } | 960 } |
| 960 } | 961 } |
| 961 | 962 |
| 962 if (collector == MARK_COMPACTOR && !ShouldFinalizeIncrementalMarking() && | 963 if (collector == MARK_COMPACTOR && !ShouldFinalizeIncrementalMarking() && |
| 963 !ShouldAbortIncrementalMarking() && !incremental_marking()->IsStopped() && | 964 !ShouldAbortIncrementalMarking() && !incremental_marking()->IsStopped() && |
| 964 !incremental_marking()->should_hurry() && FLAG_incremental_marking && | 965 !incremental_marking()->should_hurry() && FLAG_incremental_marking && |
| 965 OldGenerationSpaceAvailable() <= 0) { | 966 OldGenerationSpaceAvailable() <= 0) { |
| 966 if (!incremental_marking()->IsComplete() && | 967 if (!incremental_marking()->IsComplete() && |
| 967 !mark_compact_collector()->marking_deque()->IsEmpty() && | 968 !mark_compact_collector()->marking_deque()->IsEmpty() && |
| 968 !FLAG_gc_global) { | 969 !FLAG_gc_global) { |
| 969 if (FLAG_trace_incremental_marking) { | 970 if (FLAG_trace_incremental_marking) { |
| 970 isolate()->PrintWithTimestamp( | 971 isolate()->PrintWithTimestamp( |
| 971 "[IncrementalMarking] Delaying MarkSweep.\n"); | 972 "[IncrementalMarking] Delaying MarkSweep.\n"); |
| 972 } | 973 } |
| 973 collector = SCAVENGER; | 974 collector = YoungGenerationCollector(); |
| 974 collector_reason = "incremental marking delaying mark-sweep"; | 975 collector_reason = "incremental marking delaying mark-sweep"; |
| 975 } | 976 } |
| 976 } | 977 } |
| 977 | 978 |
| 978 bool next_gc_likely_to_collect_more = false; | 979 bool next_gc_likely_to_collect_more = false; |
| 979 intptr_t committed_memory_before = 0; | 980 intptr_t committed_memory_before = 0; |
| 980 | 981 |
| 981 if (collector == MARK_COMPACTOR) { | 982 if (collector == MARK_COMPACTOR) { |
| 982 committed_memory_before = CommittedOldGenerationMemory(); | 983 committed_memory_before = CommittedOldGenerationMemory(); |
| 983 } | 984 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1028 if (collector == MARK_COMPACTOR && | 1029 if (collector == MARK_COMPACTOR && |
| 1029 (gc_callback_flags & (kGCCallbackFlagForced | | 1030 (gc_callback_flags & (kGCCallbackFlagForced | |
| 1030 kGCCallbackFlagCollectAllAvailableGarbage)) != 0) { | 1031 kGCCallbackFlagCollectAllAvailableGarbage)) != 0) { |
| 1031 isolate()->CountUsage(v8::Isolate::kForcedGC); | 1032 isolate()->CountUsage(v8::Isolate::kForcedGC); |
| 1032 } | 1033 } |
| 1033 | 1034 |
| 1034 // Start incremental marking for the next cycle. The heap snapshot | 1035 // Start incremental marking for the next cycle. The heap snapshot |
| 1035 // generator needs incremental marking to stay off after it aborted. | 1036 // generator needs incremental marking to stay off after it aborted. |
| 1036 // We do this only for scavenger to avoid a loop where mark-compact | 1037 // We do this only for scavenger to avoid a loop where mark-compact |
| 1037 // causes another mark-compact. | 1038 // causes another mark-compact. |
| 1038 if (collector == SCAVENGER && !ShouldAbortIncrementalMarking()) { | 1039 if (IsYoungGenerationCollector(collector) && |
| 1040 !ShouldAbortIncrementalMarking()) { |
| 1039 StartIncrementalMarkingIfAllocationLimitIsReached(kNoGCFlags, | 1041 StartIncrementalMarkingIfAllocationLimitIsReached(kNoGCFlags, |
| 1040 kNoGCCallbackFlags); | 1042 kNoGCCallbackFlags); |
| 1041 } | 1043 } |
| 1042 | 1044 |
| 1043 return next_gc_likely_to_collect_more; | 1045 return next_gc_likely_to_collect_more; |
| 1044 } | 1046 } |
| 1045 | 1047 |
| 1046 | 1048 |
| 1047 int Heap::NotifyContextDisposed(bool dependant_context) { | 1049 int Heap::NotifyContextDisposed(bool dependant_context) { |
| 1048 if (!dependant_context) { | 1050 if (!dependant_context) { |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1268 static_cast<double>(start_new_space_size) * 100); | 1270 static_cast<double>(start_new_space_size) * 100); |
| 1269 | 1271 |
| 1270 double survival_rate = promotion_ratio_ + semi_space_copied_rate_; | 1272 double survival_rate = promotion_ratio_ + semi_space_copied_rate_; |
| 1271 tracer()->AddSurvivalRatio(survival_rate); | 1273 tracer()->AddSurvivalRatio(survival_rate); |
| 1272 } | 1274 } |
| 1273 | 1275 |
| 1274 bool Heap::PerformGarbageCollection( | 1276 bool Heap::PerformGarbageCollection( |
| 1275 GarbageCollector collector, const v8::GCCallbackFlags gc_callback_flags) { | 1277 GarbageCollector collector, const v8::GCCallbackFlags gc_callback_flags) { |
| 1276 int freed_global_handles = 0; | 1278 int freed_global_handles = 0; |
| 1277 | 1279 |
| 1278 if (collector != SCAVENGER) { | 1280 if (!IsYoungGenerationCollector(collector)) { |
| 1279 PROFILE(isolate_, CodeMovingGCEvent()); | 1281 PROFILE(isolate_, CodeMovingGCEvent()); |
| 1280 } | 1282 } |
| 1281 | 1283 |
| 1282 #ifdef VERIFY_HEAP | 1284 #ifdef VERIFY_HEAP |
| 1283 if (FLAG_verify_heap) { | 1285 if (FLAG_verify_heap) { |
| 1284 VerifyStringTable(this); | 1286 VerifyStringTable(this); |
| 1285 } | 1287 } |
| 1286 #endif | 1288 #endif |
| 1287 | 1289 |
| 1288 GCType gc_type = | 1290 GCType gc_type = |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1299 } | 1301 } |
| 1300 } | 1302 } |
| 1301 | 1303 |
| 1302 EnsureFromSpaceIsCommitted(); | 1304 EnsureFromSpaceIsCommitted(); |
| 1303 | 1305 |
| 1304 int start_new_space_size = static_cast<int>(Heap::new_space()->Size()); | 1306 int start_new_space_size = static_cast<int>(Heap::new_space()->Size()); |
| 1305 | 1307 |
| 1306 { | 1308 { |
| 1307 Heap::PretenuringScope pretenuring_scope(this); | 1309 Heap::PretenuringScope pretenuring_scope(this); |
| 1308 | 1310 |
| 1309 if (collector == MARK_COMPACTOR) { | 1311 switch (collector) { |
| 1310 UpdateOldGenerationAllocationCounter(); | 1312 case MARK_COMPACTOR: |
| 1311 // Perform mark-sweep with optional compaction. | 1313 UpdateOldGenerationAllocationCounter(); |
| 1312 MarkCompact(); | 1314 // Perform mark-sweep with optional compaction. |
| 1313 old_generation_size_configured_ = true; | 1315 MarkCompact(); |
| 1314 // This should be updated before PostGarbageCollectionProcessing, which | 1316 old_generation_size_configured_ = true; |
| 1315 // can cause another GC. Take into account the objects promoted during GC. | 1317 // This should be updated before PostGarbageCollectionProcessing, which |
| 1316 old_generation_allocation_counter_at_last_gc_ += | 1318 // can cause another GC. Take into account the objects promoted during |
| 1317 static_cast<size_t>(promoted_objects_size_); | 1319 // GC. |
| 1318 old_generation_size_at_last_gc_ = PromotedSpaceSizeOfObjects(); | 1320 old_generation_allocation_counter_at_last_gc_ += |
| 1319 } else { | 1321 static_cast<size_t>(promoted_objects_size_); |
| 1320 Scavenge(); | 1322 old_generation_size_at_last_gc_ = PromotedSpaceSizeOfObjects(); |
| 1323 break; |
| 1324 case MINOR_MARK_COMPACTOR: |
| 1325 MinorMarkCompact(); |
| 1326 break; |
| 1327 case SCAVENGER: |
| 1328 Scavenge(); |
| 1329 break; |
| 1321 } | 1330 } |
| 1322 | 1331 |
| 1323 ProcessPretenuringFeedback(); | 1332 ProcessPretenuringFeedback(); |
| 1324 } | 1333 } |
| 1325 | 1334 |
| 1326 UpdateSurvivalStatistics(start_new_space_size); | 1335 UpdateSurvivalStatistics(start_new_space_size); |
| 1327 ConfigureInitialOldGenerationSize(); | 1336 ConfigureInitialOldGenerationSize(); |
| 1328 | 1337 |
| 1329 isolate_->counters()->objs_since_last_young()->Set(0); | 1338 isolate_->counters()->objs_since_last_young()->Set(0); |
| 1330 | 1339 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1433 | 1442 |
| 1434 LOG(isolate_, ResourceEvent("markcompact", "end")); | 1443 LOG(isolate_, ResourceEvent("markcompact", "end")); |
| 1435 | 1444 |
| 1436 MarkCompactEpilogue(); | 1445 MarkCompactEpilogue(); |
| 1437 | 1446 |
| 1438 if (FLAG_allocation_site_pretenuring) { | 1447 if (FLAG_allocation_site_pretenuring) { |
| 1439 EvaluateOldSpaceLocalPretenuring(size_of_objects_before_gc); | 1448 EvaluateOldSpaceLocalPretenuring(size_of_objects_before_gc); |
| 1440 } | 1449 } |
| 1441 } | 1450 } |
| 1442 | 1451 |
| 1452 void Heap::MinorMarkCompact() { UNREACHABLE(); } |
| 1443 | 1453 |
| 1444 void Heap::MarkCompactEpilogue() { | 1454 void Heap::MarkCompactEpilogue() { |
| 1445 TRACE_GC(tracer(), GCTracer::Scope::MC_EPILOGUE); | 1455 TRACE_GC(tracer(), GCTracer::Scope::MC_EPILOGUE); |
| 1446 gc_state_ = NOT_IN_GC; | 1456 gc_state_ = NOT_IN_GC; |
| 1447 | 1457 |
| 1448 isolate_->counters()->objs_since_last_full()->Set(0); | 1458 isolate_->counters()->objs_since_last_full()->Set(0); |
| 1449 | 1459 |
| 1450 incremental_marking()->Epilogue(); | 1460 incremental_marking()->Epilogue(); |
| 1451 | 1461 |
| 1452 PreprocessStackTraces(); | 1462 PreprocessStackTraces(); |
| (...skipping 5002 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6455 } | 6465 } |
| 6456 | 6466 |
| 6457 | 6467 |
| 6458 // static | 6468 // static |
| 6459 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6469 int Heap::GetStaticVisitorIdForMap(Map* map) { |
| 6460 return StaticVisitorBase::GetVisitorId(map); | 6470 return StaticVisitorBase::GetVisitorId(map); |
| 6461 } | 6471 } |
| 6462 | 6472 |
| 6463 } // namespace internal | 6473 } // namespace internal |
| 6464 } // namespace v8 | 6474 } // namespace v8 |
| OLD | NEW |