| Index: third_party/tcmalloc/page_heap.cc
|
| diff --git a/third_party/tcmalloc/page_heap.cc b/third_party/tcmalloc/page_heap.cc
|
| index b46e7284fa616ce9d820d5c2bf3ea71c2273dc2f..f92cfc47afddeb83786933bb3ef4dae84f3c581b 100644
|
| --- a/third_party/tcmalloc/page_heap.cc
|
| +++ b/third_party/tcmalloc/page_heap.cc
|
| @@ -51,6 +51,7 @@ PageHeap::PageHeap()
|
| pagemap_cache_(0),
|
| free_pages_(0),
|
| system_bytes_(0),
|
| + committed_bytes_(0),
|
| scavenge_counter_(0),
|
| // Start scavenging at kMaxPages list
|
| scavenge_index_(kMaxPages-1) {
|
| @@ -153,11 +154,13 @@ Span* PageHeap::Split(Span* span, Length n) {
|
| void PageHeap::CommitSpan(Span* span) {
|
| TCMalloc_SystemCommit(reinterpret_cast<void*>(span->start << kPageShift),
|
| static_cast<size_t>(span->length << kPageShift));
|
| + committed_bytes_ += span->length << kPageShift;
|
| }
|
|
|
| void PageHeap::DecommitSpan(Span* span) {
|
| TCMalloc_SystemRelease(reinterpret_cast<void*>(span->start << kPageShift),
|
| static_cast<size_t>(span->length << kPageShift));
|
| + committed_bytes_ -= span->length << kPageShift;
|
| }
|
|
|
| Span* PageHeap::Carve(Span* span, Length n) {
|
| @@ -233,6 +236,14 @@ void PageHeap::Delete(Span* span) {
|
| // Merge preceding span into this span
|
| ASSERT(prev->start + prev->length == p);
|
| const Length len = prev->length;
|
| + if (prev->location == Span::ON_RETURNED_FREELIST) {
|
| + // We're about to put the merge span into the returned freelist and call
|
| + // DecommitSpan() on it, which will mark the entire span including this
|
| + // one as released and decrease committed_bytes_ by the size of the
|
| + // merged span. To make the math work out we temporarily increase the
|
| + // committed_bytes_ amount.
|
| + committed_bytes_ += prev->length << kPageShift;
|
| + }
|
| DLL_Remove(prev);
|
| DeleteSpan(prev);
|
| span->start -= len;
|
| @@ -245,6 +256,10 @@ void PageHeap::Delete(Span* span) {
|
| // Merge next span into this span
|
| ASSERT(next->start == p+n);
|
| const Length len = next->length;
|
| + if (next->location == Span::ON_RETURNED_FREELIST) {
|
| + // See the comment below 'if (prev->location ...' for explanation.
|
| + committed_bytes_ += next->length << kPageShift;
|
| + }
|
| DLL_Remove(next);
|
| DeleteSpan(next);
|
| span->length += len;
|
| @@ -299,8 +314,7 @@ void PageHeap::IncrementalScavenge(Length n) {
|
| Span* s = slist->normal.prev;
|
| ASSERT(s->location == Span::ON_NORMAL_FREELIST);
|
| DLL_Remove(s);
|
| - TCMalloc_SystemRelease(reinterpret_cast<void*>(s->start << kPageShift),
|
| - static_cast<size_t>(s->length << kPageShift));
|
| + DecommitSpan(s);
|
| s->location = Span::ON_RETURNED_FREELIST;
|
| DLL_Prepend(&slist->returned, s);
|
|
|
| @@ -430,6 +444,7 @@ bool PageHeap::GrowHeap(Length n) {
|
|
|
| uint64_t old_system_bytes = system_bytes_;
|
| system_bytes_ += (ask << kPageShift);
|
| + committed_bytes_ += (ask << kPageShift);
|
| const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
|
| ASSERT(p > 0);
|
|
|
| @@ -491,7 +506,7 @@ bool PageHeap::CheckList(Span* list, Length min_pages, Length max_pages,
|
| return true;
|
| }
|
|
|
| -static void ReleaseFreeList(Span* list, Span* returned) {
|
| +void PageHeap::ReleaseFreeList(Span* list, Span* returned) {
|
| // Walk backwards through list so that when we push these
|
| // spans on the "returned" list, we preserve the order.
|
| while (!DLL_IsEmpty(list)) {
|
| @@ -500,8 +515,7 @@ static void ReleaseFreeList(Span* list, Span* returned) {
|
| DLL_Prepend(returned, s);
|
| ASSERT(s->location == Span::ON_NORMAL_FREELIST);
|
| s->location = Span::ON_RETURNED_FREELIST;
|
| - TCMalloc_SystemRelease(reinterpret_cast<void*>(s->start << kPageShift),
|
| - static_cast<size_t>(s->length << kPageShift));
|
| + DecommitSpan(s);
|
| }
|
| }
|
|
|
|
|