Index: src/heap/heap.cc |
diff --git a/src/heap/heap.cc b/src/heap/heap.cc |
index b39bd81ffd4c14b4245dbd0041353fbc32a75001..9350c0aa85064169bfd2b1f4ee51137d075be1fb 100644 |
--- a/src/heap/heap.cc |
+++ b/src/heap/heap.cc |
@@ -68,7 +68,6 @@ class IdleScavengeObserver : public AllocationObserver { |
Heap& heap_; |
}; |
- |
Heap::Heap() |
: amount_of_external_allocated_memory_(0), |
amount_of_external_allocated_memory_at_last_global_gc_(0), |
@@ -92,6 +91,7 @@ Heap::Heap() |
survived_since_last_expansion_(0), |
survived_last_scavenge_(0), |
always_allocate_scope_count_(0), |
+ memory_pressure_level_(MemoryPressureLevel::kNone), |
contexts_disposed_(0), |
number_of_disposed_maps_(0), |
global_ic_age_(0), |
@@ -790,12 +790,19 @@ class GCCallbacksScope { |
void Heap::HandleGCRequest() { |
- if (incremental_marking()->request_type() == |
- IncrementalMarking::COMPLETE_MARKING) { |
+ if (memory_pressure_level_.Value() == MemoryPressureLevel::kCritical) { |
+ CollectAllGarbage(kReduceMemoryFootprintMask | kAbortIncrementalMarkingMask, |
+ "critical memory pressure notification (interrupt)"); |
+ } else if (incremental_marking()->request_type() == |
+ IncrementalMarking::COMPLETE_MARKING) { |
+ incremental_marking()->reset_request_type(); |
CollectAllGarbage(current_gc_flags_, "GC interrupt", |
current_gc_callback_flags_); |
- } else if (incremental_marking()->IsMarking() && |
+ } else if (incremental_marking()->request_type() == |
+ IncrementalMarking::FINALIZATION && |
+ incremental_marking()->IsMarking() && |
!incremental_marking()->finalize_marking_completed()) { |
+ incremental_marking()->reset_request_type(); |
FinalizeIncrementalMarking("GC interrupt: finalize incremental marking"); |
} |
} |
@@ -1456,6 +1463,8 @@ void Heap::MarkCompactEpilogue() { |
incremental_marking()->Epilogue(); |
PreprocessStackTraces(); |
+ |
+ memory_pressure_level_.SetValue(MemoryPressureLevel::kNone); |
} |
@@ -4416,6 +4425,29 @@ bool Heap::RecentIdleNotificationHappened() { |
MonotonicallyIncreasingTimeInMs(); |
} |
+void Heap::MemoryPressureNotification(MemoryPressureLevel level, |
+ bool is_isolate_locked) { |
+ MemoryPressureLevel previous = memory_pressure_level_.Value(); |
+ memory_pressure_level_.SetValue(level); |
+ if (previous != MemoryPressureLevel::kCritical && |
+ level == MemoryPressureLevel::kCritical) { |
+ if (is_isolate_locked) { |
+ CollectAllGarbage( |
Hannes Payer (out of office)
2016/03/18 13:27:26
When the level is critical, one memory reducing GC
ulan
2016/03/18 16:10:00
We also restart memory reducer.
Hannes Payer (out of office)
2016/03/21 09:58:26
Depending on what critical means, starting the mem
|
+ kReduceMemoryFootprintMask | kAbortIncrementalMarkingMask, |
+ "critical memory pressure notification"); |
+ } else { |
+ ExecutionAccess access(isolate()); |
+ isolate()->stack_guard()->RequestGC(); |
+ } |
+ } |
+ if (previous == MemoryPressureLevel::kNone && |
+ level != MemoryPressureLevel::kNone) { |
+ MemoryReducer::Event event; |
+ event.type = MemoryReducer::kPossibleGarbage; |
+ event.time_ms = MonotonicallyIncreasingTimeInMs(); |
+ memory_reducer_->NotifyPossibleGarbage(event); |
+ } |
+} |
#ifdef DEBUG |