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(); |
} |