Index: third_party/tcmalloc/page_heap.cc |
diff --git a/third_party/tcmalloc/page_heap.cc b/third_party/tcmalloc/page_heap.cc |
index f9ffd9d5dfefc0a15f19df8a7be9998857332c8d..fda189b60dde7f9b0ed08c43e78b42675183992d 100644 |
--- a/third_party/tcmalloc/page_heap.cc |
+++ b/third_party/tcmalloc/page_heap.cc |
@@ -157,6 +157,11 @@ void PageHeap::CommitSpan(Span* span) { |
); |
} |
+void PageHeap::DecommitSpan(Span* span) { |
+ TCMalloc_SystemRelease(reinterpret_cast<void*>(span->start << kPageShift), |
+ static_cast<size_t>(span->length << kPageShift)); |
+} |
+ |
Span* PageHeap::Carve(Span* span, Length n) { |
ASSERT(n > 0); |
ASSERT(span->location != Span::IN_USE); |
@@ -201,6 +206,7 @@ void PageHeap::Delete(Span* span) { |
ASSERT(GetDescriptor(span->start + span->length - 1) == span); |
span->sizeclass = 0; |
span->sample = 0; |
+ DecommitSpan(span); |
// Coalesce -- we guarantee that "p" != 0, so no bounds checking |
// necessary. We do not bother resetting the stale pagemap |
@@ -208,9 +214,8 @@ void PageHeap::Delete(Span* span) { |
// care about the pagemap entries for the boundaries. |
// |
// Note that the spans we merge into "span" may come out of |
- // a "returned" list. We move those into "normal" list |
- // as for 'immediate' operations we favour committing over |
- // decommitting (decommitting is performed offline). |
+ // a "normal" or "returned" list. We move those into the |
+ // "returned" list in order to favor decommitting over committing. |
const PageID p = span->start; |
const Length n = span->length; |
Span* prev = GetDescriptor(p-1); |
@@ -218,8 +223,8 @@ 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) { |
- CommitSpan(prev); |
+ if (prev->location == Span::ON_NORMAL_FREELIST) { |
+ DecommitSpan(prev); |
} |
DLL_Remove(prev); |
DeleteSpan(prev); |
@@ -233,8 +238,8 @@ 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) { |
- CommitSpan(next); |
+ if (next->location == Span::ON_NORMAL_FREELIST) { |
+ DecommitSpan(next); |
} |
DLL_Remove(next); |
DeleteSpan(next); |
@@ -244,7 +249,7 @@ void PageHeap::Delete(Span* span) { |
} |
Event(span, 'D', span->length); |
antonm
2009/10/01 11:59:27
why you don't decommit the span itself? is it by
|
- span->location = Span::ON_NORMAL_FREELIST; |
+ span->location = Span::ON_RETURNED_FREELIST; |
if (span->length < kMaxPages) { |
DLL_Prepend(&free_[span->length].normal, span); |
Mike Belshe
2009/10/01 02:39:48
I think this is a bug -
DLL_Prepend(&free_[span->
antonm
2009/10/01 11:59:27
That's definitely a bug and I would expect immedia
|
} else { |