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

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

Issue 1813963002: Add memory pressure notification API (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: GC interrupt on kModerate to start incremental marking Created 4 years, 9 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') | src/heap/incremental-marking.h » ('j') | 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/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/scopeinfo.h" 9 #include "src/ast/scopeinfo.h"
10 #include "src/base/bits.h" 10 #include "src/base/bits.h"
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 : AllocationObserver(step_size), heap_(heap) {} 61 : AllocationObserver(step_size), heap_(heap) {}
62 62
63 void Step(int bytes_allocated, Address, size_t) override { 63 void Step(int bytes_allocated, Address, size_t) override {
64 heap_.ScheduleIdleScavengeIfNeeded(bytes_allocated); 64 heap_.ScheduleIdleScavengeIfNeeded(bytes_allocated);
65 } 65 }
66 66
67 private: 67 private:
68 Heap& heap_; 68 Heap& heap_;
69 }; 69 };
70 70
71
72 Heap::Heap() 71 Heap::Heap()
73 : amount_of_external_allocated_memory_(0), 72 : amount_of_external_allocated_memory_(0),
74 amount_of_external_allocated_memory_at_last_global_gc_(0), 73 amount_of_external_allocated_memory_at_last_global_gc_(0),
75 isolate_(NULL), 74 isolate_(NULL),
76 code_range_size_(0), 75 code_range_size_(0),
77 // semispace_size_ should be a power of 2 and old_generation_size_ should 76 // semispace_size_ should be a power of 2 and old_generation_size_ should
78 // be a multiple of Page::kPageSize. 77 // be a multiple of Page::kPageSize.
79 reserved_semispace_size_(8 * (kPointerSize / 4) * MB), 78 reserved_semispace_size_(8 * (kPointerSize / 4) * MB),
80 max_semi_space_size_(8 * (kPointerSize / 4) * MB), 79 max_semi_space_size_(8 * (kPointerSize / 4) * MB),
81 initial_semispace_size_(Page::kPageSize), 80 initial_semispace_size_(Page::kPageSize),
82 max_old_generation_size_(700ul * (kPointerSize / 4) * MB), 81 max_old_generation_size_(700ul * (kPointerSize / 4) * MB),
83 initial_old_generation_size_(max_old_generation_size_ / 82 initial_old_generation_size_(max_old_generation_size_ /
84 kInitalOldGenerationLimitFactor), 83 kInitalOldGenerationLimitFactor),
85 old_generation_size_configured_(false), 84 old_generation_size_configured_(false),
86 max_executable_size_(256ul * (kPointerSize / 4) * MB), 85 max_executable_size_(256ul * (kPointerSize / 4) * MB),
87 // Variables set based on semispace_size_ and old_generation_size_ in 86 // Variables set based on semispace_size_ and old_generation_size_ in
88 // ConfigureHeap. 87 // ConfigureHeap.
89 // Will be 4 * reserved_semispace_size_ to ensure that young 88 // Will be 4 * reserved_semispace_size_ to ensure that young
90 // generation can be aligned to its size. 89 // generation can be aligned to its size.
91 maximum_committed_(0), 90 maximum_committed_(0),
92 survived_since_last_expansion_(0), 91 survived_since_last_expansion_(0),
93 survived_last_scavenge_(0), 92 survived_last_scavenge_(0),
94 always_allocate_scope_count_(0), 93 always_allocate_scope_count_(0),
94 memory_pressure_level_(MemoryPressureLevel::kNone),
95 contexts_disposed_(0), 95 contexts_disposed_(0),
96 number_of_disposed_maps_(0), 96 number_of_disposed_maps_(0),
97 global_ic_age_(0), 97 global_ic_age_(0),
98 new_space_(this), 98 new_space_(this),
99 old_space_(NULL), 99 old_space_(NULL),
100 code_space_(NULL), 100 code_space_(NULL),
101 map_space_(NULL), 101 map_space_(NULL),
102 lo_space_(NULL), 102 lo_space_(NULL),
103 gc_state_(NOT_IN_GC), 103 gc_state_(NOT_IN_GC),
104 gc_post_processing_depth_(0), 104 gc_post_processing_depth_(0),
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 ~GCCallbacksScope() { heap_->gc_callbacks_depth_--; } 783 ~GCCallbacksScope() { heap_->gc_callbacks_depth_--; }
784 784
785 bool CheckReenter() { return heap_->gc_callbacks_depth_ == 1; } 785 bool CheckReenter() { return heap_->gc_callbacks_depth_ == 1; }
786 786
787 private: 787 private:
788 Heap* heap_; 788 Heap* heap_;
789 }; 789 };
790 790
791 791
792 void Heap::HandleGCRequest() { 792 void Heap::HandleGCRequest() {
793 if (incremental_marking()->request_type() == 793 if (HighMemoryPressure()) {
794 IncrementalMarking::COMPLETE_MARKING) { 794 incremental_marking()->reset_request_type();
795 CheckMemoryPressure();
796 } else if (incremental_marking()->request_type() ==
797 IncrementalMarking::COMPLETE_MARKING) {
798 incremental_marking()->reset_request_type();
795 CollectAllGarbage(current_gc_flags_, "GC interrupt", 799 CollectAllGarbage(current_gc_flags_, "GC interrupt",
796 current_gc_callback_flags_); 800 current_gc_callback_flags_);
797 } else if (incremental_marking()->IsMarking() && 801 } else if (incremental_marking()->request_type() ==
802 IncrementalMarking::FINALIZATION &&
803 incremental_marking()->IsMarking() &&
798 !incremental_marking()->finalize_marking_completed()) { 804 !incremental_marking()->finalize_marking_completed()) {
805 incremental_marking()->reset_request_type();
799 FinalizeIncrementalMarking("GC interrupt: finalize incremental marking"); 806 FinalizeIncrementalMarking("GC interrupt: finalize incremental marking");
800 } 807 }
801 } 808 }
802 809
803 810
804 void Heap::ScheduleIdleScavengeIfNeeded(int bytes_allocated) { 811 void Heap::ScheduleIdleScavengeIfNeeded(int bytes_allocated) {
805 scavenge_job_->ScheduleIdleTaskIfNeeded(this, bytes_allocated); 812 scavenge_job_->ScheduleIdleTaskIfNeeded(this, bytes_allocated);
806 } 813 }
807 814
808 815
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 // - this GC decreased committed memory, 1036 // - this GC decreased committed memory,
1030 // - there is high fragmentation, 1037 // - there is high fragmentation,
1031 // - there are live detached contexts. 1038 // - there are live detached contexts.
1032 event.next_gc_likely_to_collect_more = 1039 event.next_gc_likely_to_collect_more =
1033 (committed_memory_before - committed_memory_after) > MB || 1040 (committed_memory_before - committed_memory_after) > MB ||
1034 HasHighFragmentation(used_memory_after, committed_memory_after) || 1041 HasHighFragmentation(used_memory_after, committed_memory_after) ||
1035 (detached_contexts()->length() > 0); 1042 (detached_contexts()->length() > 0);
1036 if (deserialization_complete_) { 1043 if (deserialization_complete_) {
1037 memory_reducer_->NotifyMarkCompact(event); 1044 memory_reducer_->NotifyMarkCompact(event);
1038 } 1045 }
1046 memory_pressure_level_.SetValue(MemoryPressureLevel::kNone);
1039 } 1047 }
1040 1048
1041 tracer()->Stop(collector); 1049 tracer()->Stop(collector);
1042 } 1050 }
1043 1051
1044 if (collector == MARK_COMPACTOR && 1052 if (collector == MARK_COMPACTOR &&
1045 (gc_callback_flags & (kGCCallbackFlagForced | 1053 (gc_callback_flags & (kGCCallbackFlagForced |
1046 kGCCallbackFlagCollectAllAvailableGarbage)) != 0) { 1054 kGCCallbackFlagCollectAllAvailableGarbage)) != 0) {
1047 isolate()->CountUsage(v8::Isolate::kForcedGC); 1055 isolate()->CountUsage(v8::Isolate::kForcedGC);
1048 } 1056 }
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
1448 1456
1449 1457
1450 void Heap::MarkCompactEpilogue() { 1458 void Heap::MarkCompactEpilogue() {
1451 gc_state_ = NOT_IN_GC; 1459 gc_state_ = NOT_IN_GC;
1452 1460
1453 isolate_->counters()->objs_since_last_full()->Set(0); 1461 isolate_->counters()->objs_since_last_full()->Set(0);
1454 1462
1455 incremental_marking()->Epilogue(); 1463 incremental_marking()->Epilogue();
1456 1464
1457 PreprocessStackTraces(); 1465 PreprocessStackTraces();
1458
1459 DCHECK(incremental_marking()->IsStopped()); 1466 DCHECK(incremental_marking()->IsStopped());
1460 1467
1461 // We finished a marking cycle. We can uncommit the marking deque until 1468 // We finished a marking cycle. We can uncommit the marking deque until
1462 // we start marking again. 1469 // we start marking again.
1463 mark_compact_collector()->marking_deque()->Uninitialize(); 1470 mark_compact_collector()->marking_deque()->Uninitialize();
1464 mark_compact_collector()->EnsureMarkingDequeIsCommitted( 1471 mark_compact_collector()->EnsureMarkingDequeIsCommitted(
1465 MarkCompactCollector::kMinMarkingDequeSize); 1472 MarkCompactCollector::kMinMarkingDequeSize);
1466 } 1473 }
1467 1474
1468 1475
(...skipping 2947 matching lines...) Expand 10 before | Expand all | Expand 10 after
4416 return result; 4423 return result;
4417 } 4424 }
4418 4425
4419 4426
4420 bool Heap::RecentIdleNotificationHappened() { 4427 bool Heap::RecentIdleNotificationHappened() {
4421 return (last_idle_notification_time_ + 4428 return (last_idle_notification_time_ +
4422 GCIdleTimeHandler::kMaxScheduledIdleTime) > 4429 GCIdleTimeHandler::kMaxScheduledIdleTime) >
4423 MonotonicallyIncreasingTimeInMs(); 4430 MonotonicallyIncreasingTimeInMs();
4424 } 4431 }
4425 4432
4433 class MemoryPressureInterruptTask : public CancelableTask {
4434 public:
4435 explicit MemoryPressureInterruptTask(Heap* heap)
4436 : CancelableTask(heap->isolate()), heap_(heap) {}
4437
4438 virtual ~MemoryPressureInterruptTask() {}
4439
4440 private:
4441 // v8::internal::CancelableTask overrides.
4442 void RunInternal() override { heap_->CheckMemoryPressure(); }
4443
4444 Heap* heap_;
4445 DISALLOW_COPY_AND_ASSIGN(MemoryPressureInterruptTask);
4446 };
4447
4448 void Heap::CheckMemoryPressure() {
4449 if (memory_pressure_level_.Value() == MemoryPressureLevel::kCritical) {
4450 CollectGarbageOnMemoryPressure("memory pressure");
4451 } else if (memory_pressure_level_.Value() == MemoryPressureLevel::kModerate) {
4452 if (FLAG_incremental_marking && incremental_marking()->IsStopped()) {
4453 StartIdleIncrementalMarking();
4454 }
4455 }
4456 MemoryReducer::Event event;
4457 event.type = MemoryReducer::kPossibleGarbage;
4458 event.time_ms = MonotonicallyIncreasingTimeInMs();
4459 memory_reducer_->NotifyPossibleGarbage(event);
4460 }
4461
4462 void Heap::CollectGarbageOnMemoryPressure(const char* source) {
4463 CollectAllGarbage(kReduceMemoryFootprintMask | kAbortIncrementalMarkingMask,
4464 source);
4465 }
4466
4467 void Heap::MemoryPressureNotification(MemoryPressureLevel level,
4468 bool is_isolate_locked) {
4469 MemoryPressureLevel previous = memory_pressure_level_.Value();
4470 memory_pressure_level_.SetValue(level);
4471 if ((previous != MemoryPressureLevel::kCritical &&
4472 level == MemoryPressureLevel::kCritical) ||
4473 (previous == MemoryPressureLevel::kNone &&
4474 level == MemoryPressureLevel::kModerate)) {
4475 if (is_isolate_locked) {
4476 CheckMemoryPressure();
4477 } else {
4478 ExecutionAccess access(isolate());
4479 isolate()->stack_guard()->RequestGC();
4480 V8::GetCurrentPlatform()->CallOnForegroundThread(
4481 reinterpret_cast<v8::Isolate*>(isolate()),
4482 new MemoryPressureInterruptTask(this));
4483 }
4484 }
4485 }
4426 4486
4427 #ifdef DEBUG 4487 #ifdef DEBUG
4428 4488
4429 void Heap::Print() { 4489 void Heap::Print() {
4430 if (!HasBeenSetUp()) return; 4490 if (!HasBeenSetUp()) return;
4431 isolate()->PrintStack(stdout); 4491 isolate()->PrintStack(stdout);
4432 AllSpaces spaces(this); 4492 AllSpaces spaces(this);
4433 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) { 4493 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
4434 space->Print(); 4494 space->Print();
4435 } 4495 }
(...skipping 1977 matching lines...) Expand 10 before | Expand all | Expand 10 after
6413 } 6473 }
6414 6474
6415 6475
6416 // static 6476 // static
6417 int Heap::GetStaticVisitorIdForMap(Map* map) { 6477 int Heap::GetStaticVisitorIdForMap(Map* map) {
6418 return StaticVisitorBase::GetVisitorId(map); 6478 return StaticVisitorBase::GetVisitorId(map);
6419 } 6479 }
6420 6480
6421 } // namespace internal 6481 } // namespace internal
6422 } // namespace v8 6482 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/heap.h ('k') | src/heap/incremental-marking.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698