Chromium Code Reviews| Index: src/heap/array-buffer-tracker.cc |
| diff --git a/src/heap/array-buffer-tracker.cc b/src/heap/array-buffer-tracker.cc |
| index 62b848ef70c5339bf6bd3be7585b9290a4b022fb..fb5f513ebc156747565fb3bc4c15c02f2c97c1d6 100644 |
| --- a/src/heap/array-buffer-tracker.cc |
| +++ b/src/heap/array-buffer-tracker.cc |
| @@ -14,8 +14,9 @@ LocalArrayBufferTracker::~LocalArrayBufferTracker() { |
| } |
| template <LocalArrayBufferTracker::FreeMode free_mode> |
| -void LocalArrayBufferTracker::Free() { |
| +LocalArrayBufferTracker::ProcessResult LocalArrayBufferTracker::Free() { |
| size_t freed_memory = 0; |
| + size_t live_memory = 0; |
| for (TrackingData::iterator it = array_buffers_.begin(); |
| it != array_buffers_.end();) { |
| JSArrayBuffer* buffer = reinterpret_cast<JSArrayBuffer*>(it->first); |
| @@ -27,23 +28,25 @@ void LocalArrayBufferTracker::Free() { |
| freed_memory += len; |
| it = array_buffers_.erase(it); |
| } else { |
| + live_memory += it->second; |
| ++it; |
| } |
| } |
| - if (freed_memory > 0) { |
| - heap_->update_external_memory_concurrently_freed( |
| - static_cast<intptr_t>(freed_memory)); |
| - } |
| + return ProcessResult(freed_memory, live_memory, 0); |
| } |
| template <typename Callback> |
| -void LocalArrayBufferTracker::Process(Callback callback) { |
| +LocalArrayBufferTracker::ProcessResult LocalArrayBufferTracker::Process( |
| + Callback callback) { |
| JSArrayBuffer* new_buffer = nullptr; |
| size_t freed_memory = 0; |
| + size_t live_memory = 0; |
| + size_t promoted_memory = 0; |
| for (TrackingData::iterator it = array_buffers_.begin(); |
| it != array_buffers_.end();) { |
| const CallbackResult result = callback(it->first, &new_buffer); |
| if (result == kKeepEntry) { |
| + live_memory += it->second; |
| ++it; |
| } else if (result == kUpdateEntry) { |
| DCHECK_NOT_NULL(new_buffer); |
| @@ -58,7 +61,12 @@ void LocalArrayBufferTracker::Process(Callback callback) { |
| } |
| DCHECK_NOT_NULL(tracker); |
| tracker->Add(new_buffer, it->second); |
| - if (target_page->InNewSpace()) target_page->mutex()->Unlock(); |
| + if (target_page->InNewSpace()) { |
| + target_page->mutex()->Unlock(); |
| + live_memory += it->second; |
| + } else { |
| + promoted_memory += it->second; |
| + } |
| it = array_buffers_.erase(it); |
| } else if (result == kRemoveEntry) { |
| const size_t len = it->second; |
| @@ -70,10 +78,13 @@ void LocalArrayBufferTracker::Process(Callback callback) { |
| UNREACHABLE(); |
| } |
| } |
| - if (freed_memory > 0) { |
| - heap_->update_external_memory_concurrently_freed( |
| - static_cast<intptr_t>(freed_memory)); |
| - } |
| + return ProcessResult(freed_memory, live_memory, promoted_memory); |
| +} |
| + |
| +void ArrayBufferTracker::AccountForConcurrentlyFreedMemory() { |
| + heap_->update_external_memory( |
| + static_cast<int64_t>(concurrently_freed_.Value())); |
| + concurrently_freed_.SetValue(0); |
| } |
| void ArrayBufferTracker::FreeDeadInNewSpace(Heap* heap) { |
| @@ -83,7 +94,7 @@ void ArrayBufferTracker::FreeDeadInNewSpace(Heap* heap) { |
| bool empty = ProcessBuffers(page, kUpdateForwardedRemoveOthers); |
| CHECK(empty); |
| } |
| - heap->account_external_memory_concurrently_freed(); |
| + AccountForConcurrentlyFreedMemory(); |
| } |
| void ArrayBufferTracker::FreeDead(Page* page) { |
| @@ -91,7 +102,13 @@ void ArrayBufferTracker::FreeDead(Page* page) { |
| LocalArrayBufferTracker* tracker = page->local_tracker(); |
| if (tracker == nullptr) return; |
| DCHECK(!page->SweepingDone()); |
| - tracker->Free<LocalArrayBufferTracker::kFreeDead>(); |
| + LocalArrayBufferTracker::ProcessResult result = |
| + tracker->Free<LocalArrayBufferTracker::kFreeDead>(); |
| + if (page->InNewSpace()) { |
| + retained_from_new_space_.Increment(-static_cast<intptr_t>(result.freed)); |
| + } else { |
| + retained_from_old_space_.Increment(-static_cast<intptr_t>(result.freed)); |
| + } |
| if (tracker->IsEmpty()) { |
| page->ReleaseLocalTracker(); |
| } |
| @@ -100,7 +117,14 @@ void ArrayBufferTracker::FreeDead(Page* page) { |
| void ArrayBufferTracker::FreeAll(Page* page) { |
| LocalArrayBufferTracker* tracker = page->local_tracker(); |
| if (tracker == nullptr) return; |
| - tracker->Free<LocalArrayBufferTracker::kFreeAll>(); |
| + LocalArrayBufferTracker::ProcessResult result = |
| + tracker->Free<LocalArrayBufferTracker::kFreeAll>(); |
| + concurrently_freed_.Increment(static_cast<intptr_t>(result.freed)); |
| + if (page->InNewSpace()) { |
| + retained_from_new_space_.Increment(-static_cast<intptr_t>(result.freed)); |
| + } else { |
| + retained_from_old_space_.Increment(-static_cast<intptr_t>(result.freed)); |
| + } |
| if (tracker->IsEmpty()) { |
| page->ReleaseLocalTracker(); |
| } |
| @@ -111,7 +135,7 @@ bool ArrayBufferTracker::ProcessBuffers(Page* page, ProcessingMode mode) { |
| if (tracker == nullptr) return true; |
| DCHECK(page->SweepingDone()); |
| - tracker->Process( |
| + LocalArrayBufferTracker::ProcessResult result = tracker->Process( |
| [mode](JSArrayBuffer* old_buffer, JSArrayBuffer** new_buffer) { |
| MapWord map_word = old_buffer->map_word(); |
| if (map_word.IsForwardingAddress()) { |
| @@ -122,6 +146,15 @@ bool ArrayBufferTracker::ProcessBuffers(Page* page, ProcessingMode mode) { |
| ? LocalArrayBufferTracker::kKeepEntry |
| : LocalArrayBufferTracker::kRemoveEntry; |
| }); |
| + concurrently_freed_.Increment(static_cast<intptr_t>(result.freed)); |
| + if (page->InNewSpace()) { |
| + retained_from_new_space_.Increment( |
|
Michael Lippautz
2016/08/04 11:50:02
General: When (and if) https://codereview.chromium
Hannes Payer (out of office)
2016/08/05 12:14:13
Nice, please do that.
Michael Lippautz
2016/08/08 08:34:46
Done.
|
| + -(static_cast<intptr_t>(result.freed) + |
| + static_cast<intptr_t>(result.promoted))); |
| + } else { |
| + retained_from_old_space_.Increment(-static_cast<intptr_t>(result.freed)); |
| + } |
| + retained_from_old_space_.Increment(static_cast<intptr_t>(result.promoted)); |
| return tracker->IsEmpty(); |
| } |