Index: src/heap/heap.cc |
diff --git a/src/heap/heap.cc b/src/heap/heap.cc |
index 316c5772a04d5bd941fb8bf863769a7580e38a43..ec2a470abb8268897290511a34ea60ec5be12c57 100644 |
--- a/src/heap/heap.cc |
+++ b/src/heap/heap.cc |
@@ -95,6 +95,8 @@ Heap::Heap() |
survived_last_scavenge_(0), |
always_allocate_scope_count_(0), |
memory_pressure_level_(MemoryPressureLevel::kNone), |
+ out_of_memory_callback_(nullptr), |
+ out_of_memory_callback_data_(nullptr), |
contexts_disposed_(0), |
number_of_disposed_maps_(0), |
global_ic_age_(0), |
@@ -867,6 +869,9 @@ void Heap::CollectAllAvailableGarbage(GarbageCollectionReason gc_reason) { |
// Note: as weak callbacks can execute arbitrary code, we cannot |
// hope that eventually there will be no weak callbacks invocations. |
// Therefore stop recollecting after several attempts. |
+ if (gc_reason == GarbageCollectionReason::kLastResort) { |
+ InvokeOutOfMemoryCallback(); |
+ } |
RuntimeCallTimerScope(isolate(), &RuntimeCallStats::GC_AllAvailableGarbage); |
if (isolate()->concurrent_recompilation_enabled()) { |
// The optimizing compiler may be unnecessarily holding on to memory. |
@@ -4534,6 +4539,18 @@ void Heap::MemoryPressureNotification(MemoryPressureLevel level, |
} |
} |
+void Heap::SetOutOfMemoryCallback(v8::debug::OutOfMemoryCallback callback, |
+ void* data) { |
+ out_of_memory_callback_ = callback; |
+ out_of_memory_callback_data_ = data; |
+} |
+ |
+void Heap::InvokeOutOfMemoryCallback() { |
+ if (out_of_memory_callback_) { |
+ out_of_memory_callback_(out_of_memory_callback_data_); |
+ } |
+} |
+ |
void Heap::CollectCodeStatistics() { |
CodeStatistics::ResetCodeAndMetadataStatistics(isolate()); |
// We do not look for code in new space, or map space. If code |