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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 max_executable_size_(256ul * (kPointerSize / 4) * MB), | 88 max_executable_size_(256ul * (kPointerSize / 4) * MB), |
89 // Variables set based on semispace_size_ and old_generation_size_ in | 89 // Variables set based on semispace_size_ and old_generation_size_ in |
90 // ConfigureHeap. | 90 // ConfigureHeap. |
91 // Will be 4 * reserved_semispace_size_ to ensure that young | 91 // Will be 4 * reserved_semispace_size_ to ensure that young |
92 // generation can be aligned to its size. | 92 // generation can be aligned to its size. |
93 maximum_committed_(0), | 93 maximum_committed_(0), |
94 survived_since_last_expansion_(0), | 94 survived_since_last_expansion_(0), |
95 survived_last_scavenge_(0), | 95 survived_last_scavenge_(0), |
96 always_allocate_scope_count_(0), | 96 always_allocate_scope_count_(0), |
97 memory_pressure_level_(MemoryPressureLevel::kNone), | 97 memory_pressure_level_(MemoryPressureLevel::kNone), |
| 98 out_of_memory_callback_(nullptr), |
| 99 out_of_memory_callback_data_(nullptr), |
98 contexts_disposed_(0), | 100 contexts_disposed_(0), |
99 number_of_disposed_maps_(0), | 101 number_of_disposed_maps_(0), |
100 global_ic_age_(0), | 102 global_ic_age_(0), |
101 new_space_(nullptr), | 103 new_space_(nullptr), |
102 old_space_(NULL), | 104 old_space_(NULL), |
103 code_space_(NULL), | 105 code_space_(NULL), |
104 map_space_(NULL), | 106 map_space_(NULL), |
105 lo_space_(NULL), | 107 lo_space_(NULL), |
106 gc_state_(NOT_IN_GC), | 108 gc_state_(NOT_IN_GC), |
107 gc_post_processing_depth_(0), | 109 gc_post_processing_depth_(0), |
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
860 // not matter, so long as we do not specify NEW_SPACE, which would not | 862 // not matter, so long as we do not specify NEW_SPACE, which would not |
861 // cause a full GC. | 863 // cause a full GC. |
862 // Major GC would invoke weak handle callbacks on weakly reachable | 864 // Major GC would invoke weak handle callbacks on weakly reachable |
863 // handles, but won't collect weakly reachable objects until next | 865 // handles, but won't collect weakly reachable objects until next |
864 // major GC. Therefore if we collect aggressively and weak handle callback | 866 // major GC. Therefore if we collect aggressively and weak handle callback |
865 // has been invoked, we rerun major GC to release objects which become | 867 // has been invoked, we rerun major GC to release objects which become |
866 // garbage. | 868 // garbage. |
867 // Note: as weak callbacks can execute arbitrary code, we cannot | 869 // Note: as weak callbacks can execute arbitrary code, we cannot |
868 // hope that eventually there will be no weak callbacks invocations. | 870 // hope that eventually there will be no weak callbacks invocations. |
869 // Therefore stop recollecting after several attempts. | 871 // Therefore stop recollecting after several attempts. |
| 872 if (gc_reason == GarbageCollectionReason::kLastResort) { |
| 873 InvokeOutOfMemoryCallback(); |
| 874 } |
870 RuntimeCallTimerScope(isolate(), &RuntimeCallStats::GC_AllAvailableGarbage); | 875 RuntimeCallTimerScope(isolate(), &RuntimeCallStats::GC_AllAvailableGarbage); |
871 if (isolate()->concurrent_recompilation_enabled()) { | 876 if (isolate()->concurrent_recompilation_enabled()) { |
872 // The optimizing compiler may be unnecessarily holding on to memory. | 877 // The optimizing compiler may be unnecessarily holding on to memory. |
873 DisallowHeapAllocation no_recursive_gc; | 878 DisallowHeapAllocation no_recursive_gc; |
874 isolate()->optimizing_compile_dispatcher()->Flush(); | 879 isolate()->optimizing_compile_dispatcher()->Flush(); |
875 } | 880 } |
876 isolate()->ClearSerializerData(); | 881 isolate()->ClearSerializerData(); |
877 set_current_gc_flags(kMakeHeapIterableMask | kReduceMemoryFootprintMask); | 882 set_current_gc_flags(kMakeHeapIterableMask | kReduceMemoryFootprintMask); |
878 isolate_->compilation_cache()->Clear(); | 883 isolate_->compilation_cache()->Clear(); |
879 const int kMaxNumberOfAttempts = 7; | 884 const int kMaxNumberOfAttempts = 7; |
(...skipping 3647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4527 } else { | 4532 } else { |
4528 ExecutionAccess access(isolate()); | 4533 ExecutionAccess access(isolate()); |
4529 isolate()->stack_guard()->RequestGC(); | 4534 isolate()->stack_guard()->RequestGC(); |
4530 V8::GetCurrentPlatform()->CallOnForegroundThread( | 4535 V8::GetCurrentPlatform()->CallOnForegroundThread( |
4531 reinterpret_cast<v8::Isolate*>(isolate()), | 4536 reinterpret_cast<v8::Isolate*>(isolate()), |
4532 new MemoryPressureInterruptTask(this)); | 4537 new MemoryPressureInterruptTask(this)); |
4533 } | 4538 } |
4534 } | 4539 } |
4535 } | 4540 } |
4536 | 4541 |
| 4542 void Heap::SetOutOfMemoryCallback(v8::debug::OutOfMemoryCallback callback, |
| 4543 void* data) { |
| 4544 out_of_memory_callback_ = callback; |
| 4545 out_of_memory_callback_data_ = data; |
| 4546 } |
| 4547 |
| 4548 void Heap::InvokeOutOfMemoryCallback() { |
| 4549 if (out_of_memory_callback_) { |
| 4550 out_of_memory_callback_(out_of_memory_callback_data_); |
| 4551 } |
| 4552 } |
| 4553 |
4537 void Heap::CollectCodeStatistics() { | 4554 void Heap::CollectCodeStatistics() { |
4538 CodeStatistics::ResetCodeAndMetadataStatistics(isolate()); | 4555 CodeStatistics::ResetCodeAndMetadataStatistics(isolate()); |
4539 // We do not look for code in new space, or map space. If code | 4556 // We do not look for code in new space, or map space. If code |
4540 // somehow ends up in those spaces, we would miss it here. | 4557 // somehow ends up in those spaces, we would miss it here. |
4541 CodeStatistics::CollectCodeStatistics(code_space_, isolate()); | 4558 CodeStatistics::CollectCodeStatistics(code_space_, isolate()); |
4542 CodeStatistics::CollectCodeStatistics(old_space_, isolate()); | 4559 CodeStatistics::CollectCodeStatistics(old_space_, isolate()); |
4543 CodeStatistics::CollectCodeStatistics(lo_space_, isolate()); | 4560 CodeStatistics::CollectCodeStatistics(lo_space_, isolate()); |
4544 } | 4561 } |
4545 | 4562 |
4546 #ifdef DEBUG | 4563 #ifdef DEBUG |
(...skipping 1998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6545 } | 6562 } |
6546 | 6563 |
6547 | 6564 |
6548 // static | 6565 // static |
6549 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6566 int Heap::GetStaticVisitorIdForMap(Map* map) { |
6550 return StaticVisitorBase::GetVisitorId(map); | 6567 return StaticVisitorBase::GetVisitorId(map); |
6551 } | 6568 } |
6552 | 6569 |
6553 } // namespace internal | 6570 } // namespace internal |
6554 } // namespace v8 | 6571 } // namespace v8 |
OLD | NEW |